ロボコン-缶を積み上げるロボット-

目次

はじめに

ども、また私です。ついにやってきたぜ、この日が!というわけで、ロボコンです。今回も例のごとくどえりゃあ苦労しましたよ(泣)。でも、完成した時の「このロボット、俺が作ってやったんだぜ!?」という満足感は半端じゃなかったです。今回は今までの集大成ゆえ、説明などが長ったらしくなってしまいますが最後までお付き合いください。

ルール

今回はルールが複雑なうえに専用のフィールドなどもあるので、ロボコンのページのリンクを貼っておきます。手抜きみたいであまり気は進みませんがwww。

2012年度前期ロボコン

製作したロボット、プログラム

ロボットの構造

今回はRISを2セット使って1つのロボットを作りました。

20120727_183443.jpg

相変わらずゴツいですね。ハイ。なぜ私がロボットを作るとこんな重量級になってしまうのでしょうかwww。写真ではわかりづらいですが、実際ロボット本体はかなり大きく重いです。

20120727_185237.jpg 20120727_183736.jpg

ドライブベースの部分です。機体が重いので結構頑丈に作ってあります。動力源(モーター)の部分にはギアをかなり噛ませてあります。こうすることで、ロボットの移動自体は遅くなりますが、重い機体をしっかり運べるほどのパワーが出ます。

20120727_183640.jpg

ロボットの裏側です。青い丸で囲まれた赤く光っている2つの部品が光ーセンサーです。これを利用してフィールド上の円などをライントレースします。原理は課題2と全く同じですね。

20120727_183407.jpg 20120727_185015.jpg

続いてアームというか、缶をつかむハサミの部分です。左上の写真の赤い四角形で囲まれているのがモーターです。このモーターが回転すると、その次の赤い丸で囲まれたギアに動きが伝わり、同時に回転の方向を変換し、下の左側のハサミについているギアが動きます。そうすると、右側のハサミについているギアも回り、ハサミを開閉します。このユニットがあると、左のハサミと右のハサミの動きを同期させることができるうえに、すべての動きをモーター1つで済ませることができます。センサーについては、ハサミの下側には黒い丸で囲ってある通りタッチセンサーを、上側には右上の写真の緑の丸で囲ってある通り光センサーを取り付けてあります。まず、光センサーで緑の缶の位置を読み取り、ハサミではさんでからリフトでその缶を持ち上げて移動し、黒い中身入りの缶がタッチセンサーに触れたらその場でリフトをおろして、黒缶の上に緑缶を積み上げます。最初は緑缶もタッチセンサーで認識させようとしましたが、缶が軽すぎてタッチセンサーが缶にあたっても反応しないので、このように2種類のセンサーを使い分けました。

20120727_183515.jpg

ハサミの先端の部分です。実は赤い丸で囲ってある部分にはゴムを付けていて、缶ができるだけ滑り落ちないようにしてあります。細かいですが、こういう目立たないところも大事ですね。

20120727_183532.jpg 20120727_183955.jpg

最後にリフトの部分です。今回のロボット作りではこれが鬼門でしたね。しくみとしてはいたってシンプル。左上の写真のモーターが回転すると、それにともなってギザギザのついているシャフトがモーターとかみ合ってリフトが上下に移動するという単純なものです。しかし、ただモーターにシャフトをかみ合わせただけだと上下に移動する際、シャフトがモーターから離れてしまいますし、それを解消したとしてもシャフトは左側についているので、リフトの右側はうまく動きません。そこで、シャフトの部分には左側にブロックを添えてモーターのギアとそのブロックでシャフトを挟み込むようにし、リフト右側には、シャフトと同じような支柱、レールのようなものを作りリフトがそれを伝っていくようにしました。また、右上の写真にあるROTATION SENSORというのは回転センサーのことです。この部品はモーターの回転と連動していて、リフトをどれだけ上げ下げすればいいかは時間ではなく、回転センサーがどれだけ回転したかによって決定しました。

プログラム

今回の課題を攻略する方針としては、下図にあるようにスタートゾーンから1番近場にある缶を持ち上げて左側の円を抜け、センターラインを越えて右側の円に行き黒い缶の上に持ち上げていた缶を積み上げます。1個積み上げるだけでも相当大変だったもので、プログラムはそこまでしか組まれていません。

robocon2012a.png

<ロボット移動制御>

