今回は二輪車型を採用した。ラインという道路を走るので、この形状が一番適しているのはいうまでもない。
ボールをうまく掴むために、今回は以下のような機構を用意した。
左右両側から覆うような構造にしたため、ボールに到達した時完全にボール正面に位置しなくても、ボールを捉えやすい。
この機構は、ボールを離した状態ではボールを弾いてキックすることもできる。
ラインセンサーを用いれば、センサー先の色の濃さが判別できる。これを用いて、黒色だったら線の外側へ斜め前方向に、白色だったら線の内側に斜め前方向に移動することができれば、線の「縁」をたどることができる。
#define BLACK 37 #define BLACKandGLAY 45 #define GLAYandWHITE 55 #define WHITE 60(数値は調整済み)
#define go OnRev(OUT_BC,35); #define turn_leftFwd OnRev(OUT_B,35);Off(OUT_C); #define turn_rightFwd Off(OUT_B);OnRev(OUT_C,35); #define turn_left OnRev(OUT_B,35);OnFwd(OUT_C,35); #define turn_right OnFwd(OUT_B,35);OnRev(OUT_C,35); #define short_break Off(OUT_BC);Wait(1000); #define back OnFwd(OUT_BC,35);※35というパワーは、正確さを失わずに全行程を終了させることのできる最高の速さとして調整した。
sub Rside_trace() { long t0 = CurrentTick(); while(CurrentTick()-t0<150) { if (SENSOR_3 < BLACK) { turn_right; } else if (SENSOR_3 < BLACKandGLAY) { t0=CurrentTick();turn_rightFwd; } else if (SENSOR_3 < GLAYandWHITE) { t0=CurrentTick();go; } else if (SENSOR_3 < WHITE) { t0=CurrentTick();turn_leftFwd; } else { turn_left;t0=CurrentTick(); }} Off(OUT_BC); } sub Lside_trace() { long t0 = CurrentTick(); while(CurrentTick()-t0<150) { if (SENSOR_3 < BLACK) { turn_left; } else if (SENSOR_3 < BLACKandGLAY) { t0=CurrentTick();turn_leftFwd; } else if (SENSOR_3 < GLAYandWHITE) { t0=CurrentTick();go; } else if (SENSOR_3 < WHITE) { t0=CurrentTick();turn_rightFwd; } else { turn_right;t0=CurrentTick(); }} Off(OUT_BC); }※このサブルーチンの説明
sub Rcross_line() { OnRev(OUT_C,60);Wait(800); Off(OUT_BC); } sub Lcross_line() { OnRev(OUT_B,60);Wait(800); Off(OUT_BC); } sub cross_line() { OnRev(OUT_BC,50);Wait(350); Off(OUT_BC); }
2回目のK以外は音が鳴って、交差点を渡る合図となるようにした。
task main() { SetSensorLight(S3); while(SENSOR_3>BLACKandGLAY){ go;} go;Wait(800);//A~Bへ直進黒になるまで直進する。しかしそれだけでは直進方向と垂直方向の線上に行くので、交差点として認識してしまう。そこで少し直進を入れた。
Rside_trace();//B~Cを右端走行 PlaySound(SOUND_CLICK);//Cを斜め横断する合図 Lcross_line();//Cを左斜めに横断 Lside_trace();//C~Dを左側走行 short_break;//Dで一時停止 PlaySound(SOUND_CLICK);//Dを横断する合図 cross_line();//Dをまっすぐ渡るCに到達したことを明確にしたいので、敢えてCまで右側で、C点の交差点で右側から左側への移動を入れた。
Lside_trace();//D~Gを左側走行 PlaySound(SOUND_CLICK);//横断する合図 OnFwd(OUT_B,30);OnRev(OUT_C,60);Wait(1300);D~Gは左端、枠の外側を移動すれば、このマシンは正確なので(外側の白では回転の動作というのもあるが)、90度の角をトレースできる。
int n=0;//円周上で横断する回数を定義 while(n<2){ //H,Iで二回。Jで違う挙動を取りたい。 Rside_trace();//円周を右側(外側)走行 n++;//交差点通過時にカウントを1追加 PlaySound(SOUND_CLICK);//横断する合図 OnRev(OUT_B,60);Wait(500);//交差点通過 } Rside_trace();//円周を右側(外側)走行 PlaySound(SOUND_CLICK);//横断する合図 OnFwd(OUT_B,30);OnRev(OUT_C,70);Wait(900);//JKの右側へ出る Rside_trace();//J~Kを右側走行カウンターを用いてトレース、交差点通過を2回繰り返した。(repeat記号でもよかった)JKの右側に出る動作は、調整して線右側の白い部分に出るようにした。
PlaySound(SOUND_CLICK);//横断する合図 OnFwd(OUT_C,30);OnRev(OUT_B,70);Wait(1300);//KLの左側へ出る int a=0; int b=0; while((a<2000)&&(b<2500)){ if (SENSOR_3 < BLACK) { b++;turn_left; } else if (SENSOR_3 < BLACKandGLAY) { a++;b++;turn_leftFwd; } else if (SENSOR_3 < GLAYandWHITE) { a++;go; } else if (SENSOR_3 < WHITE) { a++;b++;turn_rightFwd; } else { b++;turn_right;}}//K~Lを左側走行(回数指定で距離を制限)まず、原始的な調整で、KLの左側に行くよう点Kで回る。次だが、論理積を用いてカウンターを用いた条件が両方とも満たされた時だけトレースするようにした。線の外側のカウントと内側のカウントを二つ用意して、ボールのところまでで、止めるようにした。
Off(OUT_BC);OnFwd(OUT_A,100);Wait(700);Off(OUT_A);// turn_left OnRev(OUT_B,35);OnFwd(OUT_C,35);Wait(300); Rside_trace();//L~Mを右側走行(白の場合左回転なので方向修正の回転もこれに含まれる) cross_line();//Kを横断 Rside_trace();//K~Mを右側走行 short_break;//Mで一時停止 OnRev(OUT_A,100);Wait(700);Off(OUT_A);//ボールを離す OnRev(OUT_BC,-100);Wait(1000);Off(OUT_BC);//後退 OnRev(OUT_A,-100);Wait(700);Off(OUT_A);//アームもどす OnRev(OUT_BC,100);Wait(1000);Off(OUT_BC);//前進 OnRev(OUT_A,100);Wait(700);Off(OUT_A);//ボールを撃つ OnRev(OUT_BC,100);Wait(500);Off(OUT_BC);//進む }Lでの方向転換を少しすれば、あとは線の右側走行に切り替えることで、白の時は回転し軌道修正してくれる。その後は上記注釈通りに実行する。問題はヘアピンカーブだが、これも外側ならば問題なく辿ることができる。
グレーの綴が間違っていました、GLAYではなくて、GRAYが正解でした。すみませんでした。