目次
#contents

*課題について [#ucad970a]
詳しくは[[課題2 >2017a/Mission2]]を参照。今回は、交差点や急カーブを含めたライントレースを行った。

*ロボットについて [#fc2eff43]
今回は、下記の写真のように、ライントレースの授業で使用したものと全く同じ形のロボットでライントレースを行った。
#ref(./無題.jpg,50%,robote)
*プログラムについて [#redfa641]
ロボットは以下の写真の赤線のように動く。
以下は、そのプログラムである。
#ref(./ロボ画像.jpg,50%,robote)
**定義 [#k4e15aa5]
まず、しきい値や速さなど基本となる値を定義した。
 #define threshold 46
 #define SPEED_H 30
 #define SPEED_L 20
 #define OnRL(speedR,speedL) 
   OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL);
 #define go_forward OnRL(SPEED_H,SPEED_H);
 #define turn_left1 OnRL(SPEED_L,-SPEED_L);
 #define turn_left0 OnRL(SPEED_L,0);
 #define turn_right0 OnRL(0,SPEED_L);
 #define turn_right1 OnRL(-SPEED_L,SPEED_L);
 #define STEP 1
 #define nMax 10
 #define STEP 1  // 1回の判断で動作させる時間
 #define nMax 10  // 通常のカーブとして許容できる繰り返しの最大値
**交差点判断 [#o73b60e3]
まずしきい値(threshold)である46を基準とし
しきい値-12未満(34未満)を黒としカウンタを使って、ライントレースが始まってから黒いところを何回連続で通ったかで交差点を判断した。黒いところを通るたびに回数が1回ずつ増えていきそれ以外のところ通った場合には回数は0に戻るようにした。
今回は、10回(nMax)連続で黒を通った場合を交差点と判断するようにした。10回だと基本的にカーブを交差点と間違えることなく進むことができた。
交差点と判断した後は回数を0に戻すようにした。
電池残量によってモーターの速さも変わるため回数を決めるのに苦労した。
ちなみに、電池を変えたばかりの時は30回連続くらいがちょうどいいように感じた。
**線の右側のライントレース [#x6bfbae0]
次に、黒線の右側を走るプログラムをつくった。
 sub line_right()
 {
   int nOnline = 0;
   int nOnline = 0;  // 続けて黒になった回数 (カウンタ)
 
   while (nOnline < mMax) {
 
       if (SENSOR_1 < threshold -12) {
        turn_right1;
         nOnline++;
       } else {
       if (SENSOR_1 < threshold -7) {
        turn_right0;
       } else if (SENSOR_1 < threshold +7) {
        go_forward;
       } else if (SENSOR_1 < threshold +12) {
        turn_left0;
       } else {
        turn_left1;
       }
        nOnline = 0;
       }
           turn_right1;
           nOnline++;  // カウンタを1増やす
          } else {
                  if (SENSOR_1 < threshold -7) {
                      turn_right0;
                     } else if (SENSOR_1 < threshold +7) {
                      go_forward;
                     } else if (SENSOR_1 < threshold +12) {
                      turn_left0;
                     } else {
                      turn_left1;
                     }
                      nOnline = 0;  // カウンタをリセット
                     }
        Wait(STEP);
       }
     }
  Off(OUT_BC);
  nOnline = 0;
  nOnline = 0;  // カウンタをリセット
 }
**線の左側のライントレース [#zd740c09]
次に、黒線の左側を走るプログラムをつくった。
 sub line_left()
 {
   int nOnline = 0;
   int nOnline = 0;  // 続けて黒になった回数 (カウンタ)
   while (nOnline < mMax) {
 
       if (SENSOR_1 < threshold -12) {
        turn_left1;
         nOnline++;
       } else {
       if (SENSOR_1 < threshold -7) {
        turn_left0;
       } else if (SENSOR_1 < threshold +7) {
        go_forward;
       } else if (SENSOR_1 < threshold +12) {
        turn_right0;
       } else {
        turn_right1;
       }
        nOnline = 0;
       }
           turn_left1;
           nOnline++;  // カウンタを1増やす
          } else {
               if (SENSOR_1 < threshold -7) {
                   turn_left0;
                  } else if (SENSOR_1 < threshold +7) {
                   go_forward;
                  } else if (SENSOR_1 < threshold +12) {
                   turn_right0;
                  } else {
                   turn_right1;
                  }
                   nOnline = 0;  // カウンタをリセット
                  }
        Wait(STEP);
       }
     }
  Off(OUT_BC);
  nOnline = 0;
  nOnline = 0;  // カウンタをリセット
 }
以下からはコースをいくつかに区切り、その区切りごとのプログラムである。
**AからEまで [#h827110b]
 sub line_cross1()
 {
   go_forward;
   Wait(600);
   line_right();
 }
**EからPまで・GからSまで [#i456e9f4]
 sub line_cross2()
 {
   turn_right0;
   Wait(800);
   line_left();
   Wait(1000);
 }
**PからQまで・SからPまで [#zaa99072]
 sub line_cross3()
 {
   turn_left0;
   Wait(2000);
   line_left();
 }
**QからRまで・PからQまで [#nab8d20f]
 sub line_cross4()
 {
   turn_right0;
   Wait(400);
   go_forward;
   Wait(200);
   line_left();
 }
**RからTまで・QからFまで [#le3b9e30]
 sub line_cross5()
 {
   go_forward;
   Wait(200);
   line_right();
   Wait(1000);
 }
**TからTまで [#ve922076]
 sub line_cross6()
 { 
   go_forward;
   Wait(300);
   line_right();
   Off(1000);
 }
**TからHまで [#lc364667]
 sub line_cross7()
 {
   go_forward;
   Wait(300);
   line_right();
 }
**Hから2回目の急カーブまで [#zbd54424]
 sub line_cross8()
 {
   turn_right0;
   Wait(2800);
   go_forward;
   Wait(200);
   line_right();
 }
**2回目の急カーブからGまで [#g56c02b6]
 sub line_cross9()
 {
   turn_right1;
   Wait(2500);
   line_right();
 }
**FからAまで [#g30a1e2c]
 sub line_cross10()
 {
   turn_right0;
   Wait(2000);
   line_right();
   go_forward;
   Wait(600);
   Off(OUT_BC);
 }
**SOUND_UPの音を出すtask [#kdd9b352]
task play_music1()
 {
  Wait(100);
  PlaySound(SOUND_UP);
  Wait(1000);
 }
**SOUND_DOWNの音を出すtask [#a7e0b7d7]
 task play_music2()
 {
  Wait(100);
  PlaySound(SOUND_DOWN);
  Wait(1000);
 }
**task main [#d02cd950]
 task main()
 {
  SetSensorLight(S1);
 
  line_cross1();      //A-E
  start play_music1;
  line_cross2();     //E-P
  start play_music2;
  line_cross3();     //P-Q
  start play_music1;
  line_cross4();     //Q-R
  start play_music1;
  line_cross5();     //R-T
  start play_music2;
  line_cross6();     //T-T
  start play_music2;
  line_cross7();     //T-H
  start play_music1;
  line_cross8();     //H-2回目の急カーブ
  line_cross9();     //2回目の急カーブ-G
  start play_music1;
  line_cross2();     //G-S
  start play_music2;
  line_cross3();     //S-P
  start play_music1;
  line_cross4();     //P-Q
  start play_music1;
  line_cross5();     //Q-F
  start play_music1;
  line_cross10();    //F-A
}

*反省・考察 [#z21d5eb0]
やはり、タイヤとセンサーが離れていたせいか急カーブの内側をうまく曲がれることができなかった。そこをプログラムで補おうとしたが、それも難しかった。結局は外側を通ることやコースが決まっているので、止まったところから回転させることでなんとか曲がれはしたものの不本意な結果となった。そして、ロボットに手を加える必要性と自分自身の見通しの甘さを痛感させられた。これからは、先を見通し、ロボットをうまく改良することでプログラミングを楽にさせていきたい。
 



トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS