目次 #contents * メンバー [#ibb85475] suiden : 主に機体を担当~ kiyomizu : 主にアーム全体を担当~ kowhich: 主にプログラムを担当~ ryu-abe: 主に数値計測を担当~ * 課題の内容 [#w222b816] 左半分に設置されたA,B,Cの紙コップを、ロボットを右上のスタート地点で起動させ、Aを1、Bを2、Cを3の紙コップに重ねる。~ ただし、A,B,Cの紙コップは、さいころを振り、その結果によりランダムに設置する。 &ref(robo mission2.png); ** ルール [#gcb7688d] -競技時間は審判が続行不能と判断するまで、あるいはリタイアするまで。 -図の右上のスタートエリアからスタートする(課題1と同じ)。接地している部分がスタートエリア内に入って入ればよい。 -右半分の紙コップは10cm内の移動は認める -開始の合図から5秒以内にスタートボタンを押す作業を完了すること。 -競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。途中でうまく動かなくなった場合、1回限り再スタートすることができる(再スタートの際に別プログラムで起動してよい) ** 細かいルール [#q561b39a] 紙コップの置き方や得点の計算方法などの細かいルールは http://yakushi.shinshu-u.ac.jp/robotics/?2014a%2FMission2 で確認してください。 * ロボットの紹介 [#qd0e48a4] ** ロボットの外観 [#e9cd888b] &ref(robo1.jpg);~ 最初に組み立てた機体は、本体を最後に取り付けようとしたが、空いている場所がなかったため、上部に取り付けたところ、重心が高くなりすぎてしまい、様々な不具合が生じてしまった。~ そのため、本体を下部に取り付けられるように、一から足回りやアームを組み立て直した。その結果、不具合も解消され、安定した動作ができる機体になった。 ** 光センサー ・ アーム ・ バンパー [#l1d78243] &ref(robo5.jpg);~ 光センサーは、ライントレース用と紙コップの識別用に2つを取り付けている。手前に見えるものが紙コップの識別用で、その奥に見えるのがライントレース用である。~ アームは、紙コップを確実に取るために、滑り止めとして摩擦の大きいタイヤを付けている。~ バンパーは、紙コップをより確実に取ることができるように取り付けたのだが、アームとの干渉や移動の際に他の紙コップに当たることを防ぐために、小さなものしか取り付けることができなかった。 そのため、あまり成功率の上昇には影響しなかった。 ** 紙コップの取り方 ・ 重ね方[#t5345db0] &ref(robo2.jpg); &ref(robo3.jpg); &ref(robo4.jpg);~ モーターが回転することにより、歯車が連動していき、アームが閉じて紙コップを挟む。~ さらに、モーターが回転すると、歯車の連動が止まり、アーム全体が持ち上がり、紙コップを運べるようになる。~ 紙コップを重ねるときは、モーターを逆回転させる。 * プログラムの内容 [#t4cb2c52] &ref(robo mission.jpg);~ 紙コップを識別するプログラムを組めなかったので、上図のような動きをするプログラムを作成した。~ このプログラムでは、上図におけるAを1、Bを2、Cを3に重ねるようになっている。~ ※本番ではA,B,Cはランダムに設置されるため、高得点を狙うためには運が必要である。 ** 定義 [#g2e707e7] #define THRESHOLD 50 #define turn_left0 OnFwd(OUT_B,30); #define turn_left1 OnFwd(OUT_B,30);OnFwd(OUT_C,-30); #define turn_right0 OnFwd(OUT_C,30); #define turn_right1 OnFwd(OUT_C,30);OnFwd(OUT_B,-30); #define STEP 1 #define nMAX 250 #define short_break Off(OUT_BC);Wait(1000); #define cross_line;OnFwd(OUT_BC,40);Wait(300);short_break;PlaySound(SOUND_UP); ** サブルーチン [#r87f74a8] sub catch() { OnFwd(OUT_A,-20);Wait(1000); OnFwd(OUT_A,-50);Wait(400); Off(OUT_A); } sub release() { OnFwd(OUT_A,20);Wait(1000); OnFwd(OUT_A,50);Wait(100); Off(OUT_A); } 紙コップを取るプログラムと、重ねるプログラムをサブルーチンとして設定する。 ** Part1 [#o91ad579] task main() { SetSensorLight(S2); SetSensorLight(S3); int nOnline = 0; int nPoint = 0; OnFwdSync(OUT_BC,60,0);Wait(2000);Off(OUT_BC); OnFwdSync(OUT_BC,75,-100);Wait(450);Off(OUT_BC);Wait(1000); OnFwdSync(OUT_BC,60,0);Wait(1200);Off(OUT_BC); catch(); OnFwdSync(OUT_BC,60,0);Wait(700); OnFwdSync(OUT_BC,60,-100);Wait(500);Off(OUT_BC);Wait(1000); スタート地点から出発し、直進 → 旋回 → 直進 → 紙コップを取る → 直進 → 旋回 の順に動作する。 ** Part2 [#b4ae5e03] long t0 = CurrentTick(); while (CurrentTick() - t0 < 3000) { if (SENSOR_3 > THRESHOLD +2) { OnFwd(OUT_B,40); } else { Off(OUT_BC); } Wait(STEP); } 3秒間、白い部分の上では左折し、黒い部分の上では静止する。 ** Part3 [#ga188815] while (nPoint <= 1) { while (nOnline < nMAX){ if (SENSOR_3 < THRESHOLD -10) { turn_right1; nOnline++; } else { if (SENSOR_3 < THRESHOLD -5) { turn_right0; } else if (SENSOR_3 < THRESHOLD +2) { OnFwdSync(OUT_BC,30,0); } else if (SENSOR_3 < THRESHOLD +8) { turn_left0; } else { turn_left1; } nOnline=0; } Wait(STEP); } short_break; turn_left1; Wait(nMAX*STEP); cross_line; nPoint++; nOnline=0; } ラインの右側をトレースし、交差点があれば渡る。 ** Part4 [#y7bb456e] while (nPoint == 2) { OnFwdSync(OUT_BC,30,0);Wait(1500);Off(OUT_BC);Wait(1000);Wait(1000); OnFwdSync(OUT_BC,-30,0);Wait(500);Off(OUT_BC); release(); OnFwd(OUT_C,-30);Wait(200); OnFwdSync(OUT_BC,-60,0);Wait(900);Off(OUT_BC); catch(); OnFwdSync(OUT_BC,75,-100);Wait(900);Off(OUT_BC); nPoint++; } 交差点を渡った後、前進 → 後退 → 紙コップを重ねる → 旋回 → 後退 → 旋回 の順で動作する。 ** Part5 [#s021d185] long t1 = CurrentTick(); while (CurrentTick() - t1 < 3000) { if (SENSOR_3 > THRESHOLD +2) { OnFwd(OUT_C,40); } else { Off(OUT_BC); } Wait(STEP); } 3秒間、白い部分の上では右折し、黒い部分の上では静止する。 ** Part6 [#f2e0d9b2] while (nPoint <= 6) { while (nOnline < nMAX + 50){ if (SENSOR_3 < THRESHOLD -10) { turn_left1; nOnline++; } else { if (SENSOR_3 < THRESHOLD -5) { turn_left0; } else if (SENSOR_3 < THRESHOLD +2) { OnFwdSync(OUT_BC,30,0); } else if (SENSOR_3 < THRESHOLD +8) { turn_right0; } else { turn_right1; } nOnline=0; } Wait(STEP); } short_break; turn_right1; Wait(nMAX*STEP); cross_line; nPoint++; nOnline=0; } ラインの右側をトレースし、交差点があれば渡る。 ** Part7 [#q86e5235] while (nPoint == 7) { OnFwdSync(OUT_BC,75,100);Wait(300);Off(OUT_BC);Wait(1000); OnFwdSync(OUT_BC,-60,0);Wait(900);Off(OUT_BC); OnFwdSync(OUT_BC,75,100);Wait(200);Off(OUT_BC);Wait(1000); release(); OnFwdSync(OUT_BC,60,0);Wait(1000);Off(OUT_BC);Wait(1000); catch(); OnFwdSync(OUT_BC,60,0);Wait(500);Off(OUT_BC);Wait(1000); nPoint++; } 交差点を渡った後、旋回 → 後退 → 旋回 → アームを開く → 前進 → 紙コップを取る → 前進 の順で動作する。 ** Part8 [#oa27304a] long t2 = CurrentTick(); while (CurrentTick() - t2 < 5000) { if (SENSOR_3 > THRESHOLD +2) { OnFwd(OUT_B,-20);OnFwd(OUT_C,50); } else { Off(OUT_BC); } Wait(STEP); } 5秒間、白い部分の上では右折し、黒い部分の上では静止する。 ** Part9 [#raa5b6d5] while (nPoint == 8) { while (nOnline < nMAX){ if (SENSOR_3 < THRESHOLD -10) { turn_left1; nOnline++; } else { if (SENSOR_3 < THRESHOLD -5) { turn_left0; } else if (SENSOR_3 < THRESHOLD +2) { OnFwdSync(OUT_BC,30,0); } else if (SENSOR_3 < THRESHOLD +8) { turn_right0; } else { turn_right1; } nOnline=0; } Wait(STEP); } short_break; turn_right1; Wait(nMAX*STEP + 600); cross_line; OnFwd(OUT_BC,30);Wait(200); nPoint++; nOnline=0; } ラインの左側をトレースし、交差点があれば渡る。 ** Part10 [#k25c65bf] long t3 = CurrentTick(); while (CurrentTick() - t3 < 18000) { if (SENSOR_3 < THRESHOLD -10) { turn_right1; } else { if (SENSOR_3 < THRESHOLD -5) { turn_right0; } else if (SENSOR_3 < THRESHOLD +2) { OnFwd(OUT_BC,30); } else if (SENSOR_3 < THRESHOLD +8) { turn_left0; } else { turn_left1; } Wait(STEP); } } OnFwdSync(OUT_BC,75,-100);Wait(1000);Off(OUT_BC);Wait(1000); 18秒間、ラインの左側をトレースする。その後、旋回する。 ** Part11 [#sa23a666] while (nPoint == 9) { while (nOnline < nMAX){ if (SENSOR_3 < THRESHOLD -10) { turn_left1; nOnline++; } else { if (SENSOR_3 < THRESHOLD -5) { turn_left0; } else if (SENSOR_3 < THRESHOLD +2) { OnFwdSync(OUT_BC,30,0); } else if (SENSOR_3 < THRESHOLD +8) { turn_right0; } else { turn_right1; } nOnline=0; } Wait(STEP); } short_break; turn_right1; Wait(nMAX*STEP); cross_line; nPoint++; nOnline=0; } ラインの右側をトレースし、交差点があれば渡る。 ** Part12 [#f5cf206b] while (nPoint == 10) { OnFwdSync(OUT_BC,30,0);Wait(800);Off(OUT_BC);Wait(1000); OnFwdSync(OUT_BC,-30,0);Wait(600);Off(OUT_BC);Wait(1000); release(); nPoint++; } 交差点を渡った後、前進 → 後退 → 紙コップを重ねる の順で動作する。 ** Part13 [#w37593ae] while (nPoint == 11) { OnFwdSync(OUT_BC,-60,0);Wait(1200);Off(OUT_BC); OnFwdSync(OUT_BC,75,-100);Wait(500);Off(OUT_BC);Wait(1000); OnFwdSync(OUT_BC,60,0);Wait(1800);Off(OUT_BC); catch(); nPoint++; } 紙コップを重ねた後、後退 → 旋回 → 前進 → 紙コップを取る の順で動作する。 ** Part14 [#u6f59499] while (nPoint == 12) { OnFwdSync(OUT_BC,75,-100);Wait(1000);Off(OUT_BC);Wait(1000); OnFwdSync(OUT_BC,60,0);Wait(2500);Off(OUT_BC); OnFwdSync(OUT_BC,-30,0);Wait(600);Off(OUT_BC);Wait(1000); release(); nPoint++; } } 紙コップを取った後、旋回 → 前進 → 後退 → 紙コップを重ねる の順で動作する。 ** 実際のプログラム [#e092ea9a] 説明しやすくするためにPartごとに区切って説明したが、実際のプログラムは定義〜Part14までをつなげたものである。~ また、次のことに注意が必要である。 + 電池残量が100%のときを想定してプログラムを組んだため、電池残量が少ないと正常に動作しない場合がある。 + しきい値が日や時間によって変わることがあるため、しきい値の変更が必要な場合がある。 * 感想・反省 [#yb026e37] ロボットの機体は、1回失敗したものの、最終的には安定感のある整ったものを組み立てることができたと思う。しかし、バンパーがあまり機能しなかったので、そこだけが残念な点だった。~ プログラムは、時間不足や実力不足で、紙コップを識別するプログラムを組むことができなかった。また、時間に頼りすぎるプログラムになってしまい、電池残量や機体の動きの誤差で失敗することが多くなってしまった。見やすく分かりやすいプログラムにすることもできず、膨大なものになってしまった。 プログラムは、時間不足や実力不足で、紙コップを識別するプログラムを組むことができなかった。また、時間に頼りすぎるプログラムになってしまい、電池残量や機体の動きの誤差で失敗することが多くなってしまった。実際、本番でも思い通りに動作せずに終わってしまった。見やすく分かりやすいプログラムにすることもできず、膨大なものになってしまった。 今回は全体的に時間が足りず、すべてにおいて中途半端な出来になった。特にプログラムの方は間に合わせで無理矢理作ったものであり、発表するのも恥ずかしいものになってしまった。 今回は全体的に時間が足りず、すべてにおいて中途半端な出来になった。特にプログラムの方は間に合わせで無理矢理作ったものであり、発表するのも恥ずかしいものになってしまった。時間に余裕をもって計画的に作成するべきだった。 今回で終わりなので次回はないが、これからは「早く正確に」を心掛けていきたい。