目次 #contents *はじめに [#h4d14bfa] Mission:次のいずれかのコースで黒い線に沿って動き、紙コップを移動させるロボットを製作せよ。 Dをスタート Cを直進 Bを左折 Pを左折(一時停止) Qを直進 Rを左折 Fを左折 Sを直進(一時停止) Y地点の紙コップを取得してコースに戻る Sを直進(一時停止) Qを左折(一時停止) Rを直進 X地点に紙コップを置いてコースに戻る Pを左折 B を左折(一時停止) A地点へ(ゴール) つまり、自立型ロボットでライントレースをして、紙コップを運ぶというのだ。 *ロボットの説明 [#n9c03d70] 全体図:ビジュアル度はかなり高得点だと言える。 #ref(2017b/Member/tetsuya/Mission2/image1 (1).jpeg,70%) **光センサーについて [#ucb31a14] 今回のロボットで重要かつ苦労したのは、「光センサーの数値を安定させること」だ。 光センサーは中心に近いほど、滑らかな動きになると考えた。ノーマルの四輪型の頭にセンサーを付けると、センサーと車輪の距離が大きいため、うまくライントレースできなかった。 次に、ノーマル四輪型の中心にセンサーをつけた。すると、旋回するときにずっと回転し続けてしまうことが分かった。 そして、カエル型のロボットが完成した。地面との距離、四輪の中心との距離、どちらもベストだった。 #ref(2017b/Member/tetsuya/Mission2/image2 (1).jpeg,60%) ↑光センサーの位置が絶妙。 **紙コップついて [#gda5797e] #ref(2017b/Member/tetsuya/Mission2/image2.jpeg,60%) ↑紙コップを捕らえるための装置。 「両側が挟む」や「持ち上げる」など考えたが、「被せて引きずる」のが簡易的だと考えた。 ロボットの背面にスペースがあったので、活用した。 **前輪について [#m7b7debf] このロボットの前輪はモータの力が伝わらない。そこで、どのパーツが極力摩擦力を減らせるのか試行錯誤した。 #ref(2017b/Member/tetsuya/Mission2/image1.jpeg,60%) ↑選ばれし前輪。 *プログラミングの説明 [#e6266252] **define [#b115edcc] #define turn_right SetPower(OUT_AC,3); Off(OUT_C);OnFwd(OUT_A); #define turn_left SetPower(OUT_AC,3); Off(OUT_A);OnFwd(OUT_C); #define go_straight SetPower(OUT_AC,3); OnFwd(OUT_AC); #define shift_right SetPower(OUT_AC,3); OnFwd(OUT_A);OnRev(OUT_C); #define shift_left SetPower(OUT_AC,3); OnFwd(OUT_C);OnRev(OUT_A); マクロで定義する。"SetPower(OUT_AC,?)"でモータの力を制御し、滑らかな動きになった。 **サブルーチン [#gd376d53] sub trace() { SetSensor(SENSOR_2,SENSOR_LIGHT); SetSensorMode(SENSOR_2,SENSOR_MODE_RAW); ClearTimer(0); while (FastTimer(0) < 34) { if (SENSOR_2 > 837){ shift_left;} else if (SENSOR_2 < 750){ ClearTimer(0); shift_right;} else{ ClearTimer(0); if (SENSOR_2 > 815){ turn_left;} else if (SENSOR_2 < 770){ turn_right;} else{ OnFwd(OUT_AC);} } } } サブルーチンで、ライントレースの動きをする関数を作った。 "SetSensorMode(SENSOR_?,SOR_MODE_RAW)"で、より詳細な値を測定する。(?は数字) このプログラムはラインの左側の境界線に沿ってトレースする。 光センサーで、5つの動きに分けた。 今回のMissionの難所の一つは、交差点を判断することだ。 "ClearTimer()"を使い、左旋回のときのみ時間を計測し、0.34秒以上で、交差点と判断し、"while"のループから抜け出す仕組みになっている。 急なカーブと交差点を区別するために、何回も実行し、光センサーの値を調べた。 **task main [#p27b4b36] task main () { //C go_straight;Wait(200); trace(); //B shift_left;Wait(60); trace(); //P* shift_left;Wait(60);Off(OUT_AC); PlaySound(SOUND_UP); Wait(100); trace(); このように、基本的には、交差点判断すると"while"から抜け出し、約90度旋回させ、また、トレースを繰り返していく。 "PlaySound();Wait(?)"で1秒間音を鳴らしている。 **紙コップを取る動作 [#t93f93f8] "PlaySound();Wait(?)"で1秒間音を鳴らしている。 //Q turn_right;Wait(30);Off(OUT_AC); trace(); //R shift_left;Wait(60);Off(OUT_AC); trace(); //E shift_left;Wait(60);Off(OUT_AC); trace(); //F shift_left;Wait(60);Off(OUT_AC); trace(); //S Off(OUT_AC);PlaySound(SOUND_UP);Wait(100); turn_right;Wait(30);Off(OUT_AC); shift_left;Wait(125);Off(OUT_AC);Wait(100); //Y OnFwd(OUT_B);Wait(40);Off(OUT_B);Wait(100); shift_right;Wait(125);Off(OUT_AC);Wait(100); trace(); 紙コップを捕える動作。背面に捕える装置があるため、旋回させている。 Y地点で紙コップを捕える動作。背面に捕える装置があるため、旋回させている。 //S* Off(OUT_AC);PlaySound(SOUND_UP);Wait(100); turn_right;Wait(30);Off(OUT_AC); trace(); //Q shift_left;Wait(60);Off(OUT_AC); trace(); //R* turn_right;Wait(30);Off(OUT_AC); trace(); //P shift_left;Wait(60);Off(OUT_AC); OnRev(OUT_B);Wait(40);Off(OUT_B); //X trace(); //B* shift_left;Wait(60); Off(OUT_AC);PlaySound(SOUND_UP);Wait(100); go_straight;Wait(185);Off(OUT_AC); } 最後の直進だけレースしなかった。 最後は、トレースしずに直進することで、動きを止めた。 *おわりに [#v230fe39] 今回のMissionを知った時、かなり難題に感じ、早くからロボット制作を行った。すると、一週間前に完成することができた。 しかし、本番当日の朝に電池が切れ、新しい電池に切り替えなければいけないことになった。 新しい電池にすると、光センサーの値、旋回の量が変わることに気づいた。なかなか調整できず、本番では、なんとかライントレースはできたものの、紙コップが取れなかったことが悔しかった。 このことから、何かしらの不具合が生じたときに、すぐに直せるようなプログラミングが良いプログラミングだと思った。