2008b

2008b

'' ロボコン''

内容

グループで一台、もしくは二台のロボットを作成しロボコンをする。

目次

ルール

コース上に積まれた四個の缶をゴールへと運ぶ。

基本ルール

  • 4段に積まれた空き缶を運びだし、ゴールに入れる。
  • 競技時間は審判が続行不能と判断するまで、あるいはリタイアするまで。
  • 2隅のコーナー(30cm四方)からスタートする。
  • スタート時のロボットは2個を越えないこと (スタート後はいくつに分裂してもかまわない)。
  • 開始の合図から5秒以内にRCXのスタートボタンを押す作業を完了すること。
  • 競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。
  • 途中でうまく動かなくなった場合、1回限り再スタートすることができる(再スタートの際に別プログラムで起動してよい)。
基本得点の計算方法
  • 緑の空き缶を1個ゴールに運べば4点。
  • 黒い空き缶(最上の空き缶)を運べば8点
  • 空き缶を場外に出してしまった場合は一個につきマイナス1点。
  • 半分以上ゴールに入った空き缶だけを得点の対象とする。ただし空き缶がゴールからはみ出している場合は、マイナス1点
技術点の計算方法
以下の動作の精度・スピード・確実性などを含めた技術的な工夫や芸術性について他の全てのチーム(9チーム+TAor教員)が20点満点で採点し、その平均点を求める。 得点の目安:
  • 空き缶までたどり着く動作 (3点)
  • 空き缶を運ぶ動作 (転がす・掴むなど) (4点)
  • 空き缶をゴールに入れる動作 (2点)
  • 2台以上のロボット、あるいは単体のロボットの場合は2台のRCXの連携の良さ(3点)
  • 自立型のロボットとしての形や動作の美しさ、斬新さ(3点)
  • その他 (5点)

コース

コース コース

缶にたどり着く直前に障害物が設置してありなかなか難解なコースとなっている。

ゴールの周りも細めの木材で囲んであるため缶をゴールに入れるプログラムにも工夫が必要となる。

ロボットの製作

今回は2つのキットを利用してロボットを作るので、大きな一つのロボットを作るか、2つのロボットを作るかで作戦が大きく変わる。

コンセプト

今回はどのような作戦をとるかによってロボットの形も大きく変わってくる。

そこで作戦としては、一度に4つの缶をつかみ運ぶという作戦をとることにした。

一度に運ぶにはロボットにも重さが必要なので一つの大きなロボットを作ることにした。

アーム

アーム部分

まず最初に考えたのはどのように缶を掴むかだ。今回は缶を一つ掴むだけの長さがあり、ゴムのグリップ力で滑らないという利点からキャタピラを使用した。

アーム片方.JPG

ゴールには段差がありそのままでは缶を入れることができないので、このアームにギアをつけることによってキャタピラを回転させ缶を持ち上げるギミックを搭載した。

次に考えたのがアームの上部だ。この部分には大きなホールド力は求めなかった。もともと四つの缶は上の缶が下の缶にピッタリとはまっていたので一番下の缶だけをうまく持ち上げることができれば四つの缶を持ち上げることができると考えた。なので、ただ缶を支えることができればいいと考えた。

アーム上部.jpg

この部分を強くしすぎるとそれは使用するパーツの量が増えるということになり、マシンの重心がずれてマシンが傾いてしまうのでなるべく軽く、少ないパーツで作ることも大切だった。

ギミック

アームを開閉するためにウォームギアを使用した。

ギア側面.JPG

これによってひとつのモーターで二つのアームを開閉することに成功した。

本体

タイヤ

タイヤは最も大きいタイヤを使用した。最初は曲がるときに抵抗にならないように二つのタイヤとキャスター一つで作り始めたが、今回のロボコンでは曲がりやすさよりもマシンの安定性を重視することにした。キャスターでは曲がりやすさのために軸が細く弱いので、小さなホイールを動かないように固定して取り付けた。

IMGP0187.JPG 支えキャスター.jpg

