フィールド上の紙パックを、クレーンロボットがつかめる位置まで運搬するロボット。

紙パックをいい感じの場所にもってきて、クレーンロボに「この愛を受け取って」とラブコールを送り、 またせっせとプレゼントを探しに行く健気な子。

プログラムは最終的にこんな感じに。 (プログラム製作・柳澤)


#define GREEN_LINE 42 //緑の線は42以下
#define BLACK_LINE 37 //黒の線は37以下

int raddar ;          // raddar という整数型の変数を定義

sub ret_prot()    // 帰還ルーチン。主に通信
{

   OnRev(OUT_A+OUT_C);    // 後進。ここで箱が置かれる(予定)
   Wait(100);
   until (SENSOR_3 < GREEN_LINE);    // 緑線を感知するまで
   Off(OUT_A+OUT_C);    // 一旦停止

   ClearMessage();           // Message() を 0 に設定
   ClearTimer(0);
   while ( Message() == 76 ) { SendMessage(67); }  // 返事が来るまで 67 を送信
   PlaySound(SOUND_CLICK) ;    // 受信しましたよ(対人用)

   while ( Timer(0) <= 50 ) { SendMessage(107); }  // 5秒間 107 を送信

   PlaySound(SOUND_CLICK) ;    // 出るとき音を鳴らす(対人用)
}


sub chrad_R()    // 方向転換右
{
   while (raddar != 1) {    
       OnRev(OUT_C);OnFwd(OUT_A);
       Wait(10);    // 向きをちょっと変える
       OnFwd(OUT_A+OUT_C);
       Wait(40);    // ちょっと前進
       if (SENSOR_3 < GREEN_LINE)  {    // 緑線を感知
           raddar = 1 ;    //  変数raddarに値1を代入
       }
       OnRev(OUT_A+OUT_C);
       Wait(40);    // 後退
   }
   
   raddar = 0 ;    // 変数リセット
}

sub chrad_L()    // 方向転換左
{
   while (raddar != 1) {    // 試作方向転換
       OnRev(OUT_A);OnFwd(OUT_C);
       Wait(10);    // 向きをちょっと変える
       OnFwd(OUT_A+OUT_C);
       Wait(40);    // ちょっと前進
       if (SENSOR_3 < GREEN_LINE)  {    // 緑線を感知
           raddar = 1 ;    //  変数raddarに値1を代入
       }
       OnRev(OUT_A+OUT_C);
       Wait(40);    // 後退
   }

   raddar = 0 ;    // 変数リセット
}

sub trace_R()    // ライントレース右
{ 
   PlaySound(SOUND_DOUBLE_BEEP) ;        // ライントレースに入ったという合図(対人用)

   while (SENSOR_3 > BLACK_LINE) {  
      if (SENSOR_3 < GREEN_LINE) {      // こうすると、緑線上にいるときのみ
           OnFwd(OUT_A);
           Off(OUT_C);Wait(10);
       } else {                        // 線から外れたとき
           Off(OUT_A);
           OnFwd(OUT_C);Wait(10);
       }
   }

   PlaySound(SOUND_DOUBLE_BEEP) ;    // ライントレース終了の合図(対人用)
}

sub trace_L()    // ライントレース左
{
   PlaySound(SOUND_DOUBLE_BEEP) ;        // ライントレースに入ったという合図(対人用)

   while (SENSOR_3 > BLACK_LINE) {  
      if (SENSOR_3 < GREEN_LINE) {      // こうすると、緑線上にいるときのみ?
           Off(OUT_A);
           OnFwd(OUT_C);Wait(10);
       } else {                        // 線から外れたとき
           OnFwd(OUT_A);
           Off(OUT_C);Wait(10);
       }
   }

   PlaySound(SOUND_DOUBLE_BEEP) ;    // ライントレース終了の合図(対人用)
}



