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

白いホイールを投げるロボットを作成し、以下の動きをするようにプログラムを作成せよ。

1. 全方向から懐中電灯の方向を探しだし、懐中電灯に向けてブロックを投げる。懐中電灯は動かさない。
2. 懐中電灯をゆっくり動かしたとき懐中電灯に向かって進み、懐中電灯の動きを止めればブロックを投げる。
3. 懐中電灯をゆっくり動かしたとき懐中電灯に向かって進み、懐中電灯の動きを止めれば50cmの距離まで近づいてブロックを投げる。

ただし、モータ、光センサ、タッチセンサはそれぞれ2個まで使用可。懐中電灯の代わりに携帯のライトなどを利用してもよい。

ロボットの説明

光センサー

光センサー
  • 光センサーは2つ使って、より光源を探しやすくした。

投げるところ

投げるところ
  • いろいろと試行錯誤した結果、このかたちが一番ホイールを投げやすかった。
  • ホイールを落とすことなく、遠くへ飛ばすことができる。

ディファレンシャルギア

ディファレンシャルギア
  • 今回の課題の一番の問題でもある“1つのモータで2つのタイヤを動かす”ために、このギアを使った。

タイヤ

ストッパー
  • 1つのモータで2つのタイヤを動かしているので、普通には曲がれない。曲がれるようにするために、このようなストッパーをタイヤにつけることによって曲がれるようにした。
  • ロボをバックさせればこのストッパーがタイヤにひっかかり、ディファレンシャルギアとの兼ね合いで片方のタイヤだけを動かすことが可能になった。
  • また、1つのモータで2つのタイヤをそれぞれお互いに逆回転させるために、左右のタイヤにつけるギアの数を変えた。
    三輪
  • このように前にある三輪をホイールだけにすることによって、スムーズに回転して光源を探せるようになった。

全体

全体
  • 最終的にこのようなロボが完成した。

プログラム

1. 全方向から懐中電灯の方向を探しだし、懐中電灯に向けてブロックを投げる。懐中電灯は動かさない。

授業で教わったプログラムを元に光センサー1個だけを使ったプログラムを作成した。

task main(){
 
      SetSensor(SENSOR_1,SENSOR_LIGHT);
                         

      int light_max;
      int time_max;
      ClearTimer(0);
      
             
      while(FastTimer(0)<300){               
      
        OnRev(OUT_A);
        
         if(SENSOR_1>light_max){
         
                                
         
             light_max = SENSOR_1;
             time_max = FastTimer(0);            //一回転して光の最大値を見つける
         
         
         }
         
         
        OnRev(OUT_A);                                       //光の最大値を感じた場所まで逆回転する
        Wait(300 - time_max);
         
        Off(OUT_A);               
        OnFwd(OUT_C);
        Wait(20); 
    Off(OUT_C);                      //光源に向かってホイールを投げる
         
       }   
      
      
  }

(作成者 ミムラ)

2. 懐中電灯をゆっくり動かしたとき懐中電灯に向かって進み、懐中電灯の動きを止めればブロックを投げる。

方向変換しかできない構造なので、ロボットにどう前進させればいいか考えるのに苦労した。最終的に蛇行運転することでロボットを前進させることにした。
また、懐中電灯が止まるということをどのように認識させるか考えた結果
「懐中電灯が止まる」=「ある一定の秒数以上前方に光を感じる」
ということでロボットに認識させることにした。ある一定の秒数を測るために前回の課題で使ったタイマー機能 を使うことにする。

#define LIGHT 42

task main(){

      SetSensor(SENSOR_1,SENSOR_LIGHT);
      SetSensor(SENSOR_3,SENSOR_LIGHT);


         if(SENSOR_1 > LIGHT && SENSOR_3 > LIGHT){       //光源が前方に来た場合の行動
           ClearTimer(0);                    //前進する時間を測るためタイマーを0にする
           
           while(SENSOR_1 > LIGHT && SENSOR_3 > LIGHT){ 

               OnFwd(OUT_A);                  //蛇行運転(前進)する
               Wait(10);
               OnRev(OUT_A);
               Wait(10);

               if(FastTimer(0) > 200){             //タイマーが200をこえたら止まってホイールを投げる

                    Off(OUT_A);
                    OnFwd(OUT_C);
                    Wait(20);  
         
                    Off(OUT_A+OUT_C);
                    
                    goto OUT;

                }     
            }  
                
         }
         else if(SENSOR_1 < LIGHT && SENSOR_3 > LIGHT){    //光源が右側にあったら右折
         
           OnFwd(OUT_A);
         
         }
         else if(SENSOR_1 > LIGHT && SENSOR_3 < LIGHT){    //光源が左側にあったら左折
         
           OnRev(OUT_A);
         
         }
         else if(SENSOR_1 < LIGHT && SENSOR_3 < LIGHT){    //どちらに光源があるかわからないときは、時計周りに回転して光源を探す
         
           OnRev(OUT_A);
            
         
         }
         
                                
OUT:
         Off(OUT_A+OUT_C);
      
}

