自律的に動くロボットの制御
研究の目的
何かを達成するための考え方、つまりアルゴリズムの構築をロボットを通して練習する。
基本動作を制御する
port_a_two(0,0,0,1); //右タイヤ前向きに回転 左方向転換
port_a_two(0,0,1,0); //左タイヤ前向きに回転 右方向転換
port_a_two(0,1,0,0); //右タイヤ後ろ向きに回転
port_a_two(1,0,0,0); //左タイヤ後ろ向きに回転
ロボットを動かす
基本的な文
port_a_two(0,0,1,1);
delay_ms(1000); //1000ミリ秒間(1秒間)前進
ロボットを動かす
基本動作を用いて、スタートから丸イスを一周してゴールへとロボットを動かす。
main() { set_tris_a (0x00); set_tris_b (0x00); port_a = TWO(0,0,1,1); //1 【スタート】直進 delay_ms(4000); port_a = TWO(0,0,1,0); //2 右方向転換 delay_ms(1300) port_a = TWO(0,0,1,1); //3 直進 delay_ms(5000); port_a = TWO(0,0,0,1); //4 左方向転換 delay_ms(900); port_a = TWO(0,0,1,1); //5 直進 delay_ms(5000); port_a = TWO(0,0,0,1); //6 左方向転換 delay_ms(1000); port_a = TWO(0,1,0,1); //7 直進 delay_ms(7000); port_a = TWO(0,0,0,1); //8 左方向転換 delay_ms(800); port_a = TWO(0,0,1,1); //9 直進 delay_ms(8000); port_a = TWO(0,0,1,0); //10 右方向転換 delay_ms(1000); port_a = TWO(0,0,1,1); //11 直進【ゴール】 delay_ms(10000); }
円軌道
直進→方向転換→直進→方向転換→...で丸イスを周ってゴールしたが、より速く丸いイスを周るには"円軌道"を描かせるのが一番速い。 これまで「2000ms直進」や「600ms右方向転換」といったように、ミリ秒(10のマイナス3乗)単位でプログラムを組んでいた。しかし「700us直進」といったようにマイクロ秒(10のマイナス6乗)単位でプログラムを組むこともできる。 そもそも円を描くということはどういうことか。左右のタイヤの単位時間当たりの回転数を変えれば円軌道を描く。しかし、そのような命令文はない。直進と方向転換だけでどのようにして円を描かせるか。 500ms直進と200ms方向転換を繰り返すとする。近くで見れば円軌道にはほど遠いが、真上10mから見たらどうであろう。いびつではあるが円軌道を描いているように見えるのではなかろうか。 100ms直進100ms方向転換を繰り返すとする。いびつではあるが近くでも円軌道に見える。 700us直進50us方向転換を繰り返すとする。きれいな円軌道を描く。つまり、直進、方向転換を短い周期で繰り返すことに円軌道を描かせることができる。 我々が円を描いているように見えても、ロボットは直進、方向転換を繰り返しているに過ぎなかったのである。 余談であるが、円の定義は丸い線ではなく、ある点から等距離にある点の集合なのである。
for(;;){ port_a = TWO(0,0,1,1); delay_us(700); //円軌道を描かせるプログラム port_a = TWO(0,0,0,1); delay_us(50); }
時間指定、forループ、無限ループ、赤外線で丸イス一周
port_a = TWO(0,0,1,1); delay_ms(1000); //1000ms直進 port_a = TWO(0,0,1,0); delay_ms(700); //700ms右方向転換
このように直進、方向転換は時間指定することができる。
port_a = TWO(0,0,1,1); delay_us(700); //700us直進 port_a = TWO(0,0,0,1); delay_us(50); //50us方向転換
円軌道は直進、方向転換を"無限ループ"させるため時間指定することはできない。
ちょうど1周するようforループで直進、方向転換を回数指定するのも手だが、赤外線を用いることで簡単にプログラムを組むことができた。
main() { set_tris_a(0x10); set_tris_b(0x00); port_a = TWO(0,0,1,1); //1 直進 delay_ms(1000); port_a = TWO(0,0,1,0); //2 右方向転換 delay_ms(700); for(;;){ port_a = TWO(0,0,1,1); delay_us(700); port_a = TWO(0,0,0,1); delay_us(50); //3 円軌道(無限ループ) if(input(PIN_A4)==0) break;//4 赤外線を受信したら無限ループから出る } port_a = TWO(0,0,1,0); delay_ms(700); port_a = TWO(0,0,1,1);//5 直進 delay_ms(1000); }
考察
「スタート→丸イスを一周→ゴール」とロボットを動かすのが課題であったが、図1のように直進、左右方向転換の繰り返しは何秒間それらの行動をさせるかだけを調べればよかった。しかし図2のように円軌道を描かせる際に、人間が見たら円軌道でもロボットからしたら直進と右(左)方向転換を短い周期で繰り返しているに過ぎなかった点で、ロボット目線で考えれば意外とプログラをすんなり組むことができる。