2009a

目次

ロボコン

課題:紙パック収集・分別ロボット

コースについて

?plugin=attach&refer=2009a%2F%A5%ED%A5%DC%A5%B3%A5%F3&openfile=robocon2009a-1.png

 ・紙パックを収集して色ごとに別の目的地まで運ぶ
 ・フィールドは約160cm×110cm
 ・運搬する500mlの紙パック(以下単に紙パックと呼ぶ)は約7cm×7cm×10.3cm
 ・紙パックはすべての面に白あるいは緑色の画用紙がはられている
 ・スタート地点の壁、中央の壁、ゴール近くの障害壁の断面は約89mm x 38mm
 ・目的地の正方形の3辺は19mm×19mmの角材で仕切られている
 ・黒い線の太さは約25mm

ルールについて

 ・紙パックを所定の場所に運ぶ。
 ・競技時間は審判が続行不能と判断するまで、あるいはリタイアするまでとする。
 ・スタート時は上空も含め「スタート地点」からはみ出さないこと。
 ・スタート時のロボットは2個を越えないこと (スタート後はいくつに分裂してもかまわない)。
 ・開始の合図から5秒以内にRCXのスタートボタンを押す作業を完了すること。
 ・競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。
 ・途中でうまく動かなくなった場合、1回限り再スタートすることができる。
 ・競技終了時点で、運んだ紙パックにロボットの一部が触れていてはならない。触れている場合は、その紙パックは加算しない。
 ・ゴール内のフィールドに接地している紙パックだけを得点の対象とする。

ロボットの説明

ロボットA(ロボット運搬用):てつお

初めは四輪にしていたが旋回性能が極端に低くうまく曲がれなかったので、前二輪を排除して底部に滑りやすいパーツを付けた脚柱に交換した。

ロボットBを降ろすスロープはロボットに押されたときに倒れやすいようにそれぞれ1点で固定してある。また。倒れた時の衝撃を少しでも緩和するために接地点をチューブで保護した。(あまり効果はなかったようだが)

最後にロボットBを降ろした後にロボットBの作業の妨げにならないようにスロープを回収する必要があり、その作業を確実にするために凹凸の多いスロープの裏に直角三角形のパーツを仕込んだ。

ロボットB(牛乳パック運搬用);ごんぞう

ロボットBの移動は2つの光センサーによるライントレースで行った。

ロボットAに載せて運搬するためになるべく全体が小さくまとまるように制作した。

パックを掴む動作は4本のアームで左右からはさみこむように掴むものにした。

パックをしっかりと保持するためにギヤにトルクギヤを使い常にパックに力がかかるようにした。

ただし、パック同士の間隔が狭いのでアームが必要以上に開かない様にストッパーを付けた。

また、ロボットが壁に近づきすぎるとパックを押し出してしまうのでタッチセンサーを少し前に出してロボットと壁の間隔を確保している。

プログラム

てつお

#define go_straight(t)  OnFwd(OUT_A+OUT_C);Wait(t);Off(OUT_A+OUT_C); //直進のマクロ
#define turn_right  OnFwd(OUT_A);OnRev(OUT_C);Wait(90);Off(OUT_A+OUT_C); //右旋回のマクロ
#define turn_left  OnFwd(OUT_C);OnRev(OUT_A);Wait(90);Off(OUT_C+OUT_A); /左旋回のマクロ
#define SIGNALON 11 //行動開始の信号を11に設定

task main()
{ 
SetPower(OUT_A,7);   //モーターA,Bの出力を7(最大)に設定
SetPower(OUT_C,7);
go_straight(150);     // 1.5秒間直進
turn_right;      //右旋回
go_straight(150);   //1.5秒間直進
turn_right;      //右旋回
go_straight(150);   //1.5秒間直進
turn_left;       //左旋回
go_straight(100);   //1秒間直進
Off(OUT_A+OUT_B);   //停止
ClearTimer(0);    //タイマーリセット
ClearMessage();   //メッセージリセット
while((Message()!==1)||(FastTimer(0)<700)){  //返事1を受け取る、または7秒経過するまで
 SendMessage(SIGNALON); //信号11を送り続ける
}
ClearTimer(0);    //タイマーリセット
until(FastTimer>150); //1.5秒経過するまで待機
OnRev(OUT_A+OUT_C);  //1秒後退
wait(100);
Off(OUT_A+OUT_C);   //停止
}

