[[2018a/Member]] #contents * 課題[#w3f30b24] **ライントレースロボットの製作 [#v30a912c] 幅2ミリの黒線をトレースするロボットを作る **以下のコースを進み,課題を達成させる(課題としてはAコース) [#u99b98ee] #ref(./コース.png,70%,コース) 1. Aをスタート 2. Bを直進 3. Cで一時停止の後、直進 4. Dで一時停止の後、Xの空き缶をキャッチしてD地点に戻る 5. DからEに向かい、Eを直進 6. Fを左折 7. Gで一時停止の後、左折 8. Hで一時停止の後、右折 9. Iで一時停止の後、右折 10. Lを直進 11. Kを直進 12. Jで一時停止の後、空き缶をYに置きてJに戻りBに向かう 13. Bで一時停止の後、左折 14. Aで停止 (一時停止の指定がある場所は、1秒間停止すること) * 製作したロボット[#wbc0bea6] 小回りを利かせるために2輪ローバーにした.また,そのためのバランサーの先に光センサーを取り付けた.光センサーの高さは床から3mm程の位置になるよう調整した.缶をつかむ機構はクワガタのような型にした.開閉にはラックを前後させ,2本の角に支点を設けることで動かす機構を採用した. **全体像 [#k59e399b] #ref(./全体像.jpg,50%,全体像) **車体下部 [#nd75eca7] #ref(./車体下.jpg,40%,車体下部) **上から見た車体 [#yf0066e9] #ref(./車体上.jpg,40%,車体上) **つかみ部のラック [#i5815de7] #ref(./つかみ部.jpg,40%,つかみ部) **つかみ部の動き方 [#ie2da74d] &ref(./アーム1.png,70%,作動前); &ref(./アーム2.png,70%,作動後); * 製作したプログラム[#i91f01f2] A端子が左車輪,B端子がつかみ部の開閉,C端子が右車輪を制御する.また,2番端子に光センサーを接続している. **ライントレースプログラムの仕組み [#sf71d29d] 光センサーは赤色光を照射し,その反射光を検知し,明るいほど高い数値を表す.ライントレースのプログラムはそれを利用して,黒い部分と白い部分の中間をたどるように閾値を設定し,それぞれの明るさに応じた行動をとらせる.また,機体の向きを修正する時間がある値以上になったらそこを交差点と判断するようにする.今回は光センサーの値が45となるところを基準とし,+ー7以上で急旋回,+−5以上で曲がり,−5から+5の間で直進するように設定している.また,急旋回する向き・曲がる向きは,右側トレースの時は+5以上で左,−5以下で右に,左側トレースの時は+5以上で右,−5以上で左となる. 光センサーは赤色光を照射し,その反射光を検知し,明るいほど高い数値を表す.ライントレースのプログラムはそれを利用して,黒い部分と白い部分の中間をたどるように閾値を設定し,それぞれの明るさに応じた行動をとらせる.また,機体の向きを修正する時間がある値以上(FastTimer(0)<=55/2)になったらそこを交差点と判断するようにする.(これは直線や曲線ではこの時間以内に次の動作に入りFastTimer(0)がリセットされるが,交差点ではこの時間以内に次の動作に入らず,FastTimer(0)がリセットされないからである.)今回は光センサーの値が45となるところを基準とし,+ー7以上で急旋回,+−5以上で曲がり,−5から+5の間で直進するように設定している.また,急旋回する向き・曲がる向きは,右側トレースの時は+5以上で左,−5以下で右に,左側トレースの時は+5以上で右,−5以上で左となる. **使用したマクロ [#ce259723] #define x 45 //閾値の設定 #define r 65 //90度の旋回時間(roll time) #define g 35 //缶をつかみに・離しに行くまでの時間(go time) **サブルーチン・右側トレース [#qb0298bf] sub line2() { ClearTimer(0); while(FastTimer(0)<=55/2){ //交差点を判断する値 if(SENSOR_2>x+7){ //光センサーの値が閾値+7以上だったら左に急旋回 OnRev(OUT_A); OnFwd(OUT_C); ClearTimer(0); }else if(SENSOR_2>=x+5){ //光センサーの値が閾値+5以上だったら左に曲がる Off(OUT_A); OnFwd(OUT_C); ClearTimer(0); }else if(SENSOR_2>x){ //光センサーの値が閾値より大きかったら直進 OnFwd(OUT_AC); ClearTimer(0); }else if(SENSOR_2>=x-5){ //光センサーの値が閾値-5以上だったら右に曲がる Off(OUT_C); OnFwd(OUT_A); ClearTimer(0); }else{ //それ以外だったら右に急旋回 OnRev(OUT_C); OnFwd(OUT_A); } } Off(OUT_AC); //交差点が来たらとまれ PlaySound(SOUND_DOUBLE_BEEP); //停止と同時に音を出せ } **サブルーチン・左側トレース(基本) [#eb284728] sub line() { ClearTimer(0); while(FastTimer(0)<=55/2){ //交差点を判断する値 if(SENSOR_2>x+7){ //光センサーの値が閾値+7以上だったら右に急旋回 OnRev(OUT_C); OnFwd(OUT_A); ClearTimer(0); }else if(SENSOR_2>=x+5){ //光センサーの値が閾値+5以上だったら右に曲がる Off(OUT_C); OnFwd(OUT_A); ClearTimer(0); }else if(SENSOR_2>x){ //光センサーの値が閾値より大きかったら直進 OnFwd(OUT_AC); ClearTimer(0); }else if(SENSOR_2>=x-5){ //光センサーの値が閾値-5以上だったら左に曲がる Off(OUT_A); OnFwd(OUT_C); ClearTimer(0); }else{ //それ以外だったら右に急旋回 OnRev(OUT_A); OnFwd(OUT_C); } } Off(OUT_AC); //交差点が来たらとまれ PlaySound(SOUND_DOUBLE_BEEP); //停止と同時に音を出せ } **サブルーチン・離すプログラム [#of5668e3] sub release() { OnFwd(OUT_C); //左に曲がる OnRev(OUT_A); Wait(r); Off(OUT_AC); OnFwd(OUT_AC); //前進 Wait(g); Off(OUT_AC); OnRev(OUT_B); //腕を開く Wait(10); Off(OUT_B); OnRev(OUT_AC); //後退 Wait(g); Off(OUT_AC); OnRev(OUT_C);180度旋回 OnFwd(OUT_A); Wait(r*2);` Off(OUT_AC); } **サブルーチン・掴むプログラム [#ab92bbb8] sub cat() { OnFwd(OUT_AC); //前進 Wait(g); Off(OUT_AC); OnFwd(OUT_B); //腕を閉じる Wait(10); Off(OUT_B); OnRev(OUT_AC); //後退 Wait(g); Off(OUT_AC); } **メインプログラム [#fcaf5452] task main() { SetSensor(SENSOR_2,SENSOR_LIGHT); //光センサーを定義 OnFwd(OUT_AC); //最初の黒線を乗り越える Wait(30); Off(OUT_AC); line(); line(); Wait(100); //until C OnFwd(OUT_AC); //Cの黒線を乗り越える Wait(70); Off(OUT_AC); line(); Wait(100); //until D cat(); //缶をつかむ Wait(100); //Dで停止 OnFwd(OUT_C); //D turn OnRev(OUT_A); Wait(r); Off(OUT_AC); Wait(100); line(); //until E line(); //until G OnFwd(OUT_C); //Gで曲がる OnRev(OUT_A); Wait(r); Off(OUT_AC); Wait(100); line(); line(); Wait(100); //until H OnFwd(OUT_C); //Hで曲がる Off(OUT_C); Wait(r); Off(OUT_AC); line(); Wait(100); //until I OnFwd(OUT_A); //Iで曲がる Off(OUT_C); Wait(r/2); Off(OUT_AC); line2(); //ここから右トレース Wait(100); //until L line2(); Wait(100); //until K line2(); Wait(100); //until J release(); //缶を離す line(); //ここから左トレース Wait(100); //until B OnFwd(OUT_C); OnRev(OUT_A); Wait(r); Off(OUT_AC); //Bで曲がる line(); //until A OnFwd(OUT_AC); /枠内へ Wait(300); Off(OUT_AC); //停止 } * まとめ[#wf4cffdf] **車体について [#i6fc5bfb] センサーやタイヤの劣化による誤差によって1回1回の結果が変わってしまった.また,つかむ機構が走行中にゆるんでしまい,缶が途中でこぼれてしまうことがあった.劣化のほうはどうにもならないが,ゆるんでしまうのはモーター側のトルクを大きくすることで改善できると思う.次に,缶をつかみに行く際に,最初はタッチセンサーを使用しようと考えていたが,缶が軽すぎて反応しなかった.そのため,タッチセンサーを反応しやすくする必要があるが,その場合車体の振動で反応してしまうことが考えられる.そのため,タッチセンサー以外の使用が望ましい.しかしそれ以外の面ではおおむね良好であったと思う. **プログラムについて [#ca2ee730] ライントレースのサブルーチンを右側トレース・左側トレースの二つを作ることにより,場所に応じて好ましいほうを選択できるようになり,片側だけでは突破の難しかったところを突破できた.この時の閾値の調整に手間取った.しかし直線の途中で止まってしまうことがあったが,同じプログラムを重ねることで解決した.そのほかには特に問題はなく,しっかりと動いてくれたので良かった.