今までのおさらいをすると、I2C通信を使って8個のサーボモーターを動かし、クリーピングゲイトという、はって歩くような様子(歩容)でロボットを歩かせました。また、赤外線距離センサモジュールを使って、ある距離まで近づくと信号を出せることも確認しました。
今回は、ロボットが前進中、前方に壁を感知した場合の回避の方法として、進行方向を90°変える動作をやってみます。早速、行きます。Go!
1.旋回の動画
まずは、参考にさせてもらった、カッコいいスパイダーロボットの歩きを見てみましょう。
こういうのが作れるとカッコイイですよね。
2.考え方
動きを参考にさせて頂き、このなかの旋回の部分を実際に自分でもやってみました。
考え方とすると、以下のようになります。
①まず、脚を45°(Xの文字のように)に配置する。
②胴体の部分を45°ひねる。
③脚を1本ずつ、45°回していく。
④ひと通り回したあとは、胴体の部分を90°ひねる。
⑤向きたい方向まで繰り返す。
(すべりがあるためか一回で45°の旋回はできなかった)
3.プログラムスケッチ
最初の#include から void loop(){ ところは、以前のブログ 四足歩行ロボットを作りたい!~Arduino・I2C通信 で複数サーボを動かすdo~ を参照してください。
//(目標)90°旋回する
#include<Wire.h>
#include<Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN 102 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 492 // this is the 'maximum' pulse length count (out of 4096)
void setup(){
pwm.begin();
pwm.setPWMFreq(50); // Analog servos run at ~50 Hz updates
servo_write(0,90);
}
void servo_write(int n, int ang){ // 動かすサーボと角度を引数に持つ
ang = map(ang, 0, 180, SERVOMIN, SERVOMAX); // 角度(0~180)をPWMのパルス幅(102~492)へ変換
pwm.setPWM(n, 0, ang);
}
int m = 0;
//旋回させる初期動作 旋回STEP1
void loop(){
//⓪-----<<脚を45°の位置に配置>>-----
// 0番ピンのサーボに角度45度を指示
servo_write(0,45);
// 1番ピンのサーボに角度135度を指示
servo_write(1,135);
// 2番ピンのサーボに角度135度を指示
servo_write(2,135);
// 3番ピンのサーボに角度45度を指示
servo_write(3,45);
delay(1000);
//3回、回します。
while ( m < 3 ){
m = m + 1;
//⓪’-----<<準備動作 :45°から胴体だけ旋回>>-----
// 0番ピンのサーボに角度10度を指示
servo_write(0,10);
// 1番ピンのサーボに角度90度を指示
servo_write(1,90);
// 2番ピンのサーボに角度90度を指示
servo_write(2,90);
// 3番ピンのサーボに角度10度を指示
servo_write(3,10);
delay(1000);
//①-----<<旋回のための STEP1>>-----
//5番ピンの脚(サーボ)を少し持ち上げて、1番ピンのサーボに角度90度→170度を指示、
servo_write(5,70);
delay(500);
servo_write(1,170);
delay(1000);
servo_write(5,90);
delay(1000);
//②-----<<旋回 STEP2>>-----
//同様に7番ピンの脚を少し持ち上げて、3番ピンのサーボに角度10度→90度を指示、
servo_write(7,110);
delay(500);
servo_write(3,90);
delay(1000);
servo_write(7,90);
delay(1000);
//③-----<<旋回 STEP3>>-----
servo_write(6,70);
delay(500);
servo_write(2,170);
delay(1000);
servo_write(6,90);
delay(1000);
//④-----<<旋回 STEP4>>-----
servo_write(4,110);
delay(500);
servo_write(0,90);
delay(1000);
servo_write(4,90);
delay(1000);
}
// whileまで戻って、胴体を回転させます。
}
今回は、3回動作を繰り返すので、whileを使ってみました。
実際の動作は、whileから一番下までを3回繰り返して、Whileの条件が成立すると、void loop()まで飛んでWhileの手前まで実行、終了となります。
また、Arduinoは通常、void loop()の部分を何度も繰り返し動作するように設計されていますが、上記のように、whileなどで終了した場合、一度最後まで動作が完了した場合の再起動は、USBケーブルを抜き差しすると、最初から動作させることが出来ます。
なるへそ~。では、実際の動作です。上記のスパイダーロボほどのクオリティはありませんが、ひとまず、こんな感じかな?というところです。サーボモーターや回転ブラケットのグレードも違いますし・・(←言い訳 (^^;))
とは言うものの、胴体の旋回は圧巻ですね。(ポジティブシンキングぅ!)
画面の下側にある四角いものは、障害物のイメージです。最終的にはセンサーを搭載して、ある距離まで近づいたら、旋回動作をさせる予定です。
4.別の方法
障害物を回避する動作方法としては、そのまま、真横に移動する方法もありますよね。これは、脚の動作軌跡が縦と横で同じになるような寸法で設計しているので、可能になります。
こちらも、動作の概要を書いてみます。前進が横に進むような動きに変わっただけです。(シンプルです)
#include <Wire.h> #include <Adafruit_PWMServoDriver.h> Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); #define SERVOMIN 102 // this is the 'minimum' pulse length count (out of 4096) #define SERVOMAX 492 // this is the 'maximum' pulse length count (out of 4096) void setup(){ pwm.begin(); pwm.setPWMFreq(50); // Analog servos run at 50 Hz updates servo_write(0,90); } void servo_write(int n, int ang){ // 動かすサーボと角度を引数に持つ ang = map(ang, 0, 180, SERVOMIN, SERVOMAX); // 角度(0~180)をPWMのパルス幅(102~492)へ変換 pwm.setPWM(n, 0, ang); } void loop(){ //⓪-----<< 基本姿勢 >>----- // 0番ピンのサーボに角度90度を指示 servo_write(0,90); // 1番ピンのサーボに角度180度を指示 servo_write(1,135); // 2番ピンのサーボに角度135度を指示 servo_write(2,90); // 3番ピンのサーボに角度45度を指示 servo_write(3,45); delay(1000); //①-----<< 準備動作 1>>----- // 5番ピンのサーボを少し持ち上げ、1番ピンのサーボに角度10度を指示、 servo_write(5,70); delay(500); servo_write(1,10); delay(1000); servo_write(5,90); delay(1000); //②-----<< 準備動作 2>>----- // 4番ピンのサーボを少し持ち上げ、0番ピンのサーボに角度10度を指示、 servo_write(4,110); delay(500); servo_write(0,10); delay(1000); servo_write(4,90); delay(1000); //③-----<< 移動、前進 >>----- // 0番ピンのサーボに角度45度を指示 servo_write(0,45); // 1番ピンのサーボに角度135度を指示 servo_write(1,135); // 2番ピンのサーボに角度90度を指示 servo_write(2,90); // 3番ピンのサーボに角度10度を指示 servo_write(3,10); delay(1000); //④-----<< 準備動作 1>>----- servo_write(7,110); delay(500); servo_write(3,90); delay(1000); servo_write(7,90); delay(1000); //⑤-----<< 準備動作 2>>----- servo_write(6,70); delay(500); servo_write(2,170); delay(1000); servo_write(6,90); delay(1000); //基本姿勢へ戻る }
5.最後に
これで、方向転換や違う方向にも移動できることが確認できました。あとは、センサーを付ければ、衝突を回避できます。今回は、ちょっと簡単ですが、これで終わります。次回はセンサーで距離を測定しながら、障害物を回避しながら、歩いてみたいと思います。つづく。
今回使った、部品のリストです。安価な類似品もありますが、最初は、正規品がおすすめです。
品名 | 型名(製造元) | 個数 | |
1 | マイコン基板 | Arduino Uno Rev3 ATmega328 マイ コンボード A000066 | 1 |
2 | モータードライバー | PCA9685搭載16チャネル PW M/サーボ ドライバー ←個数注意 | 1 |
3 | サーボモーター | デジタル・マイクロサーボ SG90←個数注意 | 8 |
4 | 接続電線他 | 接続電線、USBケーブル、バルサ材、針金など | 1式 |