ごんぞう

 サブルーチンを多用して調整をしやすくし、  それぞれのパックごとにプログラムを組んである  時間指定とセンサーによる2段構えの条件付けでT字路や十字路を認識させている

例えば

   { turn_l;
     until(SENSOR_2<LINE);}

とすると、turn_lの中には90度の旋回時間が入っているのでその間はセンサーが反応しないので旋回時間が終わった後の黒線に反応するので少々旋回時間がいい加減でも上手く曲がる。 

 ここからが実際のプログラム

#define T_T81         //旋回時間1
#define T_T2 170   //旋回時間2                                          
#define LINE 40
#define SIGNALON 11  //行動開始の信号
#define straight(t) OnFwd(OUT_B+OUT_C);Wait(t);Off(OUT_B+OUT_C);//直進のマクロ

   以下はサブルーチン

sub turn_l()   //左旋回1
{
 OnFwd(OUT_C);OnRev(OUT_B);  
 Wait(T_T);
 Off(OUT_B+OUT_C);
 }
 sub turn_r()  //右旋回1
{ 
OnFwd(OUT_B);OnRev(OUT_C);
Wait(T_T);
Off(OUT_B+OUT_C);
}
sub turn2_l()  //左旋回2
{
OnFwdOUT_C);Off(OUT_B);
Wait(T_T2);
Off(OUT_C);
}
sub turn2_r() //右旋回2
{
OnFwdOUT_B);Off(OUT_C);
Wait(T_T2);
Off(OUT_B);
}
sub catch()  //パックを掴む動作
 {
  OnFwd(OUT_B+OUT_C);   //タッチセンサーが反応するまで前進
  until(SENSOR_3==1);   
  Off(OUT_B+OUT_C);
  OnRev(OUT_A);        //パックを掴む
 Wait(60);
 OnRev(OUT_B+OUT_C);  //少し後退
 Wait(50);
 Off(OUT_B+OUT_C);
} 
sub relese()   //パックを放す
{
 Off(OUT_B+OUT_C);
OnFwd(OUT_A);
Wait(60);
OnRev(OUT_B+OUT_C);
Wait(50);
Off(OUT_B+OUT_C);
}

 メインプログラム

