2018a/Member

課題

2018a-mission2.png
2018a-mission2a.png

ラインをトレスして、缶を運ぶ。道順は見た通りで、Xにて350mL缶をYに移動させる。この時、缶は引きずっても構わない。

ロボットの説明

robon1.jpg
robon2.jpg

一枚目は光センサー部分。二枚目は分かりづらいのだが…クワガタのような二つのアームの写真だ。

プログラム

定義、プログラムの順に適宜解説をしていく。

光センサー

今回は光センサーを用いるので、数値を定義した。

#define BLACK 36
#define LITTLE_BLACK 40
#define LITTLE_WHITE 44 
#define WHITE 48

トレス時の行動パターン

トレス時における、微細な移動も定義した。

#define LEFT OnFwd(OUT_C,40);OnRev(OUT_A,30);Wait(1);Off(OUT_C);
#define LITTLE_LEFT OnFwd(OUT_C,30);OnFwd(OUT_A,20);Wait(1);Off(OUT_AC);
#define LITTLE_RIGHT OnFwd(OUT_A,30);OnFwd(OUT_C,20);Wait(1);Off(OUT_AC);
#define RIGHT OnFwd(OUT_A,30);OnRev(OUT_C,30);Wait(1);Off(OUT_A);
#define FRONT OnFwd(OUT_AC,30);Wait(1);Off(OUT_AC);

最初に定義したとき、Offをつけるのを忘れ直線番長となってしまった。その後、Offを入れた場合Waitがないため、ほんの少ししずつしか動かなかった。そのため、Wait(1)を入れることにより解決した。

ライントレスの定義

先に光センサーの反応で行動を変えるものも作った。たびたび現れる『KAZU』は、黒い部分を踏むことにより増加する関数となっている。

#define LINE_LEFT if (SENSOR_1 < BLACK) {LEFT;KAZU += 3;} else if (SENSOR_1 < LITTLE_BLACK)  {LITTLE_LEFT;KAZU += 1;} else if (SENSOR_1 > WHITE) {RIGHT;KAZU -= 1;}   else if (SENSOR_1 >LITTLE_WHITE) {LITTLE_RIGHT;KAZU -= 3;} else {FRONT;KAZU *= 0;}
#define LINE_RIGHT if (SENSOR_1 < BLACK) {RIGHT;KAZU += 3;} else if (SENSOR_1 < LITTLE_BLACK) {LITTLE_RIGHT;KAZU += 1;} else if (SENSOR_1 > WHITE) {LEFT;KAZU -= 1;}else if (SENSOR_1 > LITTLE_WHITE) {LITTLE_LEFT;KAZU -= 3;} else {FRONT;KAZU *= 0;}

この定義により、一度のライントレスを  while(KAZU < 任意の値){LINE_LEFT;}; で行えるようになっている。

また、交差点を直進や曲がったときに、復帰するときにも  repeat(任意の回数){LINE_LEFT;}; で復帰することが可能となっている。

FRONT時の関数計算

ライントレスは黒に近いと『KAZU』が増加し、白に近いときは減少するようになっている。が、グレーの時は0をかけて、KAZUが0になるような計算している。その理由としては、例えば白いところを長い間、ぐるぐると周り続けてからライントレスに復帰したとき、KAZUが限りなく小さくなり正確なトレスができなくなる。これを防ぐために0をかけるようにし、正確なトレスが可能となった。

復帰のプログラム

"repeat"を使うよりも、時間を定義し、何秒か繰り返すという方が容量が少なくなるのだが、なぜかうまくいかなかったので、"repeat"にした。

缶をつかむ

#define AGERU OnRev(OUT_B,10);Wait(1500);Off(OUT_B);
#define SAGERU OnFwd(OUT_B,10);Wait(2000);Off(OUT_B);

つかむ動作は"AGERU"。離す動作は"SAGERU"と定義されていて、矛盾している。これにはちゃんとした理由がある。発表直前まで缶を上から輪を下ろし、引きずるという機構だった。これを直前にクワガタのような挟める形に変えたため、定義の名称まで変更する時間がなかったのだ。

プログラム

