[[2019a/Member]] 目次 #contents *課題2について [#u74e2052] A地点を出発し、次の経路を黒い線にそって動くロボットを作成する.交差点では1秒間停止し、丁字路では直角方向に進入する時のみ一時停止すること. A地点から出発 → M → K(直進) → L(ピンポン玉をつかむ) → K(右折) → J(一時停止の後、左折) → I(直進) → H(直進) → G(左折) → F → E → D(一時停止の後、直進) → C(直進) → B(一時停止) → シュート→ A地点に入る(ゴール) 詳しくは,[[2019a/Mission2]]をご覧ください. *ロボットについて [#m5de3aaa] **タイヤ [#xf6b7f3f] **アーム [#x5e87750] *プログラムについて [#id4fac50] **ライントレースの仕組み [#ld4d1ed2] **交差点認識の方法 [#p8c71d7c] ***直角交差点 [#zcb84290] ***円形交差点 [#f1b8055c] **使用したサブルーチン [#pfa6529b] ***定義・マクロ [#c109df9b] まずグローバル変数のtを定義します. int t; 次に交差点を認識するための時間を2種類定義します. #define KOUSATEN 20 //直角交差点用 #define ENKEIKOUSATEN 13 //円形交差点用 ライントレースに使用する光センサーの値を定義します. #define kuro 41 #define kurohai 43 #define hai 45 #define shirohai 47 ライントレースの動作のマクロです. #define go_ahead OnFwd(OUT_AC); //直進 #define turn_left SetPower(OUT_AC,3);Off(OUT_A);OnFwd(OUT_C); //左回転 #define turn_right SetPower(OUT_AC,3);OnFwd(OUT_A);Off(OUT_C); //右回転 #define Uturn_left SetPower(OUT_AC,3);OnRev(OUT_A);OnFwd(OUT_C); //左旋回 #define Uturn_right SetPower(OUT_AC,3);OnFwd(OUT_A);OnRev(OUT_C); //右旋回 一時停止のマクロです.交差点では,1秒間停止しなければならないので,時間は1秒です. #define kyukei Wait(100); ライントレースの1つの動作の継続時間を定義します. #define STEP 1 ***follow_line1 [#seefd551] follow_line1はライントレースをして直角の交差点で止まるサブルーチンです.光センサーの値がkuroの状態が一定時間(KOUSATEN)の間続くと止まります.そのために,kuroの動作ではタイマーをリセットせず時間を計り続けます.それ以外の動作の時は1回ずつタイマーをリセットしています. sub follow_line1() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); //まずタイマー0をリセット while(FastTimer(0)<KOUSATEN) //タイマー0の値がKOUSATEN(20)未満のとき繰り返す { if(SENSOR_2<kuro) //光センサーの値がkuro(41)未満なら { Uturn_left; //左旋回 } else if(SENSOR_2<kurohai) //光センサーの値がkurohai(43)未満なら { turn_left;ClearTimer(0); //左回転,そしてタイマー0をリセット } else if(SENSOR_2<hai) //光センサーの値がhai(45)未満なら { go_ahead;ClearTimer(0); //直進,そしてタイマー0をリセット } else if(SENSOR_2<shirohai) //光センサーの値がshirohai(49)未満なら { turn_right;ClearTimer(0);//右回転,そしてタイマー0をリセット } else //それ以外(光センサーの値が49以上)なら { Uturn_right;ClearTimer(0);//右旋回,そしてタイマー0をリセット } Wait(STEP); //いずれかの動作をSTEP(1)だけ実行 } Off(OUT_AC); kyukei; //1秒間停止 } ***follow_line2 [#a8201e5e] follow_line2は,tの間だけライントレースをして止まるサブルーチンです.基本的な仕組みはfollow_line1と同じです.follow_line1との違いは,KOUSATENの代わりにグローバル変数tを用いることで任意の時間tの間は止まることなく進むことができます.そのために,それぞれの動作でタイマーをリセットすることはなく,このサブルーチンが始まってからの時間を計り続けます.また,最後のPlaySoundはこのサブルーチンが終わったことを知らせるためのものです. sub follow_line2() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); //まずタイマー0をリセット while(FastTimer(0)<t) //タイマー0がt未満の間繰り返す { if(SENSOR_2<kuro) //kuro未満の時左旋回 { Uturn_left; } else if(SENSOR_2<kurohai) //kurohai未満の時左回転 { turn_left; } else if(SENSOR_2<hai) //hai未満の時直進 { go_ahead; } else if(SENSOR_2<shirohai) //shirohai未満の時右回転 { turn_right; } else //それ以外(shirohai以上)の時右旋回 { Uturn_right; } Wait(STEP); } Off(OUT_AC); PlaySound(SOUND_CLICK); //確認音 } ***follow_line3 [#xd0351f1] follow_line3は,follow_line1とほぼ同じです.ただ,KOUSATENがENKEIKOUSATENに代わっているので円形交差点で止まります. sub follow_line3() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<ENKEIKOUSATEN) //タイマー0がENKEIKOUSATEN未満の時繰り返す { //以下follow_line1と同じ if(SENSOR_2<kuro) { Uturn_left; } else if(SENSOR_2<kurohai) { turn_left;ClearTimer(0); } else if(SENSOR_2<hai) { go_ahead;ClearTimer(0); } else if(SENSOR_2<shirohai) { turn_right;ClearTimer(0); } else { Uturn_right;ClearTimer(0); } Wait(STEP); } Off(OUT_AC); kyukei; } ***cross_line [#q6eff459] cross_lineは交差点を直進するためのサブルーチンです.動きは,下の図の通りです. まず,follow_line1または3で交差点を認識して停止.その時は黒の線上で止まっているので黒の線上であるとき直進をして線を越え,白になると止まります.その後,黒くなるまで右旋回をして黒の線へ戻ります.ここで,右回転ではなく右旋回を用いることで交差点を越えるときにより短い距離で越えることができます. sub cross_line() { SetSensor(SENSOR_2,SENSOR_LIGHT); while(SENSOR_2<hai) //光センサーの値がhai未満の時 { go_ahead; //直進 } Off(OUT_AC); kyukei; //一時停止 while(SENSOR_2>hai) //光センサーの値がhaiより大きい時 { Uturn_right; //右旋回 } Off(OUT_AC); kyukei; //一時停止 } ***kousaten_turn_left [#f031bf2b] kousaten_turn_leftは交差点を左折するためのサブルーチンです.交差点を認識して停止後,白になるまで左旋回しfollow_lineを再開します. sub kousaten_turn_left() { SetSensor(SENSOR_2,SENSOR_LIGHT); while(SENSOR_2<shirohai) //shirohai以下の時繰り返す { Uturn_left; //左旋回 } Off(OUT_AC); kyukei; } ***K_turn_right [#pf2f1d32] K_turn_rightはK地点で右折するためのサブルーチンです.今回のルートでは右折はK地点のみであるのでK地点限定のサブルーチンを作りました.動作は以下の図の通りです. 詳しくは,下の実際の経路に沿ったプログラムで解説します. sub K_turn_right() { OnFwd(OUT_A); //0.7秒間右に回転 Wait(70); Off(OUT_A); kyukei; while(SENSOR_2>hai) //光センサーの値がhaiより大きいとき繰り返す { Uturn_right; //右旋回 } Off(OUT_AC); kyukei; } ***pinpon_catch [#ed772a9b] pinpon_catchはピンポン玉をつかむためのサブルーチンです.アームをゆっくり動かすためにSetPowerを導入しました. sub pinpon_catch() { SetPower(OUT_B,1); OnRev(OUT_B); //アームを閉じる Wait(50); Off(OUT_B); kyukei; } ***shoot [#y1b27915] shootはピンポン玉をシュートするためのサブルーチンです. sub shoot() { OnFwd(OUT_A); //右に回転し,方向を修正 Wait(20); Off(OUT_A); Wait(10); SetPower(OUT_B,1); OnFwd(OUT_B); //アームを開く Wait(20); Off(OUT_B); Wait(10); OnRev(OUT_AC); //後ろに下がる Wait(35); Off(OUT_AC); } **実際の経路に沿ったプログラム [#ge3070f3] +AからM + + + + + + + + + + + + + + *感想・反省点 [#c3f3176f]