#contents *ロボット [#o46ebbd1] タッチセンサを前方に取り付けボールに当たったらアームを降ろしボールをつかむ構造。 矢印の部分にタッチセンサがついていてそれに光センサが直付けされている。 #ref(./DSC_043335.jpg,2%) *プログラム [#p144e270] #define THRESHOLD 45 #define SPEED_H 40 #define SPEED_L 25 #define turn_left_0 OnFwd(OUT_B,SPEED_H);Off(OUT_C); //左転回 大 #define turn_left_1 OnFwd(OUT_B,SPEED_L);Off(OUT_C); //左転回 小 #define turn_right_0 OnFwd(OUT_C,SPEED_H);Off(OUT_B); //右転回 大 #define turn_right_1 OnFwd(OUT_C,SPEED_L);Off(OUT_B); //右転回 小 #define go_forward OnFwd(OUT_BC,SPEED_L); //前進 #define STEP 1 //一回の判定で進む時間 #define nMax 80 //交差点認識に必要な数 #define short_break Off(OUT_BC);Wait(2000); #define turn_straight OnRev(OUT_B,SPEED_H);Wait(nMax*STEP);Off(OUT_BC);OnFwd(OUT_BC,30);Wait(200);Off(OUT_BC); //交差点で方向転換し渡る #define catch_boal Off(OUT_BC);OnFwd(OUT_A,30);Wait(1000);Off(OUT_A); //ボールをつかむ sub line_trace() //P三叉路を通過するまでトレースしボールをつかむ { SetSensorLight(S1); SetSensorTouch(S2); int nOnline=0; long t0 = CurrentTick(); while(CurrentTick()-t0<18000) //18秒間続ける { while(nOnline < nMax) //交差点を認識するまで続ける { if(SENSOR_2==1) { catch_boal; //トレース中ボールがあればアームを降ろす } if (SENSOR_1<THRESHOLD-14) //線上 { turn_left_0; nOnline++; //線上にいたのでカウンタを増やす } else { if (SENSOR_1<THRESHOLD-10) //線上 { turn_left_1; nOnline++; //線上にいたのでカウンタを増やす } else if (SENSOR_1<THRESHOLD-7) //境界線付近 { turn_left_1; nOnline=0; } else if (SENSOR_1<THRESHOLD+7) //境界線付近 { go_forward; nOnline=0; } else if (SENSOR_1<THRESHOLD+15) //ほぼ線上ではない { turn_right_1; nOnline=0; } else //線上ではない { turn_right_0; nOnline=0; } } Wait(STEP); } short_break; //交差点で2秒止まる turn_straight; //方向変換して交差点を渡る nOnline=0; //カウンターをリセット } } sub line_trace_2() //P三叉路からQ交差点までトレース(急カーブ) { SetSensorLight(S1); SetSensorTouch(S2); int nOnline=0; long t0 = CurrentTick(); while(CurrentTick()-t0<8000) //8秒間続ける { if (SENSOR_1<THRESHOLD-14) { turn_left_1; nOnline++; } else { if (SENSOR_1<THRESHOLD-10) { turn_left_1; nOnline++; } else if (SENSOR_1<THRESHOLD-7) { turn_left_1; nOnline=0; } else if (SENSOR_1<THRESHOLD+7) { go_forward; nOnline=0; } else if (SENSOR_1<THRESHOLD+15) { turn_right_1; nOnline=0; } else { turn_right_1; nOnline=0; } } Wait(STEP); } } sub line_trace_3() //Bゴールまでトレース、ゴールの三叉路を直進する { SetSensorLight(S1); SetSensorTouch(S2); int nOnline=0; long t0 = CurrentTick(); while(CurrentTick()-t0<10000) //10秒間続ける { while(nOnline < nMax) { if (SENSOR_1<THRESHOLD-14) turn_left_0; nOnline++; } else { if (SENSOR_1<THRESHOLD-10) { turn_left_1; nOnline++; } else if (SENSOR_1<THRESHOLD-7) { turn_left_1; nOnline=0; } else if (SENSOR_1<THRESHOLD+7) { go_forward; nOnline=0; } else if (SENSOR_1<THRESHOLD+15) { turn_right_1; nOnline=0; } else { turn_right_0; nOnline=0; } } Wait(STEP); } short_break; turn_straight; nOnline=0; } } task main() { line_trace(); line_trace_2(); line_trace_3(); } *結果 [#c94e7817] 3回に1回くらいの確率でしか成功しなかった。 原因は急カーブを曲がりきれなかったことで、時間がなかったこともあるが調整して良い値を見つけることができなかった。 *苦労した点 [#nacce347] 交差点を認識させようとすると急カーブも交差点として認識してしまった。タイマーをつけある程度時間で制御して改善した。 ボールをつかむ動作をプログラムのどこに組み込むか悩んだ。トレースのタスクの中につかむ動作を入れない方法を思いつきたかった。 *感想 [#r6e242ec] プログラムを順序立てて書いていくことの大切さがわっかた。プログラムの上と下の兼ね合いを考えて条件式など考えていくことは難しかったが頭を使ったのでとても楽しかった。 小さい頃、今回のロボットと同じような黒い線をトレースするおもちゃを動物園のお土産コーナーで買い、遊んだことがあったのだが、そのおもちゃの仕組みを理解することができたうえにプログラムがどのようになっているか想像することができるようになった。