このプログラムはラインの左側の境界線を沿うプログラムで、主に黒と判断すれば左へ、白だと判断すれば右へ曲がるようにしてライントレースをする。 なるべく簡単なプログラムにしたかったため、「基本的にはライントレース、交差点の時は別のプログラム」というようにした。 まず悩んだのは「交差点の判別をタイマーと変数のどちらを使うか」という点です。この時自分はタイマーを使っている人が多かったので、あえて変数を選んだのですが、判別できるときとできないときが場合によってできてしまいました。なので確実に判別するため、タイマーを使うことにしました。正確に素早くコースを回らせるため、その位置で停止するプログラムは一切入れないようにして、スピードをアップさせた。
#define WHITE 48 #define BLACK 37 #define go_forward OnFwd(OUT_AC); //直進 #define go_back OnRev(OUT_AC); //後退 #define LEFT OnRev(OUT_A);OnFwd(OUT_C); //左旋回 #define left Off(OUT_A);OnFwd(OUT_C); //左折 #define right OnFwd(OUT_A);OnRev(OUT_C); //右旋回 #define RIGHT OnFwd(OUT_A);Off(OUT_C); //右折 task main () { SetSensor(SENSOR_1, SENSOR_LIGHT); SetSensor(SENSOR_3, SENSOR_TOUCH); ClearTimer(0);
始めの交差点は曲がらなければいけないのでスタートしてから9秒は交差点を判断せずに左折する。
while(FastTimer(0) < 900){ if (SENSOR_1 < BLACK){ //黒なら左旋回 LEFT; } else if (SENSOR_1 < BLACK +2){ //黒になりかけていたら左折 left; } else if (SENSOR_1 > WHITE -2){ //白になりかけていたら右折 right; } else if (SENSOR_1 > WHITE){ //白なら右旋回 RIGHT;
缶を感知したら機体の後ろへ移動させる。
} else if (SENSOR_3 == 1){ //缶を感知 go_forward; //缶を元の位置に戻すため、「前進→旋回→缶を置いて旋回」という流れにする。 Wait(45); left; Wait(10); //ここで左折するのはこのロボットのモーターが同じ回転数でないため、前へ進むと少しずつ右へ曲がっていくからである go_forward; Wait(45); LEFT; Wait(30); //ここで初めからuntilを使ったものにすると、前進している間にライン上に行ってしまって、プログラムが切り替わってすぐに黒と判断してしまい、缶を思った位置に移動させられないため until(SENSOR_1 < BLACK){ LEFT; } go_forward; Wait(10); go_back; //缶をハサミから出すために後退 Wait(50); right; Wait(220); //ハサミが長いため、缶を出すために少し長い距離を後退するので、黒になるまで回転するプログラムにしてもセンサーがライン上に行かない。なので約300°旋回して、黒になるまで直進し、ライントレースに戻る until(SENSOR_1 < BLACK){ go_forward; } Off(OUT_AC); } else { //その他は直進 go_forward; } } ClearTimer(0);
ここでタイマーをリセットしないと9秒になったときにタイマーが0.25秒以上になってしまうので、交差点だと判断し、こちらの意図とは違う動きをしてしまう。
交差点とカーブの識別はタイマーを使い、黒と判断した時から次に白と判断するまでの時間を計る。微調節しながらこの境界線の時間を計った結果、0.25秒を境界にすると交差点とカーブを正しく判断することができた。
repeat(4){ while (FastTimer(0) < 25){ if (SENSOR_1 < BLACK){ //黒なら左旋回 LEFT; }else if (SENSOR_1 < BLACK +2){ //黒になりかけていたら左折 ClearTimer(0); left; }else if (SENSOR_1 > WHITE -2){ //白になりかけていたら右折 ClearTimer(0); right; }else if (SENSOR_1 > WHITE){ //白なら右旋回 ClearTimer(0); RIGHT; }else{ //その他は直進 ClearTimer(0); go_forward; } }
交差点は4つなので交差点のプログラムを4回繰り返す。 このプログラムではセンサーが黒だと判断している時間を計り、直角のカーブのときに黒だと判断している時間と普通のカーブのときに黒だと判断している時間で別れるように時間を設定。(ここでは0.25秒)
if(FastTimer(0) >= 25){ //0.25秒以上なら交差点と判断して渡る ClearTimer(0); RIGHT; //交差点判断にかかった時間で左旋回した分を右旋回し、直進して交差点を渡る Wait(30); go_forward; Wait(20); Off(OUT_AC); ClearTimer(0); } }
while(true){ if (SENSOR_1 < BLACK){ //黒なら左旋回 LEFT; } else if (SENSOR_1 < BLACK +2){ //黒になりかけていたら左折 left; } else if (SENSOR_1 > WHITE -2){ //白になりかけていたら右折 right; } else if (SENSOR_1 > WHITE){ //白なら右旋回 RIGHT; } else if (SENSOR_3 == 1){ go_forward; Wait(45); left; Wait(10); go_forward; Wait(45); LEFT; Wait(30); until(SENSOR_1 < BLACK){ LEFT; } go_forward; Wait(10); go_back; Wait(50); right; Wait(220); until(SENSOR_1 < BLACK){ go_forward; } Off(OUT_AC); } else { //その他は直進 go_forward; } } }
缶を感知して旋回し、元の位置に戻した後再び旋回するときに、すぐ「until」を使うと缶を置くため後退したときにライン上にいた場合などで思った位置まで旋回できないので、初めは「Wait」を使って旋回し、感知させたいところに近づいたら「until」を使うようにした。 缶が軽いため初めはタッチセンサーが反応しなかったので、先生のアドバイスを貰い、てこの原理を使って小さな力でも押せるように改良した。