目次
次の経路を黒い線にそって動くロボットを作成した。 •C地点からA地点へ (Q交差点では直進、P三叉路では右折)
そして、途中(P地点とQ地点の間)においたボール(ピンポン玉)を目的地まで運んで、ゴールに入れる。その途中、三叉路および交差点では2秒間停止する。
可能であれば、A,B,Cのそれぞれにエリアに入る三叉路付近からボールをシュートする。
ロボットの移動に関して、左右両方の車輪にモーターを使用することで、旋回をできるようにした。また、そのうちの片方のモーターだけを動かすことで前に移動しながらロボットの向きを少しずつ変えることができるようにした。
光センサーに関して、ロボットの先端に付けると、ロボットが曲がったとき、センサーの位置が大きく変わってしまい、ロボットはラインの上にあったとしても、センサーがラインの上を外れてしまい、滑らかな動きをさせることができなかったため、光センサーはできる限り車体の中央にくるように作った。
ピンポン玉をつかむためのアームに関して、初めはブロックを組み合わせて作ったコの字型の枠をロボットの先端に取り付けてみたが、それだけではロボットの移動による力がピンポン玉に伝わり、枠の外へ転がっていってしまったため、モーターに棒を取り付けて、それでピンポン玉を押さえることで枠の外へ転がっていかないようにした。
ピンポン玉を押さえている様子
#define THRESHOLD 42 // 閾値 #define set_power_L SetPower(OUT_AC,3); // パワーを下げる #define go_forward OnFwd(OUT_AC); // 直進 #define turn_left0 set_power_L;OnFwd(OUT_C);OnRev(OUT_A); // 左旋回 #define turn_right0 set_power_L;OnFwd(OUT_A);OnRev(OUT_C); // 右旋回 #define turn_left1 set_power_L;OnFwd(OUT_C);Off(OUT_A); // 左折 #define turn_right1 set_power_L;OnFwd(OUT_A);Off(OUT_C); // 右折 #define STEP 1 // 1回の判断で動作させる時間 #define nMAX 6 // 通常のカーブとして許容できる繰り返しの最大値 #define cross_line go_forward;Wait(15); // 交差点通過 #define hold set_power_L;OnFwd(OUT_B);Wait(15);Off(OUT_B); // ボールをつかむ #define shoot(t) set_power_L;OnRev(OUT_B);Wait(15);Off(OUT_B);OnFwd(OUT_AC);Wait(t);Off(OUT_AC); // ボールをシュートする
sub trace_line() { SetSensor(SENSOR_2,SENSOR_LIGHT); int nOnline=0; // 続けて黒になった回数 (カウンタ) ClearTimer(0); // 0番目のタイマをリセット /* 10秒間、通常のライントレースをする */ while (FastTimer(0) <= 1000) { /* 黒を続けてnMAX回繰り返さない間、通常のライントレースをする */ while (nOnline < nMAX) { if (SENSOR_2 < THRESHOLD-5) { // ラインの中央付近のとき turn_left0; // 左旋回 nOnline++; // カウンタを増やす } else { if (SENSOR_2 < THRESHOLD-2) { // ラインの左端の左側のとき turn_left1; // 左折 } else if (SENSOR_2 < THRESHOLD +2) { // ラインの左端のとき go_forward; // 直進 } else if (SENSOR_2 < THRESHOLD +5) { // ラインの左端の右側のとき turn_right1; // 右折 } else { // ラインから外れたとき turn_right0; // 右旋回 } nOnline=0; // カウンタをリセット } Wait(STEP); } PlaySound(SOUND_CLICK); // 音を鳴らす Off(OUT_AC);Wait(200); // 2秒間停止 cross_line; // 交差点通過 nOnline=0; // カウンタをリセット } }
task main() { trace_line(); // ライントレース Off(OUT_AC);Wait(100); // 1秒停止 hold; // ボールをつかむ trace_line(); // ライントレース Off(OUT_AC);Wait(100); // 1秒停止 shoot(100); // シュート }
シュートをするためにつかんでいるピンポン玉をはなしながら、ロボット全体を前に移動させることでその勢いをピンポン玉につたえて、前に転がすという方法をとったが、ロボットの移動するスピードが遅かったため、あまりシュートらしくないものになってしまった。ロボット全体によって力を与えるのではなく、アームをうまく使うことによって力を与えられれば、もっと勢いのあるシュートを打つことができたのではないかと思う。
定義やサブルーチンを使い、メインタスクを簡単に表すことができたことから、メインよりもそれの一部であるサブの方を丁寧に作っていくことが完成への近道であると気付いた。 ライントレースに関して、閾値を5つに分けて、旋回だけでなく、片方の車輪のみを動かして曲がる動作も取り入れた。また、旋回と曲がる動作のときはモーターのパワーを小さくし、緩やかな動きになるようにした。以上の2つの点によって、ほとんど角張った動きのないライントレースができたと思う。