*ロボット本体 [#sf4f476a] 本体は、サンプルのロボットの前の部分に光センサを取り付け、 センサを本体に近い位置に取り付けるために、サンプルのロボットをほんの少しだけ改造しました。 &ref(DSC02982.JPG); また、光センサの周りに囲いをすることで正確な値が出るかなと考えたので、 センサの部分にも少し手を加えてみました。 &ref(DSC02983.JPG); このようになっています。 センサの位置は、できるだけ紙面に近くなるように取り付けてあります。 紙面に近すぎて全部黒と判断することがないように気をつけました。 &ref(DSC02984.JPG); *コース説明 [#s07e9a18] &ref(DSC02989.JPG); 左下のスタート地点からはじめて、1回目の交差点は直進、 2回目は左折、3回目は直進、4回目は右折、5回目も右折をしてはじめの地点に戻るプログラムを作りました。 *プログラム [#r77e8a13] **定義 [#ib65e3ab] #define THRESHOLD 50 //しきい値 #define SPEED_H 50 //直進時のスピード #define SPEED_L 25 //カーブ時のスピード #define OnRL(speedR,speedL) OnFwd(OUT_A,speedR);OnFwd(OUT_B,speedL); #define go_forward OnRL(SPEED_H,SPEED_H); //直進 #define turn_right1 OnRL(-SPEED_L,SPEED_L); //右旋回 #define turn_right0 OnRL(0,SPEED_L); //右折 #define turn_left1 OnRL(SPEED_L,-SPEED_L); //左旋回 #define turn_left0 OnRL(SPEED_L,0); //左折 #define STEP 1 //1回の判断で動作させる時間 #define nMAX 300 //カーブとして許容できる繰り返しの最大値 #define short_break Off(OUT_AB);Wait(1000); //小休止 #define CROSS_TIME 200 //交差点通過にかかる時間 #define cross_line OnRL(SPEED_L,SPEED_L);Wait(CROSS_TIME);short_break; //交差点を渡る #define turn_left(t) ResetTachoCount(OUT_AB); Off(OUT_B); RotateMotor(OUT_A,SPEED_H,t); //右折(回転角を指定) #define turn_right(t) ResetTachoCount(OUT_AB); RotateMotor(OUT_B,SPEED_H,t); Off(OUT_A); //左折(回転角を指定) しきい値は50にしました。 nMAXの値が300なら急カーブも交差点と間違えることなく通過することができました。 交差点を右左折する動作をするとき正確に曲がれるように、モーターの回転角を指定して動かすように定義しました。 **プログラム [#e40f60c1] task main() { SetSensorLight(S1); //端子1に光センサ int nOnline=0; //続けて黒になった回数(カウンタ) int nCROSS=0; //交差点にぶつかった回数(カウンタ) 続けて黒を認識した回数と、交差点に入った回数をカウンタを使って数えました。 while(true){ /*黒を続けてnMAX回繰り返さない間、通常のライントレースをする*/ while(nOnline<nMAX){ if (SENSOR_1<THRESHOLD-15){ turn_left1; nOnline++; //カウンタを増やす(黒) } else if (SENSOR_1<THRESHOLD-7){ turn_left0; nOnline=0; } else if (SENSOR_1<THRESHOLD+7){ go_forward; nOnline=0; } else if (SENSOR_1<THRESHOLD+15){ turn_right0; nOnline=0; } else{ turn_right1; nOnline=0; } 実際に黒い部分と白い部分の値をセンサで計ったところ、 道の上(一番黒いところ)は30以下で、道以外(一番白いところ)は60よりも大きい値ということがわかりました。 このことから、閾値-15よりも黒いときに道の真ん中と判断し、閾値-7よりも黒いときは道の端にいると判断できることがわかります。 同様にして、白い部分でも判断できることが分かります。 同様にして、白い部分も判断できることが分かります。 Wait(STEP); //nOnline=0; //カウンタをリセット } nCROSS++; //カウンタを増やす(交差点) 黒い部分が続いて、nMAXの値を超えたときが交差点であるので、交差点のカウンタを一つ増やします。 そして、音を鳴らしてから交差点の動作に入ります。 if(nCROSS==1){ //1回目は直進 PlaySound(SOUND_CLICK); Wait(STEP*20); short_break; turn_right1; Wait(nMAX*STEP); cross_line; nOnline=0; }else if (nCROSS==2){ //2回目は左折 PlaySound(SOUND_CLICK); Wait(STEP*20); short_break; turn_right1; Wait(nMAX*STEP); turn_left(350); nOnline=0; }else if (nCROSS==3){ //3回目は直進 PlaySound(SOUND_CLICK); Wait(STEP*20); short_break; turn_right1; Wait(nMAX*STEP); cross_line; nOnline=0; }else if (nCROSS==4){ //4回目は右折 PlaySound(SOUND_CLICK); Wait(STEP*20); short_break; turn_right1; Wait(nMAX*STEP); turn_right(250); nOnline=0; }else if (nCROSS==5){ //5回目は右折 PlaySound(SOUND_CLICK); Wait(STEP*20); short_break; turn_right1; Wait(nMAX*STEP); turn_right(250); nOnline=0; } } } *ふりかえり [#rdc907a6] -せっかくライントレースをしたのに、道の上をうまく走れたことに気をとられていたせいか、かかった時間を計るのを忘れてしまいました。 -交差点と認識したことが分かるようにするためにに音を鳴らしました。 -最初の段階で交差点を認識してくれないという問題に対面した時にも、どういった状況なのかが分かりやすかったです。 -交差点を右折するのも左折するのも直角に移動する動作ですが、道の左端をトレースしていたので、2回目の左折と4,5回目の右折の回転の角度が違います。 -また、細かくみてみると4回目は急な右カーブを通ったあとに交差点に入っていて、5回目は左カーブを通ってから交差点にぶつかるので、同じ右折の動作でも、交差点への進入角度が違うことがわかります。 -わたしは、同じ角度でプログラムしてしまいましたが、ギリギリ曲がることができました(ぎこちなかったですが)。 -4回目の右折で曲がりすぎてしまうことも何度かあったので、そこで角度の調節をしたら、よりスムーズに動けそうです。 -また、曲がりすぎて、道を通りすぎてしまったときのために、逆の動作をして道の上に戻れるようなプログラムも加えられたらより良くなりそうだと思いました。