課題1のページ より要約すると、コースを走るロボットを作る、ということである。
今回は、E地点右折コースを選んだ。
機体は取扱説明書に記載されているものを使用した。
タイヤに直結したモーター2つで前進後退右折左折をし、前面に取り付けた光センサーで左右に身を振りながらのライントレースをする。
この機体を使用する利点は、圧倒的に機体を組む時間や機体を考える時間を短縮し、その分プログラムに時間を大きく割ける、ということだ。
#define SPEED_H 35 //スピード定義 大 #define SPEED_L 15 //スピード定義 小 #define turn_right1 OnFwd(OUT_A,SPEED_H);OnRev(OUT_C,SPEED_H); //大きく右折 #define turn_right2 OnFwd(OUT_A,SPEED_H);OnRev(OUT_C,SPEED_L); //小さく右折 #define goFwd OnFwd(OUT_AC,SPEED_H); //直進 #define turn_left1 OnRev(OUT_A,SPEED_H);OnFwd(OUT_C,SPEED_H); //大きく左折 #define turn_left2 OnRev(OUT_A,SPEED_L);OnFwd(OUT_C,SPEED_H); //小さく左折 #define TimerReset t0=CurrentTick(); //タイマーリセット #define tMAX 140
使用した定義である。
sub line_trace() { SetSensorLight(S2); long t0=CurrentTick(); while(CurrentTick()-t0<tMAX){ if (SENSOR_2 <= 30){ turn_left1; }else if(SENSOR_2 <= 40){ turn_left2 TimerReset; }else if(SENSOR_2 <= 43){ goFwd; TimerReset; }else if(SENSOR_2 <= 53){ turn_right2; TimerReset; }else { turn_right1; TimerReset; } } }
使用したライントレースのプログラムである。しきい値は慎重に検討し、概ね問題なく作動した。
sub stop_and_beep1() { Off(OUT_AC); PlaySound(SOUND_UP); Wait(1000); }
SOUND_UPをして一秒間停止するサブルーチンである。
sub stop_and_beep2() { Off(OUT_AC); PlaySound(SOUND_DOWN); Wait(1000); }
SOUND_DOWNをして一秒間停止するサブルーチンである。
sub curve_left() { Off(OUT_AC); Wait(1000); OnFwd(OUT_A,SPEED_H); OnRev(OUT_C,SPEED_H); Wait(1000); Off(OUT_AC); Wait(1000); }
sub curve_right() { Off(OUT_AC); Wait(1000); OnFwd(OUT_C,SPEED_H); OnRev(OUT_A,SPEED_H); Wait(2000); Off(OUT_AC); Wait(1000); }
一秒間停止した後、左折・右折をして一秒間停止するサブルーチンである。
課題には使用しなかった。なぜこれらのプログラムを書いたのかはわからない。
sub ignore() { Off(OUT_AC); Wait(1000); OnFwd(OUT_AC,SPEED_H); Wait(400); Off(OUT_AC); Wait(100); }
交差点に差し掛かった際、線を一部無視して少しだけ直進するプログラムである。
十字路などを渡る際に使用した。
task main() { SetSensorLight(S2); long t1=CurrentTick(); int m=0; //交差点カウンタ設定 while(m <= 13){ line_trace (); m = m+1; //交差点カウント+1 if (m == 13){ //交差点カウンタの値が13の際… stop_and_beep2 (); Off(OUT_AC); }else if(m == 12){ //交差点カウンタの値が12の際… stop_and_beep1 (); }else if(m == 11){ //交差点カウンタの値が11の際… stop_and_beep1 (); }else if(m == 10){ stop_and_beep1 (); ignore (); }else if(m == 9){ stop_and_beep2 (); }else if(m == 8){ stop_and_beep1 (); }else if(m == 7){ stop_and_beep1 (); }else if(m == 6){ stop_and_beep2 (); ignore (); }else if(m == 5){ stop_and_beep2 (); ignore (); }else if(m == 4){ stop_and_beep1 (); }else if(m == 3){ stop_and_beep1 (); ignore (); }else if(m == 2){ stop_and_beep2 (); turn_right1;Wait(430);Off(OUT_AC);Wait(100); }else if(m == 1){ stop_and_beep1 (); turn_left1;Wait(250);Off(OUT_AC);Wait(100); } } }
これがメインのタスクである。
今回は、whileで延々とライントレースを繰り返し、ライントレースのサブルーチンから外れた時を「交差点検知」とし、交差点カウンタを用いて検知した交差点の数に応じてifで条件付けをした。つまり、交差点感知1回ごとに対応する動作をそれぞれ予め決めておくことでtask_mainのプログラムをできるだけ簡単に組めるようにした。
ゴールすることはできなかった。
上のtask_mainを見てわかるように、まず大まかなプログラムを書き、細かい微調整を定義やサブルーチンの後に付け足していけばよいと思っていたが、やはりプログラムのみで動作を制御しきるのは無理があった。
具体的に言えば、E右折後にP点でS点に行かずQ点に向かわせる事ができなかった。SOUND_DOWN後に少し左折させることで交差点を無視させようとしたが、線にセンサーがなかなか反応せずプログラムの数値だけでは解決できなかった。
おそらくもう少しタイヤ幅を狭くして小回りを利かせるか、センサーの位置を機体の中心に近づければ成功できたかもしれない。
ゴールすることができず、非常に残念である。
基本的なプログラムの骨組みは当初の構想通りに組むことができ、出来もいいものであったと思うが、やはりプログラムで細かい動作を制御するのは難しかった。
次回の課題は今回の反省を踏まえて成功させたい。