2006a/A1

 

課題2:黒い線に沿って動くロボット

黒い線に沿って動くロボットを作成せよ。そして一つの周回コースを2台のロボットが走行すること想定し、以下の2種類のプログラムを作成せよ。

  1. 前方のロボットに接触したら反転して進む
  2. 前方のロボットに接触したらそのロボットを右側から追い抜いて(あるいは避けて通り)、再びライン上に戻って進む ただし、スピードと確実性をできる限り両立させること。自由課題1も参考に。光センサは2つ使用してよい。

(期限:6月15日)

完成までの道のり

6月8日

作成者;僕
作成日;6月8日

task main ()
{
  SetSensor(SENSOR_1, SENSOR_LIGHT);
  SetSensor(SENSOR_3, SENSOR_LIGHT);
  SetSensor(SENSOR_2, SENSOR_TOUCH);
  
   while (true) 
   {
       if (SENSOR_1 < THRESHOLD)           // (1)黒線上にいるとき
       {
           OnFwd(OUT_A);
           Off(OUT_C);
       } 
       if (SENSOR_3 < THRESHOLD)           // (3)黒線上にいるとき
       {
           OnFwd(OUT_C);
           Off(OUT_A);
       }
       if (SENSOR_2==1 )
      {
          OnFwd(OUT_A);OnRev(OUT_C);Wait(150);    //タッチしたら180°反転する
          OnFwd(OUT_C);
      }
        
    }         
}

<コメント>
左のセンサが触れたら右回転。右のセンサが触れたら左回転をするだけのプログラム。
逆のモータはRevではなくoffにしているので、引きずるように進みます。
マシンのテスト目的に組んでみたら意外と早かったというオチ。
結構うまくカーブを曲がることが出来たので、
速攻完成かと思ったが、直線のところが無駄の多いうごきになってしまう。

<マシーンの改良…>
自動車と同じでコンパクトにしたほうが小回りが利くと考えて、車輪の幅を6ブロックほど短くした。
そして直線では前方に2つつけた光センサーの幅を調整した結果一番近づけたときが無駄が少なくなった。

6月9日

<コメント>
直線での無駄をなくすために、センサーが両方白いときは直進するプログラムを書いたが、
カーブを曲がるときにセンサーが黒い線から両方出てしまうとうまく曲がりきれずに直進してしまった。

6月14日

作成者;僕
作成日;6月14日

#define THRESHOLD 40 
task main ()
{
  SetSensor(SENSOR_1, SENSOR_LIGHT);
  SetSensor(SENSOR_3, SENSOR_LIGHT);
  SetSensor(SENSOR_2, SENSOR_TOUCH);
   
   while (true) 
   {
       if (SENSOR_1 < THRESHOLD)           
       {
           OnFwd(OUT_A);
           Off(OUT_C);
       } 
       if (SENSOR_3 < THRESHOLD)           
       {
           OnFwd(OUT_C);
           Off(OUT_A);
       }
       if (SENSOR_2==1 )
      {
          OnFwd(OUT_A);OnRev(OUT_C);Wait(70);    
          OnFwd(OUT_A+OUT_C);Wait(30);
          OnFwd(OUT_C);OnRev(OUT_A);Wait(70);
          OnFwd(OUT_A);Wait(200);
          OnFwd(OUT_C);OnRev(OUT_A);Wait(90);
          OnFwd(OUT_A);
           
      }
        
    }
   }

<コメント>
ライントレースに加え、タッチセンサが触れたら右側から追い抜くプログラム。
ぶっちゃけ、初期のプログラムに追い抜きを追加しただけだったりします。
追い抜き機能自体も、右回転→直進→左回転→直進→左回転→直進→復帰、とかなり簡単。
そのせいか、うまく線上に復帰できなかったり、直角に線に進入するとうまくいかなかった。

6月15日

作成者;tomo
作成日;6月15日

#define THRESHOLD 40 
task main ()
{
 SetSensor(SENSOR_1, SENSOR_LIGHT);
 SetSensor(SENSOR_2, SENSOR_TOUCH);
 SetSensor(SENSOR_3, SENSOR_LIGHT);
 
  while (true) 
  {
     if (SENSOR_1 < THRESHOLD)   //黒線上にきたらAを回転         
      {
          OnFwd(OUT_A);
          OnRev(OUT_C);
      }
     else
       {
         OnFwd(OUT_C);
        }
      if (SENSOR_3 < THRESHOLD)  //黒線上にきたらCを回転         
      {
          OnFwd(OUT_C);
          OnRev(OUT_A);
      }
       else
      {
         OnFwd(OUT_A);
       }
         
      if (SENSOR_2==1 )             //ぶつかったら半回転
     {
         OnFwd(OUT_A);OnRev(OUT_C);Wait(200);
         OnRev(OUT_A);OnFwd(OUT_C);Wait(50);             
     }
       
   }
  }