task main()
{
   SetSensorLight(S1);
   int KAZU=0; 



   AGERU;

   OnFwd(OUT_AC,30);Wait(700);Off(OUT_AC);
   repeat(5000){LINE_LEFT;};KAZU *= 0;
   Off(OUT_AC);

   while(KAZU < 100){LINE_LEFT;}; Off(OUT_AC);

   PlaySound(SOUND_DOUBLE_BEEP);Wait(1000);KAZU *= 0;           //Cヲ感知

   OnFwd(OUT_AC,30);Wait(400);Off(OUT_AC);
   repeat(3000){LINE_LEFT;};KAZU *= 0;               //Cを通過の後トレスに戻る

   while(KAZU < 250){LINE_LEFT;};Off(OUT_AC);

   PlaySound(SOUND_UP);KAZU *= 0;Wait(500);          //CDの曲がり角を感知

   OnRev(OUT_A,40);OnFwd(OUT_C,40);Wait(2000);Off(OUT_AC);
   repeat(1200){LINE_LEFT};KAZU *= 0;

   while(KAZU < 100){LINE_LEFT;};Off(OUT_AC);         //曲がって復帰

   KAZU *= 0;PlaySound(SOUND_DOUBLE_BEEP);         //Dを感知

   SAGERU;              //35缶をキャッチする

   OnRev(OUT_A,30);OnFwd(OUT_C,30);Wait(2500);Off(OUT_AC);
   repeat(1500){LINE_LEFT};KAZU *= 0;          //Dを曲がって復帰

   while(KAZU < 80){LINE_LEFT;};Off(OUT_AC);

   KAZU *= 0;PlaySound(SOUND_UP);         //Eを感知

   OnFwd(OUT_A,30);Wait(600);Off(OUT_AC);
   repeat(2000){LINE_LEFT;};KAZU *= 0;

   while(KAZU < 100){LINE_LEFT;};Off(OUT_AC);
   
   PlaySound(SOUND_DOUBLE_BEEP);Wait(500);KAZU *= 0;         //Fを感知 

   OnRev(OUT_A,40);OnFwd(OUT_C,40);Wait(1500);Off(OUT_AC);
   repeat(800){LINE_LEFT;};KAZU *= 0;

   while(KAZU < 100){LINE_LEFT;};Off(OUT_AC);           

   PlaySound(SOUND_DOUBLE_BEEP);Wait(1000);KAZU *= 0;    //Gを感知

   repeat(30000){
                  if (SENSOR_1 < BLACK) {OnRev(OUT_A,40);Wait(1);Off(OUT_AC);} 
                  else if (SENSOR_1 < LITTLE_BLACK) {LEFT;}
                  else if (SENSOR_1 > WHITE) {OnRev(OUT_C,30);Wait(1);Off(OUT_AC);}
                  else if (SENSOR_1 > LITTLE_WHITE) {RIGHT;} 
                  else {FRONT;}
                 };
   repeat(1000){LINE_LEFT;};KAZU *= 0;

   while(KAZU < 120){LINE_LEFT;};Off(OUT_AC);                

   PlaySound(SOUND_DOUBLE_BEEP);Wait(1000);KAZU *= 0;       //Hを感知

   OnFwd(OUT_A,30);OnRev(OUT_C,30);Wait(2500);Off(OUT_AC);

   repeat(3000){LINE_RIGHT;};KAZU *= 0;
   while(KAZU < 120){LINE_RIGHT;};Off(OUT_AC);               

   PlaySound(SOUND_DOUBLE_BEEP);Wait(1000);KAZU *= 0;   //Iを感知
  
   OnFwd(OUT_A,30);OnRev(OUT_C,30);Wait(2500);Off(OUT_AC);

   while(KAZU < 150){LINE_RIGHT};Off(OUT_AC);

   PlaySound(SOUND_UP);KAZU *= 0;            //Lを感知

   OnFwd(OUT_C,30);Wait(300);Off(OUT_AC);

   while(KAZU < 150){LINE_RIGHT;};Off(OUT_AC);

   PlaySound(SOUND_UP);KAZU *= 0;               //Kを感知

   OnFwd(OUT_C,30);Wait(300);Off(OUT_AC);

   while(KAZU < 100){LINE_RIGHT;};Off(OUT_AC);

   PlaySound(SOUND_DOUBLE_BEEP);KAZU *= 0;Wait(1000);           //Jを感知

   OnFwd(OUT_C,30);OnRev(OUT_A,30);Wait(2500);Off(OUT_AC);

   AGERU;

   OnRev(OUT_AC,30);Wait(1000);Off(OUT_AC);
   OnFwd(OUT_A,30);OnRev(OUT_C,30);Wait(4000);Off(OUT_AC);

   repeat(2000){LINE_LEFT;};KAZU *= 0;

   while(KAZU < 100){LINE_LEFT;};Off(OUT_AC);

   PlaySound(SOUND_DOUBLE_BEEP);Wait(1000);KAZU *= 0;            //Bを感知

   OnFwd(OUT_A,30);OnRev(OUT_C,30);Wait(1500);Off(OUT_AC);

   repeat(1000){LINE_LEFT;};KAZU *= 0;

   while(KAZU < 100){LINE_LEFT;};Off(OUT_AC);

   OnFwd(OUT_AC,30);Wait(500);Off(OUT_AC);
}

…あまり解説をすることがない…

小さな工夫

  • 交差点にて停止する際に、音が鳴るようになっている。これは決められた交差点では一秒停止しなければならない交差点での停止と、それ以外での停止の際になる音を分けている。
  • GからHにかけての小さなカーブが一番の鬼門なのだが、そこはさらに細かく慎重にトレスする振り分けを使っている

最後に

今回も今回とてかなり時間がかかってしまった。が、プログラムに関する知識はかなり上がり、どこを直したらいいか、分かるようになってきた。つまり、成長を感じている。このまま、次回のミッションも頑張りたいと思う。


添付ファイル: filerobon2.jpg 35件 [詳細] filerobon1.jpg 27件 [詳細] file2018a-mission2a.png 37件 [詳細] file2018a-mission2.png 40件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-07-20 (金) 01:25:19