目次 #contents *はじめに [#rb33a45c] &ref(コース.png); 今回の課題は、上の図でA地点→P直進→Q直進→Q直進→R左折→B地点の経路を黒い線にそって動くロボットの作成である。 ただし、なるべく速く正確に動くロボットになるように工夫して、交差点では1秒間停止しなければならない。 *ロボット本体の説明 [#l6dce9dd] &ref(ロボット2.jpg); &ref(ロボット1.jpg); 最初は光センサーをロボットの前の中央に取り付けていたが、交差点Qのあとのカーブで小回りがきかなくなることに気づいたので、左前に取り付けて小回りがきくように工夫を施した。 *プログラムの説明 [#mfe7303f] -定義 今回は、サブルーチンを使ったため定義は前回に比べると短くなった。 #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; //右折したらカウンタをリセット 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; //右折したらカウンタをリセット 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; //右折したらカウンタをリセット 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); SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); while (FastTimer(0) < t) { if (SENSOR_2 < THRESHOLD) { turn_left; } else { turn_right; } Wait(STEP); } 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); } *結果 [#tcdffea6] 2回目の交差点Qを直進するところまでは上手くいった。しかし、その後の急カーブで何度やっても右旋回のプログラムがうまく作動しなかった。何がダメなのか、考察したが、わからなかった。 *感想 [#fda80d83] 今回の課題は、とても難しく感じた。 まず、交差点で止まるプログラムの作成の仕方がよくわからず、友達に相談したところ、無事解決できた。友達に感謝! コースのライントレースでは、カーブで交差点と誤認してしまい、停止してしまい困った。そこでインライン関数を使った。電池の消費具合で、関数tの秒数を変えるのがとても面倒だった。 急カーブが上手く行かなかった原因がわからず、悔しかった。