#define THERSHOLD 30//閾値
#define go_st OnFwd(OUT_A); OnFwd(OUT_C);//直進
#define go_ri OnFwd(OUT_A); OnRev(OUT_C);//右旋回 
#define go_le OnFwd(OUT_C); OnRev(OUT_A);//左旋回
#define go_ba OnRev(OUT_A); OnRev(OUT_C);//後退 
#define BLACK 38
#define WHITE 38
#define SIGNALON1 11      // アーム動作開始を知らせるメッセージ緑
#define SIGNALON2 21      // アーム動作完了を知らせるメッセージ緑
#define SIGNALON3 31      // アーム動作開始を知らせるメッセージ黒
#define SIGNALON4 41      // アーム動作完了を知らせるメッセージ黒
#define ReMessage2 32     // SIGNALON3の返事
#define RUN_SECTION2 100  //第4セクションの時間
int cross;  //黒線をまたぐ回数

sub count()
{ if ((SENSOR_1 < THERSHOLD) && (SENSOR_3 < THERSHOLD))//センサー1,3がともに黒線上のとき
{go_st;cross = cross++;}//直進してcountに+1する
       else if(SENSOR_1>THERSHOLD && SENSOR_3<THERSHOLD){   //3だけ黒線の上のとき
           OnFwd(OUT_A);
           OnRev(OUT_C);//右旋回
       
       }else if(SENSOR_1<THERSHOLD && SENSOR_3>THERSHOLD){   //1だけ黒線の上のとき
           OnFwd(OUT_C);
           OnRev(OUT_A);//左旋回
       }else if(SENSOR_1>THERSHOLD && SENSOR_3>THERSHOLD){   //両方黒線の外のとき
           OnFwd(OUT_AC);//直進
           
         }}
task line_1st()  
{
        
       if ((SENSOR_1 < BLACK) && (SENSOR_3 > WHITE)) //1だけ黒線の上のとき
          {
            go_le;//左旋回
          }
       else if ((SENSOR_1 > WHITE) && (SENSOR_3 < BLACK))//3だけ黒線の上のとき
          {
            go_ri;//右旋回
          }
       else if ((SENSOR_1 < BLACK) && (SENSOR_3 < BLACK))//))//センサー1,3がともに黒線上のとき
          {
            go_ri;
            Wait(180);  //90度回転させる 
            Off(OUT_AC);
            stop line_1st;  //このタスクを止める
          }
       else if ((SENSOR_1 > WHITE) && (SENSOR_3 > WHITE))//両方黒線の外のとき
          {
            go_ba;//後退
          }
} 
task main ()
{ 
   SetSensor(SENSOR_1, SENSOR_LIGHT);センサー1を光センサーに設定
   SetSensor(SENSOR_2, SENSOR_TOUCH);
   SetSensor(SENSOR_3, SENSOR_LIGHT);
   SetPower(OUT_A,3);
   SetPower(OUT_C,3);
   
   
   ClearMessage();
   ClearTimer(0);
   while(cross < 1){
         count()
                         }//最初の黒線を無視する
   while (Message() != SIGNALON1) {   //真ん中が反応するまで左側の円の上を通る 
         if ((SENSOR_1 < THERSHOLD) && (SENSOR_3 < THERSHOLD)) {go_st;cross =  cross++;}
       if(SENSOR_1>THERSHOLD && SENSOR_3<THERSHOLD){   //3だけ黒線の上
           OnFwd(OUT_A);
           Rev(OUT_C);
       
       }else if(SENSOR_1<THERSHOLD && SENSOR_3>THERSHOLD){   //1だけ黒線の上
           OnFwd(OUT_C);
           Rev(OUT_A);
       }else if(SENSOR_1>THERSHOLD && SENSOR_3>THERSHOLD){   //両方黒線の外
           OnFwd(OUT_AC);
           
        }         
        
        }
   Off(OUT_AC);
   
   SetPower(OUT_A,3);
   SetPower(OUT_C,3);
   
   until (Message() = SIGNALON2);
   
   go_st;
   Wait(30);
   
   until ((SENSOR_1 < BLACK) || (SENSOR_3 < BLACK) || (FastTimer(0) <=  RUN_SECTION2)); //センサーか時間で反応
   go_le;
   Wait(180);
   go_st;
   until (SENSOR_2 == 1);                //タッチのセンサーに缶が反応
  
   Off(OUT_AC);
   PlaySound(SOUND_CLICK);
   SetPower(OUT_A,3);
   SetPower(OUT_C,3);
   while ( Message() != ReMessage2) {       //メッセージを送り、缶を下ろさせる。
           SendMessage(SIGNALON3);
       }
       if (Message() == ReMessage2) {
           PlaySound(SOUND_CLICK);          // 送信に成功したときはピッと鳴らす
       } else {
           PlaySound(SOUND_LOW_BEEP);       // 送信に失敗したときはブッと鳴らす
       }
   until (Message() = SIGNALON4);
   go_ba;
   Wait(50);
   Off(OUT_AC);
  }

