はじめに
歩かせます。取り敢えず何も考えずに、モーションだけで歩かせます。センサーも使いません。
二足歩行ロボットの当初の目標である動歩行の実装となります。
歩かせるのは、Day4のステップを歩行用のポーズを用意するだけでも可能ですが、動歩行がこのロボットの目標なので特別に扱います。
(下書きの説明 ここから)
Day5をちょっとプログラム修正しているので、Day5が無くても歩かせられるので、先にDay6の歩くほうを公開します。
あと、モーションは少し調整するかもしれません。
(下書きの説明 ここまで)
それではソースコードの変更分を見ていきましょう。
// 定義
const int8_t walkPosition[][MAX_SERVO_NUM + 1] =
{
{5, 0, 0, 0, 0, 0, 0, 0, 0}, // 立つ 1
{15, -10, 0,-10, 10, 10,-18, 18, 0}, // 最初の一歩、左足に重心
{5, -30, 30,-10, 10, 22,-20, 20, 0}, // 右足上げる
{5, 15, 40,-20, 0, 15,-25, 25, 0}, // 右足前へ
{5, 10, 25,-20, 0, 5,-20, 20, 0}, // 右足着地
{5, 10, 25,-20, 0, -5, 0, 0, 0},
{5, -10, 10,-10, 0,-10, 18,-18, 0}, // 右足に重心
{5, -10, 10,-30, 30,-22, 20,-20, 0}, // 左足上げる
{5, -20, 0, 15, 40,-15, 25,-25, 0}, // 左足足前へ
{5, -20, 0, 10, 25, -5, 20,-20, 0}, // 左足着地
{5, -20, 0, 10, 25, 5, 0, 0, 0},
{5, -10, 0,-10, 10, 10,-18, 18, 0},
{15, -10, 0,-10, 0, 0, 0, 0, 0}, // 最後の一歩、右
{5, 0, 0, 0, 0, 0, 0, 0, 0} // 立つ
}
// 初期設定
// なし
// メインループ
// Walk Motion Demo
if ( command == 'W' || command == 'w' ) // 'W'is a Walk Motion Demo Command "W steps"
{
Serial.print(command);
Serial.print(',');
int steps = Serial.parseInt();
Serial.print(steps);
Serial.print('\n');
for (int i = 0; i < MAX_SERVO_NUM; i++)
{
servo[i].attach(i + 2);
}
// 最初の一歩
for (int i = 0; i < MAX_SERVO_NUM; i++)
{
servo[i].write(90+servoOffset[i] + (walkPosition[0][i + 1] * servoDir[i]));
}
delay(walkPosition[0][0] * 25); // delay time value x10 (msec)
for (int i = 0; i < MAX_SERVO_NUM; i++)
{
servo[i].write(90+servoOffset[i] + (walkPosition[1][i + 1] * servoDir[i]));
}
delay(walkPosition[1][0] * 25); // delay time value x10 (msec)
// 歩く
for (int k = 0; k < steps; k++)
{
for (int i = 2; i < 12; i++)
{
Serial.print(walkPosition[i][0]);
for (int j = 0; j < MAX_SERVO_NUM; j++)
{
servo[j].write(90+servoOffset[j] + (walkPosition[i][j + 1] * servoDir[j]));
Serial.print(',');
Serial.print(walkPosition[i][j + 1]);
}
delay(walkPosition[i][0] * 50); // delay time value x10 (msec)
Serial.print('\n');
}
}
// 最後の一歩
for (int i = 0; i < MAX_SERVO_NUM; i++)
{
servo[i].write(90+servoOffset[i] + (walkPosition[12][i + 1] * servoDir[i]));
}
delay(walkPosition[12][0] * 50); // delay time value x10 (msec)
for (int i = 0; i < MAX_SERVO_NUM; i++)
{
servo[i].write(90+servoOffset[i] + (walkPosition[13][i + 1] * servoDir[i]));
}
delay(walkPosition[13][0] * 50); // delay time value x50 (msec)
// detach
for (int i = 0; i < MAX_SERVO_NUM; i++)
{
servo[i].detach();
}
} // Walk Motion Demo End.
解説
最初の一歩と、最後の一歩がミソになります。
・最初の一歩が行進の時の”前へ進め!1,2”の号令で歩き出す最初の一歩目の動作となります。
・最後の一歩が行進の時の”全体止まれ!1,2”の号令で止まる時の最後の一歩の動作となります。
配列の2から12の間を繰り返して歩く動作を作っています。
配列の0番目の要素は、各ポーズの保持時間を変えられるようにしています。単位は50msecです。
Wコマンドの使い方
W,歩数
指定された歩数を歩きます。
調整方法
この機体は丈夫に作ってあるので、机の上で少々転んだぐらいでは壊れないと思いますが、保護と足裏の摩擦を一定にするためにカッティングマットの上で歩かせて下さい。
最初は転んだり、机から転げ落ちると思うので、二、三歩からはじめて下さい。
最初はジタバタしていると思いますが、Aコマンド等を使って初期位置やポーズの調整して行きます。
機体のバランスを変えたり、配列の速度やポーズ、歩数を変えてバランスを良くしていきます。
今はふらふらしていても、ジャイロセンサーを使えば補正できる様になるので、それはまたの機会に。
おわりに
とりあえず歩かせるところまでプログラミングできたでしょうか。
ポーズやモーションを使って、二足歩行ロボットの難しい所や、意外と簡単な所を遊んで感じてくれればと思います。
これでSW編その1と言うかシーズン2は終わりです。
次回予告
次のロボットの更新予定は、3Dプリンタを使った一部部品の制作です。
一部の加工が難しい部品だけを3Dモデルに置き換えます。モデルは公開するので、ソースコードも同梱できると思います。
3Dプリンタが無くてもこのロボットが簡単に作れるように、3Dプリンタサービスから部品を購入できるようにしようとも思っています。
SW編その2(シーズン3)は、センサ3Dプリンタを使った機体制作を挟んで、GW頃の予定です。
YouTubeのチャンネル登録しておくか、thingiversの中野島ロボットのFollowしておくとアップした時に情報が届きます。
(3Dプリンタとか違うのも届くとおもいますが・・・)
おしまい。
購入品情報