A地点を出発し、次のいずれかの経路を黒い線にそって動くロボットを作成する (他のメンバーとは別の経路になるようにする)。
A地点から出発 → B → C(直進) → D(一時停止の後、直進) → E → F → G(一時停止の後、右折) → H → I → J(右折) → K(左折) → L(ピンポン玉をつかむ) → K(直進) → M(一時停止) → シュート→ A地点に入る(ゴール) A地点から出発 → M → K(直進) → L(ピンポン玉をつかむ) → K(右折) → J(一時停止の後、左折) → I(直進) → H(直進) → G(左折) → F → E → D(一時停止の後、直進) → C(直進) → B(一時停止) → シュート→ A地点に入る(ゴール) 交差点では1秒間停止し、丁字路では直角方向に進入する時のみ一時停止すること。
デフォルトの機体にアームをつける。ボールのゴールは慣性の法則を使いボールを前に押し出させる。
小回りがきくようにデフォルトの機体を使用。
写真のように挟むように玉をつかむ。ボールの移動は挟んだ状態で引きずる。
色によって認識し、画像のように5つで判別させる。薄い黒と濁った白は前進かつ軌道修正。真っ黒と真っ白は軌道修正。黒との真ん中の色は前進。
このように光センサーが認識した色に対応した動作をすることによりライントレースをする。
この仕組みにより、急カーブをカウントや時間指定をせずにクリアさせる。
真っ黒の場合のみを時間指定して、規定した時間を超えるとロボットが停止する。
その後行きたい方向に軌道修正や方向転換、横断させライントレースを再開させる。
先に上げた通り、真っ黒は軌道修正だけのため規定した時間をかなり小さくしなければならない。
色の定義
#define BL 37 //薄い黒(black) #define WH 51 //薄い白(white) #define HB 30 //濃い黒(high black) #define HW 58 //濃い白(high white)
曲がるマクロ
#define left OnFwd(OUT_B,25);OnRev(OUT_C,30); //左方向へ軌道修正 #define right OnFwd(OUT_C,25);OnRev(OUT_B,30); //右方向へ軌道修正 #define lefts OnFwd(OUT_B,25);OnFwd(OUT_C,10); //左前方へ #define rights OnFwd(OUT_C,25);OnFwd(OUT_B,10); //右前方へ
路の左側を通り交差点を渡るサブルーチン
sub kousatenn() { SetSensorLight(S3); //交差点を認識したら止まる long t0=CurrentTick(); while(CurrentTick()-t0<=40){ //HB(真っ黒)が0.04秒続くと次のプログラムへ続く if(SENSOR_3>HW){ right; t0=CurrentTick(); //時間を0秒へと戻す(以下同) }else if(SENSOR_3>WH){ rights; t0=CurrentTick(); }else if(SENSOR_3>BL){ OnFwd(OUT_BC,25); t0=CurrentTick(); }else if(SENSOR_3>HB){ lefts; t0=CurrentTick(); }else{ left; } } Off(OUT_BC); OnFwd(OUT_C,30); //交差点を渡る OnRev(OUT_B,30); Wait(150); Off(OUT_BC); OnFwd(OUT_BC,30); Wait(500); Off(OUT_BC); }
路の右側を通り交差点を渡るサブルーチン
sub kousatennrev() { SetSensorLight(S3); //交差点を認識し止まる long t0=CurrentTick(); while(CurrentTick()-t0<=40){ if(SENSOR_3>HW){ left; t0=CurrentTick(); }else if(SENSOR_3>WH){ lefts; t0=CurrentTick(); }else if(SENSOR_3>BL){ OnFwd(OUT_BC,25); t0=CurrentTick(); }else if(SENSOR_3>HB){ rights; t0=CurrentTick(); }else{ right; } } Off(OUT_BC); OnFwd(OUT_B,30); //交差点を渡る OnRev(OUT_C,30); Wait(150); Off(OUT_BC); OnFwd(OUT_BC,30); Wait(500); Off(OUT_BC); }
路の左側を通り交差点またはT字路を認識し止まる
sub teisi() { SetSensorLight(S3); //交差点を認識して止まる long t0=CurrentTick(); while(CurrentTick()-t0<=40){ if(SENSOR_3>HW){ right; t0=CurrentTick(); }else if(SENSOR_3>WH){ rights; t0=CurrentTick(); }else if(SENSOR_3>BL){ OnFwd(OUT_BC,25); t0=CurrentTick(); }else if(SENSOR_3>HB){ lefts; t0=CurrentTick(); }else{ left; } } Off(OUT_BC); }
路の右側を通り交差点またはT字路を認識し止まる
sub teisirev() { SetSensorLight(S3); //交差点を認識して止まる long t0=CurrentTick(); while(CurrentTick()-t0<=40){ if(SENSOR_3>HW){ left; t0=CurrentTick(); }else if(SENSOR_3>WH){ lefts; t0=CurrentTick(); }else if(SENSOR_3>BL){ OnFwd(OUT_BC,25); t0=CurrentTick(); }else if(SENSOR_3>HB){ rights; t0=CurrentTick(); }else{ right; } } Off(OUT_BC); }
終着からボールシュート
sub gole() { left; //ずれを修正 Wait(200); Off(OUT_BC); OnRev(OUT_BC,30); //後退 Wait(1000); Off(OUT_BC); OnRev(OUT_A,30); //アームを開ける Wait(200); Off(OUT_A); OnFwd(OUT_BC,50); //シュート Wait(900); Off(OUT_BC); }
task main() { kousatenn(); teisi(); right; //右に旋回しコースに復帰 Wait(1000); Off(OUT_BC); kousatennrev(); kousatennrev(); teisirev(); right; //ボールの方向へ方向転換 Wait(1000); Off(OUT_BC); OnFwd(OUT_BC,30); //ボールまで接近 Wait(1500); Off(OUT_BC); OnFwd(OUT_A,50); //ボールを挟む Wait(200); Off(OUT_A); OnFwd(OUT_B,30); //コースに復帰 OnRev(OUT_C,30); Wait(900); Off(OUT_BC); kousatennrev(); teisirev(); left; gole(); }
光センサーの1の違いで交差点での動きが変化することや時間指定の細かさはその他のプログラムで補えばもっと簡単に課題をできたと思う。
アームと本体を無理矢理くっつけた形になってしまったため開始ボタンの押しにくさを生んでしまった。メイン部分をデフォルトから改造してアームをもっとうまい具合に装着できたと思う。
今回はプログラムを考えることが多く基本的なライントレースを色によって極端に変化させることで急カーブなどは簡単になったがより前に進んでしまうために交差点がうまくいかないことがあり悩んだ。結局時間を減らすことにより交差点を渡るも、もっとうまいやり方があったのではないかと感じた。