<アーム制御>

#define SIGNALON1 11    // アーム動作開始を知らせるメッセージ
#define SIGNALON2 21   // アーム動作完了を知らせるメッセージ
#define ReMessage1 12    // SIGNALON1の返事
#define SIGNALON3 31      // アーム動作開始を知らせるメッセージ黒
#define SIGNALON4 41      // アーム動作完了を知らせるメッセージ黒
#define ReMessage2 32     // SIGNALON3の返事
#define GREEN 51       // until (SENSOR_3 > GREEN); 普段と逆で行う
int i;                   // for ループのための変数
int i_min=1,i_max=3;
task main ()
{
   ClearMessage();                    // Message()の値を0に初期化
   SetSensor(SENSOR_1, SENSOR_LIGHT);
   SetSensor(SENSOR_3, SENSOR_ROTATION);
   SetPower(OUT_A,4);
   SetPower(OUT_B,7); 
   for (i=i_min; i<=i_max; i++) { //3回繰り返す   
   
     
   until (SENSOR_1 > GREEN && FastTimer()==200);
   PlaySound(SOUND_CLICK);
   SendMessage(SIGNALON1);                // 缶を見つけたことを知らせる
    
   Wait(50); 
               
   OnFwd(OUT_A);
   Wait(50);
   Off(OUT_A);                  // アームで掴む
      
   OnFwd(OUT_B);
   until (SENSOR_3 == -25);     //回転センサーを使い一定まで上げさせる。
   Off(OUT_B);                  // リフトであげる
   SendMessage(SIGNALON2);        // 動作完了の合図
   until (Message() == SIGNALON3);
      SendMessage(ReMessage2);     //返事
    SetPower(OUT_A,3);
    SetPower(OUT_B,4);
    OnRev(OUT_B);
    Wait(10);
    Float(OUT_B);
    Wait(30);                                //シャフトを缶まで下げる
    OnRev(OUT_A);
    Wait(50);
    Off(OUT_A);                              //アームを開く
    SetPower(OUT_B,7);                     
    OnRev(OUT_B);
    Wait(70);
    Float(OUT_B);                            //シャフトを一番したまで下げる
    SendMessage(SIGNALON4);
     
   }
}

工夫した点、頑張った点

工夫した点や頑張った点といってもほとんどロボットの紹介で述べちゃってますよね(笑)。あえて言うなら、プログラムを作りやすく、そして正確にするためにロボット1台に全機能をのせたことと、各センサーを用途に応じてちゃんと使い分けたことでしょうか。あと、ライントレーサーの部分にいたっては1から作ったのではなく、前の課題2で作ったものを再利用し、そこにアームなどのパーツを付けていったことです。頑張った点はとにかくリフトの部分ですねwww。おかげで相当滑らかに上下運動することはできます。ちなみに結果は、1つも積み上げられませんでした。結構頑張ったのに(泣)。

まとめ

ようやくすべてが終わりました。はあ〜疲れた・・・。やっぱりロボット作りは難しいものです。最初に今回は今までの集大成だと述べましたが、それでも反省しなければならないところが数えきれないほどあります。例えば、機体が重すぎること、コードの接触が悪くなってしまったこと、ライントレースのための光センサーに他の部品が被ってしまい、うまく黒線を認識できなかったこと、構造上とても機体がもろくなってしまったこと、etc....。ロボット本体だけでなく製作スケジュール的にも、プログラムにあまり時間をかけられなかったり、期末テストと日程が被ってしまってチームの人と集まる時間が無かったりと色々と問題がありました。でも今思えば苦労した分色々と得るものも多かったと思います。ぜひみなさんも挑戦してみてください。趣味などでやる分にはとても有意義なことだと思います。では、この辺で終わりとしましょう。さようなら〜

リンク

私と共に今プロジェクトに取り組んでくれた人たちのロボコンのページです。こちらもぜひご覧ください。

2012a/A2/yamadai/M3

2012a/A2/Jiro/M3 ・・


添付ファイル: filerobocon2012a.png 220件 [詳細] file20120727_185015.jpg 306件 [詳細] file20120727_183955.jpg 251件 [詳細] file20120727_183640.jpg 300件 [詳細] file20120727_183532.jpg 273件 [詳細] file20120727_183515.jpg 265件 [詳細] file20120727_183407.jpg 253件 [詳細] file20120727_183736.jpg 263件 [詳細] file20120727_185237.jpg 296件 [詳細] file20120727_183443.jpg 324件 [詳細]

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2012-08-08 (水) 20:07:58