今回の課題は、ライントレースと障害物の缶を避け、所定の場所にゴールするというものです。
私たちのマシンは特にシンプルな設計にしました。マシンを作り始めた当初は、説明書に書いてあった通りのものでしたが、それでは上手くいかず改良を加えました。 マシンを改良した点は以下の3つです。
まず一つ目のタイヤに関しては、四輪駆動であると力は入りますが、どうしてもカーブが回り切れないことから改良しました。 二つ目のセンサの位置に関しては、説明書通りだと感知するために大回りになってしまうので改良しました。三つ目の手は空き缶を動かすためにシンプルではありますが、付けました。
#define THERESHOLD 46 //しきい値 #define HIESTPOWER 7 #define HIPOWER 2 #define LOWPOWER 0 #define set_power_HEST SetPower(OUT_AC,HIESTPOWER); #define set_power_H SetPower(OUT_AC,HIPOWER); #define set_power_L SetPower(OUT_AC,LOWPOWER); #define go_forward set_power_H; OnFwd(OUT_AC); #define turn_left0 set_power_L; OnFwd(OUT_C); Off(OUT_A); //Cタイヤを前進、Aタイヤを停止して左折 #define turn_left1 set_power_L; OnFwd(OUT_C); OnRev(OUT_A); //Cタイヤを前進、Aタイヤを後退して左旋回 #define turn_right0 set_power_L; OnFwd(OUT_A); Off(OUT_C); //Aタイヤを前進、Cタイヤを停止して右折 #define turn_right1 set_power_L; OnFwd(OUT_A); OnRev(OUT_C); //Aタイヤを前進、Cタイヤを後退して右旋回 #define STEP 1 //1回の判断で動作させる時間 #define nMAX 35 //最大値を35秒とする #define short_break Off(OUT_AC); Wait(100); //小休止 #define CROSS_TIME 20 //交差点通過にかかる時間 #define cross_line go_forward set_power_H;\OnFwd(OUT_AC);Wait(CROSS_TIME);short_break; #define SetPower(OUT_A,1); //カーブを曲がる時の力を1にする #define go_forward1 OnFwd(OUT_AC);Wait(50) //前進して0.5秒待つ #define u_turn1 set_power_HEST;OnRev(OUT_A);OnFwd(OUT_C);\Wait(160); //Aタイヤを後退、Cタイヤを前進しUターンして1.6秒休止 #define u_turn2 set_power_HEST;OnRev(OUT_C);OnFwd(OUT_A);\Wait(150); //Cタイヤを後退、Aタイヤを前進しUターンして1.5秒休止 #define go_back OnRev(OUT_AC);Wait(50); //後退して0.5秒待つ task main() { SetSensor(SENSOR_2,SENSOR_LIGHT); SetSensor(SENSOR_1,SENSOR_LIGHT); ClearTimer(1); //タイマー1をリセットする while (FastTimer(1) <= 700) { if (SENSOR_2 < THERESHOLD -2) { turn_left1; //タイマー7秒以下でしきい値より-2小さい時、左旋回 } else { if (SENSOR_2 < THERESHOLD -1) { turn_left0; //しきい値より-1小さい時、左折 } else if (SENSOR_2 < THERESHOLD +1) { go_forward; //しきい値より+1小さい時、前進 } else if (SENSOR_2 < THERESHOLD +2) { turn_right0; //しきい値より+2小さい時、右折 } else { turn_right1; //それ以外の時、右旋回 } Wait(STEP); //判断による動作を休止 } if (SENSOR_1>=48) { go_forward1; //センサの値が >=48であった時に前進する u_turn1; go_back; u_turn2; } } ClearTimer(0); //タイマー0をリセット ClearTimer(1); //タイマー1をリセット while (FastTimer(1) <=4700) { while (FastTimer(0) < nMAX) { if (SENSOR_2 < THERESHOLD -2) { turn_left1; //タイマー1で47秒以下でタイマー0が最大値より小さくしきい値より-2小さい 時、左旋回 } else { if (SENSOR_2 < THERESHOLD -1) { turn_left0; //しきい値より-1小さい時、左折 } else if (SENSOR_2 < THERESHOLD +1) { go_forward; //しきい値より+1小さい時、前進 } else if (SENSOR_2 < THERESHOLD +2) { turn_right0; //しきい値より+2小さい時、右折 } else { turn_right1; //それ以外の時、右旋回 } ClearTimer(0); //タイマー0をリセット } Wait(STEP); //判断のよる動作を休止 } turn_right1; Wait(nMAX*STEP); //進行方向修正 cross_line; //交差点を渡る ClearTimer(0); //タイマー0をリセット } ClearTimer(0); //タイマー0をリセット ClearTimer(1); //タイマー1をリセット while (true) { if (SENSOR_2 < THERESHOLD -2) { turn_left1; //しきい値より-2小さい時、左旋回 } else { if (SENSOR_2 < THERESHOLD -1) { turn_left0; //しきい値より-1小さい時、左折 } else if (SENSOR_2 < THERESHOLD +1) { go_forward; //しきい値より+1小さい時、前進 } else if (SENSOR_2 < THERESHOLD +2) { turn_right0; //しきい値より+2小さい時、右折 } else { turn_right1; //それ以外の時、右旋回 } Wait(STEP); //判断による動作を休止 } } }
プログラムを作成していく中で、いくつもの壁にぶち当たりました。まずは、ライントレースです。光センサを付けたばかりのころは、白と黒の定義の数値を微調整することに苦労しました。線をたどることがここまで難しいとは思いませんでした。ライントレースがうまく行き始めたころに、今回の山場!交差点に当たりました。この交差点を超えるのには苦労しました。たまたま交差点を超えることは度々ありましたが、きちんとマシンが交差点を認識してのことではありませんでした。これを超えるために活用したもの!それが、タイマーです。タイマーで入り口交差点出口を認識するプログラムを変えました。そして、タイマーを微調整してこのプログラムが完成しました。そして、缶については、光センサが感知したところでUターンする方式を取りました。
マシンのプログラムに集中してしまったのでマシンのボディにあまり手をかけられませんでした。そして、プログラムをもっと簡略化できたのではないかと思いました。