目次
#contents

*課題 [#i472952a]
今回の課題は課題2で使用したコースを用いて、紙コップを運んで積み重ねるロボットを作ることである。紙コップを置く位置はコースの地点Qの円の中である。~
詳しくは[[こちら:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMission3]]

*作戦 [#s006e477]

**当初の作戦 [#v30b293a]
紙コップを運ぶロボットと積み重ねるロボットの2台を使うことにした。~
紙コップを運ぶロボットは、B地点→R地点→P地点→S地点→C地点とライントレースして動き、紙コップを1つ挟み再びライントレースをしてSPの真ん中まで紙コップを運ぶ。~
この次にD地点までライントレースしてまたSPの真ん中まで紙コップを運ぶという作業をして以下C地点、D地点と紙コップがなくなるまで同じ作業を繰り返させる。~
積み重ねる方のロボットはA地点→P地点→SPの真ん中とライントレースし、運ばれてきた紙コップを持ち上げて右折してから紙コップをQ地点の円の中に紙コップを下すという作業をさせる。~
当初はこのような作戦でいてプログラムも作ったのだが、ロボット本体が大きくなりすぎて崩れやすくなってしまったことや、時間が足りなくなってしまったためロボコン前日に3点を取る作戦に変えた。~

**ロボコン当日の作戦 [#q6bcb887]
ロボコン当日用いた作戦は、紙コップを運ぶ方のロボットだけを用いた。このロボットはB地点→R地点→P地点→S地点→C地点とライントレースして紙コップを1つ挟み、そこで右折をしてQ地点の円の中に入れるというものである。

*ロボット本体の説明 [#m03d799e]

<紙コップを運ぶロボット>
 
&ref(2016a/Member/michiya/Mission3/IMG_2230.JPG,25%,hakobiya);
&ref(2016a/Member/michiya/Mission3/roborobo.png,25%,sensa);~
2つのモーター(A,C)を用いて本体の前後、旋回、回転の動作を行なっている。~
ライントレースができるように本体の真下に光センサー(2)をつけた。~
紙コップを1つ押して運べる動かないアームを付けた。~


<紙コップを積むロボット>~
&ref(2016a/Member/michiya/Mission3/IMG_2223.JPG,25%,tumiya);
&ref(2016a/Member/michiya/Mission3/IMG_2227.JPG,25%,kasaneya);~
2つのモーター(A,C)を用いて本体の前後、旋回、回転の動作を行っている。~
モーター(B)を用いてアームで掴む、離す、上下運動ができるようになっている。~
タッチセンサー(2)を用いて紙コップが当たったことを認識できるようになっている。~

*プログラムの説明 [#s2c532db]

**当初の作戦時に作ったプログラム [#zf383bd1]

***定義 [#p12f39e9]
〈運ぶロボット〉
 #define turn_right_SENKAI OnFwd(OUT_A); OnRev(OUT_C);   //旋回
 #define turn_right OnFwd(OUT_A); Off(OUT_C);            //片方のみ動かす
 #define turn_left_SENKAI OnFwd(OUT_C); OnRev(OUT_A);    //旋回
 #define turn_left OnFwd(OUT_C); Off(OUT_A);             //片方のみ動かす
 #define go_forward(t) OnFwd(OUT_AC); Wait(t); Off(OUT_AC);
 #define cross_straight_R turn_left; Wait(50);
 #define cross_straight_L turn_right; Wait(50);
 #define cross_right turn_right; Wait(130);
 #define cross_left turn_left; Wait(130);
 
 #define Black 43     //これより小さかったら黒
 #define White 52     //これより大きかったら白
 #define STEP 1       //一回の判断の時間
 #define turn_time 400     //RからR or LからL (180°回転)
 #define turn_time_change 290      //RからL or LからR (90°ぐらい回転)
 
 #define closs_P 1    //closs Pを曲がる許可
 #define GO_cupC 2    //Cを取りに行け
 #define GO_cupD 3    //Dを取りに行け
 #define COME_cupC 4  //Cを持って来い
 #define COME_cupD 5  //Dを持って来い
〈積むロボット〉
 #define turn_right_SENKAI OnFwd(OUT_A); OnRev(OUT_C);   //旋回
 #define turn_right OnFwd(OUT_A); Off(OUT_C);            //片方のみ動かす
 #define turn_left_SENKAI OnFwd(OUT_C); OnRev(OUT_A);    //旋回
 #define turn_left OnFwd(OUT_C); Off(OUT_A);             //片方のみ動かす
 #define go_forward(t) OnFwd(OUT_AC); Wait(t); Off(OUT_AC);
 
 #define Black 43     //これより小さかったら黒
 #define White 47     //これより大きかったら白
 #define STEP 1       //一回の判断の時間
 #define age_sage 350     //上げたり下げたりする時間
 
 #define closs_P 1    //closs Pを曲がる許可
 #define GO_cupC 2    //Cを取りに行け
 #define GO_cupD 3    //Dを取りに行け
 #define COME_cupC 4  //Cを持って来い
 #define COME_cupD 5  //Dを持って来い
***サブルーチン [#ea04247b]
〈運ぶロボット〉~
線の右側をライントレースし交差点で停止するためのサブルーチン 
 sub trace_line_for_cross_R()
 {
    ClearTimer(0);
    while (FastTimer(0) <  36) {
       if (SENSOR_2 <= Black) {            //黒
          turn_right_SENKAI;
       } else if (SENSOR_2 < Black +2) {   //黒に近いグレー
          turn_right;
       } else if (SENSOR_2 > White -2) {   //白に近いグレー
          turn_left;
          ClearTimer(0);
       } else if (SENSOR_2 >= White) {     //白
          turn_left_SENKAI;
          ClearTimer(0);
       } else {                            //グレー
       OnFwd(OUT_AC);
       ClearTimer(0);
       }
       Wait(STEP);
    }
    Off(OUT_AC);
    PlaySound(SOUND_FAST_UP);
    Wait(100);
 }
線の左側をライントレースし交差点で停止するためのサブルーチン 
  sub trace_line_for_cross_L()
 {
    ClearTimer(0);
    while (FastTimer(0) <  36) {
       if (SENSOR_2 <= Black) {            //黒
          turn_left_SENKAI;
       } else if (SENSOR_2 < Black +2) {   //黒に近いグレー
          turn_left;
       } else if (SENSOR_2 > White -2) {   //白に近いグレー
          turn_right;
          ClearTimer(0);
       } else if (SENSOR_2 >= White) {     //白
          turn_right_SENKAI;
          ClearTimer(0);
       } else {                            //グレー
       OnFwd(OUT_AC);
       ClearTimer(0);
       }
       Wait(STEP);
    }
    Off(OUT_AC);
    PlaySound(SOUND_FAST_UP);
    Wait(100);
 }

 sub trace_line_to_start_R()
 {
    ClearTimer(0);
    while (FastTimer(0) < 50) {           //要調整
       if (SENSOR_2 <= Black) {            //黒
          turn_right_SENKAI;
       } else if (SENSOR_2 < Black +2) {   //黒に近いグレー
          turn_right;
       } else if (SENSOR_2 > White -2) {   //白に近いグレー
          turn_left;
       } else if (SENSOR_2 >= White) {     //白
          turn_left_SENKAI;
       } else {                            //グレー
       OnFwd(OUT_AC);
       }
       Wait(STEP);
    }
 }

 sub trace_line_to_start_L()
 {
    ClearTimer(0);
    while (FastTimer(0) < 50) {           //要調整
       if (SENSOR_2 <= Black) {            //黒
          turn_left_SENKAI;
       } else if (SENSOR_2 < Black +2) {   //黒に近いグレー
          turn_left;
       } else if (SENSOR_2 > White -2) {   //白に近いグレー
          turn_right;
       } else if (SENSOR_2 >= White) {     //白
          turn_right_SENKAI;
       } else {                            //グレー
       OnFwd(OUT_AC);
       }
       Wait(STEP);
    }
 }

 task go_to_CD()
 {
    int cupC = 0;
    int cupD = 0;
 
    repeat(3){
       int n = 0;
       int m = 0;
 
       while (n < 1) {
          if(Message() == GO_cupD) {         //C貰ったからDに行ってこい
             PlaySound(SOUND_UP);
             OnRev(OUT_AC);
             Wait(250);                 //要確認
             Off(OUT_AC);
             turn_right;
             Wait(turn_time);           //LからLへ
             trace_line_for_cross_L();
             cross_left;
             trace_line_for_cross_L();
 
             if(cupD == 0) {
                turn_right;
                Wait(turn_time_change);
                trace_line_for_cross_R();
             }
             if(cupD == 1) {
                go_forward(50);           //要確認
                trace_line_for_cross_R();
                turn_right;
                Wait(turn_time);          //180°回転
                trace_line_for_cross_R();
                cross_right;
                trace_line_for_cross_R();
              }
             if(cupD == 2) {
                while (SENSOR_2 > Black) {
                   OnFwd(OUT_AC);
                }
                turn_right;
                Wait(turn_time);
                while (SENSOR_2 > Black) {
                   OnFwd(OUT_AC);
                }
                cross_right;
                trace_line_for_cross_R();
             }
 
             cupD++;
             while (m < 1) {
                if(Message() == COME_cupD) {      //C置いたからD持って来い
                   PlaySound(SOUND_UP);
                   n++;
                   m++;
                   trace_line_to_start_R();
                } else {
                   Off(OUT_AC);
                }
                Wait(STEP);
             }
          } else {
          Off(OUT_AC);
          }
          Wait(STEP);
       }
 
       while (n < 2) {
          if(Message() == GO_cupC) {         //D貰ったからCに行ってこい
             PlaySound(SOUND_UP);
             OnRev(OUT_AC);
             Wait(250);                 //要確認
             Off(OUT_AC);
             turn_left;
             Wait(turn_time);           //RからRへ
             trace_line_for_cross_R();
             cross_right;
             trace_line_for_cross_R();
 
             if(cupC == 0) {
                go_forward(50);           //要確認
                trace_line_for_cross_L();
                turn_right;
                Wait(turn_time);          //180°回転
                trace_line_for_cross_L();
                cross_left;
                trace_line_for_cross_L();
             }
             if(cupC == 1) {
                while (SENSOR_2 > White) {
                   turn_left;
                }
                while (SENSOR_2 > Black) {
                   OnFwd(OUT_AC);
                }
                turn_right;
                Wait(turn_time);
                while (SENSOR_2 > Black) {
                   OnFwd(OUT_AC);
                }
                cross_left;
                trace_line_for_cross_L();
             }
 
             cupC++;
             while (m < 2) {
                if(Message() == COME_cupC) {      //D置いたからC持って来い
                   PlaySound(SOUND_UP);
                   n++;
                   m++;
                   trace_line_to_start_L();
                } else {
                   Off(OUT_AC);
                }
                Wait(STEP);
             }
          } else {
          Off(OUT_AC);
          }
          Wait(STEP);
       }
    }
 }
〈積むロボット〉
 sub for_cross()
 {
   ClearTimer(0);
   while (FastTimer(0) <  60) {
      if (SENSOR_2 <= Black +2) {            //黒
         Off(OUT_AC);
      } else {
      OnFwd(OUT_AC);
      ClearTimer(0);
      }
      Wait(STEP);
   }
   Off(OUT_AC);
   PlaySound(SOUND_FAST_UP);
   Wait(100);
 }

 sub trace_line()
 {
   while (true) {
      if (SENSOR_2 <= Black) {            //黒
         turn_right_SENKAI;
      } else if (SENSOR_2 < Black +2) {   //黒に近いグレー
         turn_right;
      } else if (SENSOR_2 > White -2) {   //白に近いグレー
         turn_left;
      } else if (SENSOR_2 >= White) {     //白
         turn_left_SENKAI;
      } else {                            //グレー
      OnFwd(OUT_AC);
      }
      Wait(STEP);
   }
 }

 sub crossP()                                       //合ってる??
 {
   ClearTimer(0);
   while (FastTimer(0) <  120 ) {
      if (Message() == closs_P) {
         PlaySound(SOUND_UP);
         OnFwd(OUT_AC);
      } else {
         Off(OUT_AC);
         ClearTimer(0);
      }
      Wait(STEP);
   }
 }

 sub tumutumu_C()
 {
   int cupC = 0;
   OnFwd(OUT_B);          //放す&下げる
   Wait(100);
   Off(OUT_B);
   while (cupC < 1) {
      if (SENSOR_1 == 1) {      //コップ触ってたら
         SendMessage(GO_cupD);      //Dに行ってこい(ただし交差点で待機)
         PlaySound(SOUND_CLICK);
         Wait(200);             //少し待機
         OnRev(OUT_B);          //掴む&上げる
         Wait(age_sage -100);             //これはやってみないと分からない。
         Off(OUT_B);
         turn_right;            //右向く
         Wait(200);             //これも適当
         Off(OUT_AC);
         OnFwd(OUT_B);          //放す&下げる
         Wait(age_sage);
         Off(OUT_B);
         while (SENSOR_2 > Black) {   //調整必要
            turn_left;
         }
         Off(OUT_AC); 
         SendMessage(COME_cupD);      //さあ持って来い
         PlaySound(SOUND_CLICK);
         cupC++;
      } else {                  //コップ触ってなかったら
      Off(OUT_AC);
      }
      Wait(STEP);
   }
   OnRev(OUT_B);
   Wait(100);
 }

 sub tumutumu_D()
 {
   int cupD = 0;
   OnFwd(OUT_B);          //放す&下げる
   Wait(100);
   Off(OUT_B);
   while (cupD < 1) {
      if (SENSOR_1 == 1) {      //コップ触ってたら
         SendMessage(GO_cupC);      //Cに行ってこい(ただし交差点で待機)
         PlaySound(SOUND_CLICK);
         Wait(200);             //少し待機
         OnRev(OUT_B);          //掴む&上げる
         Wait(age_sage -100);             //これはやってみないと分からない。
         Off(OUT_B);
         turn_right;            //右向く
         Wait(200);             //これも適当
         Off(OUT_AC);
         OnFwd(OUT_B);          //放す&下げる
         Wait(age_sage);
         Off(OUT_B);
         while (SENSOR_2 > Black) {   //調整必要
            turn_left;
         }
         Off(OUT_AC); 
         SendMessage(COME_cupC);      //さあ持って来い
         PlaySound(SOUND_CLICK);
         cupD++;
      } else {                  //コップ触ってなかったら
      Off(OUT_AC);
      }
      Wait(STEP);
   }
   OnRev(OUT_B);
   Wait(100);
 }

***メインプログラム [#c28047cc]
〈運ぶロボット〉
 task main()
 {
   SetSensor(SENSOR_2, SENSOR_LIGHT);
   ClearMessage();
   int cupC = 0;
   int cupD = 0;
   int n = 0;
 
   go_forward(50);
   repeat (2) {
      trace_line_for_cross_R();
      cross_straight_R;
   }
   trace_line_for_cross_R();
   cross_right;
   trace_line_for_cross_R();
   turn_right;
   Wait(turn_time_change);            //90°旋回(RからLへ)
   while(SENSOR_2 > White) {
      OnFwd(OUT_AC);
   }
   Off(OUT_AC);
   trace_line_for_cross_L();
   cross_left;
   trace_line_to_start_L();               //要確認
   SendMessage(closs_P);                   //用意できたからコッチに来て
   PlaySound(SOUND_CLICK);
   start go_to_CD;
 }
〈積むロボット〉
 
 task main()
 {
   SetSensor(SENSOR_1, SENSOR_TOUCH);
   SetSensor(SENSOR_2, SENSOR_LIGHT);
   ClearMessage();
   int n = 0;
   int cupC = 0;
   int cupD = 0;
   Wait(1000);
   OnFwd(OUT_AC);
   Wait(100);
   for_cross();
   OnRev(OUT_B);
   Wait(100);
   while (n < 1) {
      if (Message() == closs_P) {
         crossP();
         n++;
      } else {
         Off(OUT_AC);
      }
      Wait(STEP);
   }
   while (n < 2) {
      if (SENSOR_1 == 0) {
         trace_line();
      } else {
         Off(OUT_AC);
         n++;
      }
      Wait(STEP);
   }
   repeat (3) {                      //合ってるかなぁ?
      tumutumu_C();
      tumutumu_D();
   }
   turn_right;
   Wait(200);
   OnFwd(OUT_AC);
   Wait(400);
   Off(OUT_AC);
 }


**ロボコンで使ったプログラム [#vcaa551a]

***定義 [#c11501bb]
 #define turn_right_SENKAI OnFwd(OUT_A); OnRev(OUT_C);   //旋回
 #define turn_right OnFwd(OUT_A); Off(OUT_C);            //片方のみ動かす
 #define turn_left_SENKAI OnFwd(OUT_C); OnRev(OUT_A);    //旋回
 #define turn_left OnFwd(OUT_C); Off(OUT_A);             //片方のみ動かす
 #define go_forward(t) OnFwd(OUT_AC); Wait(t); Off(OUT_AC);
 #define cross_straight_R turn_left; Wait(50);
 #define cross_straight_L turn_right; Wait(50);
 #define cross_right turn_right; Wait(160);
 #define cross_left turn_left; Wait(160);
 
 #define Black 43     //これより小さかったら黒
 #define White 52     //これより大きかったら白
 #define STEP 1       //一回の判断の時間
 #define turn_time 400     //RからR or LからL (180°回転)
 #define turn_time_change 300      //RからL or LからR (90°ぐらい回転)
 
 #define closs_P 1    //closs Pを曲がる許可
 #define GO_cupC 2    //Cを取りに行け
 #define GO_cupD 3    //Dを取りに行け
 #define COME_cupC 4  //Cを持って来い
 #define COME_cupD 5  //Dを持って来い
***サブルーチン [#oeebc80a]
線の右側をライントレースし交差点で停止するためのサブルーチン 
 sub trace_line_for_cross_R()
 {
    ClearTimer(0);
    while (FastTimer(0) <  32) {
       if (SENSOR_2 <= Black) {            //黒
          turn_right_SENKAI;
       } else if (SENSOR_2 < Black +2) {   //黒に近いグレー
          turn_right;
       } else if (SENSOR_2 > White -2) {   //白に近いグレー
          turn_left;
          ClearTimer(0);
       } else if (SENSOR_2 >= White) {     //白
          turn_left_SENKAI;
          ClearTimer(0);
       } else {                            //グレー
       OnFwd(OUT_AC);
       ClearTimer(0);
       }
       Wait(STEP);
    }
    Off(OUT_AC);
    PlaySound(SOUND_FAST_UP);
    Wait(100);
 } 

線の左側をライントレースし交差点で停止するためのサブルーチン 
 sub trace_line_for_cross_L()
 {
    ClearTimer(0);
    while (FastTimer(0) <  32) {
       if (SENSOR_2 <= Black) {            //黒
          turn_left_SENKAI;
       } else if (SENSOR_2 < Black +2) {   //黒に近いグレー
          turn_left;
       } else if (SENSOR_2 > White -2) {   //白に近いグレー
          turn_right;
          ClearTimer(0);
       } else if (SENSOR_2 >= White) {     //白
          turn_right_SENKAI;
          ClearTimer(0);
       } else {                            //グレー
       OnFwd(OUT_AC);
       ClearTimer(0);
       }
       Wait(STEP);
    }
    Off(OUT_AC);
    PlaySound(SOUND_FAST_UP);
    Wait(100);
 }

 sub trace_line_to_start_R()
 {
    ClearTimer(0);
    while (FastTimer(0) < 50) {           //要調整
       if (SENSOR_2 <= Black) {            //黒
          turn_right_SENKAI;
       } else if (SENSOR_2 < Black +2) {   //黒に近いグレー
          turn_right;
       } else if (SENSOR_2 > White -2) {   //白に近いグレー
          turn_left;
       } else if (SENSOR_2 >= White) {     //白
          turn_left_SENKAI;
       } else {                            //グレー
       OnFwd(OUT_AC);
       }
       Wait(STEP);
    }
 }

 sub trace_line_to_start_L()
 {
    ClearTimer(0);
    while (FastTimer(0) < 50) {           //要調整
       if (SENSOR_2 <= Black) {            //黒
          turn_left_SENKAI;
       } else if (SENSOR_2 < Black +2) {   //黒に近いグレー
          turn_left;
       } else if (SENSOR_2 > White -2) {   //白に近いグレー
          turn_right;
       } else if (SENSOR_2 >= White) {     //白
          turn_right_SENKAI;
       } else {                            //グレー
       OnFwd(OUT_AC);
       }
       Wait(STEP);
    }
 }
***メインプログラム [#a0479a61]
 task main()
 {
    SetSensor(SENSOR_2, SENSOR_LIGHT);
    ClearMessage();
    int cupC = 0;
    int cupD = 0;
    int n = 0;
 
    go_forward(50);
    repeat (2) {
       trace_line_for_cross_R();
       cross_straight_R;
    }
    trace_line_for_cross_R();
    cross_right;
    trace_line_for_cross_R();
    turn_right;
    Wait(turn_time_change);            //90°旋回(RからLへ)
    while(SENSOR_2 > White) {
       OnFwd(OUT_AC);
    }
    Off(OUT_AC);
    trace_line_for_cross_L();
    cross_left;
    trace_line_to_start_L();               //要確認
    turn_left;
    Wait(100);
    while(SENSOR_2 > White) {
       OnFwd(OUT_AC);
    }
    Off(OUT_AC);
 }

*結果 [#f570c219]
ロボコン前日に切り替えて3点を目指し、前日に3点を取ることはできていたのだが、当日は3点も取れない結果に終わってしまった。~

*感想・反省点 [#r911301d]
ロボコンの結果は残念な結果に終わってしまったが、それまでの経過はテスト期間にも関わらず集まれるメンバーで集まることができていてよかったと思う。~
反省点としてはまず紙コップを積み重ねることから始めるべきだったと思う。~
紙コップを運ぶ→積み重ねる→ゴールに置くなどの一つずつのステップを確実に踏んでいたら満点はいかなくてももう少しいい点数をとれたと思う。


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