(作成者 スギウラ)

3. 懐中電灯をゆっくり動かしたとき懐中電灯に向かって進み、懐中電灯の動きを止めれば50cmの距離まで近づいてブロックを投げる。

上のプログラムのタイマーを使う部分のかわりに「50センチ前に光の閾値を設定してその値以上になったらホイールを投げる」というプログラムを付け足せばよい。

#define LIGHT50 45
#define LIGHT 42

task main(){

     SetSensor(SENSOR_1,SENSOR_LIGHT);
     SetSensor(SENSOR_3,SENSOR_LIGHT);
     
        if(SENSOR_1 > LIGHT && SENSOR_3 > LIGHT){       //光源が前方にあったら蛇行運転する
        
          OnFwd(OUT_A);
          Wait(10);
          OnRev(OUT_A);
          Wait(10);
               
        }
        else if(SENSOR_1 < LIGHT && SENSOR_3 > LIGHT){    //光源が右側にあったら右折
        
          OnFwd(OUT_A);
        
        }
        else if(SENSOR_1 > LIGHT && SENSOR_3 < LIGHT){    //光源が左側にあったら左折
        
          OnRev(OUT_A);
        
        }
        else if(SENSOR_1 < LIGHT && SENSOR_3 < LIGHT){    //どちらに光源があるかわからないときは、時計周りに回転して光源を探す
        
          OnRev(OUT_A);
           
        
        }
        
                               

if(SENSOR_1 > LIGHT50 && SENSOR_3 > LIGHT50) {    //50センチ手前にきたら止まってホイールを投げる
Off(OUT_A);
OnFwd(OUT_C);
Wait(20);
Off(OUT_A+OUT_C);
}

   
 }

(作成者 スギウラ)

工夫・苦労した点

図1

投げるところのストッパー

図2

延長

・ホイールを投げるところにストッパーを取り付け、より正確に投げられるようにした。(図1)
・NQC本体からモーターへとつなぐコード(?)が短く構造を変えなければならなくなったが、途中で2つつなげることによってコードを延長できることに気がついた。(図2)
・回転運動だけでホイールをどのように投げるか考えるのに苦労した。
・携帯電話を光源にしたので光が弱く、50センチ前の光の強さの値の変化が非常にシビアだった。

感想

・モーターが一つしか使えないと、モーター二つで簡単にできていた行動さえ、どのように動かせばいいか考え直さなければならないので、いろいろと勉強になった。
・ディファレンシャル・ギアを考えた人は天才だと思った。
・前回のライントレースにしてもそうだが、モーターとセンサーを組み合わせるだけでいろいろなことができることに感動した。
・期限が短い上に、二人が集まれる時間が極端に少なく、とても苦労した。

コメントをお願いします

  • 向きが固定されている前輪がある場合、横方向への摩擦を減らすためにゴムを外すというのは効果的だと思います。ついでにRCXの位置をもう少し後ろにするとさらに摩擦が減って旋回しやすくなります。 -- 松本 2008-07-08 (火) 08:45:40


添付ファイル: file中身.jpg 133件 [詳細] file光センサー3.jpg 133件 [詳細] fileストッパー3.jpg 134件 [詳細] file全体.jpg 326件 [詳細] fileストッパー2.jpg 270件 [詳細] file延長.jpg 253件 [詳細] file投げる.jpg 251件 [詳細] file光センサ.jpg 273件 [詳細] file三輪.jpg 247件 [詳細] fileストッパー.jpg 276件 [詳細] fileギア.jpg 261件 [詳細]

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