支えとなるキャスターの長さを短くすることでわざとマシンを傾かせた。これにより、缶を持ち上げた時に缶がアームの軸の方向に傾くので、缶が落ちにくくなった。

RCX

最初はRCXを寝かせて並べてつけていた。これでコースを走らせてみると必ずカーブで引っかかってしまった。そこで、RCXを縦に取り付けられないかと考え、二つ並べて縦に取り付けることにした。

RCX接続.JPG

今回はRCXの連携を使用するプログラムだったが、途中で連携がうまくいかなくなった。それを解消するためにRCXの上に反射板を取り付けた。

RCX.JPG

センサー

今回は三種類、合計六個のセンサーを使った。光センサーを三つ、タッチセンサーを二つ、回転センサーを一つ使った。

ライントレースで光センサーを一つ使用した。センサーはマシンの中央に取り付けた。

ベース.JPG

タッチセンサーを使用して壁にぶつかったときの方向修正と缶への方向修正を行った。

後部.JPG

最初はタッチセンサーによる方向修正でマシンの向きを缶に向けさせたが、なかなか誤差を修正することができなかった。

そこで先生にアドバイスをもらい、二つの光センサーとコース上のサークルを使用して缶への向きを正確にした。

正面2.JPG

回転センサーはアームの開閉に使用した。

ギア正面.JPG

回転数と絶対値によって開閉の時間を設定した。

完成図

全体.JPG

アーム部分が高さと正確さを持たせたために大きめのマシンになった。

プログラム

今回のロボコンではいかに缶へたどり着くか、が重要だった。waitやタイマーで時間指定するのでは壁に当たってしまった時にずれてしまう。そのため各種センサーを多用することで正確に缶へたどり着けるようにした。 最も工夫した点は次の二点である。

壁をつたって進む

ダブルバンパーの右のバンパーが接触すると左に進み、右のバンパーが離れると右に進むようにプログラムを作った。 これで自機の場所を確定できるようにした。 プログラムは  

缶の置いてあるところの円を確実に中心に向かって進む

二つの光センサーを使い右の光センサーが黒に触れると右に進み左の光センサーが黒に触れるとみだりに進むプログラムを作った。 これで確実に円の中心に進むようになった。 プログラムは

#define THRESHOLD 50
#define THRESHOLD_2 45
#define THRESHOLD_3 40
#define SIGNAL 11
#define SIGNAL_2 12
#define SIGNAL_3 13
#define SIGNAL_4 14
#define SIGNAL_5 15
#define SIGNAL_6 16
#define SIGNAL_7 17
#define SIGNAL_8 18
#define SIGNAL_9 19
#define SIGNAL_A 21
#define SIGNAL_B 22

int move_count;
sub turn(){                    //左に90度曲がるサブルーチン
   SetPower(OUT_A,6);
   SetPower(OUT_B,5);
   SetPower(OUT_C,7);
   
   ClearMessage();
   until((Message() == SIGNAL_A) || (Message() == SIGNAL_B));
     PlaySound(SOUND_CLICK);
     ClearMessage();
     Off(OUT_A+OUT_B);
     Wait(50);
     OnRev(OUT_A+OUT_B);
     Wait(10);
     Off(OUT_A+OUT_B);
     OnFwd(OUT_A);
     OnRev(OUT_B);
     Wait(80);
     Off(OUT_A+OUT_B);
     Wait(50);
     ClearMessage();
}         
sub turn_r(){              //右に90°曲がるサブルーチン
   until((Message() == SIGNAL_A) || (Message() == SIGNAL_B));
     ClearMessage();
     Off(OUT_A+OUT_B);
     Wait(50);
     OnRev(OUT_A+OUT_B);
     Wait(10);
     Off(OUT_A+OUT_B);
     OnFwd(OUT_B);
     OnRev(OUT_A);
     Wait(80);
     Off(OUT_A+OUT_B);
     Wait(50);
     ClearMessage();
}
      
