[[2017a/Member]] 目次 #contents *課題について [#n8eb9e7f] 空き缶を収集し、ゴールに空き缶をなるべく高く積み上げるという課題だ。 &ref(2017a/Member/ejj/Mission3/pic_ejj13.JPG,100%,); フィールドの説明 ◦フィールドは課題2で使用した紙を使用する ◦図のピンク色の場所に350mlの空き缶を置く ◦図のライトブルーの円のいずれか一箇所に中身の入った350mlの缶を置く ◦中身の入った缶には紙をはったり図などを描いてもよい #ls2(2017a/Mission3,link,詳しくはこちら) *ロボットについて [#n5945547] **最初に作ろうとしたロボット [#ma07bc8f] 初めは特に何も考えずに正しく動くロボットの完成を目指していたが、アーム部分に部品を使いすぎたためこの先部品不足になることが明らかだった。また、土台部分にRCXを取り付けるとき、横向きにして並べると線の長さが足りずまたしても部品不足に陥った。ロボット作りを初めてすぐにこのミッションの難しさを実感した。 **完成したロボット [#m8c354a8] ***ロボットの全体像 [#zef81a13] ロボットの写真を4つの方向から撮ったものだ。 &ref(2017a/Member/ejj/Mission3/pic_ejj14.JPG,100%,); &ref(2017a/Member/ejj/Mission3/pic_ejj15.JPG,100%,); &ref(2017a/Member/ejj/Mission3/pic_ejj16.JPG,100%,); &ref(2017a/Member/ejj/Mission3/pic_ejj17.JPG,100%,); 失敗作の反省からなるべく少ない部品で完成させるように心がけた。また、RCXは立てて並べることにより線が届かなかったり重心がおかしくなる問題を解決した。大きなタイヤを使うと小回りがきかなくなったり、動きが速くなり缶が落ちやすくなると考え、小さなタイヤを使った。後ろのタイヤはロボット全体を支える役割のみなので摩擦が小さい部品を使った。センサーは光センサーを3つ使った。ライントレース用に2つと缶を見つけるための1つだ。初めはタッチセンサーも使おうとしたがうまく反応しないことも多かったので使わないことにした。写真を撮り忘れてしまったが、ロボットはコンパクトに分解できるように作っており、持ち運びが楽になり、さらに途中で壊してしまうリスクも減った。 ***細かい部分の説明 [#ofdcacdf] ・正面下部分 アームは閉じたままキープする必要がありモーターが回りっぱなしになるため、負荷がかかりすぎないように白のギアを使った。ライントレース用の光センサー2つは何度か位置を変えたがこの場所が一番ロボットの動きがよかった。写真で光っているのが缶を見つけるためのセンサーだ。正面にクワガタの形を作ることにより缶が一定の位置につくようにしている。その形も特殊でプログラムに合った形をしている。 &ref(2017a/Member/ejj/Mission3/pic_ejj18.JPG,100%,); ・レール部分 レールは4つのギアで固定した。そのギアの締め付け具合によってうまくいったりいかなかったりしたので、動かす前に確認が必要だった。レールの長さは缶を積み上げるのに十分な長さだった。 &ref(2017a/Member/ejj/Mission3/pic_ejj19.JPG,100%,); ・アーム上下用のモーター部分 モーターを動かしているとモーターが外れることがあったのでがっちり固定し、コンパクトにした。 &ref(2017a/Member/ejj/Mission3/pic_ejj20.JPG,100%,); ・アーム部分 つかんだ缶が移動中の振動により少しづつ落ちてきてしまうためアームの下に小さなギアをつけ、缶の下の細くなっているところにうまくひっかかるようにした。この改良後は缶がづれる問題は一切怒らなくなった。また、全体像の写真で確認できるが、アームの上に黄色い棒を立てることにより重量を抑えつつも3段目が安定するように作った。 &ref(2017a/Member/ejj/Mission3/pic_ejj21.JPG,100%,); *プログラムについて [#t09fddd8] **アーム部分のプログラム [#v37efe9c] Aはアーム上下、Cはアーム開閉になるようにつないだ。 ***define、sub、voidなどの説明 [#p3ce94ad] 缶だけでは光が反射して正確に認識できなかったため、黒い紙を貼り光センサーが缶と認識しやすいようにした。缶判別の値は26とした。 #define kan_hanbetu 26 //光センサーが缶を判別する値 アームを閉じ、一番上まで上がるというvoidである。アームを閉じた後のwait時間は状況によって変わるためintを用い、引数とした。 void arm_close(int time) { OnRev(OUT_C); //アームを閉じる Wait(time); OnRev(OUT_A); //上に上がる Wait(280); Off(OUT_A); } 缶を持った状態でアームが一番上で停止しているところから、少し下がりアームを開いて缶を重ね、アームを一番下まで下げるsubだ。 sub arm_open() { Wait(300); OnFwd(OUT_A); //下に下がる Wait(20); Off(OUT_A); OnFwd(OUT_C); //アームを開く Wait(20); Off(OUT_AC); OnFwd(OUT_A); //下に下がる Wait(250); Off(OUT_A); } ***task main [#t925e73f] Whileとifを使うことで缶を判別したときに次のプログラムに進むようになっている。光センサーが缶を直前ではなく少し前の段階で判別してしまうため、ifの後にはWaitを入れ、調節している。その他のWaitは次の缶の場所に移動するときや、ゴールまで運んでいるときのWaitである task main () { while (true) { if (SENSOR_2 <= kan_hanbetu) { Wait(300); arm_close(300); Wait(100); OnRev(OUT_A); //上に上がる Wait(500); while (true) { if (SENSOR_2 <= kan_hanbetu) { arm_open(); Wait(80); arm_close(30); OnRev(OUT_A); //上に上がる Wait(500); while (true) { if (SENSOR_2 <= kan_hanbetu) { OnFwd(OUT_A); //下に下がる Wait(200); Off(OUT_A); Wait(200); OnFwd(OUT_C); //アームを開く Wait(30); Off(OUT_C); } } } } } } } **タイヤ部分のプログラム [#a09cb28c] ***define、sub、voidなどの説明 [#xdf801c0] 基本的な右左旋回、右左折、直進を定義した。 #define senkai_left OnRev(OUT_C);OnFwd(OUT_A);//左旋回 #define senkai_right OnFwd(OUT_C);OnRev(OUT_A); //右旋回 #define turn_left Off(OUT_C);OnFwd(OUT_A);//左折 #define turn_right OnFwd(OUT_C);Off(OUT_A);//右折 #define fwd OnFwd(OUT_AC);//直進 直進するプログラムだ。 void go_fwd(int time) { fwd; Wait(time); Off(OUT_AC); } 交差点を右折するプログラムだ。旋回をすることで小さく曲がれるようにした。 sub usetu() { turn_right; Wait(230); Off(OUT_C); senkai_right; Wait(50); Off(OUT_AC); OnRev(OUT_AC); Wait(30); Off(OUT_AC); } 交差点を左折するプログラムだ。 sub sasetu() { turn_left; Wait(190); Off(OUT_A); senkai_left; Wait(40); Off(OUT_AC); } PQRSの交差点では、90度に曲がるのではないため、時間を調整し斜めに車体を向けるようにした。その時のプログラムがこれだ。 sub naname_usetu() { OnFwd(OUT_C); Off(OUT_A); Wait(200); Off(OUT_C); OnRev(OUT_AC); Wait(40); Off(OUT_AC); } 缶を置いて離れるためのプログラムだ。 sub owari() { turn_right; Wait(70); Off(OUT_AC); Wait(450); OnRev(OUT_AC); Wait(200); Off(OUT_AC); } ライントレースのプログラムだ。左右の光センサーが白色の上なら直進、左側の光センサーが黒色に近づいたら左折、右側の光センサーが黒色に近づいたら右折、左側の光センサーが黒線上にきたら左旋回、右側の光センサーが黒線上にきたら右旋回、右側のセンサーが0.11秒黒線上なら交差点だと判断し、止まる。 sub line_trace() { SetSensor(SENSOR_1, SENSOR_LIGHT); //右 SetSensor(SENSOR_3, SENSOR_LIGHT); //左 ClearTimer(0); PlaySound(SOUND_CLICK); while(FastTimer(0)<11){ if(SENSOR_1>=49&&SENSOR_3>=55){ fwd; ClearTimer(0); }else if(SENSOR_3>=50){ turn_right; ClearTimer(0); }else if(SENSOR_1>=40){ turn_left; ClearTimer(0); }else if(SENSOR_3>=48){ senkai_right; ClearTimer(0); }else if(SENSOR_1>=38){ senkai_left; ClearTimer(0); }else if(SENSOR_3>=30){ Off(OUT_AC); PlaySound(SOUND_LOW_BEEP); }else{ fwd; Wait(30); Off(OUT_AC); } } Off(OUT_AC); PlaySound(SOUND_CLICK); } 上のライントレースのプログラムの2つ目のタイマーが設定した時間になっても止まるようにしたプログラムだ。 void line_trace_2(int time) { SetSensor(SENSOR_1, SENSOR_LIGHT); //右 SetSensor(SENSOR_3, SENSOR_LIGHT); //左 ClearTimer(0); ClearTimer(1); PlaySound(SOUND_CLICK); while(FastTimer(0)<11&&FastTimer(1)<time){ if(SENSOR_1>=49&&SENSOR_3>=55){ fwd; ClearTimer(0); }else if(SENSOR_3>=50){ turn_right; ClearTimer(0); }else if(SENSOR_1>=40){ turn_left; ClearTimer(0); }else if(SENSOR_3>=48){ senkai_right; ClearTimer(0); }else if(SENSOR_1>=38){ senkai_left; ClearTimer(0); }else if(SENSOR_1>=30){ Off(OUT_AC); PlaySound(SOUND_LOW_BEEP); }else{ fwd; Wait(30); Off(OUT_AC); } } Off(OUT_AC); } ***task main [#xef9abbd] define、sub、voidを多く用いたため、task mainはシンプルに仕上げることができた。 task main() { go_fwd(50); line_trace(); usetu(); repeat(2){ line_trace(); Wait(50); naname_usetu(); Wait(50); } line_trace_2(230); Wait(500); senkai_left; Wait(200); Off(OUT_AC); go_fwd(30); line_trace(); Wait(450); sasetu(); line_trace(); owari(); } *まとめ [#ga635d52] **結果 [#zabd8b23] 結果は中身の入っていない缶を3段積み上げた。点数は3+6+9で18点だった。 実際の動きはこちらhttps://www.youtube.com/watch?v=I_fwqzWXyB0 **感想 [#dfbf460d] 今回のミッション3では1,2とは比べ物にならないほどの努力と時間を費やした。問題が発生する度にうまくいかないのはロボットのせいか、プログラムのせいか、接続が悪いのかと多くの可能性が考えられ、原因を見つけることさえも一苦労だった。また発表が他の班よりも早いこともあり、少ない時間でどこまでやれるかという不安も大きかった。成功した時はとても安心したし、苦労した分達成感も今まで以上だった。今後ロボットを作る機会はないと思うが研究などで忍耐強く続けなければならないことがあると思うので、今回このような経験をできたことはよかったと思う。