A地点から出発 → M → K(直進) → L(ピンポン玉をつかむ) → K(右折) → J(一時停止の後、左折) → I(直進) → H(直進) → G(左折) → F → E → D(一時停止の後、直進) → C(直進) → B(一時停止) → シュート→ A地点に入る(ゴール)
交差点では1秒間停止し、丁字路では直角方向に進入する時のみ一時停止すること。
まずできる限り小型化した4輪の車を作った
上図のように車の前部に光センサーを取り付けた
上図のように4つの歯車をと2本のL字棒を使って、ピンポン玉を捕まえる
これを下図のように、車の後部に取り付けた
なお、光センサーとピンポン玉を捕まえる部分の両方を前部に用いると感知する光が低くなるため、前部と後部に分けた。
Fast Timerの時間設定を変えるため関数を定義した
int z;
sub follow_leftline() { SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<z){ if(SENSOR_2>44){OnFwd(OUT_A);OnRev(OUT_C);ClearTimer(0);}//白色の時 else if(SENSOR_2>42){OnFwd(OUT_A);ClearTimer(0);} //白灰の時 else if(SENSOR_2>38){OnFwd(OUT_AC);ClearTimer(0);} //灰の時 else if(SENSOR_2>36){OnFwd(OUT_C);ClearTimer(0);} //黒灰の時 else if(SENSOR_2>32){OnFwd(OUT_C);OnRev(OUT_A);} //黒の時 } }
sub follow_rightline() { SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<z){ if(SENSOR_2>44){OnFwd(OUT_C);OnRev(OUT_A);ClearTimer(0);}//白色の時 else if(SENSOR_2>42){OnFwd(OUT_C);ClearTimer(0);} //白灰の時 else if(SENSOR_2>38){OnFwd(OUT_AC);ClearTimer(0);} //灰の時 else if(SENSOR_2>36){OnFwd(OUT_A);ClearTimer(0);} //黒灰の時 else if(SENSOR_2>32){OnFwd(OUT_A);OnRev(OUT_C);} //黒の時 } }
sub back_follow_left() { SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<z){ if(SENSOR_2>44){OnFwd(OUT_C);OnRev(OUT_A);ClearTimer(0);}//白色の時 else if(SENSOR_2>42){OnRev(OUT_A);ClearTimer(0);} //白灰の時 else if(SENSOR_2>38){OnRev(OUT_AC);ClearTimer(0);} //灰の時 else if(SENSOR_2>36){OnRev(OUT_C);ClearTimer(0);} //黒灰の時 else if(SENSOR_2>32){OnFwd(OUT_A);OnRev(OUT_C);} //黒色の時 } }
K〜G間で交差点を認識してから、交差点をわたり、そして車体を線に近づけるように以下のサブルーチンを定義した
sub migikaiten() { OnFwd(OUT_AC); //交差点を渡る Wait(20); Off(OUT_AC); OnFwd(OUT_A); //右回転する OnRev(OUT_C); Wait(40); Off(OUT_AC); OnFwd(OUT_AC); //線に近づける Wait(20); Off(OUT_AC); }
なお、交差点では黒部分の時間が長くなるため、上記の右側または左側トレースのサブルーチンが終了する。終了した場所に交差点があると判断し、
OnFwd(OUT_AC); Wait(20); Off(OUT_AC);
で交差点の黒い部分を渡ることにした
task main() { SetSensor(SENSOR_2, SENSOR_LIGHT);
z=35; follow_rightline(); //M〜K間の最初の左カーブ Off(OUT_AC); //次の右急カーブで停止 Wait(100); OnFwd(OUT_AC); //黒線を渡る Wait(30); Off(OUT_AC); z=20; follow_leftline(); //右急カーブ Off(OUT_AC); //K地点で停止 Wait(100);
ピンポン玉は車体の後部で捕まえるため、ここで半回転する
OnFwd(OUT_AC); //K地点を渡る Wait(20); Off(OUT_AC); OnFwd(OUT_A);OnRev(OUT_C); //半回転 Wait(160); Off(OUT_AC); OnRev(OUT_AC); //車体の調整 Wait(30); Off(OUT_AC); Wait(100); z=20; back_follow_left(); //半回転したため、左トレースながら後進する Off(OUT_AC); //k地点で停止 OnRev(OUT_AC); //KからLに進む Wait(30); Off(OUT_AC); OnRev(OUT_B); //ピンポン玉を捕まえる Wait(10); Off(OUT_B);
OnFwd(OUT_A); //車体の調整 OnRev(OUT_C); Wait(30); Off(OUT_AC); z=20; //L〜K間を右側トレース follow_rightline(); Off(OUT_AC); //K地点で停止 Wait(100);
OnFwd(OUT_AC); //K地点を渡る Wait(20); Off(OUT_AC); z=20; follow_leftline(); //K〜J間を左側トレース Off(OUT_AC); //J地点で停止 Wait(100);
migikaiten(); //車体の調整 z=20; follow_leftline(); //J〜I間を左側トレース Off(OUT_AC); //I地点で停止 Wait(100);
migikaiten(); //車体の調整 z=20; follow_leftline(); //I〜H間を左側トレース Off(OUT_AC); //H地点で停止 Wait(100);
migikaiten(); //車体の調整 z=20; follow_leftline(); //H〜G間を左側トレース Off(OUT_AC); //G地点で停止 Wait(100);
OnFwd(OUT_C);OnRev(OUT_A); //車体の調整 Wait(20); Off(OUT_AC); z=20; follow_leftline(); //G〜F間を左側トレース Off(OUT_AC); //F地点で停止 Wait(100);
OnFwd(OUT_AC); //車体の調整 Wait(30); Off(OUT_AC); OnFwd(OUT_C);OnRev(OUT_A); //F〜Eの方に車体を向ける Wait(55); Off(OUT_AC); z=20; follow_leftline(); //F〜E間を左側トレース Off(OUT_AC); //E地点で停止
OnFwd(OUT_AC); //E地点の線を渡る Wait(30); Off(OUT_AC); z=20; follow_rightline(); //E〜D間を右側トレース Off(OUT_AC); //D地点で停止
OnFwd(OUT_AC); //D地点の線を渡る Wait(30); Off(OUT_AC); z=20; follow_rightline(); //D〜C〜B間を右側トレース Off(OUT_AC); //B地点で停止 OnRev(OUT_B); //シュート Wait(10); Off(OUT_B); }
ピンポン玉を捕まえるところまではうまくできた。J〜G間が毎回動きが異なり、うまく円の部分を1周できなかった。この問題を改善するには、円上の交差点の渡り方とトレースの仕方を改善する必要がある。できなかったことがかなり悔しさの残る結果となった。