目次 #contents * 課題 [#b4e354e7] 光センサを一つ用いてライントレースをするロボットを作成する。 ** 目標 [#v82ad74a] 画像のコースを次の手順で走行するロボットの作成。またロボットはコースの途中でピンポン球をキャッチし、ゴールまで運ぶ作業をする。 Aスタート → P直進 → Q直進 → (ピンポン玉をキャッチ) → Q直進 → R右折 → P直進 → S左折 → Dへシュート また、交差点では一秒間停止する。 * ロボットの説明 [#wd9f06ae] ** 機体全体の説明 [#n1c5c10b] コースには多くのコーナーや急なカーブがある。よって、小回りが効くようにするために機体全体をコンパクトにまとめ、車輪は二輪とした。二輪だけだと車体のバランスがとれないので、後ろにスペーサーを取り付けた。光センサは車輪と車輪のちょうど中央の位置から少し前方に取り付け、ロボットがライントレースをする際にスムーズに動くようにした。 ** アームの説明 [#e14035ea] 黄色いアームで左右から挟む方法でピンポン球をキャッチすることにした。アームを動かすモーターはロボットの上に取り付け、ギアを長い棒でつなげることで車体の横幅を大きくしないように工夫した。 * プログラムの説明 [#c453f9e7] ** 定義の説明 [#c1accb72] #define MASHIRO 52 //光センサが白を認識するしきい値 #define SHIRO 48 //光センサが灰色寄りの白を認識するしきい値 #define HAIIRO 42 //光センサが灰色を認識するしきい値 #define KURO 39 //光センサが灰色寄りの黒を認識するしきい値 #define MOVE_TIME 23 //光センサが黒を認識し続けて、交差点だと判断するまでの時間 #define OFF_TIME 100 //ロボットがピンポン球をつかむ前に小休止する時間 #define go_forward OnFwd(OUT_AC); //ロボットを前進 #define turn_right OnFwd(OUT_A);Off(OUT_C); //ロボットを右折 #define senkai_right OnFwd(OUT_A);OnRev(OUT_C); //ロボットを右旋回 #define turn_left OnFwd(OUT_C);Off(OUT_A); //ロボットを左折 #define senkai_left OnFwd(OUT_C);OnRev(OUT_A); //ロボットを左旋回 #define go_back OnRev(OUT_AC); //ロボットを後退 #define tukamu Off(OUT_AC);Wait(OFF_TIME);OnRev(OUT_B);Wait(12);Off(OUT_B); //ピンポン球をつかむ #define hanasu Off(OUT_AC);Wait(OFF_TIME);OnFwd(OUT_B);Wait(12);Off(OUT_B); //ピンポン球を離す #define tjiro Off(OUT_AC);Wait(50);go_back;Wait(40); //T字路でのロボットの挙動。小休止のあと少し後退する **サブルーチンの説明 [#o627cdf3] sub kihon() { if(SENSOR_3>MASHIRO){ senkai_right; ClearTimer(0); //白ければ右旋回 } else if(SENSOR_3>SHIRO){ turn_right; ClearTimer(0); //灰色よりの白ならば右折 } else if(SENSOR_3>HAIIRO){ go_forward; ClearTimer(0); //灰色なら前に直進 } else if(SENSOR_3>KURO){ turn_left; ClearTimer(0); //灰色寄りの黒ならば左折 } else{ senkai_left; //黒ならば左旋回 } } 交差点以外ではこのプログラムのとおりにロボットが動くようにした。 ** メインプログラムの説明 [#ee19f067] task main() { int n=0; SetSensor(SENSOR_3,SENSOR_LIGHT); SetPower(OUT_AC,3); SetPower(OUT_B,2); while(n<=7){ ClearTimer(0); while(FastTimer(0)<MOVE_TIME){ kihon(); } //交差点以外でのロボットの挙動 senkai_right; Wait(MOVE_TIME+4); //交差点を認識し、コースに対して斜めを向いている車体を真っ直ぐに直す Off(OUT_AC); Wait(100); //交差点で一秒止まる go_forward; Wait(28); //T字路か十字路か判断するために前進する n++; //交差点を数える if(SENSOR_3>MASHIRO){ //前進した先が白かった場合、T字路であると判断する if(n==4){ tjiro; //小休止後、コースに戻るために少し後退 turn_right; Wait(23); //右折して交差点から脱出 } if(n==6){ tjiro; //小休止後、コースに戻るために少し後退 turn_left; Wait(43); //左折して交差点から脱出 } } if(n==2){ ClearTimer(1); while(FastTimer(1)<150){ //ピンポン球があるところまで進む(1.5秒間) kihon(); } tukamu; //ピンポン球をつかむ } if(n==7){ hanasu; Off(OUT_AC); //ピンポン球を離す } } Off(OUT_AC); } ピンポン球をつかむ際に、アームの勢いが強いとピンポン球を弾いてしまうことがあるので、SetPowerで調節した。またタイヤも勢いが強すぎると誤作動を起こしやすいと考えたため、SetPowerで調節した。 交差点でT字路か十字路か判断するためにすこし前進する時、前進しすぎるとコースアウトしてしまい、少なすぎるとT字路の場合白い部分まで届かないので、ちょうどよい前進時間を模索した。交差点を判断するための時間も同じように調べた。 直線をジグザグに進むとロボットが遅くなるため、しきい値SHIROとしきい値HAIIROの数値の間を多めにとり、直進しやすくした。 * 結果 [#ve38ab95] 一度だけゴールまで進んだが、ほとんどの試行で誤作動をおこし、ゴールできなかった。 * 考察 [#g298e60d] ** 頻繁に起きた誤作動とその理由 [#p81b9faa] ・交差点を認識せずに走行 (理由)交差点を判断するための時間が長すぎるまたは黒を判断するためのしきい値に問題があったと考えられる。実際この値を調節することで頻度を抑えられた。 ・車輪が抜ける (理由)カーブやT字路を曲がったあとに頻繁におきたため、車輪がその負担に耐えられなかったからだと考えられる。なぜ耐えられないかというと、タイヤと軸の差し込みがゆるくなっていたからだと考えられる。 ・車輪が空回りをする (理由)タイヤの劣化のため、モーターもギアも回っているのにタイヤのゴムの部分だけ回転しなかった。アーム用のモーターが前のほうに取り付けられていたので、タイヤにかかる重さが大きくなり、タイヤの摩擦が上がったためとも考えられる。 * 感想 [#h65302b8]