目次
#contents

*メンバー [#q38cc42b]
arara(自分)
#ls2(2014a/Member/sakar/Mission2,link,sakar)
#ls2(2014a/Member/sugakenMission2,link,sugaken)
#ls2(2014a/Member/yokkun/Mission2,link,yokkun)

*課題の説明 [#p2ef3ea8]
[[2014a/Mission2]]に詳細が載っています

*ロボットの説明 [#ca45073f]
**全体 [#p6273d2f]
&ref(2014a/Member/arara/Mission2/S__1015863.jpg,25%);
&ref(2014a/Member/arara/Mission2/S__10158681.jpg,25%);

(写真左)黄色い本体を1つにすることができれば良かったのだが、
アーム部分に2つのモーターを使わないと持ち上がらないことと、
本体の同じ位置にコードを重ねて置く事ができないということから
2つの本体を使う事になった。
また、最初は平行に並べて細長いロボットになっていたが、
旋回能力の低さとモーターへの負荷が大きかった。
そのため、写真のように一方を立てる配置にすることで解決した。

(写真右)どのコードがどの部分につながるかを以下に示す。

 水色:右車輪を動かすモーター
 青色:左車輪を動かすモーター
 黄緑:ライントレース用の光センサー
 橙色:2つともアームを動かすモーター
 赤色:紙コップを識別する光センサー

**ドライブベース [#kdb68e58]
&ref(2014a/Member/arara/Mission2/S__1015865.jpg,25%);
&ref(2014a/Member/arara/Mission2/S__10158871.jpg,25%);

(写真左)立てている本体は安定しないため、ロボットのベースともうひとつの本体にビームを使って固定した。

(写真右)ロボットの下面の写真である。緑の方はライントレース用の光センサー、黄色の方は紙コップ識別用の光センサ−。紙コップ識別用の方はなるべくコップに近づけるためにアームの間からできるだけ前に出るように工夫した。

**アーム [#bf230652]
&ref(2014a/Member/arara/Mission2/S__1015882.jpg,25%);
&ref(2014a/Member/arara/Mission2/S__1015883.jpg,25%);
&ref(2014a/Member/arara/Mission2/S__1015884.jpg,25%);

アームが一番下まで下がると、上下運動の駆動から開閉の駆動に変わり、

アームが閉まりきると、開閉運動から上下運動の駆動に変わることを使ったアームである。

閉まるときに紙コップを置くと、紙コップをはさみ持ち上げる動作を、ひとつの命令だけで行うことができる。



*プログラム [#n07973e7]
1の紙コップはマジックペンで黒

2の紙コップは鉛筆で黒

3の紙コップは白いまま

というように色分けをして、その明るさを区別する事で判断している。


**プログラム通信の流れ [#m8833616]
プログラム通信の流れは次のようにしてなされている。ここではAの位置にある紙コップが1番だったと判断したときのものである。2番、3番だった時も同じように通信が行われる。かわるところは送受信メッセージの中の「1」が2や3になるのみである。

また、通信の際に受信ができない場合が起こり得るので、受信側は受信できた事を知らせるメッセージを送信側に送ってから行動をスタートする。送信側も、受信完了のメッセージが来るまで命令のメッセージを送り続け、3秒ごとに送信できたかどうかを音を鳴らす事で周囲に知らせる。

「動きに関するプログラム側」       「アームを動かすプログラミング側」

紙コップが1だと判断

  ↓

少しだけ後進

  ↓

停止したのちCUPA1を送信 →  CUPA1を受信

                        ↓

                       アームを下げる

                        ↓

GOFOR受信後に前進    ←  GOFOR送信

  ↓

ARMUPを送信       →  ARMUP受信後、コップを持ち上げる

                        ↓

GOA1受信        ←  GOA1を送信

  ↓

1の場所に移動(識別用の光センサーが再び1番のコップを判断する)

  ↓

着いたら少し後進

  ↓

ARMDOWNを送信     →  ARMDOWN受信

                        ↓

                   アームを下げてコップを重ねる

                        ↓

GOBACK受信後、後進  ← GOBACKを送信

**ロボットの動く方向に関するプログラム [#oaffe9a8]
#ls2(2014a/Member/arara/Mission2,link,>>目次へ)
***定義 [#w09c1c68]
 #define CUPA1   111
 #define CUPA2   112
 #define CUPA3   113
 #define GOFOR   200
 #define GOBACK  201
 #define ARMUP   202
 #define ARMDOWN 203
 #define GOA1 121
 #define GOA2 122
 #define GOA3 123
 #define SKIT 45 //トレースのしきい値
 #define JUDGE 45 //紙コップ判断のしきい値
 #define HIGHPOWER 7
 #define LOWPOWER 1
 #define set_power_H SetPower(OUT_AC,HIGHPOWER);//速度を速める
 #define set_power_L SetPower(OUT_AC,LOWPOWER);//速度を落とす
 #define turn_left1 set_power_L;\
  OnFwd(OUT_A); OnRev(OUT_C);       //左旋回
 #define turn_left0 set_power_L;\
  OnFwd(OUT_A); Off(OUT_C);         //左折
 #define turn_right0 set_power_L;\
  OnFwd(OUT_C); Off(OUT_A);         //右折
 #define turn_right1 set_power_L;\
  OnFwd(OUT_C); OnRev(OUT_A);       //右旋回
 #define go_forward set_power_H; OnFwd(OUT_AC); //直進
 #define go_back(s) OnRev(OUT_AC); Wait(s); Off(OUT_AC); //後進s秒間
 #define STEP 1 //ライントレースの判断時間
 #define noMAX 30   //右に行き過ぎた時、転回の最大回数
 #define NOSTEP 200 //右に行き過ぎた時、左に戻るための時間
 #define SENDTIME 300

***ライントレースのサブルーティン [#p2268f1b]
#ls2(2014a/Member/arara/Mission2,link,>>目次へ)
 sub line_trace(tim)
 {
    SetSensor(SENSOR_2, SENSOR_LIGHT); //ライントレース用の光センサー
    int nonline=0;
    ClearTimer(1);
 
   /*しきい値よりも6低いと左旋回 
   しきい値よりも3低いと左折 
   しきい値よりも3高いと右折
   しきい値よりも6高いと右旋回するが、
   右旋回をしすぎて逆方向に行きそうであれば左旋回して戻る*/
 
    while(Timer(1) <= tim){
     if (SENSOR_2 < SKIT-6){
       turn_left1;
      } else if (SENSOR_2 < SKIT-3) {
       turn_left0;
      } else if (SENSOR_2 < SKIT+3) {
       go_forward;
      } else {
        if(SENSOR_2 < SKIT+6) {
         turn_right0;
        } else {
         while (nonline < noMAX){
         turn_right1;
         nonline++;
          }
        turn_left1;
        Wait(noMAX*STEP*NOSTEP);
         }
      nonline=0;
      }
     Wait(STEP);
    }
 }

***メインタスク [#v95b8b85]
#ls2(2014a/Member/arara/Mission2,link,>>目次へ)
 task main()
 {
    SetSensor(SENSOR_3, SENSOR_LIGHT); //紙コップ識別用の光センサー
 
    /*下のコースに行ったあとライントレースをしながらA地点に行く
      紙コップが黒ければ()CUPA1
      紙コップが灰色なら()CUPA2
      紙コップが白ければ()CUPA3
      というメッセージを送る*/ 
 
    go_forward;
    Wait(430);
    line_trace(800);
 
    while(true){
Aから1の場合
     if (SENSOR_3 < JUDGE-7){
     Off(OUT_AC);
 
     ClearTimer(0);
     ClearMessage();
     
      while((Message() != 1)||(FastTimer(0)<SENDTIME)){
       SendMessage(CUPA1);
       }
      if(Message() == 1){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50);
     }
      until(Message() == GOFOR);
      SendMessage(2);
      OnFwd(OUT_AC);
      Wait(80); 
 
      ClearTimer(0);
      ClearMessage();
     
      while((Message() != 3)||(FastTimer(0)<SENDTIME)){
       SendMessage(ARMUP);
       }
      if(Message() == 3){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50);
      }
 
      ClearMessage();
      while(true){
 
      if(Message() == GOA1){
       SendMessage(4);
       OnRev(OUT_AC);
       Wait(100);
       turn_left1;
       Wait(30);
       OnFwd(OUT_AC);
       Wait(300);
       line_trace();
       until(SENSOR_3 < JUDGE-7);
       Off(OUT_AC);
       go_back(100);
     ClearTimer(0);
     ClearMessage();
     
      while((Message() != 5)||(FastTimer(0)<SENDTIME)){
       SendMessage(ARMDOWN);
       }
      if(Message() == 5){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50); 
 
      until(Message() == GOBACK);
      SendMessage(6);
      OnFwd(OUT_AC);
      Wait(80); 
 
      ClearTimer(0);
      ClearMessage();
       } 
 
Aから2の場合
     else if(SENSOR_3 < JUDGE-3){
     Off(OUT_AC); 
 
     ClearTimer(0);
     ClearMessage();
     
      while((Message() != 1)||(FastTimer(0)<SENDTIME)){
       SendMessage(CUPA2);
       }
      if(Message() == 1){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50);
     }
      until(Message() == GOFOR);
      SendMessage(2);
      OnFwd(OUT_AC);
      Wait(80); 
 
      ClearTimer(0);
      ClearMessage();
     
      while((Message() != 3)||(FastTimer(0)<SENDTIME)){
       SendMessage(ARMUP);
       }
      if(Message() == 3){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50);
      } 
 
      ClearMessage();
      while(true){ 
 
      if(Message() == GOA2){
       SendMessage(4);
       line_trace();
       until(SENSOR_3 < JUDGE-2);
       Off(OUT_AC);
       go_back(100);
     ClearTimer(0);
     ClearMessage();
     
      while((Message() != 5)||(FastTimer(0)<SENDTIME)){
       SendMessage(ARMDOWN);
       }
      if(Message() == 5){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50); 
 
      until(Message() == GOBACK);
      SendMessage(6);
      OnFwd(OUT_AC);
      Wait(80);
 
      ClearTimer(0);
      ClearMessage();
       }
 
Aから3の場合
     else if(SENSOR_3 > JUDGE+5){
     Off(OUT_AC);
 
     ClearTimer(0);
     ClearMessage();
     
      while((Message() != 1)||(FastTimer(0)<SENDTIME)){
       SendMessage(CUPA3);
       }
      if(Message() == 1){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50);
     }
      until(Message() == GOFOR);
      SendMessage(2);
      OnFwd(OUT_AC);
      Wait(80); 
 
      ClearTimer(0);
      ClearMessage();
     
      while((Message() != 3)||(FastTimer(0)<SENDTIME)){
       SendMessage(ARMUP);
       }
      if(Message() == 3){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50);
      }
 
      ClearMessage();
      while(true){ 
 
      if(Message() == GOA3){
       SendMessage(4);
       go_forward;
       Wait(200);
       turn_left0;
       Wait(200);
       line_trace();
       until(SENSOR_3 > JUDGE+6);
       Off(OUT_AC);
       go_back(100);
     ClearTimer(0);
     ClearMessage();
     
      while((Message() != 5)||(FastTimer(0)<SENDTIME)){
       SendMessage(ARMDOWN);
       }
      if(Message() == 1){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50); 
 
      until(Message() == GOBACK);
      SendMessage(6);
      OnFwd(OUT_AC);
      Wait(80); 
 
      ClearTimer(0);
      ClearMessage();
       }
    }
 }

**アームに関するプログラム [#efeacca7]
#ls2(2014a/Member/arara/Mission2,link,>>目次へ)
 #define CUPA1   111
 #define CUPA2   112
 #define CUPA3   113
 #define GOFOR   200
 #define GOBACK  201
 #define ARMUP   202
 #define ARMDOWN 203
 #define GOA1 121
 #define GOA2 122
 #define GOA3 123
 #define SENDTIME 300

メインタスク
 task main()
 {
    /*CUPA1が送られてきたらコップをとって1の場所へ 
    CUPA2が送られてきたらコップをとって2の場所へ
    CUPA3が送られてきたらコップをとって3の場所へ*/
 
    ClearMessage();
    OnRev(OUT_AC);    //1の場所に着くまで、アームを上げた状態で待機
    Wait(1200);
    Off(OUT_AC); 
 
    while(true){
Aから1の場合
      if(Message() == CUPA1){
       SendMessage(1);
       OnFwd(OUT_AC);
       Wait(50); 
 
      ClearTimer(0);
      ClearMessage();
     
      while((Message() != 2)||(FastTimer(0)<SENDTIME)){
       SendMessage(GOFOR);
       }
      if(Message() == 2){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50); 
 
     until(Message()==ARMUP);
      SendMessage(3);
      OnRev(OUT_AC);
      Wait(150); 
 
     ClearTimer(0);
     ClearMessage();
     
      while((Message() != 4)||(FastTimer(0)<SENDTIME)){
       SendMessage(GOA1);
       }
      if(Message() == 4){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
 
     until(Message()==ARMDOWN);
      SendMessage(5);
      OnFwd(OUT_AC);
      Wait(150);
 
     ClearTimer(0);
     ClearMessage();
     
      while((Message() != 6)||(FastTimer(0)<SENDTIME)){
       SendMessage(GOBACK);
       }
      if(Message() == 6){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50);
  
     until(Message()==ARMUP);
      SendMessage(7);
      OnRev(OUT_AC);
      Wait(150);
 
Aから2の場合
     }else if(Message() == CUPA2){
       SendMessage(1);
       OnFwd(OUT_AC);
       Wait(50); 
 
      ClearTimer(0);
      ClearMessage();
     
      while((Message() != 2)||(FastTimer(0)<SENDTIME)){
       SendMessage(GOFOR);
       }
      if(Message() == 2){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50);
 
     until(Message()==ARMUP);
      SendMessage(3);
      OnRev(OUT_AC);
      Wait(150);
 
     ClearTimer(0);
     ClearMessage();
     
      while((Message() != 4)||(FastTimer(0)<SENDTIME)){
       SendMessage(GOA2);
       }
      if(Message() == 4){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      OnRev(OUT_B);
      Wait(800);
    }
 
     until(Message()==ARMDOWN);
      SendMessage(5);
      OnFwd(OUT_AC);
      Wait(150);
 
     ClearTimer(0);
     ClearMessage();
     
      while((Message() != 6)||(FastTimer(0)<SENDTIME)){
       SendMessage(GOBACK);
       }
      if(Message() == 6){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50); 
 
     until(Message()==ARMUP);
      SendMessage(7);
      OnRev(OUT_AC);
      Wait(150); 
 
Aから3の場合
     }if(Message() == CUPA3){
       SendMessage(1);
       OnFwd(OUT_AC);
       Wait(50); 
 
      ClearTimer(0);
      ClearMessage();
     
      while((Message() != 2)||(FastTimer(0)<SENDTIME)){
       SendMessage(GOFOR);
       }
      if(Message() == 2){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50); 
 
     until(Message()==ARMUP);
      SendMessage(3);
      OnRev(OUT_AC);
      Wait(150);  
 
     ClearTimer(0);
     ClearMessage();
     
      while((Message() != 4)||(FastTimer(0)<SENDTIME)){
       SendMessage(GOA3);
       }
      if(Message() == 4){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50);  
 
     until(Message()==ARMDOWN);
      SendMessage(5);
      OnFwd(OUT_AC);
      Wait(150); 
  
     ClearTimer(0);
     ClearMessage();
     
      while((Message() != 6)||(FastTimer(0)<SENDTIME)){
       SendMessage(GOBACK);
       }
      if(Message() == 6){
       PlaySound(SOUND_CLICK);
      }else{
       PlaySound(SOUND_LOW_BEEP);
       }
      Wait(50);    
 
     until(Message()==ARMUP);
      SendMessage(7);
      OnRev(OUT_AC);
      Wait(150);
    }
 } 

*妥協案プログラム [#i5b45c62]
こちらのプログラムは、ライントレースも通信もしない、コップを重ねる事だけに重点をおいたものである

そのため、非常にシンプルかつ初歩的なプログラムとなった

さらに、Aの位置にあるコップが1番のコップであると仮定された限定的なプログラムである

**妥協案の動く方向に関するプログラム [#weca07e9]
定義
 #define HIGHPOWER 7 //HIGHPOWERの値を7に設定
 #define LOWPOWER 1  //LOWPOWERの値を1に設定
 #define set_power_H SetPower(OUT_AC,HIGHPOWER);//速度を速める
 #define set_power_L SetPower(OUT_AC,LOWPOWER);//速度を落とす
 #define turn_left1(p) set_power_L;\
  OnFwd(OUT_A); OnRev(OUT_C); Wait(p);      //左旋回
 #define turn_left0(q) set_power_L;\
  OnFwd(OUT_A); Off(OUT_C); Wait(q);        //左折
 #define turn_right0(r) set_power_L;\
  OnFwd(OUT_C); Off(OUT_A); Wait(r);        //右折
 #define turn_right1(s) set_power_L;\
  OnFwd(OUT_C); OnRev(OUT_A); Wait(s);      //右旋回
 #define go_forward(t) set_power_H; OnFwd(OUT_AC); Wait(t); //直進
 #define go_back(u) OnRev(OUT_AC); Wait(u); Off(OUT_AC); //後進s秒間

メインタスク
 task main()
 {
    turn_right1(165);
    go_forward(290);
    turn_left1(140);
    go_forward(320);
    turn_left1(120);
    go_forward(310);
    turn_left1(30);
    Off(OUT_AC);
    Wait(100);
    go_forward(50);
    Off(OUT_AC);
 }

&ref(2014a/Member/arara/Mission2/2014a-mission2妥協.jpg,40%);

1.スタート地点から右旋回をして真下を向き、Aのコップと横並びになる位置まで前進

2.左旋回をした後、Aの位置のコップに向かって前進

3.2番と3番のコップにぶつからない位置で左旋回をしたあとに前進

4.1番のコップの手前まで来たら、コップの方向を向いて1秒間停止(このときアームを上げる)

5.そのまま0.5秒間前進して(このときアームを下げてコップを重ねる)、停止



**妥協案のアームに関するプログラム [#w2c4cd77]
定義
 #define t1 165
 #define t2 290
 #define t3 140
 #define t4 320
 #define t5 120
 #define t6 310
 #define t7 30
 #define UPTIME t1+t2+t3+t4+t5+t6+t7  //ロボットが1番のコップの位置につくまでの時間

メインタスク
 task main()
 {
     Wait(UPTIME);    
     OnFwd(OUT_AC);
     Wait(150);
     Off(OUT_AC);
     OnRev(OUT_AC);
     Wait(150);
     Off(OUT_AC);
 }
1.ロボットが1番のコップの手前まで来るまで待つ

2.アームを上げてAの位置から持ってきたコップをつかむ

3.アームを下げて1番のコップの上にAの位置のコップを重ねる

*感想、反省点、注意したところ [#lcb6a496]
4人に増えた分時間はかからないと思っていたが、課題1と同じくらいか、それより多くの時間を使う事になった。今回はプログラミングを主に担当したが、時間の都合でAの位置のコップ移動をさせるものしか作れなかった。プログラミングの中で、ライントレースするものをサブルーティンとして書いたが、これを一旦とめたり、また動かしたりするプログラミングが書けなかった為、ライントレースをし続ける結果となってしまい、上手くいかなかった。

コンテストの本番には行けなかったが、チームの頑張りによってなんとか6位につけたことをうれしく思う。実際に他のチームのロボットを見てみたかった。


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