今回の課題は「ライン・トレース」。
図のコースに沿ってボールを運ぶというものです。
僕はCからAまでのコースを担当しました。ルールとして、交差点Qでは直進、三叉路Pでは右折をします。 また、交差点、三叉路では2秒間停止します。
今回作ったロボットはこちらになります。
タイヤは前に2輪、後ろに補助輪が1つあります。
分解するとこのようにパーツが分かれます。
タイヤの間に光センサーをつけ、センサーが振れすぎないようになっています。
ただし、完全に真ん中、というわけではなく、少し左にずらしてほんの少し振れるようにして、細かく動かせるようになています。
アームはギアを用いて開閉するようになっています。
今回のプログラムはこちらになります。
#define turn_left OnFwd(OUT_C);Off(OUT_A); #define turn_right OnFwd(OUT_A);Off(OUT_C); #define BLACK 38 #define nMax 10 #define Stop Off(OUT_AC);Wait(120); #define cross OnRev(OUT_C);Wait(20);OnFwd(OUT_AC);Wait(50); #define Right OnFwd(OUT_A);OnRev(OUT_C);Wait(60);OnFwd(OUT_AC);Wait(30); #define MOVE_TIME_1 1200 #define MOVE_TIME_2 900 #define close OnRev(OUT_B);Wait(27);Off(OUT_B); #define open OnFwd(OUT_B);Wait(30);Off(OUT_B); task main(){ SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<=MOVE_TIME_1){ if(SENSOR_2<BLACK){ turn_left; }else{ turn_right; } Wait(1); } int nOnline=0; while(nOnline<nMax){ if(SENSOR_2<BLACK){ turn_left; nOnline++; }else{ turn_right; nOnline=0; } Wait(1); } close; Stop; cross; nOnline=0; while(nOnline<nMax){ if(SENSOR_2<BLACK){ turn_left; nOnline++; }else{ turn_right; nOnline=0; } Wait(1); } Stop; Right; nOnline=0; ClearTimer(0); while(FastTimer(0)<=MOVE_TIME_2){ if(SENSOR_2<BLACK){ turn_left; }else{ turn_right; } Wait(1); } while(nOnline<nMax){ if(SENSOR_2<BLACK){ turn_left; nOnline=0; }else{ turn_right; nOnline++; } Wait(1); } Stop; OnRev(OUT_A); Wait(20); Off(OUT_A); Wait(30); open; OnFwd(OUT_AC); Wait(20); OnRev(OUT_AC); Wait(20); Off(OUT_AC); }
かなり長いですね。少しずつ区切って説明していきます。
#define turn_left OnFwd(OUT_C);Off(OUT_A); #define turn_right OnFwd(OUT_A);Off(OUT_C);
これは左右へ少し方向転換するときに使います。線に沿って動くときはこのプログラムを使います。
#define BLACK 38
白と黒の境界を決める値を定義しています。
#define nMax 10
後に出てくるカウンターで必要な定義です。
#define Stop Off(OUT_AC);Wait(120);
2秒間停止するためのプログラムです。
#define cross OnRev(OUT_C);Wait(20);OnFwd(OUT_AC);Wait(50); #define Right OnFwd(OUT_A);OnRev(OUT_C);Wait(60);OnFwd(OUT_AC);Wait(30);
上は十字路でまっすぐ進むためのプログラムで、 下は三叉路で右折するためのプログラムです。
#define MOVE_TIME_1 1200 #define MOVE_TIME_2 900
後に出てくるタイマーで必要な定義です。
#define close OnRev(OUT_B);Wait(27);Off(OUT_B); #define open OnFwd(OUT_B);Wait(30);Off(OUT_B);
アームの開閉のプログラムです。
task main(){ SetSensor(SENSOR_2,SENSOR_LIGHT);
ここで光センサーの定義をします。
ClearTimer(0);
タイマーのプログラムです。0番のタイマーをリセットしています。
while(FastTimer(0)<=MOVE_TIME_1){ if(SENSOR_2<BLACK){ turn_left; }else{ turn_right; } Wait(1); }
0番のタイマーがカウントし始め、その間は黒を感知すると左へ、白を感知すると右へ切り替えることで、線に沿って進みます。秒数は「MOVE_TIME_1」、つまり1200カウントするまでです。100のカウント=1秒なので、12秒ということになります。
int nOnline=0; while(nOnline<nMax){ if(SENSOR_2<BLACK){ turn_left; nOnline++; }else{ turn_right; nOnline=0; } Wait(1); } close; Stop; cross;
「nOnline」はカウンターのプログラムになります。この値が「nMax」で定義した値より小さいとき、線に沿って進みます。このプログラムは、黒色を感知すると1カウントされます。連続で感知すると次の動作に進みます。十字路はこの方法でクリアできます。
ここにボールが置いてあるので、ボールをアームでつかみます。
nOnline=0; while(nOnline<nMax){ if(SENSOR_2<BLACK){ turn_left; nOnline++; }else{ turn_right; nOnline=0; } Wait(1); } Stop; Right; nOnline=0;
三叉路も十字路と同じ要領でできます。
ClearTimer(0); while(FastTimer(0)<=MOVE_TIME_2){ if(SENSOR_2<BLACK){ turn_left; }else{ turn_right; } Wait(1); }
また、タイマーをリセットして、カウントさせます。「MOVE_TIME_2」は900で定義してあるので、9秒間動作を繰り返します。
while(nOnline<nMax){ if(SENSOR_2<BLACK){ turn_left; nOnline=0; }else{ turn_right; nOnline++; } Wait(1); } Stop; OnRev(OUT_A); Wait(20); Off(OUT_A); Wait(30); open; OnFwd(OUT_AC); Wait(20); OnRev(OUT_AC); Wait(20); Off(OUT_AC); }
ここは、Aまでの最後の直線から、ボールをゴールさせるまでのプログラムになります。
初めのほうを見ると十字路や三叉路と似たプログラムですが、今回は白を連続で感知することで次の動作に進むようにしています。どうしてかというと、ここは線が細いため、黒だと次に進めなかったからです。
残りは、ゴールにボールを入れるプログラムです。
今回は、他の2人のメンバーの頑張りもあって、何とかゴールまで運べるものができました。
プログラムには、全員が苦戦していましたが何とか完成させることができました。しかし、本体が脆かったり、プログラムが長かったりと、まだまだ改良の余地は残っています。今回は完成させることができたので、次はより良いものを作っていきたいと思います。