[[2009b]] *課題 [#j8fc75ee] 光センサーを使って線上を進むロボットの作成 また障害物に対して、⑴撤去して進む ⑵スタート地点に集める ⑶最寄りの交差点まで運ぶ 、のプログラム作成 *メンバー [#m8296b65] kata 「撤去して進む」担当 NISHI 「最寄りの交差点まで運ぶ」担当 SHIMA 「スタート地点に集める」担当 *目標 [#labab822] 速度は問わず、正確に進める個性豊かなロボットを製作できたらいいなあ。 *ロボット概要 [#r5a4ee77] **車体 [#gad521d7] #ref(body1.png,center) これが、僕たちが作成したロボットです。仕組みは、上部のアームが回転してパックを捕らえます。アームは、全面のバンパーに取り付けられたタッチセンサーにパックが反応すると、回転し始めます。後ろのバンパーは飾りです。 光センサーは、2個使用し、黒い線を挟み込む方式です。 車体は、なるべく小回りができるよう小型化に心掛けました。 **アーム [#x25eebea] #ref(arm.jpg,center,75%) 上の写真は、車体上部に設けられているアームの全体図です。このアームは、360度右回転も左回転もできます。車体上部からみて左回転でパックを確保し、右回転でパックを離します。 CENTER:&ref(f.jpg,left,60%);&ref(g.jpg,center,60%);&ref(h.jpg,right,60%); 次にアームの心臓であるギアボックスを解説します。 上の写真は、左よりギアボックスからアームを取り外したもので、右に行くにつれてギアボックスの外装が外れていってます。 このギアボックスの最大の工夫は、「カム」というギアのパーツを使用した点です。 (一番右の写真でいうとモーターから伸びている軸に取り付けられたトルネードしている物体です。) 初めは、アームはいくつかのギアを使用し取り付けていましたが、それだとアームの回転が速すぎました。 しかし、カムを用いることにより、回転速度を抑えられたので、この問題は解決しました。 ちなみに、軸先端に設けられたギアは、手動でアームを回転させるために設けられました。(すごく便利です。) **バンパー [#qd6cf1d2] CENTER:&ref(i.jpg,center,60%);&ref(j.jpg,center,60%); バンパーの工夫点は、反応しすぎず反応させる(!?)ことです。 どういうことかというと、パックが軽すぎるため通常のバンパーでは反応しません。そのためバンパーは、試行錯誤を重ねたほぼオリジナルです。 バンパーの先端は、黒と黄色の棒?を使いパックが当たりやすくなっています。なぜこの組み合わせかというと、アームの回転を妨げないからです。 **ホイール [#ve68a6c5] #ref(hoile.jpg) 上記の全体図では、後輪が設置されていませんが時と場合に応じて、上記のように後輪も設置できます。 *コースのレイアウト [#n57156b1] #ref(map.jpg) 試行錯誤の結果、上図のようになりました。 *プログラム [#sa7488f4] **NISHI,ver [#m7511be6] #define eye_L SENSOR_1 //SENSOR_1をeye_Lと定義 #define eye_R SENSOR_3 //SENSOR_3をeye_Rと定義 #define touch SENSOR_2 //SENSOR_2をtouchと定義 task main() { SetSensor(eye_L,SENSOR_LIGHT); SetSensor(eye_R,SENSOR_LIGHT); SetSensor(touch,SENSOR_TOUCH); repeat(3) { //以下の命令を3回繰り返す start follow_line; //ライントレースを開始 until (touch == 1); //停止してアームを4秒間左回転 stop follow_line; Off(OUT_A+OUT_C); OnFwd(OUT_B); Wait(800); Off(OUT_B); } ClearTimer(0); //タイマーを設定 while(Timer(0) <= 150 ){ //15秒間ライントレース start follow_line; } stop follow_line; Float(OUT_A+OUT_C); } task follow_line() { while(true) { if ((eye_L >= 36) && (eye_R >=35)) //両方白なら直進 { OnFwd(OUT_A+OUT_C); } else if ((eye_L >= 36) && (eye_R <= 35)) //右が黒なら右折 { OnFwd(OUT_A); OnRev(OUT_C); } else if ((eye_L <= 36) && (eye_R >= 35)) //左が黒なら左折 { OnRev(OUT_A); OnFwd(OUT_C); } else if ((eye_L <= 38) && (eye_R <= 39)) //両方黒なら { OnFwd(OUT_A+OUT_C); Wait(50); //0、5秒間前進 until((eye_L <= 40) && (eye_R <= 40)); //黒線に達したら Off(OUT_A+OUT_C); OnFwd(OUT_B); Wait(680); //アームを270度正回転 OnRev(OUT_B); Wait(680); //その後、270度負回転 Off(OUT_B); OnFwd(OUT_A+OUT_C); Wait(50); //0,5秒間前進 Off(OUT_A+OUT_C); } Wait(1); } } 関係ない場所で光センサーが両方反応してしまい、 いきなりアームを回し始めてしまってセンサーの値の調節がたいへんだった。 **SHIMA.ver [#x191c681] #define THRESHOLD 40 task main () { SetPriority(1); SetSensor(SENSOR_1,SENSOR_LIGHT); //SENSOR1は光センサー SetSensor(SENSOR_2, SENSOR_TOUCH); //SENSOR2はタッチセンサー SetSensor(SENSOR_3,SENSOR_LIGHT); //SENSOR3は光センサー int n; n=0 while( n<3 ) //以下の動作を3回行う。 { start follow_line; //線に沿って進む。 until(SENSOR_2==1); //タッチセンサーが反応したら stop follow_line; //線に沿って進むのをやめる。 Off(OUT_A+OUT_C); //いったん停止 OnFwd(OUT_B);Wait(820); //アームを動かし始める。 Off(OUT_B); //アームの停止 n=n+1 } if(n==3) //三回目が終わったら11秒ラインに沿って進み停止 { start follow_line;Wait(1100); Float(OUT_A+OUT_C); } } task follow_line() //ラインに沿って進むプログラム { while(true) { if (SENSOR_1>THRESHOLD) //左側のセンサーが白で { if(SENSOR_3>THRESHOLD) //かつ右側のセンサーが白なら { Off(OUT_A+OUT_C); OnFwd(OUT_A+OUT_C);//go_foward //直進する。 } else if(SENSOR_3<THRESHOLD) //かつ右側のセンサーが黒なら { Off(OUT_A+OUT_C); OnFwd(OUT_A);OnRev(OUT_C); //右折する。 } } else if(SENSOR_1<THRESHOLD) //左側のセンサーが黒で { if (SENSOR_3>THRESHOLD) //かつ右側のセンサーが白なら { Off(OUT_A+OUT_C); OnFwd(OUT_C);OnRev(OUT_A); //左折する。 } else if(SENSOR_3<THRESHOLD) //かつ右側のセンサーが黒なら { Off(OUT_A+OUT_C); OnFwd(OUT_A+OUT_C); //直進する。 } } } } 最初思ったようににアームが回転せず大変でした。 **kata.ver [#k14302a5] #define eye_L SENSOR_1 //eye_LをSENSOR_1と定義 #define push SENSOR_2 //pushをSENSOR_2と定義 #define eye_R SENSOR_3 //eye_RをSENSOR_3と定義 #define cont 40 //明暗の判断基準を40とする task main() { SetSensor(eye_L,SENSOR_LIGHT); //光センサーをセット SetSensor(push,SENSOR_TOUCH); //タッチセンサーをセット SetSensor(eye_R,SENSOR_LIGHT); //光センサーをセット Wait(100); //一秒待ってからスタート repeat(4){ start follow_line; //別のtaskをスタート until (push == 1); //タッチセンサーが反応したら、taskを停止 stop follow_line; Off(OUT_A+OUT_C); Wait(100); //パックを一旦どかし、元の位置に戻すプログラム OnFwd(OUT_B); Wait(750); Off(OUT_B); Wait(100); OnFwd(OUT_A+OUT_C); Wait(200); Off(OUT_A+OUT_C); Wait(100); OnRev(OUT_B); Wait(750); Off(OUT_B); Wait(100); } } task follow_line() //別taskの内容(ライントレース) { while(true) //常に実行する if ((eye_L >= cont ) && (eye_R >= cont )) {Off(OUT_A+OUT_C);OnFwd(OUT_A+OUT_C);} //センサー1,3とも白なら直進 else if ((eye_L >= cont ) && (eye_R <= cont )) {Off(OUT_A+OUT_C);OnFwd(OUT_A);OnRev(OUT_C);} //1が白、3が黒なら右へ曲がる else if ((eye_L <= cont ) && (eye_R >= cont )) {Off(OUT_A+OUT_C);OnRev(OUT_A);OnFwd(OUT_C);} //1が黒、3が白なら左へ曲がる else {Off(OUT_A+OUT_C);OnFwd(OUT_A+OUT_C);} 1,3ともに黒なら直進 } *感想 [#w09e510b] NISHI: 光センサーの設定でロボ自体の影に反応してしまったり、コースの微妙な位置でラインから逸れてしまったりと、大変なことばかりだったけど、おもしろかった。 SHIMA: タイマーの時間の設置が難しかったです。また、パックが軽いためタッチセンサーの製作に苦労しました。 kata: アームの形状を試行錯誤したことで、パックを安定してつかむことができた。プログラムは失敗を繰り返したが、なんとか形にすることができた。 *コメント欄(コメントをお願いします。) [#dd3b1575] ロボットの説明が、写真を使ってわかりやすくできていてとてもよいです。プログラムに関しては、if文の○○以上○○以下などの条件で漏れがないかよくチェックしてください。例えば、閾値と閾値の間になってしまって動作が定義されていないところはないかとか、閾値にしている数字ぴったりのときはどんな動作をするのかといったことです。あと、コメント欄があるとありがたいです。(こさか)