目次 はじめに †今回のミッションは、RISの光センサーを使い、決まったコースをライントレースするものだ。自分のコースは、 C地点 → S左折 → P左折 → Q直進 → Q直進 → R右折 → P左折 → A地点 をライントレースするものだった。 ロボットの説明 †今回のミッションでは、小回りを利くように3輪にし、タイヤから光センサーまでの距離を短くし、誤作動を少なくしようと、ドライブベースを初期の状態より少しだけ改造した。 ↑前輪と後輪 ↑後輪 ↑光センサー ↑上から見た ロボットのプログラム・動作の説明 †プログラム †#define THRESHOLD 42 #define gofw OnFwd(OUT_AC);Wait(5); #define turn_left Off(OUT_A); OnFwd(OUT_C); #define senkai_left OnFwd(OUT_C);OnRev(OUT_A);Wait(50); #define turn_right OnFwd(OUT_A); Off(OUT_C); #define senkai_right OnFwd(OUT_A);OnRev(OUT_C);Wait(80); #define STEP 1 void line_follow(int t) { SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); while (Timer(0)<t) { if (SENSOR_2 < THRESHOLD){ turn_left; } else { turn_right; } Wait(STEP); }Off(OUT_AC); } sub crossing_fwd() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; while(n<15){ if (SENSOR_2 < THRESHOLD){ turn_left;n++; } else { turn_right;n=0; } Wait(STEP); }Off(OUT_AC);Wait(100);gofw; } sub crossing_stop() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; while(n<15){ if (SENSOR_2 < THRESHOLD){ turn_left;n++; } else { turn_right;n=0; } Wait(STEP); }Off(OUT_AC);Wait(100); } sub crossing_right() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; while(n<15){ if (SENSOR_2 < THRESHOLD){ turn_left;n++; } else { turn_right;n=0; } Wait(STEP); }Off(OUT_AC);Wait(100);senkai_right;OnFwd(OUT_AC);Wait(60); } sub crossing_left() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; while(n<15){ if (SENSOR_2 < THRESHOLD){ turn_left;n++; } else { turn_right;n=0; } Wait(STEP); }Off(OUT_AC);Wait(100);senkai_left; } task main() { crossing_left(); crossing_left(); line_follow(50); crossing_fwd(); line_follow(90); crossing_fwd(); line_follow(105); crossing_right(); crossing_left(); line_follow(100); crossing_stop(); senkai_right;Wait(5);OnFwd(OUT_AC);Wait(80);Off(OUT_AC); } 動作 †ライントレース †今回は、ラインの左を沿うプログラムにした。光センサーが閾値42より小さい時、すなわちライン上の時左折、閾値42以上の時、すなわちライン外の時右折する。これを元にサブルーチンを作った。 if (SENSOR_2 < 42){ turn_left; } else { turn_right; } Wait(STEP); 定義 †#define THRESHOLD 42 //閾値 #define gofw OnFwd(OUT_AC);Wait(5); //0.05秒直進 #define turn_left Off(OUT_A); OnFwd(OUT_C); //左折 #define senkai_left OnFwd(OUT_C);OnRev(OUT_A);Wait(50); //0.5秒旋回左折 #define turn_right OnFwd(OUT_A); Off(OUT_C); //右折 #define senkai_right OnFwd(OUT_A);OnRev(OUT_C);Wait(80); //0.8秒旋回右折 #define STEP 1 //1回の判断で動く時間0.01秒 ラインの左を沿うプログラムなので旋回左折より旋回右折のほうが時間を長くした。 インライン関数 †void line_follow(int t) { SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); while (Timer(0)<t) { if (SENSOR_2 < THRESHOLD){ turn_left; } else { turn_right; } Wait(STEP); }Off(OUT_AC); } t秒間ライントレースするプログラム。急カーブ(P→Q、Q→Q、Q→R、P→A)で、交差点と誤認して止まらないようにインライン関数を使った。 交差点判別方法 †左に曲がるときに、カウンターを+1回、右に曲がるときに、カウンターをリセットする。今回は、カウンターが15回カウントするまで、ライントレースをする。すなわち、1回の判断で動く時間が0.01秒なので、0.01×15=0.15秒ライン上にいたとき停止するようになっている。以下のサブルーチンはこれをもとにし作り、交差点で1秒停止後のプログラムのみ変えてある。 int n=0; while(n<15){ if (SENSOR_2 < THRESHOLD){ turn_left;n++; //カウンターを+1 } else { turn_right;n=0; //カウンターをリセット } Wait(STEP); }Off(OUT_AC);Wait(100); サブルーチン †sub crossing_fwd() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; while(n<15){ if (SENSOR_2 < THRESHOLD){ turn_left;n++; } else { turn_right;n=0; } Wait(STEP); }Off(OUT_AC);Wait(100);gofw; } 交差点で1秒停止した後、交差点を直進するプログラム。交差点Qで2回使った。 sub crossing_stop() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; while(n<15){ if (SENSOR_2 < THRESHOLD){ turn_left;n++; } else { turn_right;n=0; } Wait(STEP); }Off(OUT_AC);Wait(100); } 交差点で1秒停止するプログラム。ゴール地点Aで使った。 sub crossing_right() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; while(n<15){ if (SENSOR_2 < THRESHOLD){ turn_left;n++; } else { turn_right;n=0; } Wait(STEP); }Off(OUT_AC);Wait(100);senkai_right;OnFwd(OUT_AC);Wait(60); } 交差点で1秒停止した後、交差点を右折するプログラム。交差点Rで使った。 sub crossing_left() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; while(n<15){ if (SENSOR_2 < THRESHOLD){ turn_left;n++; } else { turn_right;n=0; } Wait(STEP); }Off(OUT_AC);Wait(100);senkai_left; } 交差点で1秒停止した後、交差点を左折するプログラム。交差点Sで1回、Pで2回使った。 タスク †task main() { crossing_left(); //C→S 交差点Sで左折 crossing_left(); //S→P 交差点Pで左折 line_follow(50); //P→Qの手前 5秒間ライントレース crossing_fwd(); //Qの手前→Q 交差点Qで直進 line_follow(90); //Q→Qの手前 9秒間ライントレース crossing_fwd(); //Qの手前→Q 交差点Qで直進 line_follow(105); //Q→Rの手前 10.5秒間ライントレース crossing_right(); //Rの手前→R 交差点Rで右折 crossing_left(); //R→P 交差点Pで左折 line_follow(100); //P→Aの手前 10秒間ライントレース crossing_stop(); //Aの手前→A 交差点Aで停止 senkai_right;Wait(5);OnFwd(OUT_AC);Wait(80);Off(OUT_AC); //ゴールに入る } 結果 †1分11秒で完走した。 反省・感想 †前回の課題よりもとても難しく苦労したが、できた時の喜びは大きかった。今回は試験運転をしたため、本番当日は微調整のみで済んだ。今回の課題のプログラムは、人によって異なっていて、オリジナリティーが出たと思う。今回の課題で出た要素を次回の課題で活かせるようにしたい。 |