<コメント>
左のセンサが触れたら右回転。右のセンサが触れたら左回転をその場でするように改良。
しばらくelseではifのときの逆をプログラムしていたが、そうするとプログラムに重複する部分ができてしまい、うまく動かなかった。
そこで、elseでは片方のモータのみを動かし、両方elseのときに「結果として」直進になるよう改良してみた。
そうすると、直線、曲線共に早く進むようになった。

完成マシンの詳しい説明

完成プログラム

作成者;tomo
作成日;6月15日
#define THRESHOLD 40 
task main ()
{
 SetSensor(SENSOR_1, SENSOR_LIGHT);
 SetSensor(SENSOR_2, SENSOR_TOUCH);
 SetSensor(SENSOR_3, SENSOR_LIGHT);
 
  while (true) 
  {
     if (SENSOR_1 < THRESHOLD)   //黒線上にきたらAを回転         
      {
          OnFwd(OUT_A);
          OnRev(OUT_C);
      }
     else
       {
         OnFwd(OUT_C);      //センサー1が外れたらCのみ回転
        }
      if (SENSOR_3 < THRESHOLD)  //黒線上にきたらCを回転         
      {
          OnFwd(OUT_C);
          OnRev(OUT_A);
      }
       else
      {
         OnFwd(OUT_A);      //センサー3が外れたらAのみ回転
       }
         
      if (SENSOR_2==1 )             //ぶつかったら半回転
     {
         OnFwd(OUT_A);OnRev(OUT_C);Wait(200);
         OnRev(OUT_A);OnFwd(OUT_C);Wait(50);             
     }

//ここから、右から追い抜くプログラム

  if (SENSOR_2==1 )            //ぶつかったら右側から追い抜く
     {
        OnFwd(OUT_A);OnRev(OUT_C);Wait(70);    
          OnFwd(OUT_C);Wait(30);
          OnFwd(OUT_C);OnRev(OUT_A);Wait(70);
          OnFwd(OUT_A);Wait(200);
          OnFwd(OUT_C);OnRev(OUT_A);Wait(90);
          OnFwd(OUT_A);
      } 
   }
  }

省略のため逆回転と、右側から追い抜くプログラムの両方を載せています。

課題となったところ

elaeを使わないとカーブが滑らかに曲がることが出来たが、直線での無駄が大きいので両方のセンサーが白(線外)のとき直進するプログラムを書いた。
すると、確かに直線をまっすぐ進むが、カーブを曲がるときに両方のセンサーが線から外れると、曲がりきらずに直進してしまった。

まとめると…

  1. カーブで両方のセンサーをはずさないこと。
  2. 直線での無駄を極力省くこと。
  3. ぶつかったら逆方向に進むとき、また、右側から追い抜くときにうまく線上に復帰すること。

解決(工夫した点)

  1. else を使い、片側のセンサーが外れたときの動きを変えたところ、滑らかさはなくなったが確実に曲がるようになった。
  2. elseを使うことで直線でも両方センサーが外れたとき直進するようなプログラムになり直線のスピードが上がった。
  3. 逆方向に進むときの反転で、確実に線に乗るために180度回転ではなく、
    おおきめに回転してから頭を振って線を探すようにしたところ、かならず線に乗るようになった。

ロボットの説明

カーブでなるべくスムーズに曲がるためにタイヤの幅を狭くして小回りが利くようにした。

コピー 〜 060614_1929~0001.JPG

タッチセンサを取ると、RCXよりも小さいです。

コピー 〜 060614_1930~0001.JPG
 

感想&考察

今回はマシーンは簡単に作れたが、プログラムに手間取った。
プログラムを書いて、予想道理に動くことのほうが少ないので試行錯誤にかなり時間を使ってしまった。




添付ファイル: file060616_1419~01001.JPG 152件 [詳細] file060616_1418~01001.JPG 136件 [詳細] fileコピー 〜 060614_1930~0001.JPG 276件 [詳細] fileコピー 〜 060614_1929~0001.JPG 260件 [詳細]

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2006-07-16 (日) 01:46:56