[[2018a/Member]] #contents *課題2 [#pd053fea] 製作したコースをライントレースし、缶を移動させるロボットの製作 *ロボの説明 [#x1cf7e1f] 二つのモータACが左右のタイヤを回す。またモータBは缶を運ぶ機構に用いた。 #ref(全体像.jpg) ロボットの前方には、ライントレースを行うための光センサがついている。 #ref(前.jpg) 缶を運ぶ機構は虫取り網をもとに製作した。 #ref(上から.jpg) #ref(横から.jpg) *プログラムの説明 [#cd5339dc] 今回は第二コースを走るプログラムを書いた。内容は以下の通りである。 1.Aをスタート 2.Bを右折 3.Jで一時停止の後、Yの空き缶をキャッチしてJに戻る 4.JからKに向かい、Kを直進 5.Lを直進 6.Iを左折 7.Hで一時停止の後、左折 8.Gで一時停止の後、右折 9.Fで一時停止の後、右折 10.Eを直進 11.Dで一時停止の後、空き缶をXに置いてDに戻り、Cに向かう 12.Cで一時停止の後、直進 13.Bを直進 14.Aで停止 #ref(レースコース.png) ***defineの説明[#e93143b6] 今回は右折・左折・右旋回・左旋回と、しきい値、直進・停止、右に曲がる・左に曲がるをdefineで用意した。 最初の5つはサブルーチン用。 残りの4つはプログラム用で分けてある。 特に、旋回については数値がプログラムの中で変わるので、サブルーチンに支障が出ないように分けている。 #define USETSU OnFwd(OUT_A);Off(OUT_C); //右折 #define SASETSU OnFwd(OUT_C);Off(OUT_A); //左折 #define MIGI_SEN OnFwd(OUT_A);OnRev(OUT_C); //右旋回 #define HIDARI_SEN OnFwd(OUT_C);OnRev(OUT_A); //左旋回 #define SIKII 45 //しきい値 #define TEISI Off(OUT_AC);Wait(100);PlaySound(SOUND_DOUBLE_BEEP); //停止後に音が鳴る #define ZENSIN OnFwd(OUT_AC); //前進 #define MAGARU_R OnFwd(OUT_A);OnRev(OUT_C);Wait(60);Off(OUT_C); //右に曲がる #define MAGARU_L OnFwd(OUT_C);OnRev(OUT_A);Wait(60);Off(OUT_C); //左に曲がる ***サブルーチンの説明 [#n7b916e2] サブのプログラムは3つあり、ライントレース・缶を取る・缶を置くの3つである。 ライントレースのプログラム sub trace(){ SetSensor(SENSOR_1, SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<=25){ if(SENSOR_1 > SIKII+5){ HIDARI_SEN //左旋回する ClearTimer(0); // timerを0にする }else if(SENSOR_1 > SIKII+3){ SASETSU //左折する ClearTimer(0); // timerを0にする }else if(SENSOR_1 > SIKII){ OnFwd(OUT_AC); //前進 ClearTimer(0); // timerを0にする }else if(SENSOR_1 > SIKII-3){ USETSU //右折する ClearTimer(0); //timerを0にする }else{ MIGI_SEN //右旋回する } Off(OUT_AC); //止まる } } 缶を持ち上げるプログラム sub kan_toru(){ OnFwd(OUT_AC); //前進 Wait(0); Off(OUT_AC); //止まる OnFwd(OUT_B); //アームを動かす Wait(25); //缶を取る Off(OUT_B); //アームを止める OnRev(OUT_AC); //後進 Wait(0); Off(OUT_AC); //止まる } 缶を置くプログラム sub kan_oku(){ OnFwd(OUT_AC); //前進 Wait(0); Off(OUT_AC); //止まる OnRev(OUT_B); //アームを上げる Wait(25); //缶を置く Off(OUT_B); //アームを止める OnRev(OUT_AC); //後進 Wait(0); Off(OUT_AC); //止まる } ***メインプログラム [#p066acb1] メインプログラムは次の通りである。 task main(){ trace(); //Aをスタート OnFwd(OUT_AC); //切り返す Wait(50); MAGARU_R; //Bを右折 trace(); TEISI; //Jで一時停止 kan_toru(); //缶を取る ZENSIN; Wait(10); MAGARU_L; //Jを左折 ClearTimer(1); while(FastTimer(1) <= 2400){ trace(); } OnFwd(OUT_AC); //切り返す Wait(30); MAGARU_L; //Iを左折 trace(); TEISI; //Hで一時停止 OnFwd(OUT_AC); //切り返す Wait(30); MAGARU_L; //Hで左折 trace(); TEISI; //Gで一時停止 OnFwd(OUT_AC); //切り返す Wait(30); MAGARU_R; //Gを右折 trace(); TEISI; //Fで一時停止 MAGARU_R; //Fを右折 trace(); ZENSIN; //Eを通過 trace(); TEISI; //Dで一時停止 MAGARU_L; //Dで左折 Wait(30); kan_oku(); //缶を置く MAGARU_L; //Dを回れ左 Wait(120); trace(); OnFwd(OUT_AC); //切り返す Wait(30); trace(); TEISI; //Cで一時停止 ZENSIN; trace(); ZENSIN; //ゴール! } *結果 [#o6aa08b1] 細かいカーブを曲がりきることができなかった。これは、左右のタイヤの幅が大きすぎたため小回りが利かなかったと考えられる。 また、線の右側と左側のトレースを使い分けるプログラムは大変だと思い、常に線の右側をトレースするようにしたのだが、うまく走れない箇所が多く、かえって難しくなってしまった。