[[2012b/Member]] #contents *課題1[#dcd57e50] 課題内容については[[2012b/Mission]]の課題1をご覧ください。 **メンバー [#j0aa4162] -naotoxu 相方。 -candle 自分。蝋燭さん。 **ロボット概要 [#y8106bb5] #ref(HI380002.JPG) 今回作成したロボット。今のところ名無し。 コンピュータ部分を横からがっちり固定する固定具付き。 #ref(HI380003.JPG) 小回りの利く構造の秘訣、回転補助輪。 回転パーツで本体に接続することで柔軟な稼働を実現。 #ref(HI380004.JPG) ピンポン球をつかむアーム。単純な構造だがピンポン球をしっかりと掴んでくれる。 輪ゴムでモーターの動力を伝える。ギアの接続で両側同時に動く。 **プログラム概要 [#h14e8308] /* アーム関連 */ #define opn OnRev(OUT_B); //アームを開く #define cls OnFwd(OUT_B); //アームを閉じる #define hld Off(OUT_B); //アームを固定する /* タイヤ関連 */ #define fwd Off(OUT_AC); OnFwd(OUT_AC); //前進 #define rev Off(OUT_AC); OnRev(OUT_AC); //後退 #define trn_r Off(OUT_AC); Off(OUT_C); OnFwd(OUT_A); //右折 #define trn_l Off(OUT_AC); Off(OUT_A); OnFwd(OUT_C); //左折 #define grt_r Off(OUT_AC); OnFwd(OUT_A); OnRev(OUT_C); //右旋回 #define grt_l Off(OUT_AC); OnFwd(OUT_C); OnRev(OUT_A); //左旋回 #define stp Off(OUT_AC); //停止 /* ライントレースのしきい値 * 現在地の明るさを「白」「やや白」「中間」「やや黒」「黒」の5段階に分ける */ #define white 47 //「白」と「やや白」の境界 #define white_b 44 //「やや白」と「中間」の境界 #define black_b 40 //「中間」と「やや黒」の境界 #define black 37 //「やや黒」と「黒」の境界 /* その他 */ #define crt 150 //連続カウント防止時間(単位1/100秒) task main () { /* 変数・センサー・タイマーの準備 */ int count = 0; int time = 0; int count = 0; //カウント用変数 int time = 0; //タイマー用変数 SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); /* 開始動作 * アームを開き、前進しながらアームを閉じピンポン球を掴み、右旋回してラインに乗る。 */ Wait(200); opn; Wait(40); fwd; Wait(20); cls; Wait(40); hld; Wait(40); grt_r; until(white_b > SENSOR_2 && SENSOR_2 >= black_b); /* 動作 */ while(true) { //以降繰り返し /* 基本動作 */ while(white_b > SENSOR_2 && SENSOR_2 >= black_b) { fwd; //明るさ「中間」のとき前進 } while(white > SENSOR_2 && SENSOR_2 >= white_b) { trn_r; //明るさ「やや白」のとき右折 } while(black_b > SENSOR_2 && SENSOR_2 >= black) { trn_l; //明るさ「やや黒」のとき左折 } while(SENSOR_2 >= white) { grt_r; //明るさ「白」のとき右旋回 } /* 明るさ「黒」のとき */ if(black > SENSOR_2) { if(count < 2) { //カウント数に応じて左旋回 /* 前回のカウントからの時間に応じてカウントの有無を判断 * 結果に応じて音を出す */ if(FastTimer(0) - time >= crt) { count++; PlaySound(SOUND_UP); } else { PlaySound(SOUND_DOWN); } time = FastTimer(0); while(black > SENSOR_2) { grt_l; } } /*T字路*/ if(count == 2) { //カウント数に応じてT字路を判断 count++; PlaySound(SOUND_FAST_UP); /* 若干右旋回して軌道修正し前進 */ trn_r; Wait(10); while(black > SENSOR_2) { fwd; } } /*終了動作*/ if(count == 3) { //カウント数に応じてゴール地点を判断 PlaySound(SOUND_FAST_UP); /* 少し下がり、前進しながらアームを開いてピンポン球を転がし、アームを閉じてはじき出す */ rev; Wait(60); stp; Wait(100); fwd; Wait(20); opn; Wait(12); rev; Wait(5); cls; Wait(25); stp; Wait(30); hld; while(true){ } } } } } ※このプログラムは''逆方向''の課題用です。 ***開始動作 [#c77bd096] ピンポン球を掴んでから道に乗るまでの動作。プログラムを起動して2秒後から動き始めるようになっている。アームを開く、前進しながらピンポン球を掴む、そして右旋回で道に乗るという手順。道に乗る際の旋回が終わるタイミングは、ライントレース(明るさを測る機能)を使って決めている。 ***基本動作 [#id55daa8] これ以降の動作は何度も繰り返すことを前提としているため、while(true)による無限ループで囲んである。基本動作は、ラインの境目を中心に5段階に明るさを分類して設定している。ちょうど白黒の境目の真ん中だと前進、黒色側(右側)にずれたら左向きに曲がるなどの設定で線の左端をなぞるように動くようにした。左旋回のみT字路を渡る関係で基本動作に含んでいない。左旋回も含め、動作はモーターのONとOFFを高速で繰り返しているため移動速度は通常の半分になっている。これにより行き過ぎによる誤作動を防止できる。 ***左旋回 [#ybd8842d] 今回の課題で左旋回の判定になりうる場所は図の赤丸の4ヶ所。 #ref(2012b-mission1b.png) 逆走のため、T字路は3番目となる。そこに至るまでの2か所では旋回し、T字路は横断、最後の場所ではゴールに向かってシュートする必要がある。これを実現するために、左旋回の判定になる場所を通過した回数を記録するプログラムを作成した。これにより、3番目ではまっすぐ通過、4番目ではシュートの動作に切り替えができる。しかし、普通に旋回した回数を記録させると2番目の赤丸の急カーブで複数回、それも回数が安定しないカウントをしてしまう。そこで、旋回を短時間に連続して行った場合にはカウントを行わないように設定した。これによりかなり安定したカウントができるようになった。なお、カウントされたかどうかが確認しやすいように音を出すようにしてある。ちなみに、条件のカウンタ値を変えれば通常の方向でも可能。 ***T字路 [#m7fcf39d] 前述のとおり、3番目の旋回判定の場所をまっすぐ通過するように設定した。ここに至るまでに通過した旋回の場所の数は二つなので、条件のカウンタの値は2になる。直前の左折を考慮し、一瞬だけ右折してから通過するようにした。 ***終了動作 [#d2768768] 最後のT字路についたら、シュートのための動作を行う。このロボットのアームは掴むことに関しては安定性は高いが、シュートするためのはじき出す機能を持たない。そこで、後退しながらアームを開きすぐに閉じることで、掴み損なってはさんではじく方法でシュートできるようにした。 **感想 [#q897cb8f] ロボットのプログラミングの経験は皆無だったが、だんだん自分の思うようにできていくのが楽しかった。最終的に課題の目的であるシュートが決まったときはとても嬉しかった。