目次

メンバー

arara(自分)

sakar

sugaken

yokkun

課題の説明

2014a/Mission2に詳細が載っています

ロボットの説明

全体

S__1015863.jpg S__10158681.jpg

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

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

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

ドライブベース

S__1015865.jpg S__10158871.jpg

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

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

アーム

S__1015882.jpg S__1015883.jpg S__1015884.jpg

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

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

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

プログラム

1の紙コップはマジックペンで黒

2の紙コップは鉛筆で黒

3の紙コップは白いまま

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

プログラム通信の流れ

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

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

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

紙コップが1だと判断

  ↓

少しだけ後進

  ↓

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

                        ↓

                       アームを下げる

                        ↓

GOFOR受信後に前進    ←  GOFOR送信

  ↓

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

                        ↓

GOA1受信        ←  GOA1を送信

  ↓

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

  ↓

着いたら少し後進

  ↓

ARMDOWNを送信     →  ARMDOWN受信

                        ↓

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

                        ↓

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

ロボットの動く方向に関するプログラム

>>目次へ

定義

#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

ライントレースのサブルーティン

>>目次へ

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);
   }
}

メインタスク

>>目次へ

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();
      }
   }
}

アームに関するプログラム

>>目次へ

#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);
   }
} 

妥協案プログラム

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

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

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

妥協案の動く方向に関するプログラム

定義

#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);
}

2014a-mission2妥協.jpg

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

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

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

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

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

妥協案のアームに関するプログラム

定義

#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の位置のコップを重ねる

感想、反省点、注意したところ

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

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


添付ファイル: fileS__10158871.jpg 262件 [詳細] fileS__10158681.jpg 236件 [詳細] fileS__1015884.jpg 255件 [詳細] fileS__1015883.jpg 281件 [詳細] fileS__1015882.jpg 252件 [詳細] fileS__1015865.jpg 247件 [詳細] fileS__1015863.jpg 309件 [詳細] file2014a-mission2妥協.jpg 224件 [詳細]

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2014-08-12 (火) 15:50:44