[[2017a/Member]]
[[2017a/Member]]~
目次
#contents
*課題2について [#m74bffdd]
詳しくは[[課題2>2017a/Mission2]]を参照。
詳しくは[[課題2>2017a/Mission2]]を参照。~
私はE地点直進コースを担当しました。
*ロボットについて [#je9d5340]
できるだけコンパクトなつくりにすることで小回りが効くようになっています。また車体の後方はブロックに任せて支えることで、タイヤに比べて摩擦の軽減ができています。
できるだけコンパクトなつくりにすることで小回りが効くようになっています。また車体の後方はブロックに任せて支えることで、後輪タイヤに比べて摩擦を軽減できています。
&ref(2017a/Member/kosih/Mission2/IMG_20170707_161942.jpg,50%,robot);
&ref(2017a/Member/kosih/Mission2/IMG_20170707_162023.jpg,50%,robot);
&ref(2017a/Member/kosih/Mission2/IMG_20170707_162034.jpg,50%,robot);

*プログラム [#faa14e36]
 #define shikii 40
 #define kuro 36
 #define siro 44
 #define tyottosiro 43
 #define tyottokuro 37
 #define migimae OnFwd(OUT_A);
 #define hidarimae OnFwd(OUT_C);
 #define migi OnFwd(OUT_A);OnRev(OUT_C);
 #define hidari OnFwd(OUT_C);OnRev(OUT_A);
 #define mae OnFwd(OUT_AC);
 #define STEP 2
 #define movetime 22
 #define kyuumovetime 52
 #define yuruimovetime 19
 #define tyokkakumovetime 25

 sub tadoru()                                      //たどる
 { 
 ClearTimer(0);
 SetPower(OUT_AC,1);
 SetSensor(SENSOR_2, SENSOR_LIGHT);

 while (FastTimer(0)<=movetime)
 if (SENSOR_2 < kuro){  //黒以下なら
   hidari; 
   }
  else if (SENSOR_2 < tyottokuro){  //黒〜ちょっと黒なら
   hidarimae;ClearTimer(0); 
  ClearTimer(0);
  SetPower(OUT_AC,1);
  SetSensor(SENSOR_2, SENSOR_LIGHT);
  while (FastTimer(0)<=movetime)
   if (SENSOR_2 < kuro){  //黒以下なら
     hidari; 
    }
  else if (SENSOR_2 < tyottosiro){  //ちょっと黒〜ちょっと白なら
   mae;ClearTimer(0);
   }
  else if (SENSOR_2 < siro){  // ちょっと白〜白なら
    migimae;ClearTimer(0); 
   else if (SENSOR_2 < tyottokuro){  //黒〜ちょっと黒なら
     hidarimae;ClearTimer(0); 
     }
 else if (SENSOR_2 > siro){  // 白以上なら
    migi;ClearTimer(0); 
   else if (SENSOR_2 < tyottosiro){  //ちょっと黒〜ちょっと白なら
     mae;ClearTimer(0);
    }
   else if (SENSOR_2 < siro){  // ちょっと白〜白なら
     migimae;ClearTimer(0); 
      }
   else if (SENSOR_2 > siro){  // 白以上なら
     migi;ClearTimer(0); 
      }
    Wait(STEP);
     }
    Wait(STEP);
    }

 sub tadorusecond()                                      //特殊な道をたどる
 { 
 ClearTimer(0);
 SetPower(OUT_AC,1);
 SetSensor(SENSOR_2, SENSOR_LIGHT);
  ClearTimer(0);
  SetPower(OUT_AC,1);
  SetSensor(SENSOR_2, SENSOR_LIGHT);
 
 while (FastTimer(0)<=18)
 if (SENSOR_2 < kuro){  //黒以下なら
   hidari; 
   }
  else if (SENSOR_2 < tyottokuro){  //黒〜ちょっと黒なら
   hidarimae;ClearTimer(0); 
  while (FastTimer(0)<=18)
   if (SENSOR_2 < kuro){  //黒以下なら
     hidari; 
    }
  else if (SENSOR_2 < tyottosiro){  //ちょっと黒〜ちょっと白なら
   mae;ClearTimer(0);
   }
  else if (SENSOR_2 < siro){  // ちょっと白〜白なら
    migimae;ClearTimer(0); 
   else if (SENSOR_2 < tyottokuro){  //黒〜ちょっと黒なら
     hidarimae;ClearTimer(0); 
    }
   else if (SENSOR_2 < tyottosiro){  //ちょっと黒〜ちょっと白なら
     mae;ClearTimer(0);
    }
   else if (SENSOR_2 < siro){  // ちょっと白〜白なら
     migimae;ClearTimer(0); 
     }
 else if (SENSOR_2 > siro){  // 白以上なら
    migi;ClearTimer(0); 
   else if (SENSOR_2 > siro){  // 白以上なら
     migi;ClearTimer(0); 
     }
    Wait(STEP);
    }
 

 sub kyuutadoru()                                //急カーブをたどる
 { 
 ClearTimer(0);
 SetPower(OUT_AC,0);
 SetSensor(SENSOR_2, SENSOR_LIGHT);
  ClearTimer(0);
  SetPower(OUT_AC,0);
  SetSensor(SENSOR_2, SENSOR_LIGHT);
 
 while (FastTimer(0)<=kyuumovetime)
 if (SENSOR_2 < kuro){  //黒以下なら
   hidari; 
  while (FastTimer(0)<=kyuumovetime)
   if (SENSOR_2 < kuro){  //黒以下なら
     hidari; 
   }
  else if (SENSOR_2 < tyottokuro){  //黒〜ちょっと黒なら
   hidarimae;ClearTimer(0); 
   else if (SENSOR_2 < tyottokuro){  //黒〜ちょっと黒なら
     hidarimae;ClearTimer(0); 
    }
  else if (SENSOR_2 < tyottosiro){  //ちょっと黒〜ちょっと白なら
   mae; ClearTimer(0); 
 }
  else if (SENSOR_2 < siro){  //ちょっと白〜白なら
    migimae;ClearTimer(0); 
   else if (SENSOR_2 < tyottosiro){  //ちょっと黒〜ちょっと白なら
     mae; ClearTimer(0); 
    }
   else if (SENSOR_2 < siro){  //ちょっと白〜白なら
     migimae;ClearTimer(0); 
     }
 else if (SENSOR_2 > siro){  // 白以上なら
    migi;ClearTimer(0); 
   else if (SENSOR_2 > siro){  // 白以上なら
     migi;ClearTimer(0); 
     }
    Wait(STEP);
    }
 

 sub yurukutadoru()                              //緩いカーブをたどる
 { 
 ClearTimer(0);
 SetPower(OUT_AC,1);
 SetSensor(SENSOR_2, SENSOR_LIGHT);
  ClearTimer(0);
  SetPower(OUT_AC,1);
  SetSensor(SENSOR_2, SENSOR_LIGHT);
 
 while (FastTimer(0)<=yuruimovetime)
 if (SENSOR_2 < kuro){  //黒以下なら
   hidari; 
  while (FastTimer(0)<=yuruimovetime)
   if (SENSOR_2 < kuro){  //黒以下なら
     hidari; 
   }
  else if (SENSOR_2 < tyottokuro){  //黒〜ちょっと黒なら
   hidarimae;ClearTimer(0); 
   else if (SENSOR_2 < tyottokuro){  //黒〜ちょっと黒なら
     hidarimae;ClearTimer(0); 
    }
  else if (SENSOR_2 < tyottosiro){  //ちょっと黒〜ちょっと白なら
   mae;ClearTimer(0);
   else if (SENSOR_2 < tyottosiro){  //ちょっと黒〜ちょっと白なら
     mae;ClearTimer(0);
   }
  else if (SENSOR_2 < siro){  // ちょっと白〜白なら
    migimae;ClearTimer(0); 
   else if (SENSOR_2 < siro){  // ちょっと白〜白なら
     migimae;ClearTimer(0); 
     }
 else if (SENSOR_2 > siro){  // 白以上なら
    migi;ClearTimer(0); 
   else if (SENSOR_2 > siro){  // 白以上なら
     migi;ClearTimer(0); 
     }
  PlaySound(SOUND_UP);
    }

 sub tomaru()                                   //止まる
 {
 PlaySound(SOUND_DOWN);
 Off(OUT_AC);
 Wait(100);
 hidarimae;
 Wait(75);
 mae;
 Wait(40);
 }
  PlaySound(SOUND_DOWN);
  Off(OUT_AC);
  Wait(100);
  hidarimae;
  Wait(75);
  mae;
  Wait(40);
  }

 sub tyokkakutadoru()                                      //直角をたどる
 { 
 ClearTimer(0);
 SetPower(OUT_AC,0);
 SetSensor(SENSOR_2, SENSOR_LIGHT);
  ClearTimer(0);
  SetPower(OUT_AC,0);
  SetSensor(SENSOR_2, SENSOR_LIGHT);
 
 while (FastTimer(0)<=tyokkakumovetime)
 if (SENSOR_2 < kuro){  //黒以下なら
   hidari; 
  while (FastTimer(0)<=tyokkakumovetime)
   if (SENSOR_2 < kuro){  //黒以下なら
     hidari; 
   }
  else if (SENSOR_2 < shikii){  //黒〜閾値なら
   hidarimae;ClearTimer(0); 
   else if (SENSOR_2 < shikii){  //黒〜閾値なら
     hidarimae;ClearTimer(0); 
    }
  else if (SENSOR_2 < siro){  // 閾値〜白なら
    migimae;ClearTimer(0); 
   else if (SENSOR_2 < siro){  // 閾値〜白なら
     migimae;ClearTimer(0); 
     }
 else if (SENSOR_2 > siro){  // 白以上なら
    migi;ClearTimer(0); 
   else if (SENSOR_2 > siro){  // 白以上なら
     migi;ClearTimer(0); 
     }
    Wait(STEP);
    }

  task main()
 {
  tadoru();
  PlaySound(SOUND_UP);//1回目
  migimae;
  Wait(10);
  hidari;
  Wait(40);
  tadoru();
  tomaru();//2回目
  yurukutadoru();//3回目
  Off(OUT_C);
  OnFwd(OUT_A);
  Wait(80);
  yurukutadoru();//4回目
  Off(OUT_A);
  OnFwd(OUT_C);
  Wait(80);
  tadoru();
  PlaySound(SOUND_UP);//5回目
  migimae;
  Wait(10);
  hidari;
  Wait(40);
  kyuutadoru();
  tadorusecond();
  tadorusecond();
  PlaySound(SOUND_UP);//6回目
  tadorusecond();
  PlaySound(SOUND_DOWN);
  Off(OUT_AC);
  Wait(100);
  migimae;
  Wait(25);
  mae;
  Wait(20);
  tadorusecond();
  PlaySound(SOUND_DOWN);//7回目
  Off(OUT_AC);
  Wait(100);
  migimae;
  Wait(25);
  mae;
  Wait(20);
  tadoru();
  tomaru();//8回目
  yurukutadoru();//9回目
  Off(OUT_C);
  OnFwd(OUT_A);
  Wait(80);
  yurukutadoru();//10回目
  Off(OUT_A);
  OnFwd(OUT_C);
  Wait(80);
  tadoru();
  PlaySound(SOUND_UP);//11回目
  migimae;
  Wait(10);
  hidari;
  Wait(40);
  tadoru();
  mae;
  Wait(250);
  Off(OUT_AC);//ゴール
 }
*交差点の判断 [#x163f1fe]
交差点の判断はセンサーが黒色を認識している時間を計って行いました。曲率やその時のロボットの速さに合わせて4パターンの判別の仕方をサブルーチンで予め書いておき、必要なときに自由に呼べるようにしています。
*プログラムの工夫点 [#d8f05fe2]
カウンターは使わず、タスクメインに順番通りに指令を書き並べていきました。ロボットの基本的な動きはサブルーチンで書き、移動する道の状態にあわせて適切な動きができるように細かく場合分けをしました。一番の難所は急なカーブからの直角曲がり(5回目〜6回目の間)でした。急カーブか直角な曲がり角、どちらかに焦点を絞ってプログラムを書くと必ず不都合が生じてしまうので、急なカーブではあえてカーブを交差点と判断させて、2回同じプログラムを連ねることで見た目の上では急なカーブをなめらかに進んでいるように演出できました。(つまりプログラムの上では2つの同じ動作が続けて起こっているので、見た目は1つの動作しかしていないように見えているわけです。)コースが予め分かっていたのでこのようにすることができました。また、モーターの回転スピードも場所によって使い分けることで時間の短縮をすることができました。
*反省点 [#k0355a59]
今回光センサを使った課題で、道の識別に必要な色の値の設定が大切だったのですがそれぞれの値の差が小さくなるように設定してしまったためにロボットの動きがとてもぎこちないものになってしまいました。値を早い段階でうまく定義できていれば、無駄がない動きでさらに時間短縮が可能になったと思われます。

ロボットの基本的な動きはサブルーチンで書き、移動する道の状態にあわせて適切な動きができるように細かく場合分けをしました。一番の難所は急なカーブからの直角曲がりでした。(5回目〜6回目の間)急カーブか、直角な曲がり角のどちらかに焦点を絞ってプログラムを書くと必ず不都合が生じてしまうので、急なカーブではあえてカーブを交差点と判断させて、2回同じプログラムを連ねることで見た目の上では急なカーブをなめらかに進んでいるように演出できました。(つまりプログラムの上では2つの同じ動作が続けて起こっているので、見た目は1つの動作しかしていないように見えているわけです。)コースが予め分かっていたのでこのようにできました。


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