[[2019a/Member]]
#contents
*課題について [#v6c2d16f]
下の図のようなコースを各チームで作成し、「ミッション」を遂行するためのロボットを作成せよ。
#ref(2019a-mission2.png)
**コース [#td5ea28e]
黒線の幅は20mmでなるべく均等な濃さにすること。 ゴールには、長さ15または16のブロックおく。
**ミッション [#rf0d0d52]
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秒間停止し、丁字路では直角方向に進入する時のみ一時停止すること。


私は後者のコースを選んだ。
*ロボット [#wbceb1bc]
#ref(DSC_0103 (2).jpg)
先端にボールを掴むためのアームがあり、左右のタイヤの間のあたり(アームの根本の下あたり)に光センサーがある。~
カーブを曲がりやすくするために、タイヤとセンサーの距離が離れないようにした。

#ref(DSC_0105.jpg)
正面から見るとこのようになっている。~
アームの幅が狭いので、位置がずれるとボールを掴めないことがある。

#ref(sketch-1563513748461.jpg)
アームはこのように一回転できるようにした。~
これによって、ボールを掴む動作とシュートがこのアームだけでできるようになっている。
*プログラム [#g9df1802]
必要な数値や基本的な動きは最初に定義した。
 #define BLACK      37
 #define GRAY_BLACK 45
 #define GRAY_WHITE 52
 #define WHITE      60
 #define go_l   OnRev(OUT_B,30);OnFwd(OUT_C,30);
 #define go_s_l OnRev(OUT_B,35);Off(OUT_C);
 #define go_s   OnRev(OUT_B,35); OnRev(OUT_C,37);
 #define go_s_r Off(OUT_B);OnRev(OUT_C,35);
 #define go_r   OnFwd(OUT_B,30);OnRev(OUT_C,30);
 #define short_brake Wait(1000);
 #define BLACK      37   //黒
 #define GRAY_BLACK 45   //黒灰
 #define GRAY_WHITE 52   //白灰
 #define WHITE      60   //白
 #define go_l   OnRev(OUT_B,30);OnFwd(OUT_C,30);     //進みつつ左に曲がる
 #define go_s_l OnRev(OUT_B,35);Off(OUT_C);          //左折
 #define go_s   OnRev(OUT_B,35); OnRev(OUT_C,37);    //直進
 #define go_s_r Off(OUT_B);OnRev(OUT_C,35);          //右折
 #define go_r   OnFwd(OUT_B,30);OnRev(OUT_C,30);     //進みつつ右に曲がる
 #define short_brake Wait(1000);                     //小休止

今回の最も重要なプログラム。~
ラインの左側の白と黒の境界線を辿る。
~タイマーを使用し、常に時間を計っている。125/1000秒以上黒いところにいると交差点と判断する。
~タイマーを使用し、常に時間を計っている。連続して0.125秒以上黒いところにいたら交差点と判断する。
 sub follow_line()
 {
  SetSensorLight(S3);
  long t0=CurrentTick();
  while(CurrentTick()-t0<125) {
    if (SENSOR_3 < BLACK) {
     go_l;
    } else if (SENSOR_3 < GRAY_BLACK) {
     go_s_l; t0=CurrentTick();
    } else if (SENSOR_3 < GRAY_WHITE) {
     go_s;   t0=CurrentTick();
    } else if (SENSOR_3 < WHITE) {
     go_s_r; t0=CurrentTick();
    } else {
     go_r;   t0=CurrentTick();
    }
  }
  Off(OUT_BC);
 }
交差点を渡る。
 sub cross_line()
 {
  go_s_r;
  Wait(100);
  go_s;
  Wait(400);
  Off(OUT_BC);
 }
左折する。
 sub turn_left()
 {
  go_s_l;
  Wait(700);
  go_l;
  Wait(1200);
  Off(OUT_BC);
 }
右折する。
 sub turn_right()
 {
  go_s_r;
  Wait(900);
  go_r;
  Wait(900);
  Off(OUT_BC);
 }
ボールを掴む。
 sub ball_catch()
 {
  go_r;
  Wait(100);
  go_s;
  Wait(1200);
  Off(OUT_BC);
  OnFwd(OUT_A,30);
  Wait(600);
  Off(OUT_A);
  OnFwd(OUT_BC,35);
  Wait(2500);
 }
シュートする。
 sub shoot()
 {
  go_r;
  Wait(200);
  Off(OUT_BC);
  Wait(1000);
  OnRev(OUT_A,70);
  Wait(900);
  Off(OUT_A);
 }

サブルーチンを並べ、全体の動きを作る。~
同じ動きが続く部分はrepeatを使用してまとめた。
 task main()
 {
  go_s; Wait(500);   // A->M
  follow_line(); cross_line();   // M->K
  ball_catch(); follow_line(); turn_left();   // K->L->K ボールをつかむ
  follow_line(); short_brake; turn_left();   // K->J
  repeat(2){follow_line(); cross_line();};   // J->I->H 
  repeat(3){follow_line(); turn_left();};   // H->G->F->E
  follow_line(); short_brake; cross_line();   //E->D
  follow_line(); cross_line();   // D->C
  follow_line(); short_brake;   // C->B
  shoot();   // シュート
  go_s; Wait(1500);   // B->A
 }
*まとめ [#z561431e]
センサーの位置や、アームの構造を工夫したおかげでかなりプログラムが楽になったと思う。うまく動くようにできて良かった。

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS