#contents *はじめに [#t4ac362b] ロボコンに向けた準備を進めていく中で以前よりも精度の高いロボット、プログラムができたので新しいロボットについてレポートします。 コースはAからB *ロボット [#o46ebbd1] 三輪車タイプの本体に光センサーを前方に取り付け、上部には写真のようにボールを挟むためのアームを取り付けている。 モーターの役割はそれぞれ -A_ボールをつかむためのアームを動かす -B_右タイヤを動かす -C_左タイヤを動かす &ref(./DSC_0487.JPG,50%); &ref(./DSC_0486.JPG,50%); &ref(./DSC_0488.JPG,50%); *プログラム [#j9993c45] #define THRESHOLD 50 #define SPEED_H 40 #define SPEED_L 25 #define turn_left_0 OnFwd(OUT_B,SPEED_H);Off(OUT_C); //左転回 大 #define turn_left_1 OnFwd(OUT_B,SPEED_L);Off(OUT_C); //左転回 小 #define turn_right_0 OnFwd(OUT_C,SPEED_H);Off(OUT_B); //右転回 大 #define turn_right_1 OnFwd(OUT_C,SPEED_L);Off(OUT_B); //右転回 小 #define go_forward OnFwd(OUT_BC,SPEED_L); //前進 #define STEP 1 //一回の判定で進む時間 #define nMax 180 //交差点認識に必要な数 #define short_break Off(OUT_BC);Wait(2000); #define turn_straight OnRev(OUT_B,SPEED_H);Wait(nMax*STEP);Off(OUT_BC);OnFwd(OUT_BC,30);Wait(200);Off(OUT_BC); //交差点で方向転換し渡る #define catch_boal Off(OUT_BC);OnFwd(OUT_A,30);Wait(800);Off(OUT_A); //ボールをつかむ #define catch_bboal OnFwd(OUT_A,-30);Wait(1000);Off(OUT_A); //ボールをはなす sub line_trace() //P三叉路を通過するまでトレースしボールをつかむ { SetSensorLight(S1); SetSensorTouch(S2); int nOnline=0; long t0 = CurrentTick(); while(CurrentTick()-t0<14000) //14秒間続ける { while(nOnline < nMax) //交差点を認識するまで続ける { if(CurrentTick()-t0==13000) { catch_boal; //スタートして13秒後にボールを掴む。 } if (SENSOR_1<THRESHOLD-14) //線上 { turn_left_0; nOnline++; //線上にいたのでカウンタを増やす } else { if (SENSOR_1<THRESHOLD-10) //線上 { turn_left_1; nOnline++; //線上にいたのでカウンタを増やす } else if (SENSOR_1<THRESHOLD-5) //境界線付近 { turn_left_1; nOnline=0; } else if (SENSOR_1<THRESHOLD+3) //境界線付近 { go_forward; nOnline=0; } else if (SENSOR_1<THRESHOLD+7) //ほぼ線上ではない { turn_right_1; nOnline=0; } else //線上ではない { turn_right_0; nOnline=0; } } Wait(STEP); } short_break; //交差点で2秒止まる turn_straight; //方向変換して交差点を渡る nOnline=0; //カウンターをリセット } } sub line_trace2() //P三叉路からQ交差点までトレース(急カーブ) { SetSensorLight(S1); SetSensorTouch(S2); int nOnline=0; long t0 = CurrentTick(); while(CurrentTick()-t0<9000) //9秒間続ける { if (SENSOR_1<THRESHOLD-14) { turn_left_1; nOnline++; } else { if (SENSOR_1<THRESHOLD-7) { turn_left_1; nOnline++; } else if (SENSOR_1<THRESHOLD-3) { turn_left_1; nOnline=0; } else if (SENSOR_1<THRESHOLD+7) { go_forward; nOnline=0; } else if (SENSOR_1<THRESHOLD+15) { turn_right_1; nOnline=0; } else { turn_right_1; nOnline=0; } } Wait(STEP); } } sub line_trace3() //Bゴールまでトレース、ゴールの三叉路を直進する { SetSensorLight(S1); SetSensorTouch(S2); int nOnline=0; long t0 = CurrentTick(); while(CurrentTick()-t0<6000) //6秒間続ける { while(nOnline < nMax) { if (SENSOR_1<THRESHOLD-14) { turn_left_0; nOnline++; } else { if (SENSOR_1<THRESHOLD-10) { turn_left_1; nOnline++; } else if (SENSOR_1<THRESHOLD-7) { turn_left_1; nOnline=0; } else if (SENSOR_1<THRESHOLD+3) { go_forward; nOnline=0; } else if (SENSOR_1<THRESHOLD+7) { turn_right_1; nOnline=0; } else { turn_right_0; nOnline=0; } } Wait(STEP); } short_break; turn_straight; nOnline=0; } } task main() { line_trace(); line_trace2(); line_trace3(); } 線の左側をトレースしていくプログラム。 コースを時間で3つのブロックに分けた。 スタートして -14秒以内(Pを通過し急カーブ手前まで)...交差点判定のあるライントレースをしつつスタート後13秒のところでボールを掴む。 -14~23秒(急カーブ)...交差点判定をやめライントレースだけする。 -23~29秒(Qを通過してBゴールまで)...交差点判定のあるライントレースをしBゴールで終了する。 *結果 [#c94e7817] ボールをシュートすることはできなかったがAからBまでトレースすることはできた。 *苦労した点 [#nacce347] 交差点を認識させようとすると急カーブも交差点として認識してしまった。タイマーをつけ、ある程度時間で制御するのと急カーブでは速度を落とすことで改善した。また、線の左側をトレースすることで右に直角に曲がるところを外側から回りこむようになるので交差点と錯覚させないことに成功した。 当初はタッチセンサーでアームを降ろすタイミングを決めていたがボールを押さえていないとセンサーが反応しないので時間でタイミングを決めることにした。超音波センサーを使えばうまくできるはず。 線の濃さにそれぞれの場所によってむらがあったので苦労した。コースを3つのブロックに分けたのでそれぞれのブロックによって線上かどうか判断する値を少し変えた。 *感想 [#r6e242ec] プログラムを順序立てて書いていくことの大切さがわっかた。プログラムの上と下の兼ね合いを考えて条件式など考えていくことは難しかったが頭を使ったのでとても楽しかった。 小さい頃、今回のロボットと同じような黒い線をトレースするおもちゃを動物園のお土産コーナーで買い、遊んだことがあったのだが、そのおもちゃの仕組みを理解することができたうえにプログラムがどのようになっているか想像することができるようになった。