task main()
{
SetSensor(SENSOR_1,SENSOR_LIGHT); センサー1、2は光センサー
SetSensor(SENSOR_2,SENSOR_LIGHT);
SetSensor(SENSOR_3,SENSOR_TOUCH); センサー3はタッチセンサー
ClearTimer(0);    タイマーリセット
ClearMessage();    メッセージクリア
until((Message()==SIGNALON)||(FastTimer(0)>1900));//信号を受信または19秒経過
SendMessage(1); // 返事を返す                  まで待機
OnFwd(OUT_B+OUT_C); //ロボットAから降りる
Wait(130);
OnFwd(OUT_A);
Wait(50);
Off(OUT_A+OUT_B+OUT_C);
Wait(150);
OnRev(OUT_B+OUT_C);
until((SENSOR_1<LINE)&&(SENSOR_2<LINE)); //ラインを探す
OnFwd(OUT_C);Off(OUT_B);
Wait(150);
start folloW_line;   
until(SENSOR_3==1);   //タッチセンサーが反応するまでライントレース
stop follow_line;
Off(OUT_B+OUT_C);    //停止
Wait(30);
turn_l();        //左旋回
OnRev(OUT_B+OUT_C);    //位置を調整
Wait(30);
Off(OUT_B+OUT_C);
catch();        //パックを掴む
turn_l();        //左旋回
start follow_line;   //光センサーが十字路を見つけるまでトレース
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_l;          //光センサー2がラインに反応するまで右旋回
until(SENSOR_2<LINE);  
start follow_line; //2.1秒間ライントレース
Wait(210);
stop follow_line;      
relese();       //パックを放す
OnFwd(OUT_C);OnRev(OUT_B);  //反転
Wait(170);
start follow_line; //タッチセンサーが反応するまでトレース
until(SENSOR_3==1);
stop follow_line;
catch();     //パックを掴む
OnFwd(OUT_C);OnRev(OUT_B); //反転
Wait(170);
start follow_line;    //2.1秒間ライントレース
 Wait(210);
stop follow_line;
relese();        //パックを放す
OnFwd(OUT_C);OnRev(OUT_B);   //反転
Wait(170);
start follow_line;  //十字路までトレース
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_r;        //光センサー1が右旋回
until(SENSOR_1<LINE);  
straight(50);      //0.5秒間直進
turn_l;         //左旋回
catch();       //パックを掴む
turn_l();
start follow_line;  //十字路までトレース
Wait(100);
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_l();         //センサー2が反応するまで左旋回
until(SENSOR_2<LINE);
start follow_line;      //2.1秒間直進
Wait(210);
stop follow_line;
relese();        //パックを放す
OnFwd(OUT_C);OnRev(OUT_B);  //反転
Wait(170);
start follow_line;   //タッチセンサーが反応するまでトレース
until(SENSOR_3==1);
stop follow_line;
catch();      //パックを掴む
OnFwd(OUT_C);OnRev(OUT_B); //反転
Wait(170);
start follow_line; //2.1秒間ライントレース
Wait(210);
stop follow_line;
relese();      //パックを放す
OnFwd(OUT_C);OnRev(OUT_B); //反転
Wait(170);
start follow_line;   //十字路までトレース
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_l()       //光センサー2が反応するまで左旋回
until(SESOR_2<LINE); 
start follow_line;  //タッチセンサーが反応するまでトレース
until(SENSOR_3==1);
 stop follow_line;
turn_r();       //右旋回
OnRev(OUT_B+OUT_C);  //位置を調整
Wait(30);
Off(OUT_B+OUT_C);
catch();     //パックを掴む
turn_r();        //右旋回
start follow_line;      //十字路までトレース
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_r;         //光センサー1が反応するまで右旋回
until(SENSOR_1<LINE); 
start follow_line;   //2.1秒間トレース
Wait(210);
stop follow_line;
relese();        //パックを放す
OnFwd(OUT_B);OnRev(OUT_C);  //反転
Wait(170);
start follow_line;    //十字路までトレース
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_l;        //光センサー2が反応するまで左旋回
until(SENSOR_2<LINE);
straight(50);     //0.5秒間直進
turn_r;        //右旋回
catch();        //パックを掴む
turn_r();       //右旋回
start follow_line;    //十字路までトレース
Wait(120);
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_r();      //光センサー1が反応するまで右旋回
until(SENSOR_1<LINE);
start follow_line;   //2.1秒間トレース
Wait(210);
stop follow_line;   
relese();       //パックを放す
}
task follow_line();{  //ライントレースのタスク
 while(true){        
    if(SENSOR_1>LINE){    //センサー1白    
               if(SENSOR_2<LINE){  //センサー2黒のとき
                      OnFwd(OUT_B);Float(OUT_C);  //右へ
                                 }
                          else{  //センサー2白のとき
                             OnFwd(OUT_B+OUT_C);  //直進
                               }
                       }
              else{     //センサー1黒
               if(SENSOR_2>LINE){    //センサー2白のとき
                          OnFwd(OUT_C);Float(OUT_B);  //左へ
                                 }
                          else{  //センサー2黒のとき
                OnFwd(OUT_B+OUT_C);  //直進
                              }
                   }
              } 
  }

反省&感想

ロボットBをコンパクトにまとめたつもりだったけど実際にはまだ大きかった様に思えた。また、プログラムについてはパックごとに分けたために非常に長くなってしまったのが反省点かと思う。(T.I)

ロボットAは、細部にわたって頑丈にしたつもりだったけど、本番では壊れてしまったのが残念だった。(naoto)

コメント欄(ご自由にどうぞ)



添付ファイル: fileロボコンのコース画像 146件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-08-09 (日) 12:25:25