sub line(){                //ライントレースのサブルーチン
   SetPower(OUT_A,6);
   SetPower(OUT_B,5);
   SetSensor(SENSOR_1,SENSOR_LIGHT);     

   move_count = 0;
     ClearMessage();
     ClearTimer(0); 
     while(move_count < 1){
     if(((Message() == SIGNAL_A) || (Message() == SIGNAL_B))  &&  (FastTimer(0) > 500)){ 
         PlaySound(SOUND_CLICK);
         ClearMessage();
         (move_count);
         move_count = move_count + 1; 
     }
     if(SENSOR_1>THRESHOLD){
       OnFwd(OUT_A);
       Off(OUT_B);
     if(FastTimer(0) > 400){
      ClearMessage();
     }}
     else{
       Off(OUT_A);
       OnFwd(OUT_B);
     if(FastTimer(0) > 400){
      ClearMessage();
      
     } 
     }
    }
}
task main(){
   SetPower(OUT_A,6);
   SetPower(OUT_B,5);
   SetSensor(SENSOR_1,SENSOR_LIGHT);

  ClearMessage();
   OnFwd(OUT_A+OUT_B);
   until(SENSOR_1<THRESHOLD);
     Off(OUT_A+OUT_B);
     Wait(50);
     OnFwd(OUT_A+OUT_B);
   until((Message() == SIGNAL_A) || (Message() == SIGNAL_B));
     PlaySound(SOUND_CLICK);
     ClearMessage();
     OnRev(OUT_A+OUT_B);
     Wait(20);
     OnFwd(OUT_B);
     OnRev(OUT_A);
     Wait(57);
     OnFwd(OUT_A+OUT_B);
     Wait(250);
     OnFwd(OUT_A);
     OnRev(OUT_B);
     Wait(40);
     OnFwd(OUT_A+OUT_B);
   until(SENSOR_1<THRESHOLD);
     line();
     Off(OUT_A+OUT_B);
     Wait(50);
     OnRev(OUT_A+OUT_B);
     Wait(10);
     Off(OUT_A+OUT_B);
     OnFwd(OUT_A);
     OnRev(OUT_B);
     Wait(80);
     Off(OUT_A+OUT_B);
     Wait(50);
     OnFwd(OUT_A+OUT_B);
     ClearMessage();
   until((Message() == SIGNAL_A) || (Message() == SIGNAL_B));
     move_count = 0;
        ClearMessage();
        while(move_count < 1){            //
         if(Message() == SIGNAL_A){
          ClearMessage();
         (move_count);
          move_count = move_count + 1;
 
         }
        if(Message() == SIGNAL_B){
         OnFwd(OUT_A);
         Off(OUT_B);
         Wait(10);
         ClearMessage();
        }
       else{
         Off(OUT_A);
         OnFwd(OUT_B);
       }
      }
   
   Off(OUT_A+OUT_B);
   PlaySound(SOUND_CLICK);
   OnRev(OUT_A);
   Wait(145);
   OnRev(OUT_A+OUT_B);
   Wait(30);
   Off(OUT_A+OUT_B);
   ClearMessage();
   SendMessage(SIGNAL);
   until(Message() == SIGNAL_2);
     PlaySound(SOUND_CLICK);
     Off(OUT_A+OUT_B);
   move_count = 0;
   while(move_count < 2){              //
     if((SENSOR_2 < THRESHOLD_2) && (SENSOR_3 > THRESHOLD_3)){
       OnRev(OUT_A);
       Off(OUT_B);
     }
     if((SENSOR_2 > THRESHOLD_2) && (SENSOR_3 < THRESHOLD_3)){
        OnRev(OUT_B);
        Off(OUT_A);
     }
     if((SENSOR_2 < THRESHOLD_2) && (SENSOR_3 < THRESHOLD_3)) {
       OnRev(OUT_A+OUT_B);
       Wait(20);
     (move_count);
     move_count = move_count + 1;
    }
    if((SENSOR_2 > THRESHOLD_2) && (SENSOR_3 > THRESHOLD_3)) {
      OnRev(OUT_A+OUT_B);
    }
   }
    OnRev(OUT_A+OUT_B);
    Wait(28);
   Float(OUT_A+OUT_B);
   SendMessage(SIGNAL_3);
   until(Message() == SIGNAL_4);
     PlaySound(SOUND_CLICK);
     OnFwd(OUT_A);
     OnRev(OUT_B);
     Wait(100);
     Off(OUT_A+OUT_B);
     OnFwd(OUT_A+OUT_B);
  ClearMessage();
   until((Message() == SIGNAL_A) || (Message() == SIGNAL_B));
     PlaySound(SOUND_CLICK);
     ClearMessage();
     Off(OUT_A+OUT_B);
     Wait(50);
     OnRev(OUT_A+OUT_B);
     Wait(15);
     Off(OUT_A+OUT_B);
     OnFwd(OUT_A);
     OnRev(OUT_B);
     Wait(80);
     Off(OUT_A+OUT_B);
     Wait(50);
     ClearMessage();
     
     PlaySound(SOUND_CLICK);
     OnFwd(OUT_A+OUT_B); 
     turn_r();
     OnFwd(OUT_B);
     OnRev(OUT_A);
     Wait(25);
     Off(OUT_A+OUT_B); 
     OnFwd(OUT_A+OUT_B); 
     Wait(35); 
     line();
     turn_r();   
     Off(OUT_A+OUT_B); 
     OnRev(OUT_A+OUT_B);
     Wait(200);
     Off(OUT_A+OUT_B);
     SendMessage(SIGNAL_8);
    ClearMessage(); 
    until(Message() == SIGNAL_9); 
     SendMessage(SIGNAL_5);
     ClearMessage();
     until(Message() == SIGNAL_6);
     OnFwd(OUT_A+OUT_B);
     Wait(200);
     Off(OUT_A+OUT_B);
      SendMessage(SIGNAL_7); 
     Wait(200); 
     OnRev(OUT_A+OUT_B); 
     Wait(200); 
     Off(OUT_A+OUT_B);  
     OnFwd(OUT_A+OUT_B);
     Wait(150);
     Off(OUT_A+OUT_B);
     
 
}

