課題2では課題1のコースを2つ組み合わせ新たなコースを造り、物を運ぶ動作に加え、物を受け渡す動作をが加わった。
前回と同じ部品点数で物を投げる・受け取ると言う動作を加えなければいけなかった。
1つのコースを往復することが課題の最終目標であった。
得点を獲得するためには計10箇所のポイントをクリアする必要があった。
ここで最も重要なことは途中で失敗をするとそれ以降の得点が取れないことにある。
開発はこの事を意識してやらなくてはならなかった。
つまり最初のボールを掴む動作を失敗した時点で、得点は取れずに終わってしまう。
自分が開発を進める中で気を使った部分はこの初めのボールを掴む動作でもあった。
http://yakushi.shinshu-u.ac.jp/robotics/?2013a%2FMission2
機体には“染五郎”と言う名前を付けた。
機体は出来るだけ同じプログラムで動くように同じ設計の機体を2機作った。
前回から使っていた機体を改良して使った。
しかし、前回の機体と今回の機体では掴む動作の他に投げる動作を必要ようとしていたため、前回より難しかった。
掴む動作と投げる動作を逆向きにすることで2つの動作を1つのモータで実現した。
機体の全体像
プルグラムは基本的に前回の課題で扱ったものを基準に作った。
なのでここでは新しく使いされたマクロと主なプログラムのアウトラインを紹介したい。
まず今回の課題でつかされたプログラムは共同で作業を行っていた人から受け継いで使ったものである。
プログラムを参考にさしていただいたのはチームメンバーの"ryu"さんとです。
このプログラムのマクロで追加されたのは基本的に投げる部分だけである。
このプログラムのほとんどは以前の課題で使ってきたプログラムを組み合われているので、一から作らずに楽にできる。
しかし、細かい部分では調整が必要だった。
特に90°を正確に曲がるところが気を使った。
////////////////////////////ryu////////////////////////////////////////////////////// #define BLACK_02 35 // #define WHITE_01 50 // #define WHITE_02 60 // #define SPEED 30 // #define go_forward OnFwd(OUT_AC,SPEED); // #define turn_right OnRev(OUT_A,SPEED);OnFwd(OUT_C,SPEED); // #define turn_left OnFwd(OUT_A,SPEED);OnRev(OUT_C,SPEED); // #define right Off(OUT_A);OnFwd(OUT_C,SPEED); // #define left OnFwd(OUT_A,SPEED);Off(OUT_C); // ///////////////////////////////////////////////////////////////////////////////////// //以下のマクロは次のURLに記載してあります //http://yakushi.shinshu-u.ac.jp/robotics/?2013a%2FMember%2Fwani%2FMission1#p61f65e3 //ここから #define STEP 1 #define CENTER 45 #define CCC 14000 #define SPEED_H 45 #define SPEED_L 25 #define turn_R Off(OUT_A); OnFwd(OUT_C,SPEED_L); #define turn_L Off(OUT_C); OnFwd(OUT_A,SPEED_L); #define turn_SR OnRev(OUT_A,SPEED_L); OnFwd(OUT_C,SPEED_L); #define turn_SL OnRev(OUT_C,SPEED_L); OnFwd(OUT_A,SPEED_L); #define go_F OnFwd(OUT_AC,SPEED_H); #define nMAX 250 #define short_break Off(OUT_AC);Wait(400); #define CROSS_TIME 400 #define cross_line OnFwd(OUT_A,SPEED_L);OnFwd(OUT_C,SPEED_L);Wait(CROSS_TIME);short_break; #define cross OnFwd(OUT_C,SPEED_L);OnFwd(OUT_A,SPEED_L);Wait(CROSS_TIME+200);short_break; #define go_b OnFwd(OUT_A,-40);OnFwd(OUT_C,-40); //ここまで(URL:http://yakushi.shinshu-u.ac.jp/robotics/?2013a%2FMember%2Fwani%2FMission1#p61f65e3) #define catch OnFwd(OUT_B,33);Wait(600);Off(OUT_B);//ボールを掴むための動作 #define throw OnRev(OUT_B,80);Wait(1000);Off(OUT_B); //ボールを投げるための動作 ////////////////////////////ryu////////////////////////////////////////////////////// sub right_n() // { // if (SENSOR_1<BLACK_01) {turn_left;} // else if (SENSOR_1<BLACK_02) {left;} // else if (SENSOR_1<WHITE_01) {go_forward;} // else if (SENSOR_1<WHITE_02) {right;} // else {turn_right;}Wait(STEP); // } // // sub left_n() // { // if (SENSOR_1<BLACK_01) { // turn_right; // } // else if (SENSOR_1<BLACK_02) { // right; // } // else if (SENSOR_1<WHITE_01) { // go_forward; // } // else if (SENSOR_1<WHITE_02) { // left; // } // else { // turn_left; // } // Wait(STEP); // } // ///////////////////////////////////////////////////////////////////////////////////// //以下のサブルーチンの説明は次のURLを参照 //ここから(URL:http://yakushi.shinshu-u.ac.jp/robotics/?2013a%2FMember%2Fwani%2FMission1#mbb67ccf) sub trace_R() { int n; while(true) { while(n < nMAX) { if(SENSOR_1 < CENTER-12) { turn_SL; n++; } else { if(SENSOR_1 < CENTER-6) { turn_L; } else if(SENSOR_1 < CENTER+6) { go_F; } else if(SENSOR_1 < CENTER+12) { turn_SL turn_R; } else { turn_SR; } n=0; } Wait(STEP); } short_break; turn_SR;Wait(nMAX*STEP*2); cross; n=0; break; } } sub trace_L() { int n = 0; while(true) { while(n < nMAX) { if(SENSOR_1 < CENTER-12) { turn_SR; n++; } else { if(SENSOR_1 < CENTER-6) { turn_R; } else if(SENSOR_1 < CENTER+6) { go_F; } else if(SENSOR_1 < CENTER+12) { turn_L; } else { turn_SL; } n=0; } Wait(STEP); } short_break; turn_SL;Wait(nMAX*STEP); cross; n=0; break; } } //ここまで(URL:http://yakushi.shinshu-u.ac.jp/robotics/?2013a%2FMember%2Fwani%2FMission1#mbb67ccf) task main() { //センサーの起動 SetSensorLight(S1); SetSensorLight(S2); //時間制御のための変数 long timess = 0; //ここから機体は動き出す trace_L(); Wait(1000); go_b; Wait(950); turn_SL; Wait(800); PlaySound(SOUND_CLICK);//ブザー1(ブザーは動作確認のため3回鳴らしている) go_F; Wait(550); go_F; catch; while(SENSOR_1 > CENTER+8 ) { Wait(STEP); } PlaySound(SOUND_CLICK);//ブザー2 Off(OUT_AC); /////////////////////////////ボールキャッチ後//////////////////////////////////////// go_F; Wait(90); turn_SR; Wait(750); PlaySound(SOUND_CLICK);//ブザー3 Wait(1000); trace_R(); turn_SR; Wait(700); //////////////////////////////二回目の交差点終了///////////////////////////////////// trace_L(); Wait(1000); PlaySound(SOUND_CLICK); PlaySound(SOUND_CLICK); //////////////////////////////////三回目の交差点認識//////////////////////////////// go_b; Wait(800); Off(OUT_AC); Wait(100); RotateMotor(OUT_A,-70,410);//90°向きを変える throw; RotateMotor(OUT_A,70,470);//向きをもどす。少し多めに回すことで確実にライン上にセンサーがくるようにした。 go_F; Wait(200); ///////////////////////////////////一回目の発射終了///////////////////////////////// timess = CurrentTick(); while(CurrentTick() - timess < 4000) { left_n(); } Off(OUT_AC); Wait(2000); RotateMotor(OUT_A,-70,440); Off(OUT_AC); Wait(10000); catch; catch; RotateMotor(OUT_A,70,440); ///////////////////////////////////一回目のボールキャッチ//////////////////////////// go_F; Wait(1700); timess = CurrentTick(); Off(OUT_AC); RotateMotor(OUT_A,-70,460); Wait(2000); throw; ///////////////////////////////////行きの最後のパス////////////////////////////////// }
自分が担当した初めのボールを取りにいく部分と初めの投げる角度を調整するところが最も苦労した。
今回のプログラミングでは、出来るだけ一定の動きだけで動けないかということを考えました。今まで使ってきたライントレースのプログラムに加え、ボールを打つ・取るという動作をルーチンとして加えました。このプログラムのまとまりを組み合わせることですべての動作を実現しようとしました。
最も苦労した部分は最初のボールを取る部分だった。
一度ラインから離れるためその後の動作をどうするかで苦労しました。
何度もライン際の動きを観察しながらもっとも良い動きを試行錯誤した。
最終的に本番ではうまくいって良かった。
また、ボールを投げる動作への移り変わるがなかなか難しかった。
機種の向きや投げる強さは何回か繰り替え調整することで出来た。
最終課題はなかなか難しかった。最終日に空き缶に当てるようにまで改良が出来たが本番では2本パスが通った状態で終了してしまた。
ロボコンでの自分の力を十分に発揮するためには事前に成功する確立を十分に上げる必要があると感じた。
今回のようなハード制御のプログラミングは珍しいので特別な経験になって良かった。