目次
今回の課題は、上の図でA地点→P直進→Q直進→Q直進→R左折→B地点の経路を黒い線にそって動くロボットの作成である。
ただし、なるべく速く正確に動くロボットになるように工夫して、交差点では1秒間停止しなければならない。
最初は光センサーをロボットの前の中央に取り付けていたが、交差点Qのあとのカーブで小回りがきかなくなることに気づいたので、左前に取り付けて小回りがきくように工夫を施した。
今回は、サブルーチンを使ったため定義は前回に比べると短くなった。
#define THRESHOLD 42 //しきい値 #define go_Fwd OnFwd(OUT_AC); Wait(5); //前進 #define senkai_left OnFwd(OUT_C); OnRev(OUT_A); Wait(50); //左旋回 #define senkai_right OnFwd(OUT_A); OnRev(OUT_C); //右旋回 #define turn_left OnFwd(OUT_C); Off(OUT_A); //左折 #define turn_right OnFwd(OUT_A); Off(OUT_C); //右折 #define STEP 1 //1回の判定で進む時間
以下のサブルーチンにはライントレースも含まれている。
sub crossing_Fwd() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; //左折する回数を数える変数 while (n<10) { //左折する回数が10回未満だったら永遠に繰り返し if (SENSOR_2 < THRESHOLD) { turn_left; n++; //左折したらカウンタを+1 } else { turn_right; n=0; //右折したらカウンタをリセット } Wait(STEP); } Off(OUT_AC); PlaySound(SOUND_CLICK); Wait(100); go_Fwd; }
交差点で直進するサブルーチンである。交差点Pで1回、交差点Qで2回使った。
sub crossing_left() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; //左折する回数を数える変数 while (n<10) { //左折する回数が10回未満だったら永遠に繰り返し if (SENSOR_2 < THRESHOLD) { turn_left; n++; //左折したらカウンタを+1 } else { turn_right; n=0; //右折したらカウンタをリセット } Wait(STEP); } Off(OUT_AC); PlaySound(SOUND_CLICK); Wait(100); senkai_left; }
交差点で左折するサブルーチンである。交差点Rで1回使った。
sub crossing_stop() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; //左折する回数を数える変数 while (n<10) { //左折する回数が10回未満だったら永遠に繰り返し if (SENSOR_2 < THRESHOLD) { turn_left; n++; //左折したらカウンタを+1 } else { turn_right; n=0; //右折したらカウンタをリセット } Wait(STEP); } Off(OUT_AC); PlaySound(SOUND_CLICK); Wait(100); }
交差点で1秒間停止するサブルーチンである。すべての交差点で使った。
sub line_follow_kyukabu() { SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); while (FastTimer(0) < 800) { if (SENSOR_2 < THRESHOLD) { turn_left; } else { senkai_right; } Wait(STEP); } Off(OUT_AC); }
2回目の交差点Qから交差点Rへ進む途中の急カーブをトレースするサブルーチンである。
交差点以外のライントレースをサブルーチンでやろうとすると、途中のカーブで交差点と誤認してしまい、カーブの途中で止まってしまうことに気づいたので、インライン関数を使った。
void line_follow(int t) { SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); while (FastTimer(0) < t) { if (SENSOR_2 < THRESHOLD) { turn_left; } else { turn_right; } Wait(STEP); } Off(OUT_AC); }
時間tより短い時間は単にライントレースするインライン関数である。
task main() { line_follow(1000); //10秒間ライントレース crossing_stop(); //交差点で1秒間停止 crossing_Fwd(); //交差点Pを直進 line_follow(1400); //14秒間ライントレース crossing_stop(); crossing_Fwd(); //交差点Qを直進 line_follow(1300); //13秒間ライントレース crossing_stop(); crossing_Fwd(); //交差点Qを直進 line_follow_kyukabu(); //急カーブをライントレース line_follow(400); //4秒間ライントレース crossing_stop(); crossing_left(); //交差点Rを左折 crossing_stop(); go_Fwd; //直進 Off(OUT_AC); }
2回目の交差点Qを直進するところまでは上手くいった。しかし、その後の急カーブで何度やっても右旋回のプログラムがうまく作動しなかった。何がダメなのか、考察したが、わからなかった。
今回の課題は、とても難しく感じた。
まず、交差点で止まるプログラムの作成の仕方がよくわからず、友達に相談したところ、無事解決できた。友達に感謝!
コースのライントレースでは、カーブで交差点と誤認してしまい、停止してしまい困った。そこでインライン関数を使った。電池の消費具合で、関数tの秒数を変えるのがとても面倒だった。
急カーブが上手く行かなかった原因がわからず、悔しかった。