目次 #contents *Mission1について [#pa195eee] 課題2:決められた黒いラインの上を沿って進むロボットを作るというものでした。 詳しくはこちらをご覧ください。→http://yakushi.shinshu-u.ac.jp/robotics/?2014b%2FMission2 *コース [#cdc0922b] &ref(2014b/Member/edaeda/Mission2/image4.JPG,50%,画像の説明); 今回のコース *ロボットの紹介 [#wdebb8bc] 今回活躍してくれたロボット→ &ref(2014b/Member/edaeda/Mission2/image1.JPG,25%,画像の説明); &ref(2014b/Member/edaeda/Mission2/image2.JPG,25%,画像の説明); **工夫した点 [#z5f1b064] ***光センサ [#c58e7dfd] 光センサとロボットの距離が離れると、光センサが少し先の位置で読み取った数値をもとにロボットが動いてしまい、ロボットの動きがずれてしまいます。そこでこのように光センサの位置をロボットに近づけて、ずれが生じないようにしました。 また、数値を読み取りやすくするため、地面と光センサの距離を適度に近づけました。 &ref(2014b/Member/edaeda/Mission2/image3.JPG,25%,画像の説明); **ラインの上を通る仕組み [#e5fe6f36] 光センサは自分で光を発し、紙に反射して戻ってきた光から、紙に黒いラインが書かれているか読み取ることができるセンサーです。それを利用して、ロボットを紙の白い部分と黒いラインの境目を走らせるようにし、白ければ右(または左)に、黒ければ左(または右)に進むようにプログラムをして、ライン(正確にはラインの端)に沿って進むようになりました。 **交差点を見分ける仕組み [#qd1ef6b8] 交差点を見分けることが出来なければ、交差点でロボットが左折(または右折)してしまい、右折(または左折)と直進が出来なくなってしまうので、一定時間以上黒いラインの上にいた場合はそこが交差点だと判断し、体制を戻し、そこから右折・左折・直進が出来るようにプログラムをしました。 *プログラム [#ja825ece] #define THRESHOLD 49//しきい値は49 #define SPEED 50 #define LOWSPEED 45 #define go_forward OnFwd(OUT_BC,SPEED); #define high_turn_left OnFwd(OUT_B,SPEED);OnRev(OUT_C,LOWSPEED); #define high_turn_right OnRev(OUT_B,LOWSPEED);OnFwd(OUT_C,SPEED); #define turn_left OnFwd(OUT_B,SPEED); #define turn_right OnFwd(OUT_C,SPEED); #define STEP 1 #define tMAX 350//交差点だと判断する時間が0.35秒 #define TURN_RIGHT 750 #define TURN_LEFT 800//右折と左折で角度が違うので、時間が違う #define sound PlaySound(SOUND_CLICK);//交差点でサウンドを鳴らす task main() { SetSensorLight(S3); long t0=CurrentTick(); int nOnline=0; while(true) {if(CurrentTick()-t0<tMAX) {if(SENSOR_3<THRESHOLD-9){high_turn_left;Wait(STEP);} else{if(SENSOR_3<THRESHOLD-5){turn_left;} else if(SENSOR_3<THRESHOLD+5){go_forward;} else if(SENSOR_3<THRESHOLD+9){turn_right;} else {high_turn_right;} t0=CurrentTick();Wait(STEP); } } else{ Off(OUT_BC); high_turn_right; Wait(550); if(nOnline<1){ sound;} else if(nOnline<2){ sound;sound;high_turn_left;Wait(TURN_LEFT);} else if(nOnline<3){ sound;sound;sound;go_forward;Wait(300);} else if(nOnline<5){ sound;sound;sound;sound;go_forward;Wait(225);high_turn_right;Wait(TURN_RIGHT);} go_forward;Wait(200);nOnline++;t0=CurrentTick();Wait(STEP); } } } **解説 [#i62526d5] task main() { SetSensorLight(S3); long t0=CurrentTick(); int nOnline=0; まずタイマーとカウンタを使うことにしました。 while(true) そしてwhile(true)を使いこれ以後のプログラムは常に繰り返されるようになっています。 {if(CurrentTick()-t0<tMAX) あらかじめtMAXの値を定めておき、タイマーで図った時間がそれより少ないときに下のプログラムが実行されます。 {if(SENSOR_3<THRESHOLD-9){high_turn_left;Wait(STEP);} else{if(SENSOR_3<THRESHOLD-5){turn_left;} else if(SENSOR_3<THRESHOLD+5){go_forward;} else if(SENSOR_3<THRESHOLD+9){turn_right;} else {high_turn_right;} t0=CurrentTick();Wait(STEP); } } あらかじめTHRESHOLDで紙の白い部分と黒いライン上の境目近くの基準となる値を定めておきます。 明るさを5つに分け、明るさが黒から白になるにつれて、急な左折・左折・直進・右折・急な右折をするようになっています。 ちなみに前に回転させているタイヤではない、もう片方のタイヤを少し遅めに後ろに回転させることで 急な右左折をするようにしました。 また、 t0=CurrentTick();でずっと黒いライン上にいるとき以外はタイマーをリセットして、tMAXの値を超えないようにしました。 else {Off(OUT_BC); high_turn_right; Wait(550); if(nOnline<1){sound;} else if(nOnline<2){sound;sound;high_turn_left;Wait(TURN_LEFT);} else if(nOnline<3){sound;sound;sound;go_forward;Wait(300);} else if(nOnline<5) {sound;sound;sound;sound;go_forward;Wait(225);high_turn_right;Wait(TURN_RIGHT);} go_forward;Wait(200);nOnline++;t0=CurrentTick();Wait(STEP); } } } 交差点を通りタイマーがtMAXの値を超えた時は、elseにより上のプログラムが実行されます。 Off(OUT_BC);で一度動きをとめ、high_turn_right;で交差点だと判別する前に曲がってしまったロボットの向きを直します。 nOnlineつまりカウンタで何回目の交差点を通過したかを判別し、直進→左折→直進→右折→右折の順で動くようにしました。 カウンタの値は、交差点を通過した後にnOnline++;t0=CurrentTick();で1増やしています。 交差点を何回通過したか分かりやすいように、サブルーチンとして定めたsound;を使い、その回数分音が出るようにしました。 **苦労した点 [#wb7355d7] 一番苦労したのが、交差点の判断をどうさせるかでした。カウンターでは交差点を通過した回数を数えさせたかったので、交差点はタイマーで判断させることにしたのですが、タイマーの基準値(tMAX)を定めるときに、tMAXが短すぎるとすべてのカーブも交差点と判断してしまったり、逆にtMAXが長すぎると交差点をただのカーブだと勘違いしたりしてしまいまいました。私のパソコンはnxcと相性が悪いのか、運が悪いと1時間に一回も接続できないことがあったので、このtMAXの調整が一番大変でした。 また今回のプログラムではelseやif、whileを何度も使ったので、{}の位置や個数などで何度もプログラムがFailedになってしまい、どこが違うのか見つけるのにも時間がかかってしまいました。そこで自分なりに改行などをして分かりやすくして改善しました。 *反省と感想 [#c0f2ed64] 前回とは違い、プログラムを組む前にどういう形のロボットを作ればよいか考えることができて、良いロボットを作ることが出来ました。また、前回は最後に急いで課題に取り組んだせいで、ぎりぎりになってしまったので、今回は期限の一週間前に終わらすことを目標に取り組んだので、期限内に終わらすことができ、最後の一週間は動作の調整を行うことが出来ました。 次のロボットを作るときも計画的に進めていきたいと思います。