*課題 [#b7a8adc9] [[mission2:http://yakushi.shinshu-u.ac.jp/robotics/?2014b%2FMission2]]参照。1人目の課題をやった。 *ロボット組み立て [#mfcf9c67] ロボットはnxt組み立て解説書に掲載されているモデルを真似して全く同じものを作った。課題を行う上で、特にロボット自体による問題はで気になる点もなかったので、このロボットで課題を進めた。ロボット前方下部分に光センサーが地面ぎりぎりの位置にくるように取り付けてある。 **全体 [#tea90503] #ref(all.jpg) **真横 [#ocf89543] #ref(yoko.jpg) *課題攻略に向けて [#f1f4a875] ロボットは黒色を探知したら左へ、白色を探知したら右へ曲がるようにして黒線の左側を走行する。交差点とカーブでは連続で黒色を認識するので、これらを区別するために黒を認識した回数を数えるカウンタをプログラムで設定し、一定数以上の認識をした時、そこが交差点だと判断するようになっている。今回はその定数をnMAXとnMAX2と置いている。交差点を直進する時と右折するときは小さい値のnMAXを用い、左折するときは大きい値のnMAX2を用いる。これは交差点を左折する時を通常のカーブだと認識させるためである。交差点を直進するときは交差点と判断したときに右旋回することでセンサーの位置を横切っている黒線の向こう側へ調整する。右折させたいときは、そこからさらに右旋回させることで曲がる方向のコースに合うようにセンサーの位置を調整する。 **交差点直進[#c5e48063] #ref(11.jpg) **交差点左折→交差点直進 [#v194c7de] #ref(12.jpg) #ref(13.jpg) **交差点右折→交差点右折 [#mef3f306] #ref(14.jpg) #ref(15.jpg) *プログラム [#v575e7e7] **定義 [#e1cfad46] #define THRESHOLD 49 #define SPEED_H 35 #define SPEED_L 25 #define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL); #define go_forward OnRL(SPEED_H,SPEED_H); #define turn_left1 OnRL(SPEED_L,-SPEED_L);//左旋回 #define turn_left0 OnRL(SPEED_L,0);//左折 #define turn_right0 OnRL(0,SPEED_L);//右折 #define turn_right1 OnRL(-SPEED_L,SPEED_L);//右旋回 #define STEP 1//1回の動作で判断させる時間 #define nMAX 300//交差点を直進するプログラム時のカーブとして許容できる繰り返しの最大値 #define nMAX2 450//交差点を左折するプログラム時のカーブとして許容できる繰り返しの最大値 #define short_break Off(OUT_BC);Wait(1000);//小休止 #define CROSS_TIME 250//交差点通過にかかる時間 #define cross_line OnRL(SPEED_L,SPEED_L);Wait(CROSS_TIME);short_break; **カウンタと光センサの設定 [#qaf75295] task main() { SetSensorLight(S3); int nOnline=0;//黒になった回数 int cross_number=0;//交差点に差し掛かった回数 **1回目と3回目の交差点を直進するためのプログラム [#rd9a766e] while(cross_number<1||2<=cross_number<3){//1回目と3回目の交差点を直進 while(nOnline<nMAX) { if(SENSOR_3<THRESHOLD-15) { turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7) { turn_left0; } else if(SENSOR_3<THRESHOLD+7) { go_forward; }else if(SENSOR_3<THRESHOLD+15) { turn_right0; }else{ turn_right1; } nOnline=0;//カウンタをリセット } Wait(STEP); } PlaySound(SOUND_CLICK);Wait(1000);//交差点のたびに鳴らす short_break; turn_right1;Wait(nMAX*STEP);//進行方向を右に修正し直進コースの黒線位置に合わせる cross_line; nOnline=0; cross_number++;//交差点の判断をする毎にカウンタを増やす。 } **2回目の交差点を左折するためのプログラム [#tb0865e2] while(1<=cross_number<2){//2回目の交差点で左折 while(nOnline<nMAX2) { if(SENSOR_3<THRESHOLD-15) { turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7) { turn_left0; } else if(SENSOR_3<THRESHOLD+7) { go_forward; }else if(SENSOR_3<THRESHOLD+15) { turn_right0; }else{ turn_right1; } nOnline=0;//カウンタをリセット } Wait(STEP); } PlaySound(SOUND_CLICK);Wait(1000);//交差点のたびに鳴らす short_break; turn_right1;Wait(nMAX*STEP);//進行方向修正 cross_line; nOnline=0; cross_number++; } **4回目以降の交差点を右折するためのプログラム [#rea7e84f] while(cross_number>=3){//4回目以降の交差点で右折 while(nOnline<nMAX) { if(SENSOR_3<THRESHOLD-15) { turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7) { turn_left0; } else if(SENSOR_3<THRESHOLD+7) { go_forward; }else if(SENSOR_3<THRESHOLD+15) { turn_right0; }else{ turn_right1; } nOnline=0;//カウンタをリセット } Wait(STEP); } PlaySound(SOUND_CLICK);Wait(1000);//交差点のたびに鳴らす short_break; turn_right1;Wait(nMAX*STEP);//進行方向を右に修正し直進コースの黒線位置に合わせる cross_line; Wait(1000); turn_right1;Wait(600);//進行方向をさらに右に修正し右折コースの黒線位置に合わせる nOnline=0; cross_number++; } } *感想・反省 [#g2db524b] プログラムを分かりやすくするために大きく3つに分けたので量が多くなってしまったが、他にやり方が分からなかったので、この作戦で進めた。もっとプログラミングを理解し、コンパクトに作れるようになりたい。また、ロボットが交差点に差し掛かった時にセンサーが黒線の向こう側に勝手に行ってしまうことやセンサーの位置がコースから大きくずれた所へ行ってしまうなどの、主にセンサーの位置取りの失敗が目立っていたので、タイヤの回転数値をより正確に設定すれば、もっと正確なライントレースが出来たと思う。明らかにプログラムしていない動作をすることが何度もあり、とても厄介だったが、来年も勉強する内容なので今のうちに勉強できてよかった。