もう一つのRCX

#define SIGNAL 11
#define SIGNAL_2 12
#define SIGNAL_3 13
#define SIGNAL_4 14
#define SIGNAL_5 15
#define SIGNAL_6 16
#define SIGNAL_7 17
#define SIGNAL_8 18
#define SIGNAL_9 19
#define SIGNAL_A 21
#define SIGNAL_B 22


task main(){
  SetSensor(SENSOR_1,SENSOR_ROTATION);
  SetSensor(SENSOR_2,SENSOR_TOUCH);
  SetSensor(SENSOR_3,SENSOR_TOUCH);
  ClearMessage();
  
 while(true){
  if(Message() == SIGNAL){           // SIGNALを受信したとき
    PlaySound(SOUND_CLICK);            腕を開く
    OnFwd(OUT_A);
    until(SENSOR_1 == 90);
      Off(OUT_A);
      Wait(50);
     ClearMessage();
      SendMessage(SIGNAL_2);
     }
  if(Message() ==  SIGNAL_3){         //SIGNAL_3を受信したとき
    ClearSensor(SENSOR_1);            腕を閉じ、缶を持ち上げる
    OnRev(OUT_A);
    until(abs(SENSOR_1) == 68);
      ClearSensor(SENSOR_1);
      Off(OUT_A);
      Wait(30);
      OnFwd(OUT_B+OUT_C);
      Wait(30);
      Off(OUT_B+OUT_C);
      SendMessage(SIGNAL_4);
      ClearMessage();
  }
  if(Message() ==  SIGNAL_5){          //SIGANAL_5を受信した時
    OnRev(OUT_C+OUT_B);              缶を持ち上げながら腕を開く
    Wait(30);
    Off(OUT_C+OUT_B);
    OnFwd(OUT_A);
    until(abs(SENSOR_1) == 65);
      Off(OUT_A);
      Wait(50);
      SendMessage(SIGNAL_6);
      ClearSensor(SENSOR_1);
      ClearMessage();
  }
  if(Message() ==  SIGNAL_7){         //signal_7を受信したとき
  ClearSensor(SENSOR_1);            腕を閉じる
     OnRev(OUT_A);
    until(abs(SENSOR_1) == 90);
      Off(OUT_A);
      Wait(50);
      ClearMessage();
  }
  if(Message() ==  SIGNAL_8){        //SIGNAL_8を受信したとき
    OnFwd(OUT_B+OUT_C);            缶を持ち上げる
     Wait(30);
     Off(OUT_B+OUT_C);
    SendMessage(SIGNAL_9); 
    }
  if(SENSOR_2 == 1){            //タッチセンサー_1が押されたとき
    SendMessage(SIGNAL_A);          SIGNAL_Aを送信する
  }
  if(SENSOR_3 == 1){            //タッチセンサー_2が押されたとき
    SendMessage(SIGNAL_B);          SIGNAL_Bを送信する
  }
 }
}