task main()
{


   SetSensor(SENSOR_2,SENSOR_TOUCH); //タッチセンサーを定義
   SetSensor(SENSOR_1,SENSOR_LIGHT); //光センサー1を定義(色判別用)
   SetSensor(SENSOR_3,SENSOR_LIGHT); //光センサー2を定義(トレース用)

   raddar = 0 ;    // 変数初期定義

   OnFwd(OUT_A+OUT_C);Wait(200);    // 箱から落ちるまで進む
   OnRev(OUT_A+OUT_C);
   Wait(200);                       // 壁まで一旦バック

   OnFwd(OUT_A+OUT_C);
   until (SENSOR_3 < GREEN_LINE);    // 緑線を感知するまで進む
   PlaySound(SOUND_CLICK) ;          // 感知したら音を鳴らす(対人用)

   Wait(50);                         // 感知した緑線を越えるまで待って
   until (SENSOR_3 < GREEN_LINE);    // その次の緑線を感知するまで進む
   PlaySound(SOUND_CLICK) ;          // 感知したら音を鳴らす(対人用)

   chrad_R();    // 方向転換右(サブルーチン)

   OnFwd(OUT_A);
   Off(OUT_C);
   Wait(40);    // ちょっと右折

   trace_R();    // 右側トレース(サブルーチン)

   OnRev(OUT_C);OnFwd(OUT_A);
   Wait(75);    // 右折(90°)

   OnFwd(OUT_A+OUT_C);    // 前進
   Wait(100);
   until (SENSOR_3 < GREEN_LINE);    // 緑線を感知するまで
   PlaySound(SOUND_CLICK) ;    // 感知したら音を鳴らす(対人用)

   ret_prot();    // 帰還モードへ(サブルーチン)

   OnRev(OUT_A);OnFwd(OUT_C);
   Wait(120);    // 180°旋回
   Off(OUT_A+OUT_C);

   // とりあえず終了。ここからループ

while (true) {

   chrad_L();    // 方向転換左(サブルーチン)

   OnFwd(OUT_A+OUT_C);
   Wait(50);    // ちょっと進む

   trace_R();    // 右側トレース(サブルーチン)

   OnRev(OUT_C);OnFwd(OUT_A);
   Wait(140);    // 180°旋回。わざと少なめに設定。
   Off(OUT_A+OUT_C);


   chrad_R();    // 方向転換右(サブルーチン)

   OnFwd(OUT_A+OUT_C);
   Wait(50);    // ちょっと進む

   trace_L();    // 左側トレース(サブルーチン)

   if (SENSOR_1 <= 37 )  {  // 色判定を行う(黒なら取り除く)
       PlaySound(SOUND_DOWN) ;           // 反応あり、捨てる(対人用)
       OnRev(OUT_C);OnFwd(OUT_A);
       Wait(50);    // 適宜、右折
       OnFwd(OUT_A+OUT_C);Wait(100);
       OnRev(OUT_A+OUT_C);Wait(100);
       OnFwd(OUT_C);OnRev(OUT_A);
       Wait(50);    // 適宜、左折

   } else {  
        PlaySound(SOUND_UP) ;           // 反応あり、持ってく(対人用)

           OnFwd(OUT_A+OUT_C);    // 前進
           Wait(100);
           until (SENSOR_3 < GREEN_LINE);    // 緑線を感知するまで
           PlaySound(SOUND_CLICK) ;    // 感知したら音を鳴らす(対人用)

           ret_prot();    // 帰還モードへ(サブルーチン)
   }   

   OnRev(OUT_A);OnFwd(OUT_C);
   Wait(120);    // 180°旋回
   Off(OUT_A+OUT_C);

}

}

    持ってくる子の勇姿。  20050212_0948_0000.jpg 20050212_1131_0001.jpg

・苦労した点

とにかく最初は、タッチセンサーやら光センサー(しかも2つ)やら、
いろいろ搭載した複雑なロボットだったので、プログラムがややこしく、
誤動作も多かった。
ちなみに、タッチセンサーで箱をキャッチしていることを確認、光センサーのひとつで箱の色を確認、
もうひとつの光センサーでラインを判断させていた。
緑と黒の判定があいまいで、うまく戻って来れなかったのも大変だったが、
特に問題だったのは、方向転換。
回転軸からずれないよう、カーブとトレースを組み合わせてあるのだが、ここの時間設定が難しかった。
方向転換の確実性を重視すると、アームから紙パックがこぼれてしまうのだ。
この問題には、アームを長くするという処置をとったが、
残りパーツの状況などからそれだけではまだ不十分だった。
これらの問題をうまく解決できたのは、ロボコン当日の朝、
ぎりぎりになってからタッチセンサーをはずしたことが大きい。
プログラムがシンプルになり、なおかつセンサー用のバンパーの分、アームが深くなったことで、
パックをこぼさず、かつきちんと帰還するようになった。

戻る


添付ファイル: file20050212_0948_0000.jpg 147件 [詳細] file20050212_1131_0001.jpg 146件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2005-02-28 (月) 22:33:45 (5288d)