2009aへ戻る

課題:懐中電灯に向かってブロックを投げるロボット

目次

ロボットの概要

動力部分

タイヤの回転にディファレンシャルギア(通称デフ)を用い、内輪差を修正した。
deferential gear.JPG

一つのモーターで左右の回転をさせるには、左右のギアの数を偶数と奇数で変え、さらにストッパーで逆方向の回転を抑える必要があった。
タイヤまでのギアはそれぞれ次のようになっている。(右の写真:左タイヤ 左の写真:右タイヤ)
right2.JPGleft1.JPG

アーム(投げる部分)

投げる動作に耐えるため強度重視で制作した。
arm1.JPG

モーターに接続すると次のようになる。
armgear.JPG

全体像

完成したロボットはこのようなもの。小回りが利くように3輪を採用。また光センサは二つ搭載し、全体的に強度を上げた。
finished.JPG

問題点と改善

強度を重視したアーム部分が重すぎてホイールがうまく飛ばなかったため、軽量化した。
arm2.JPG

プログラムについて

〜簡向から止まっている懐中電灯の方向を探しだし、懐中電灯を狙ってブロックを投げ
るプログラム。

懐中電灯をゆっくり動かしたとき懐中電灯に向かって進み、懐中電灯の動きを止めれば一定の距離(懐中電灯から30cm以上離れた距離)まで近づいて懐中電灯を狙ってブロックを投げるプログラム。

プログラム全般

共通の命令
OnFwd(OUT_A); : 機体を右回りに旋回
OnRev(OUT_A); : 機体を左回りに旋回

KEIのプログラム(,離廛蹈哀薀)

#define TURN_TIME 300 //一周する時間

task main()
{
     int light_max=0; //光センサの最大値
     int t_max=0; //光センサの最大値を与える時刻
     SetSensor(SENSOR_1,SENSOR_LIGHT); //センサー1は光センサー
     ClearTimer(0); //タイマーセット
     OnFwd(OUT_A); //右回りに回転
     while(FastTimer(0)<TURN_TIME){ //機体が一周するまで繰り返す
          if (SENSOR_1>light_max){ //センサーが読み取った明るさが今までの光センサの最大値を上回っていた場合
               light_max=SENSOR_1; //光センサの最大値に現在センサーが読み取った値を代入
               t_max=FastTimer(0); //現在の時刻を光センサの最大値を与える時刻に代入
          }
     }
     Off(OUT_A); //一旦停止
     Wait(50);
     OnFwd(OUT_A); //右回りに回転
     Wait(t_max);
     Off(OUT_A); //回転停止
     OnRev(OUT_C); //ブロックを投げる
     Wait(40);
     Off(OUT_C); //停止
}
  • まず右回りに一回転して一番明るい方向を探し、二回転目でその方向を向き、ブロックを投げます

  • 没プログラム

    #define TURN_TIME 300 //一周する時間

    task main()
    {
      int light_max=0; //光センサの最大値
      int t_max=0; //光センサの最大値を与える時刻
      SetSensor(SENSOR_1,SENSOR_LIGHT); //センサー1は光センサー
      ClearTimer(0); //タイマーセット
      OnFwd(OUT_A); //右回りに回転
      while(FastTimer(0)<TURN_TIME){
      if (SENSOR_1>light_max){
      light_max=SENSOR_1;
      t_max=FastTimer(0);
      }
      }
      Off(OUT_A); //一旦停止
      Wait(50);
      OnRev(OUT_A); //左回りに回転
      Wait(TURN_TIME-t_max);
      Off(OUT_A);
      OnRev(OUT_C); //ブロックを投げる
      Wait(40);
      Off(OUT_C);
      }

  • 変更点は、赤い文字の部分です
  • 右回転の場合と左回転ではギア比の関係から旋回する速度が違うので、このままのプログラムでは光源へブロックを投げることができませんでした
  • 一回目と二回目で旋回する向きを同じにすることで、この問題を解決いたしました

俺のプログラム(△離廛蹈哀薀)

#define THERESHOLD 45 //光を追う動作で用いる闘値
#define LIGHTMAX 50 //ブロックを投げる動作で用いる闘値

task main ()
{
     SetSensor(SENSOR_1,SENSOR_LIGHT); //センサー1は光学センサー
     SetSensor(SENSOR_3,SENSOR_LIGHT); //センサー3は光学センサー

     while(SENSOR_3<=LIGHTMAX){ //ロボットが光源にある程度まで近づくまで繰り返す
          if (SENSOR_1<THERESHOLD){
               if (SENSOR_3<THERESHOLD){
                    OnRev(OUT_A);
               } else {
                    OnFwd(OUT_A);
               }
          } else {
               if (SENSOR_3<THERESHOLD){
                    OnRev(OUT_A);
               } else {
                    OnRev(OUT_A);
               }
          }
     } //ここまでwhileの間

     Off(OUT_A); //移動停止
     OnRev(OUT_C); //ブロックを投げる
     Wait(40);
     Off(OUT_C); //アーム停止
}
  • ロボットは基本的に左回りに回転しながら光を探しています
  • 光を見つけると、それを追いかけていきます。右旋回と左旋回を交互に行うことで前進します。
  • ある程度まで近づくとブロックを投げるようになっています。約30cmの距離まで近づくとブロックを投げます

感想

ディファレンシャルギアについて理解を深めることが出来た。
左右のギア比を変えたことで左右の回転スピードが異なっていたり、同心円状で時計
回りと反時計回りが出来なかったので、プログラムで修正していく過程が苦労した。

コメントをどうぞ

  • コメント、宜しくお願い致します -- ? 2009-07-10 (金) 17:32:57
  • ロボットもプログラムも、説明がわかりやすく、また、構造もわかりやすいです。 -- こさか? 2009-07-17 (金) 04:25:38
  • 簡潔でわかりやすいです。ただ、2つ目のプログラムに関して言うと、下から11行目のelseの意味がなくなっています。左右のセンサが光を感じた時には懐中電灯が真正面にあると考え、左右の回転を小刻みに繰り返して前進させた方がより正確に追跡できます。また、できればもっと懐中電灯が止まったということを明確に認識できるとなお良いと思います -- FI? 2009-08-05 (水) 08:28:08


添付ファイル: filearm2.JPG 252件 [詳細] fileright2.JPG 256件 [詳細] filearm1.JPG 254件 [詳細] fileright1.JPG 130件 [詳細] fileleft1.JPG 249件 [詳細] fileside.JPG 135件 [詳細] fileright.JPG 128件 [詳細] fileleft .JPG 120件 [詳細] filefinished.JPG 237件 [詳細] filedeferential gear.JPG 232件 [詳細] filearmgear.JPG 262件 [詳細] filearm.JPG 132件 [詳細]

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