Sample Programs

多サーボモータを使う(6脚歩行ロボットの場合)

サーボモータを沢山使う多関節ロボットの作り方の参考になればと思い6脚歩行ロボットを制作しました。

上から見たところ(このポーズをサーボ角度0度の基本姿勢としてくみ上げました。)

横から見たところ

各関節2個使用し6脚でサーボ12個にてくみ上げました。
関節を沢山動かすプログラムのコツは、ポーズをいくつか制作しその間の動きを「補完する」ことにあります。プログラム中ではその補完をp2Pose()という関数で行っています。
此の場合は7種類のポーズを制作し、その間の繋ぎ方で前後左右旋回を実現しています。

p2Pose(分割数、サンプリングタイム、ポーズ1、ポーズ2)
分割数:補完の荒さ、小さいと動きが荒くなります。大きすぎるとその分、動きが遅くなります。
サンプリングタイム:指令値を出す間隔、荒いとぎこちなくなります。※20msec以下にしてもあまり意味はありません。
ポーズ1:現在の姿勢
ポーズ2:次の姿勢

各ポーズとサーボの接続方法は以下の図

トライポッド歩行のプログラムとその様子です。

サンプルプログラム(ポーズのデータが入っているのでちょっと長いです。)
必ずベースには14サーボ制御の14サーボ基本サンプルプログラムを使用してください。

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include "NolibM.h"

/* ニュートラル状態設定 */
#define neuServoPos1  60.0  // 右前先
#define  neuServoPos2  0  // 右前胴
#define  neuServoPos3  60.0  // 右中先
#define  neuServoPos4  0  // 右中胴
#define  neuServoPos5  60.0  // 右後先
#define  neuServoPos6  0  // 右後胴

#define  neuServoPos8  -60.0  // 左前先
#define  neuServoPos9  0  // 左前胴
#define  neuServoPos10  -60.0  // 左中先
#define  neuServoPos11  0  // 左中胴
#define  neuServoPos12  -60.0  // 左後先
#define  neuServoPos13  0  // 左後胴

/* モーションパラメータ */
#define LEGUP 45.0    //脚の上下幅 deg
#define LEGFB 25.0    //脚の前後幅 deg

static int svid[]={1,2,3,4,5,6,8,9,10,11,12,13}; //使用サーボのIDを定義

/* ポスチャーデータ列 */
static float motion[][12]={
    {// posture ID0 Neutral
    neuServoPos1,
    neuServoPos2,
    neuServoPos3,
    neuServoPos4,
    neuServoPos5,
    neuServoPos6,

    neuServoPos8,
    neuServoPos9,
    neuServoPos10,
    neuServoPos11,
    neuServoPos12,
    neuServoPos13
  },//posture ID1  WALKING1
  {
    neuServoPos1,
    neuServoPos2 +LEGFB,
    neuServoPos3,
    neuServoPos4 -LEGFB,
    neuServoPos5,
    neuServoPos6 +LEGFB,

    neuServoPos8,
    neuServoPos9 +LEGFB,
    neuServoPos10,
    neuServoPos11 -LEGFB,
    neuServoPos12,
    neuServoPos13 +LEGFB
  }
,//posture ID2 WALKING2
  {
    neuServoPos1,
    neuServoPos2 -LEGFB,
    neuServoPos3,
    neuServoPos4 +LEGFB,
    neuServoPos5,
    neuServoPos6 -LEGFB,

    neuServoPos8,
    neuServoPos9 -LEGFB,
    neuServoPos10,
    neuServoPos11 +LEGFB,
    neuServoPos12,
    neuServoPos13 -LEGFB
  }
,// posture ID3 WALKING-TRANSITION 1
  {
  	neuServoPos1,
    neuServoPos2,
    neuServoPos3 -LEGUP,
    neuServoPos4,
    neuServoPos5,
    neuServoPos6,

    neuServoPos8 +LEGUP,
    neuServoPos9,
    neuServoPos10,
    neuServoPos11,
    neuServoPos12 +LEGUP,
    neuServoPos13
  },// posture ID4 WALKING-TRANSITION 1
  {
    neuServoPos1 - LEGUP,
    neuServoPos2,
    neuServoPos3,
    neuServoPos4,
    neuServoPos5 - LEGUP,
    neuServoPos6,

    neuServoPos8,
    neuServoPos9,
    neuServoPos10 + LEGUP,
    neuServoPos11,
    neuServoPos12,
    neuServoPos13
  }
,//posture ID5  TURN 1
  {
    neuServoPos1,
    neuServoPos2 -LEGFB,
    neuServoPos3,
    neuServoPos4 +LEGFB,
    neuServoPos5,
    neuServoPos6 -LEGFB,

    neuServoPos8,
    neuServoPos9 +LEGFB,
    neuServoPos10,
    neuServoPos11 -LEGFB,
    neuServoPos12,
    neuServoPos13 +LEGFB
  }
,//posture ID6 TURN 2
  {
    neuServoPos1,
    neuServoPos2 +LEGFB,
    neuServoPos3,
    neuServoPos4 -LEGFB,
    neuServoPos5,
    neuServoPos6 +LEGFB,

    neuServoPos8,
    neuServoPos9 -LEGFB,
    neuServoPos10,
    neuServoPos11 +LEGFB,
    neuServoPos12,
    neuServoPos13 -LEGFB
  }
};

