[[2017a/Member]]
#contents
*課題について [#ecb7b652]
#ref(./2017a-mission2.png,11.8KB ,image/jpeg)
上の図にあるコースを
��Aスタート
��E直進
��F(SOUND_UP)
��Q一時停止(SOUND_DOWN)&左折
��R直進(SOUND_UP)
��S左折(SOUND_UP)
��G(SOUND_UP)
��H(SOUND_UP)
��T一時停止(SOUND_DOWN)&直進
��T一時停止(SOUND_DOWN)&直進
��R一時停止(SOUND_DOWN)&左折
��S直進(SOUND_UP)
��P左折(SOUND_UP)
��E一時停止(SOUND_DOWN)&左折
��A停止(SOUND_DOWN)
といった道順で進むようなロボットを作ること。
ただし、以下の条件を満たさなければならない。
・なるべく速く正確に動くロボットになるように工夫すること。
・一時停止の交差点および丁字路ではSOUND_DOWNを鳴らした後、1秒間停止すること。
・直角コーナーおよび一時停止が不要は丁字路ではSOUND_UPを鳴らし、停止しないで進むこと。
・ロボットはサイズは、15cm四方以内とする(高さは無制限)。
・交差点、丁字路、直角コーナーについては、差し掛かった時点で判別するものとし、予め設定した走行時間のみで判定したり、走行距離のみで判定してはならない。
*ロボットについて [#q1233b12]
**全体図 [#b59deb95]
ロボット本体は15�兒擁�内に収めるという制限があったので、なるべくコンパクトになるようにした。
#ref(./IMG_0128.JPG,134.7KB ,image/jpeg)
#ref(./IMG_0129.JPG,125.6KB ,image/jpeg)
**車輪部分 [#s0f2e5bf]
初めは前二輪、後ろ一輪の三輪にしていたが、後ろにタイヤをつけると小回りが利かなくなってしまうので、後ろは支えるだけにした。
また、小回りが利くように両側の車輪を近くなる様にしてみた。
#ref(./IMG_0132.JPG,104.7KB ,image/jpeg)
**センサー部分 [#a2016db7]
センサーの位置で動きが変わったりするので、本体から遠すぎず近すぎず、また、紙になるべく近くなるようにした。
#ref(./IMG_0133.JPG,100.4KB ,image/jpeg)
*プログラムについて [#n8bb806b]
前回は、マクロなどを定義しなかったせいでプログラムが長くなりアドバイスを受けたので、今回はなるべくまとめられるところはまとめて、コンパクトになるようにした。
**定数・マクロ [#i8468af5]
あらかじめ明るさの基準値を決めておいて、その値からいくつ離れたらこうする、といったような感じにした。
また、曲がる場所によって角度が変わるので、曲がる方向が同じでも場所に応じて2つに分けてみたり、交差点の直進か左折かの判断をするために時間を計ったりした。
#define THRESHOLD 45
#define go_forward OnFwd(OUT_AC); //直進
#define turn_right0 OnFwd(OUT_A);OnRev(OUT_C); //右旋回
#define turn_right1 OnFwd(OUT_A); //右折
#define turn_left0 OnRev(OUT_A);OnFwd(OUT_C); //左旋回
#define turn_left1 OnFwd(OUT_C); //左折
#define s_up PlaySound(SOUND_UP);
#define s_down PlaySound(SOUND_DOWN);
#define Tmax 29 //ライン上を走る時間の上限
int t=0; //ライン上にTmax以上いた回数
**サブルーチン [#c0601493]
一時停止しなければならないところでの動作。
sub cross_stop(){
Off(OUT_AC);Wait(100);
s_down;
}
直角に左折するところでの動作。
sub cross_left(){
s_up;
turn_left0;
until(SENSOR_2 < THRESHOLD -3);
}
}
�キ�において、交差点を直進するためのもの。
sub cross_straight(){
turn_right1;
Wait(20);
go_foward;
go_forward;
until(SENSOR_2 < THRESHOLD -3);
turn_right1;
until(SENSOR_2 < THRESHOLD +8);
}
Tmaxを超えるまでラインの左側をなぞる。
sub linetrace0(){
SetSensor(SENSOR_2,SENSOR_LIGHT);
ClearTimer(0);
while(FastTimer(0)<MaxT){
while(FastTimer(0)<Tmax){
if(SENSOR_2 < THRESHOLD -8){
turn_left0; //濃い黒のときは左旋回
}else if(SENSOR_2 < THRESHOLD -3){
turn_left1; //薄い黒のときは左折
}else if(SENSOR_2 < THRESHOLD +3){
go_forward; //黒と白の中間のときは直進
}else if(SENSOR_2 < THRESHOLD +8){
turn_right1; //薄い白のときは右折
}else {
turn_right0; //濃い白のときは右旋回
}
if(SENSOR_2 < THRESHOLD -8){
ClearTimer(0);
} //濃い黒の上にいる時間を計る
}
t+=1; //Tmaxをこえたらtを1増やす
}
s秒間、時間を計らずにラインの左側をたどる
void linetrace1(int s){
SetSensor(SENSOR_2,SENSOR_LIGHT);
ClearTimer(2);
while(FastTimer(2)<s){
if(SENSOR_2 < THRESHOLD -8){
turn_left0;
}else if(SENSOR_2 < THRESHOLD -3){
turn_left1;
}else if(SENSOR_2 < THRESHOLD +3){
go_forward;
}else if(SENSOR_2 < THRESHOLD +8){
turn_right1;
}else {
turn_right0;
}
ClearTimer(0);
}
}
細かいところをきれいにたどれるように、そこだけは特別にプログラムを組んだ。
sub linetrace_2(){
SetSensor(SENSOR_2,SENSOR_LIGHT);
while(FastTimer(0)<26){
if(SENSOR_2 < THRESHOLD -8){
turn_left0;
}else if(SENSOR_2 < THRESHOLD -3){
turn_left1;
}else if(SENSOR_2 < THRESHOLD +3){
go_forward;
}else if(SENSOR_2 < THRESHOLD +8){
turn_right1;
}else {
turn_right0;
}
if(SENSOR_2 < THRESHOLD -8){
ClearTimer(0);
}
}
t+=1;
}
**プログラム [#rc5bcfc9]
「t==0」のとき、最初の「if」の中に入る。交差点を見つけると「linetrace0」が終わる。
このとき「t==1」になるが、「if」の動作が終わるまで「if」のまま。
そして「cross_left」に移る。 「cross_left」が終わると「t==0」の「if」から出て、「t==1」の「if」に入る。
(何度試しても「task mainが定義されていない」となってしまい、動かすことができなかった)
task main()
{
SetSensor(SENSOR_2,SENSOR_LIGHT);
ClearTimer(0);
while(n<=13){
while(<=13){
if(t==0){
linetrace1(6000); //�´�
linetrace0();
cross_left(); //��
}else if((t==1)||(t==8)||(t==11)){
linetrace0();
cross_stop();
turn_left0;until(SENSOR_2 < THRESHOLD +3); //�き���
}else if((t==2)||(t==9)){
linetrace1(500);
linetrace2();
s_up;
cross_straight(); //�キ�
}else if((t==3)||(t==10)){
linetrace1(500);
linetrace0();
cross_left(); //�Ν�
}else if(t==4){
linetrace0();
cross_left(); //��
}else if(t==5){
linetrace1(4000);
linetrace0();
cross_left();
ClearTimer(0); //��
}else if(t==6){
linetrace0();
cross_stop();
cross_straight(); //��
}else if(t==7){
linetrace1(2000);
linetrace0();
cross_stop();
cross_straight(); //��
}else if(t==12){
linetrace0();
s_down;
Off(OUT_AC); //��
}
}
}
*結果と反省 [#i2e58b0b]
ただ単にラインとレースをするプログラムは簡単に作ることができた。
しかし、交差点の判断などのプログラムに関しては、自分一人でやってみてもうまく動かないところがあったので、できている人のものを参考にしたり、教えてもらったりして何とか完成したと思ったが、なぜかtask mainが定義されていないと表示されてできなかった。
また、課題の内容は前回より単純なものだったが、プログラムを組むとなるとそうもいかずとても苦労した。中でも、交差点を曲がるか曲がらないかの区別をさせるのが一番難しかった。