目次
・初め、交差点などはタイマーを使って攻略しようとしていたが、そのときのロボットのコンディションにより時間がバラバラだったのであきらめ、交差点の数を数える方法に変更した。
・ロータリーを進んでいくとき、なぜか知らないが交差点の数を数え間違える時があるので、黒線を踏んで軌道を修正するとき、細かくではなく大きく曲がるようにした。そうすることでうまくいった。
・「黒線を踏んだ」と認識させるとき、初めは{(SENSOR_1<XX)}などと片方についてしか定義していなかったが、そうすると、たまに間違えて反応したりしてしまったので、{*1} と、左右のセンサーについてそれぞれ定義することによりこれを克服した。
・音を出すことにより、今どのプログラムが実行されているかを確認できるようにした。
・曲がるときも、2種類の曲がり方をその都度適したところでそれぞれ使用した。
・センサーどうしの感覚を広くとることによって、カーブなどで曲がった時にお互いが黒線の上に乗るのを防いだ。
・ロボットについては色々と考えたがやはり無難なシンプル四輪車にした。
・プログラムに時間を割くために、基本のマシンをほとんどそのままで使用した。
・初め、タイマーで交差点を無視させるプログラムを組んだが、条件に左右されやすかったため、forを使った繰り返しで交差点をカウントさせた。これは後でロータリーでも効果を発揮した。
・回転、前進の関数を定義したことで、プログラムの修正が楽になった。
・近道を無視して進む際にのみ、タイマーを使用した。ライントレースではない直進の時間を多めにとって、多少の誤差があっても問題が無いようにした。
・左右のタイヤをお互いに逆回転させることで、マシンの回転半径が小さくなり、直角でも正確に曲がれるようになった。
#define GO OnFwd(OUT_A+OUT_C); //直進 #define TR OnFwd(OUT_A);Off(OUT_C); //右に大きく曲がる #define TL OnFwd(OUT_C);Off(OUT_A); //左に大きく曲がる #define TRX OnFwd(OUT_A);OnRev(OUT_C); //右に曲がる #define TLX OnFwd(OUT_C);OnRev(OUT_A); //左に曲がる #define XX 40 //閾値の値 #define STOP Off(OUT_A+OUT_C); //止まる #define TIME 50 //タイマーなどの時間 task main() {SetSensor(SENSOR_1, SENSOR_LIGHT);SetSensor(SENSOR_3, SENSOR_LIGHT); int a = 0; //交差点の数を数える while( a <= 2 ) //初めは二回数える { if((SENSOR_1>XX) && (SENSOR_3>XX)) //どっちのセンサーも黒線に乗っていないときは直進 {GO;} if((SENSOR_1<XX) && (SENSOR_3>XX)) //もし左が黒線に乗ったら左に曲がる {TLX;} if((SENSOR_3<XX) && (SENSOR_1>XX)) //もし右が黒線に乗ったら右に曲がる {TRX;} if((SENSOR_1<XX) && (SENSOR_3<XX)) //両方のセンサーが黒線に乗ったら直進 {STOP;GO;Wait(TIME);a = a+1;} }PlaySound(SOUND_UP); //動作終了確認音 TRX;until((SENSOR_1<XX) && (SENSOR_3>XX)); //ここからロータリー開始 PlaySound(SOUND_DOWN); int t = 0; //一回めの交差点は無視する while( t <= 0 ) { if((SENSOR_1<XX) && (SENSOR_3>XX)) //細かく曲がるのではなく少し大きく曲がる {TLX;Wait(20);} if((SENSOR_1<XX) && (SENSOR_3<XX)) {TLX;Wait(20);} if((SENSOR_1>XX) && (SENSOR_3<XX)) {TLX;Wait(20);t = t+1;} if((SENSOR_1>XX) && (SENSOR_3>XX)) {GO;} }PlaySound(SOUND_UP); //ロータリー終了 int u = 0; while( u<=1 ) {TRX;if(SENSOR_1<XX){u=u+1;};}PlaySound(SOUND_DOWN); //軌道が戻るまで右旋回
ClearTimer(0); //近道に近づくまでは今まで通り進む while( Timer(0) <= 22 ) { if((SENSOR_1<XX) && (SENSOR_3>XX)) {TLX;} if((SENSOR_3<XX) && (SENSOR_1>XX)) {TRX;} if((SENSOR_1>XX) && (SENSOR_3>XX)) {GO;} }PlaySound(SOUND_UP); TRX;Wait(80);GO;until((SENSOR_1<XX) || (SENSOR_3<XX));PlaySound(SOUND_DOWN); //近道に入って通り抜ける TRX;until((SENSOR_1<XX) && (SENSOR_3>XX));PlaySound(SOUND_UP); //近道終了 int c = 0; //交差点の数を数えロータリーに入る。それまでは今まで通り進む。 while( c <= 1 ) { if((SENSOR_1>XX) && (SENSOR_3>XX)) {GO;} if((SENSOR_1<XX) && (SENSOR_3>XX)) {TLX;} if((SENSOR_3<XX) && (SENSOR_1>XX)) {TRX;} if((SENSOR_1<XX) && (SENSOR_3<XX)) {STOP;GO;Wait(TIME);c = c+1;} }PlaySound(SOUND_DOWN);PlaySound(SOUND_DOWN); TRX;until((SENSOR_1<XX) && (SENSOR_3>XX)); //ロータリー開始 int z = 0; while( z <= 1 ) {if(SENSOR_1<XX){u=u+1;} if((SENSOR_1<XX) && (SENSOR_3>XX)) {TLX;Wait(20);} if((SENSOR_1<XX) && (SENSOR_3<XX)) {TLX;Wait(20);} if((SENSOR_1>XX) && (SENSOR_3<XX)) {TLX;Wait(20);z= z+1;} if((SENSOR_1>XX) && (SENSOR_3>XX)) {GO;} }PlaySound(SOUND_UP); //ロータリー終了 int n = 0; while( n<=0 ) {TRX;if(SENSOR_1<XX){n=n+1;}}PlaySound(SOUND_DOWN); //軌道が乗るまで右旋回する int y = 0; //交差点を無視しながら線に沿って今まで通り進む while( y <= 1 ) { if((SENSOR_1>XX) && (SENSOR_3>XX)) {GO;} if((SENSOR_1<XX) && (SENSOR_3>XX)) {TLX;} if((SENSOR_3<XX) && (SENSOR_1>XX)) {TRX;} if((SENSOR_1<XX) && (SENSOR_3<XX)) {STOP;GO;Wait(TIME);y = y+1;} //ゴールしたら止まる } }
#define Go OnFwd(OUT_A);OnFwd(OUT_C); //前に進む #define Left OnFwd(OUT_C);OnRev(OUT_A); //左に回転 #define Right OnFwd(OUT_A);OnRev(OUT_C); //右に回転 void Advance(int t1) //前にt1秒進む { OnFwd(OUT_A+OUT_C); Wait(t1); Off(OUT_A+OUT_C); } void Turn_right(int t2) //右にt2秒回転 { OnFwd(OUT_A); Wait(t2); OnRev(OUT_C); } void Turn_Left(int t3) //左にt3秒回転 { OnFwd(OUT_C); Wait(t3); OnRev(OUT_A); }
task main() {SetSensor(SENSOR_1,SENSOR_LIGHT);SetSensor(SENSOR_3,SENSOR_LIGHT); int i=0; //交差点の数をカウント 急カーブ開始 while(i<=2) //交差点を二回通過させる { if ((SENSOR_1 > 40 && SENSOR_3 > 40)) {Go;} //両方のセンサーが黒線上にないとき、前進 if ((SENSOR_1 < 40 && SENSOR_3 > 40)) {Left;} //左のセンサーのみが黒線上にあるとき、左方向に修正 if ((SENSOR_1 > 40 && SENSOR_3 < 40)) {Right;} //右のセンサーのみが黒線上にあるとき、右方向に修正 if ((SENSOR_1 < 40 && SENSOR_3 < 40)) {i=i+1;Advance(20);Off(OUT_A+OUT_C);} } //両方のセンサーが黒線上にあるとき、交差点としてカウント OnRev(OUT_A+OUT_C); // Wait(30); Off(OUT_A+OUT_C); //急カーブ終了 Turn_right(80); //ロータリー開始 Off(OUT_A+OUT_C); int j=0; //右センサーが黒線を通過する回数をカウント while(j<=1) //黒線上を一回通過させる {if ((SENSOR_1 > 40 && SENSOR_3 > 40)) {Go;} //両方のセンサーが黒線上にないとき、前進 if ((SENSOR_1 > 40 && SENSOR_3 < 40)) {j=j+1;Advance(10);Off(OUT_A+OUT_C);} //右のセンサーのみが黒線上にあるとき、カウントし、1秒前進 if ((SENSOR_1 < 40 && SENSOR_3 > 40)) {Left;} //左のセンサーのみが黒線上にあるとき、左方向に修正 } Off(OUT_A+OUT_C); Turn_right(110); Off(OUT_A+OUT_C); //ロータリー終了 ClearTimer(0); //近道まで基本のライントレース while (Timer(0) <= 25) { Go; if (SENSOR_1 < 40) {Left;until(SENSOR_1 > 40);} if (SENSOR_3 < 40) {Right;until(SENSOR_3 > 40);} } Advance(100); //近道の線を無視 ClearTimer(1); //近道まで基本のライントレース while (Timer(1) <= 50) { Go; if (SENSOR_1 < 40) {Left;until(SENSOR_1 > 40);} if (SENSOR_3 < 40) {Right;until(SENSOR_3 > 40);} } Advance(90);Off(OUT_A+OUT_C); //ロータリーまで前進 Turn_right(90); //ロータリー開始
int k=0; //前回同様にロータリーを通過 while(k<=1) {if ((SENSOR_1 > 40 && SENSOR_3 > 40)) {Go;} if ((SENSOR_1 > 40 && SENSOR_3 < 40)) {k=k+1;Advance(10);Off(OUT_A+OUT_C);} if ((SENSOR_1 < 40 && SENSOR_3 > 40)) {Left;} } Off(OUT_A+OUT_C); Turn_right(100); Off(OUT_A+OUT_C); //ロータリー終了 int l=0; //急カーブと同様に交差点を通過 while(l<=2) { if ((SENSOR_1 > 40 && SENSOR_3 > 40)) {Go;} if ((SENSOR_1 < 40 && SENSOR_3 > 40)) {Left;} if ((SENSOR_1 > 40 && SENSOR_3 < 40)) {Right;} if ((SENSOR_1 < 40 && SENSOR_3 < 40)) {l=l+1;Advance(20);Off(OUT_A+OUT_C);} } if ((SENSOR_1 < 40 && SENSOR_3 < 40)) {Off(OUT_A+OUT_C);} //両方のセンサーが黒線上にあるとき、ゴール、ストップ