目次 #contents *課題について [#p32e005d] 今回の課題は指定された黒い線に沿ってロボットを動かす。私が選んだコースはE地点直進コースである。 詳しい内容については[[課題2>2017a/Mission2]]より。 *ロボット本体について [#we65960b] ロボット本体を横からみた写真である。センサーとタイヤをできるだけ近づけ、ロボットの回転半径をできるだけ小さくした。 #ref(2017a/Member/rock/Mission2/zenntai.JPG,50%); 今回の課題は、光センサーを使っているため照明や人影で読み取る値に差が生まれ、動きが変わることがあったため、センサーを床に近づけて周りの状況によらないようにした。 #ref(2017a/Member/rock/Mission2/sensor.JPG,50%); ロボット本体の後ろ側にタイヤをつけると自由に動くようにしなければいけないが、今回は球状になっているブロックを使い摩擦を小さくしている。 #ref(2017a/Member/rock/Mission2/usiro.JPG,50%); *プログラミングについて [#lf910492] 前回の課題ではメインのプログラムが長々となってしまったため、今回はサブルーチンを使うなどしてコンパクトになるべくしようとした。 **defineについて [#v9c94d32] 基本的な色の値と右左折、直進を定義した。 &br; 最後の2つの定義は線を左側から右側へ行くプログラムとその逆のプログラムである。本当はサブルーチンにしたかったが、数に制限がありdefineで定義した。 #define white 49 #define white_gray 48 #define gray 40 #define black_gray 38 #define black 35 #define go_forward OnFwd(OUT_AC); //直進 #define turn_left0 Off(OUT_A);OnFwd(OUT_C); //左折 #define turn_left1 OnRev(OUT_A);OnFwd(OUT_C); //左旋回 #define turn_right0 OnFwd(OUT_A);Off(OUT_C); //右折 #define turn_right1 OnFwd(OUT_A);OnRev(OUT_C); //右旋回 #define migigawa turn_right0;Wait(20);Off(OUT_A);turn_right1;Wait(60);Off(OUT_AC); //右側に移動 #define hidarigawa turn_left0;Wait(20);Off(OUT_C);turn_left1;Wait(60);Off(OUT_AC); //左側に移動 **サブルーチンについて [#s470c00b] 最初と最後、交差点で状況に適した動きができるようなプログラムを、サブルーチンにより定義した。 sub hajime() //Aからスタート { OnFwd(OUT_AC); Wait(60); Off(OUT_AC); } sub owari() //最後の直線からAに入る { OnFwd(OUT_AC); Wait(180); Off(OUT_AC); PlaySound(SOUND_DOWN); } sub line_go() //線の左側をトレースし走行 { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<20){ if(SENSOR_2>=white){ turn_right1; ClearTimer(0); }else if(SENSOR_2>white_gray){ turn_right0; ClearTimer(0); }else if(SENSOR_2>gray){ go_forward; ClearTimer(0); }else if(SENSOR_2>black_gray){ turn_left0; ClearTimer(0); }else{ turn_left1; } } Off(OUT_AC); } sub line_go2() //線の右側をトレースし走行 { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<20){ if(SENSOR_2>=white){ turn_left1; ClearTimer(0); }else if(SENSOR_2>white_gray){ turn_left0; ClearTimer(0); }else if(SENSOR_2>gray){ go_forward; ClearTimer(0); }else if(SENSOR_2>black_gray){ turn_right0; ClearTimer(0); }else{ turn_right1; } } Off(OUT_AC); } sub tyokusinn_sound() //交差点で音を鳴らし直進する { PlaySound(SOUND_UP); OnFwd(OUT_AC); Wait(40); Off(OUT_AC); } sub sasetu_sound() //交差点で音を鳴らし左折する { PlaySound(SOUND_UP); turn_left0; Wait(90); turn_left1; Wait(50); Off(OUT_AC); } sub ichijiteisi_tyokusinn() //交差点で音を鳴らし一時停止し直進する { PlaySound(SOUND_DOWN); Off(OUT_AC); Wait(100); Off(OUT_AC); OnFwd(OUT_AC); Wait(40); Off(OUT_AC); } sub ichijiteisi_sasetu() //交差点で音を鳴らし一時停止し左折する { PlaySound(SOUND_DOWN); Off(OUT_AC); Wait(100); Off(OUT_AC); turn_left0; Wait(90); turn_left1; Wait(40); Off(OUT_AC); } **ライントレースのプログラム [#u8bf72e8] サブルーチンひとつで状況に適した曲がり方をできるようにしたため、メインのプログラムが比較的簡潔になったのではないかと思う。 task main() { hajime(); //Aから出て線をトレースし始める line_go(); sasetu_sound(); //Fで左折 line_go(); ichijiteisi_sasetu(); //Qで一時停止、左折 line_go(); tyokusinn_sound(); //Rで直進 line_go(); sasetu_sound(); //Sで左折 line_go(); sasetu_sound(); //Gで左折 line_go(); migigawa; line_go2(); hidarigawa; line_go(); sasetu_sound(); //Hで左折 line_go(); ichijiteisi_tyokusinn(); //T一回目、一時停止、直進 line_go(); ichijiteisi_tyokusinn(); //T二回目、一時停止、直進 line_go(); ichijiteisi_sasetu(); //Rで一時停止、左折 line_go(); tyokusinn_sound(); //Sで直進 line_go(); sasetu_sound(); //Pで左折 line_go(); ichijiteisi_sasetu(); //Eで一時停止、左折 line_go(); owari(); //Aに入る } *まとめ [#g0d650f9] 前回のプログラムが長くなってしまった反省を活かして、サブルーチンをできるだけ活用してプログラムを短くした。また、そのおかげで試行錯誤している時に、どこを変えればいいかが格段にわかりやすくなった。その上、同じ動きで交差点を曲がる時にプログラミングが簡単であった。 &br; 交差点Qで、交差点判定するプログラムがなかなかできずに苦労した。交差点判定をするまでの時間を短くしすぎると、急なカーブで誤作動が起きるため、そこをうまいことプログラムするのが難しいため、急なカーブでカーブの外側を走ることにすることでこの問題を解決することに成功した。 &br; 課題1ではどちらかというとロボットの組み立てにも苦戦をしたが、今回の課題2ではプログラムがさらに難しくなり苦戦したが、プログラムを前回より簡潔にできたのは大きな成果ではないかと思う。