[[2017a/Member]]
目次
#contents
*課題について [#yc8c3ac9]
下の図のようなコースを各チームで作成し、「ミッション」を遂行するためのロボットを作成する。
下の図のようなコースを各チームで作成し、ライントレースしながら決められたコースを走るロボットを作成する。~
黒線の幅は20mmでなるべく均等な濃さにすること。なお図の中の寸法の単位はcmで、黒線についてはその真ん中からの距離である。
#ref(./2017a-mission2.jpg,50%,コース)
#ref(./2017a-mission2.png,75%,コース)
#ref(./linetrace1.jpg,50%,ロボット)

**コース [#g21e1a0e]
・E地点直進コース~
 Aスタート~
 E直進~
 F(SOUND_UP)~
 Q一時停止(SOUND_DOWN)&左折~
 R直進(SOUND_UP)~
 S左折(SOUND_UP)~
 G(SOUND_UP)~
 H(SOUND_UP)~
 H(SOUND_UP)~toku
 T一時停止(SOUND_DOWN)&直進~
 T一時停止(SOUND_DOWN)&直進~
 R一時停止(SOUND_DOWN)&左折~
 S直進(SOUND_UP)~
 P左折(SOUND_UP)~
 E一時停止(SOUND_DOWN)&左折~
 A停止(SOUND_DOWN)~

*ロボットについて [#e03e1d96]
タッチセンサーと紙の距離を近くして、トレースしやすくした。~
あと、ロボットにセンサーを近づけて回転しやすくした。
#ref(./robot1.jpg,50%,ロボット)
#ref(./robot2.jpg,50%,ロボット)

*プログラムについて [#f0503ae3]
**定義 [#g265a1e0]
 #define BLACK 38
 #define WHITE 63
 #define BLACKGLAY 43
 #define WHITEGLAY 58
 #define GLAY 50
 #define SPEED 50
 #define SPEED_L 25
 #define go_forward OnFwd(OUT_BC,SPEED); //直進
 #define turn_left OnFwd(OUT_B,SPEED);Off(OUT_C);  //左折
 #define turn_right Off(OUT_B);OnFwd(OUT_C,SPEED);//右折
 #define spin_left OnFwd(OUT_B,SPEED_L);OnRev(OUT_C,SPEED_L);  //左旋回
 #define spin_right OnFwd(OUT_C,SPEED_L);OnRev(OUT_B,SPEED_L);  //右旋回

**サブルーチン [#c852158f]
線の左側でトレース
 sub line1(long tmax)
 {
 long t0=CurrentTick();
 while (CurrentTick()-t0<tmax) {
  if (SENSOR_1 > WHITE) {
   spin_right;  //閾値が58〜63のとき右旋回
   t0=CurrentTick();
  } else if (SENSOR_1>WHITEGLAY) {
   turn_right;  //閾値が50〜58のとき右回転
   t0=CurrentTick();
  } else if (SENSOR_1>GLAY) {
   go_forward;  //閾値が43〜50のとき直進
   t0=CurrentTick();
  } else if (SENSOR_1> BLACKGLAY){
   turn_left;  //閾値が38〜43のとき左回転
   t0=CurrentTick();
  } else{
   spin_left;} //閾値が〜38のとき左旋回
  }
 }

線の右側でトレース
 sub line2(long tmax)
 {
 long t0=CurrentTick();
 while (CurrentTick()-t0<tmax) {
  if (SENSOR_1 > WHITE) {
   spin_left;  //閾値が58〜63のとき左旋回
   t0=CurrentTick();
  } else if (SENSOR_1>WHITEGLAY) { 
   turn_left;  //閾値が50〜58のとき左回転
   t0=CurrentTick();
  } else if (SENSOR_1>GLAY) {
   go_forward;  //閾値が43〜50のとき直進
   t0=CurrentTick();
  } else if (SENSOR_1> BLACKGLAY){
   turn_right;  //閾値が38〜43のとき右回転
   t0=CurrentTick();
  } else{
   spin_right;}  //閾値が〜38のとき右旋回
  }
  Off(OUT_BC);
 }

**サウンド [#ke17c635]
サウンドアップのときに一時停止しないため、メインタスクに入れると音を鳴らしている間に少し進んでしまうから、別のタスクにして、音を鳴らしている間もちゃんとライントレースするようにした。
 task play_music()
 {
 PlaySound(SOUND_UP);
 Wait(100);
 }

**メインタスク [#p715e0d5]
曲がり角か交差点かは、黒が何秒続くかで判断した。
 task main()
 {
 SetSensorLight(S1);
 line1(130);start play_music; //F
 line1(230);Off(OUT_BC);PlaySound(SOUND_DOWN); //Qで左折
 Wait(100); //一時停止
 turn_left;
 Wait(840);
 line1(100);start play_music; //R直進
 turn_right;
 Wait(400);
 go_forward;
 Wait(200);
 line1(100);Off(OUT_BC);PlaySound(SOUND_DOWN); //Sで左折
 line1(190);start play_music; //G
 Wait(100); //一時停止
 go_forward;
 Wait(200);
 line2(130);
 line1(220);
 line1(110);start play_music; //H
 line1(200);Off(OUT_BC);PlaySound(SOUND_DOWN); //T直進
 Wait(100); //一時停止
 go_forward;
 Wait(200);
 line1(110);Off(OUT_BC);PlaySound(SOUND_DOWN); //T直進
 Wait(100); //一時停止
 turn_right;
 Wait(200);
 line1(190);start play_music; //Rで左折
 Wait(100); //一時停止
 turn_left;
 Wait(450);
 line1(120);start play_music; //S直進
 turn_left;
 Wait(200);
 go_forward;
 Wait(150);
 line1(110);Off(OUT_BC);PlaySound(SOUND_DOWN); //Pで左折
 line1(190);Off(OUT_BC);PlaySound(SOUND_DOWN); //Eで左折
 Wait(100); //一時停止
 go_forward;
 Wait(200);
 line2(140);
 go_forward;
 Wait(1100);
 Off(OUT_BC);PlaySound(SOUND_DOWN); //Aで停止
 }

**工夫したところ [#hdd63a7e]
急カーブは一回目は外側をトレースしていくため、普通のカーブと同様に曲がれたが、二回目は内側をトレースするため、曲がりきることができなかったので、内側から外側にトレースするところを変えることで解決した。~
Tの交差点で直進するときに、少し前に進ませて交差点を通過してからまたトレースを始めるようにすることで、間違えて右や左に曲がってしまうことを防いだ。
 
*まとめ [#a14db9e5]
なかなか黒の時間が合わなくて、交差点や曲がり角で反応してくれなかったり、変なところで反応してしまったり、サウンドアップのときに余分に進んでしまうなどの様々な問題で、最後までほとんど完走させることがほとんどできなかったですが、プログラムの工夫で、完走できる確率が上がりました。センサーとの距離が少し離れていたので、プログラムでその分をカバーしました。ペアの人にトレースするのを右と左で変える方法を教えてもらえたおかげで課題をクリアして走らせることができたので、助かりました。


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