右折のプログラムを二種類に分けることで素早く稼動できる。
交差点判別のプログラムの他に、急左折のあとに前進のプログラムを組むことで交差点を素早く突破できることが判明、タイマーによりプログラムを変えることで実用できた。
急カーブではロボットが脱線することが多かったのでタイマーを使い急カーブ部分で細かく敷居値を判定するプログラムに切り替えて対応した。
タイマーでアームに取り付けたモーターを稼働させ、空き缶の保持と設置のプログラムを稼働させた。
#define THRESHOLD 42 #define HIPOWER 9 // 直線用の強めのパワー #define LOWPOWER 1 // カーブ、旋回用の弱めのパワー #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_left1 set_power_L; Off(OUT_A); OnFwd(OUT_C); // 左にカーブする動作 #define turn_right1 set_power_L; OnFwd(OUT_A); Off(OUT_C); // 右にカーブする動作 #define turn_left2 set_power_L; OnRev(OUT_A); OnFwd(OUT_C); // 左に旋回する動作 #define turn_right2 set_power_L; OnFwd(OUT_A); OnRev(OUT_C); // 右に旋回する動作 #define STEP 1 // 1回の判断で動作させる時間 #define nMAX 7 // 通常のカーブとして許容できる繰り返しの最大値 #define short_break Off(OUT_AC); Wait(100); // 小休止 #define CROSS_TIME 20 // 交差点通過にかかる時間 #define cross_line go_forward;Wait(CROSS_TIME);short_break; // 交差点を通過する動作 task main() { SetSensor(SENSOR_2,SENSOR_LIGHT); // 「2」に光センサーを設置 ClearTimer(0); // タイマーをリセット while (FastTimer(0) <= 1000) { // 10秒間通常のライントレース(線の右側) if (SENSOR_2 < THRESHOLD-3) { // 光センサーの値が39未満の時、右に旋回 turn_right2; } else if (SENSOR_2 < THRESHOLD-1) { // 光センサーの値が41未満の時、右にカーブ turn_right1; } else if (SENSOR_2 < THRESHOLD+2) { // 光センサーの値が44未満の時、直進 go_forward; } else if (SENSOR_2 < THRESHOLD+10) { // 光センサーの値が52未満の時、左にカーブ turn_left1; } else { // その他の時は左に旋回 turn_left2; } Wait(STEP); } int nOnline=0; // 続けて黒になった回数を数える PlaySound(SOUND_UP); // ピロピロ〜と高い音を鳴らす Off(OUT_AC); // タイヤを止める OnRev(OUT_B);Wait(120);Off(OUT_B); // 上あごを動かして、缶を挟む→1.2秒で停止 ClearTimer(0); // タイマーをリセット while (FastTimer(0) <= 1600) { // 16秒間交差点のプログラム→線の右側をライントレース if ((nOnline < nMAX)&&(SENSOR_2 < THRESHOLD-3)) { // 黒がnMAX回繰り返さない、かつ、光センサーの値が39未満の時、右に旋回 turn_right2; nOnline++; // カウンタを増やす } else { if ((nOnline < nMAX)&&(SENSOR_2 < THRESHOLD-1)) { // 黒がnMAX回繰り返さない、かつ、光センサーの値が41未満の時、右にカーブ turn_right1; } else if ((nOnline < nMAX)&&(SENSOR_2 < THRESHOLD+2)) { // 黒がnMAX回繰り返さない、かつ、光センサーの値が44未満の時、直進 go_forward; } else if ((nOnline < nMAX)&&(SENSOR_2 < THRESHOLD+10)) { // 黒がnMAX回繰り返さない、かつ、光センサーの値が52未満の時、左にカーブ turn_left1; } else if ((nOnline < nMAX)&&(SENSOR_2 >= THRESHOLD+10)){ // 黒がnMAX回繰り返さない、かつ、光センサーの値が52以上の時、左に旋回 turn_left2; } nOnline=0; // カウンタをリセット } if(nOnline >= nMAX) { // 黒がnMAX回繰り返された時、交差点を渡る動作 short_break; // 小休憩 turn_left2; Wait(nMAX*STEP); // 進行方向修正 cross_line; // 交差点を渡る nOnline=0; // カウンタをリセット } } PlaySound(SOUND_UP); // ピロピロ〜と高い音を鳴らす Off(OUT_AC); タイヤを止める OnRev(OUT_B);Wait(120);Off(OUT_B); // 上あごを動かして、缶を挟む→1.2秒で停止 OnFwd(OUT_AC);Wait(50);Off(OUT_AC); // 0.5秒間前進(次の左沿いにライントレースする動作をしやすくするため) ClearTimer(0); // タイマーをリセット while (FastTimer(0) <= 3500) { // 35秒間交差点のプログラム→線の左側をライントレース if ((nOnline < nMAX)&&(SENSOR_2 < THRESHOLD-3)) { 黒がnMAX回繰り返さない、かつ、光センサーの値が39未満の時、左に旋回 turn_left2; nOnline++; // カウンタを増やす } else { if ((nOnline < nMAX)&&(SENSOR_2 < THRESHOLD-1)) { // 黒がnMAX回繰り返さない、かつ、光センサーの値が41未満の時、左にカーブ turn_left1; } else if ((nOnline < nMAX)&&(SENSOR_2 < THRESHOLD+2)) { // 黒がnMAX回繰り返さない、かつ、光センサーの値が44未満の時、直線 go_forward; } else if ((nOnline < nMAX)&&(SENSOR_2 < THRESHOLD+10)) { // 黒がnMAX回繰り返さない、かつ、光センサーの値が52未満の時、右にカーブ turn_right1; } else if ((nOnline < nMAX)&&(SENSOR_2 >= THRESHOLD+10)) { // 黒がnMAX回繰り返さない、かつ、光センサーの値が52以上の時、右に旋回 turn_right2; } nOnline=0; // カウンタをリセット } if(nOnline >= nMAX) { // 黒がnMAX回繰り返された時、交差点を渡る動作 short_break; // 小休憩 turn_right2; Wait(nMAX*STEP); // 進行方向修正 cross_line; // 交差点を渡る nOnline=0; // カウンタをリセット } } PlaySound(SOUND_UP); // ピロピロ〜と高い音を鳴らす Off(OUT_AC); // タイヤを止める OnRev(OUT_B);Wait(120);Off(OUT_B); // 上あごを動かして缶を挟む→1.2秒で停止 OnFwd (OUT_AC);Wait (50); // 0.5秒間前進(次の右沿いにライントレースする動作をしやすくするため) ClearTimer(0); // タイマーをリセット while (FastTimer(0) <= 1800) { // 18秒間交差点のプログラム→線の右側をライントレース if ((nOnline < nMAX)&&(SENSOR_2 < THRESHOLD-3)) { // 黒がnMAX回繰り返さない、かつ、光センサーの値が39未満の時、右に旋回 turn_right2; nOnline++; // カウンタをリセット } else { if ((nOnline < nMAX)&&(SENSOR_2 < THRESHOLD-1)) { // 黒がnMAX回繰り返さない、かつ、光センサーの値が41未満の時、右にカーブ turn_right1; } else if ((nOnline < nMAX)&&(SENSOR_2 < THRESHOLD+2)) { // 黒がnMAX回繰り返さない、かつ、光センサーの値が44未満の時、直進 go_forward; } else if ((nOnline < nMAX)&&(SENSOR_2 < THRESHOLD+10)) { // 黒がnMAX回繰り返さない、かつ、光センサーの値が52未満の時、左にカーブ turn_left1; } else if ((nOnline < nMAX)&&(SENSOR_2 >= THRESHOLD+10)){ // 黒がnMAX回繰り返さない、かつ、光センサーの値が52以上の時、左に旋回 turn_left2; } nOnline=0; } if(nOnline >= nMAX) { // 黒がnMAX回繰り返された時、交差点を渡る動作 short_break; // 小休憩 turn_left2; Wait(nMAX*STEP); // 進行方向修正 cross_line; // 交差点を渡る nOnline=0; // カウンタをリセット } } PlaySound(SOUND_UP); // ピロピロ〜と高い音を鳴らす Off(OUT_AC); // タイヤを止める OnRev(OUT_B);Wait(120);Off(OUT_B); // 上あごを動かして缶を挟む→1.2秒で停止 ClearTimer(0); // タイマーをリセット while (FastTimer(0) <= 1600) { // 16秒間通常のライントレース(線の右側) if (SENSOR_2 < THRESHOLD-3) { // 光センサーの値が39未満の時、右に旋回 turn_right2; // 光センサーの値が41未満の時、右にカーブ turn_right1; } else if (SENSOR_2 < THRESHOLD+2) { // 光センサーの値が44未満の時、直進 go_forward; } else if (SENSOR_2 < THRESHOLD+10) { // 光センサーの値が52未満の時、左にカーブ turn_left1; } else { その他の時は左に旋回 turn_left2; } Wait(STEP); } PlaySound(SOUND_UP); // ピロピロ〜と高い音を鳴らす OnFwd(OUT_A); OnRev(OUT_C);OnRev(OUT_B);Wait(50);Off(OUT_ABC); // 缶をつかみながら0.5秒間右に旋回(ターンして缶を置きに行くのに缶を倒さないようにするため) ClearTimer(0); // カウンタをリセット while (FastTimer(0) <= 500) { // 5秒間通常のライントレース(線の左側) if (SENSOR_2 < THRESHOLD-3) { // 光センサーの値が39未満の時、左に旋回 turn_left2; } else if (SENSOR_2 < THRESHOLD-1) { // 光センサーの値が41未満の時、左にカーブ turn_left1; } else if (SENSOR_2 < THRESHOLD+2) { // 光センサーの値が44未満の時、直進 go_forward; } else if (SENSOR_2 < THRESHOLD+10) { // 光センサーの値が52未満の時、右にカーブ turn_right1; } else { // その他の時は右に旋回 turn_right2; } Wait(STEP); } PlaySound(SOUND_UP); // ピロピロ〜と高い音を鳴らす Off(OUT_AC); // タイヤを止める OnFwd(OUT_B);Wait(100);Off(OUT_B); // 1秒間上あごを動かして缶を離す OnRev(OUT_AC);Wait(100);Off(OUT_AC); // 1秒間後進 OnRev(OUT_A); OnFwd(OUT_C);Wait(80);Off(OUT_AC); // 0.8秒間左に旋回 ClearTimer(0); // タイマーをリセット while (FastTimer(0) <= 2000) { // 20秒間通常のライントレース(線の右側) if (SENSOR_2 < THRESHOLD-3) { // 光センサーの値が39未満の時、右に旋回 turn_right2; } else if (SENSOR_2 < THRESHOLD-1) { // 光センサーの値が41未満の時、右にカーブ turn_right1; } else if (SENSOR_2 < THRESHOLD+2) { // 光センサーの値が44未満の時、直進 go_forward; } else if (SENSOR_2 < THRESHOLD+10) { // 光センサーの値が52未満の時、左にカーブ turn_left1; } else { // その他の時は左に旋回 turn_left2; } Wait(STEP); } }
結果として課題攻略には失敗してしまいました。(練習時には成功有り)
いろいろと失敗してしまったので悔しいです。しかし改善点やプログラミングのコツなど、失敗することで多くのものを吸収できました。次回の課題では確実に動作するプログラミングを作成するために取り組んでいきたいです。