// These are defined by the linker (see F2808.cmd)
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;

volatile struct EPWM_REGS *ePWM[] =
 				  { &EPwm1Regs,			//intentional: (ePWM[0] not used)
				  	&EPwm1Regs,
					&EPwm2Regs,
					&EPwm3Regs,
					&EPwm4Regs,
					&EPwm5Regs,
					&EPwm6Regs,
					&EPwm7Regs,
				  };

/**********************************/
/******    setPose        **********/
/**********************************/

int setPose(int pose_id)
{
int ii;
for(ii=0;ii<12;ii++)
{
servo(motion[pose_id][ii],svid[ii]);
}

return 0;
}

/**********************************/
/****     p2Pose            *******/
/**********************************/

void p2Pose(int div,int sampleT, int pose1, int pose2)
{
int diff[12],i,j;

for(i=0;i<12;i++)
{
diff[i]=(motion[pose2][i]-motion[pose1][i]);
diff[i]=diff[i]/div;
servo(motion[pose1][i],svid[i]);
}

for(j=1;j<=div;j++)
{
  for(i=0;i<12;i++)
    {
    servo(motion[pose1][i]+j*diff[i],svid[i]);
    }

wait(sampleT);
}
}

}

void main(void)
{
	int ii;

	initNolibM(); //初期化

  	//Set Neutral Position
	 for(ii=0;ii<12;ii++)
 	{
 		servo(motion[0][ii],svid[ii]);
 		GpioDataRegs.GPBTOGGLE.bit.GPIO39=1;
 	}

	while(1)
	{
		while(sw1(OFF));  //スイッチが入るまで待つ

	 	for(ii=0;ii<6;ii++)//動き出しまで3秒待つ
 		{
 	 		GpioDataRegs.GPBTOGGLE.bit.GPIO39=1;  //CPUのLEDが点滅
  			wait(500);
		}

   	    p2Pose(20,20,0,3);

	//start acceleration
		for(ii=20;ii>4;ii-=10)
		{
			p2Pose(ii,20,3,1);
   			p2Pose(ii,20,1,4);
   	 		p2Pose(ii,20,4,2);
    		p2Pose(ii,20,2,3);
    	}

	//high speed walking
		for(ii=0;ii<8;ii++)
		{
    		p2Pose(5,20,3,1);
    		p2Pose(5,20,1,4);
   	 	p2Pose(5,20,4,2);
    		p2Pose(5,20,2,3);
 		}

 		for(ii=5;ii<21;ii+=10)
 		{
			p2Pose(ii,20,3,1);
   			p2Pose(ii,20,1,4);
   			p2Pose(ii,20,4,2);
    		p2Pose(ii,20,2,3);
		}

// turn left

		for(ii=0;ii<3;ii++)
  		{
    		p2Pose(15,20,3,5);
    		p2Pose(15,20,5,4);
    		p2Pose(15,20,4,6);
    		p2Pose(15,20,6,3);
 		}
    	p2Pose(20,20,3,0);
    }  //while end
}

ちなみにロボットの足のサーボモータはKONDO KRS788HVを使用しています。
また足の棒はIKEAにてうっています「鍋ぶたオーガナイザー
コレ

ステンレスでとても奇麗だったので脚にしました。しかも安いんですよ(499円)ステンレス加工するとかなり高価になるので迷わずゲットしました。14本入っているので二体は作れますね。

Follow Me!
  • Twitter