今回は光センサーを用いて、マジックで書いた線をたどりながら動くロボットを作成した。
コースは下の図であり、交差点で数えてA→直進→直進→右折→右折→左折→左折→Bの順番で走らせた。
ロボット本体は左右の車輪が別々に動いてくれればよいのでドライブベースをそのまま用いた。また光センサーの数値の変化が少なくするためにできるだけ床に近づけた。
今回の課題は交差点で曲がるということと黒線をトレースするというものなので交差点の数、時間などの変数を用いた。
しかし黒線のトレースは比較的うまくいったが交差点の判断に苦労した。
最初は黒線の右側だけを動くプログラムだったので円の内側を通るルートになりそこを交差点と判断してしまったのだ。
そこでサブルーチンとして黒線の右側、左側を動くプログラムをそれぞれサブルーチンとして用いた。
#define TMAX 23 //交差点と識別するための時間 #define oto PlaySound(SOUND_CLICK);Off(OUT_AC);Wait(100); //交差点で音を鳴らす int t=0; //交差点を通った回数
黒線の右側を動く
sub susume_1() { SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0) < TMAX){ //TMAXだけ黒線の中にいるときまで行う if(SENSOR_2 > 54){ OnFwd(OUT_C);OnRev(OUT_A);ClearTimer(0); //真っ白なとき左旋回 } else if(SENSOR_2 > 51){ OnFwd(OUT_C);Off(OUT_A);ClearTimer(0); //少し白いとき左回転 } else if(SENSOR_2 > 44){ OnFwd(OUT_AC);ClearTimer(0); //黒と白の間のとき直進 } else if(SENSOR_2 > 41){ OnFwd(OUT_A);Off(OUT_C);ClearTimer(0); //少し黒いとき右回転 } else{ OnFwd(OUT_A);OnRev(OUT_C); //真っ黒なとき右旋回 } } t=t+1; }
黒線の左側を動く
sub susume_2() { SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0) < TMAX){ if(SENSOR_2 > 54){ OnFwd(OUT_A);OnRev(OUT_C);ClearTimer(0); //真っ白なとき右旋回 } else if(SENSOR_2 > 51){ OnFwd(OUT_A);Off(OUT_C);ClearTimer(0); //少し白いとき右回転 } else if(SENSOR_2 > 44){ OnFwd(OUT_AC);ClearTimer(0); //黒と白の間のとき直進 } else if(SENSOR_2 > 41){ OnFwd(OUT_C);Off(OUT_A);ClearTimer(0); //少し黒いとき左回転 } else{ OnFwd(OUT_C);OnRev(OUT_A); //真っ黒なとき左旋回 } } t=t+1; }
task main() { /* 黒線の左側を進む */ while(t <= 9){ if(t <= 2){ susume_2(); oto;OnFwd(OUT_AC); Wait(30);Off(OUT_AC);Wait(100); //スタート地点、1個目の交差点は直進する } else if(t <= 3){ OnFwd(OUT_A);Off(OUT_C);Wait(30);OnFwd(OUT_AC);Wait(20); /*2個目は直進するが黒線の右側を進むので位置を変える。*/ /* 黒線の右側を進む */ susume_1(); } else if(t <= 4){ oto; OnFwd(OUT_A);OnRev(OUT_C);Wait(80); //3個目は右折する OnFwd(OUT_A);Off(OUT_C);Wait(40); OnFwd(OUT_AC);Wait(20); Off(OUT_AC);Wait(100); susume_1(); } else if(t <= 5){ oto; OnFwd(OUT_A);OnRev(OUT_C);Wait(30); //4個目も右折する Off(OUT_AC);Wait(30); OnFwd(OUT_AC);Wait(30); Off(OUT_AC);Wait(100); /* 黒線の左側を進む */ susume_2(); } else{ oto; OnFwd(OUT_C);OnRev(OUT_A);Wait(30); //これ以降は左へ旋回する Off(OUT_AC);Wait(100); susume_2(); } } OnFwd(OUT_AC);Wait(50);Off(OUT_AC); }
このプログラムを何回か試してみたが誤差が出てしまい最後までたどり着けないことが多かった。しかし右と左の両方を走ることにより大回りをするのでカーブを交差点と判断することは少なくなった。