本番

プログラムは本番当日に完成した。調整では何回も成功した。練習の段階では一回で平均三個の缶を運ぶことができた。缶を運びきる個数を四個にするために最終ギミックを作った。しかしこのギミックを取り付けてから成功率がガクッと下がった。結局この間は一度も成功することがなく、マシンのバランスが悪くなったという理由で取り外した。

そして本番。缶を持ち上げるところまではうまくいった。しかしその帰路でマシンがコースに引っかかってしまいゴールにたどり着くことができなかった。しかしマシン自体の評価としては、14〜16点を全体からもらうことができた。

結局このあと点数半減で再チャレンジすることができた。この時は見事に四個の缶すべてを運ぶことに成功した。

競技中の写真がこちらです。

ロボコン2.jpg ロボコン1.jpg

DSC00490.JPG DSC00491.JPG

感想

結果として完成度の高いマシンに仕上がったと思う。ロボコンでも成功するチームが少なく、未完成のチームもあったけど、自分たちのマシンは一回失敗したとしても二回目に成功することができて四個すべてを運ぶことができたので出来として授業の中でも高いレベルに仕上がったと思う。

もちろん成功率が100%ではないし、不確定要素として初期位置によって成否が決まったりマシンが引っ掛かるかどうかが運次第という場所もあったのでそこを改善して少しでも成功率を100%に近づけたかった。

全体で二位という結果を残せたが、できたら一回目で成功して優勝したかった。

コメントをどうぞ

  • ロボットの説明はとてもよくできています。ただ、全体として何をしているかわかりにくいので、プログラムに説明が必要ですし、全体の動きを示した図を使ってもよいです。 -- FI? 2009-02-14 (土) 03:45:26
  • ろぼがなにをしているのかわかりにくいので説明があると有難いです。 -- なかむら? 2009-02-16 (月) 06:26:55


添付ファイル: file支えキャスター.jpg 391件 [詳細] fileロボコン2.jpg 385件 [詳細] fileロボコン1.jpg 193件 [詳細] fileDSC00491.JPG 381件 [詳細] fileDSC00490.JPG 424件 [詳細] fileDSC00489.JPG 137件 [詳細] fileDSC00488.JPG 136件 [詳細] fileアーム上部.jpg 263件 [詳細] fileRCX.JPG 389件 [詳細] fileRCX接続.JPG 243件 [詳細] fileアーム片方.JPG 314件 [詳細] fileアーム片方2.JPG 155件 [詳細] fileギア正面.JPG 324件 [詳細] fileギア側面.JPG 315件 [詳細] file後部.JPG 386件 [詳細] file正面.JPG 141件 [詳細] file正面2.JPG 382件 [詳細] file全体.JPG 387件 [詳細] file全体2.JPG 169件 [詳細] fileベース.JPG 286件 [詳細] fileIMGP0187.JPG 308件 [詳細] fileIMGP0169.JPG 292件 [詳細] file-1.png 291件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-02-16 (月) 06:26:55 (3835d)