目次

課題

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

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

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

課題の要点

モーター

片方のモーターで移動
もう一方でブロッックを投げる

光センサー

光センサーに光の強弱を認識させる
2個の光センサーで光の強さを比較させ、より光の強い方に移動する。
光源との距離はおおよその光量から認識する

プログラム

光源を探し、その方向に進ませる。
光源の静止を認識し、ブロックを投げる。

ロボットの説明

全体

TS3H0095.JPG

移動部分にデファレンスギアを用いた。
デファレンスギアはタイヤの進行方向を合わせるためにギアを組み合わせた結果、若干車高が高くなった。

光センサーは前方に2個取り付けた。
重心は若干前方に偏ってしまったがシャフトで支えることでバランスをとった。

ディファレンシャルギア

ディファレンンシャルギア.JPG

モーターの回転の方向によって常に片方のギアしか回らないギアである。
ディファレンシャルギアは今回の課題において最も重要な機構であり、
同時に製作時に最も苦労した所である。

ロボットを前進させるためにはタイヤを一定の方向にそろえる必要があり、
ギヤを複数組み合わせなければならなかった。
その際、「タイヤの軸の位置がうまい具合に合わない」
「ギヤ比の違いによりかなりのトルクをかけなければ回らない」といった問題が発生した。
これらの問題は多くのギアの組み合わせを試すことよって解決した。

光センサー

光.JPG

ロボットに前方に2個の光センサーを取り付けた。
本来なら、センサーの間に「ついたて」を取り付けたほうが光を読み取りやすいらしいのだが試験的に「ついたて」の有無での課題の成功率を調べたが、ほとんど大差がなかったので「ついたて」を取り外すことにした。

発射装置

TS3H0097.JPG

モーターも用いてブロックを弾き飛ばす発射装置を製作した。
自由に発射台の角度を変更できるようにブロックを取り付けたのである程度の飛距離の調整が可能。

また、全体的に傾いているのでブロックを発射する際に飛ばし損ねても自動的に戻ってくるのでほぼ確実にブロックを投げることができる。
写真の黄色い出っ張りはロボットが移動するときにブロックが落ちないようにするためである。

車体安定装置

TS3H0096001.JPG

はじめはキャスターを用いていたが、キャスターの摩擦、タイヤが反転するのに必要な距離などを考え車体をシャフトを用いて「点」で支えることにした。

キャスターの短所
・摩擦が大きく前に進みにくい
・タイヤを反転させるのにある程度の距離を必要とし、今回のように方向転換を短い距離で繰り返すロボットに向かない

シャフトについて
意外にもシャフトはキャスターよりも摩擦が小さいためよりスムーズに移動できる。
だが、絨毯のように床が柔らかいところではかえって引っかかってしまう欠点をもつ。

プログラム

1:全方向から懐中電灯の方向を探しだし、懐中電灯に向けてブロックを投げる

#define left OnFwd(OUT_A)           
#define right OnRev(OUT_A);Wait(30);
task main()
{
SetSensor(SENSOR_1,SENSOR_LIGHT);        //センサー1に光センサーをセット
SetSensor(SENSOR_3,SENSOR_LIGHT);        //センサー2に光センサーをセット
int light ;                                      //変数「light」を定義
int direction ;                 //変数「direction」を定義
int count ;                   //変数「count」を定義
light = 0;
direction = 1;
count = 0;
while (direction <2)
{
if (SENSOR_3 > light){             //光センサーが「light」の値よりも大きい値を得たとき
                      light =SENSOR_3 ;     //その時に得た値を「light」に代入
                      right           //次の方向に移動
                      direction=2;
                      count=0;         //「count」の値を0にする
                      }
else{right;count=count+1;direction=2;}      //光センサーが「light」よりも小さな値を得たとき、「count」値+1
}
while (direction <3)  //「direction」が1〜8の時、上と同様の動作を繰り返す
{
if (SENSOR_3 > light){
                      light =SENSOR_3 ;
                      right
                      direction=3;
                      count=0;
                     }
else{right;count=count+1;direction=3;}
}
while (direction < 4)
{
if (SENSOR_3 > light){
                      light =SENSOR_3 ;
                      right
                      direction=4;
                      count=0;
                     }
else{right;count=count+1;direction=4;}
}
while (direction < 5)
{
if (SENSOR_3 > light){
                      light =SENSOR_3 ;
                      right
                      direction=5;
                      count=0;
                     }
else{right;count=count+1;direction=5;}
}
while (direction<6)
{
if (SENSOR_3 > light){
                      light =SENSOR_3 ;
                      right
                      direction=6;
                      count=0;
                      }
else{right;count=count+1;direction=5;}
}
while(direction<7)
{
if (SENSOR_3 > light){
                      light =SENSOR_3 ;
                      right
                      direction=7;
                      count=0;
                      }
else{right;count=count+1;direction=7;}
}
while(direction<8)
{
if (SENSOR_3 > light){
                      light =SENSOR_3 ;
                      right
                      direction=8;
                      count=0;
                      }
else{right;count=count+1;direction=8;}
}
while(direction<9)       //「direction」の値が9よりも小さい、つまり8の時
{
  if(count<1)          //「count」が0の時、停止
  {
   Off(OUT_A+OUT_C);
   direction=9;
  }
     if(count<2)        //「count」が1のとき方向7に移動
  {
   left ;
   Wait(30);
   Off(OUT_A+OUT_C);
   direction=9;
  }
    if(count<3)         //「count」が2のとき方向6に移動
  {
   left ;             
   Wait(60);
   Off(OUT_A+OUT_C);
   direction=9;
  }
    if(count<4)         //「count」が3のとき方向5に移動
  {
   left ;
   Wait(90);
   Off(OUT_A+OUT_C);
   direction=9 ;
  }
    if(count<5)         //「count」が4のとき方向4に移動
  {
   left ;
   Wait(120);
   Off(OUT_A+OUT_C);
   direction=9 ;
  }
    if(count<6)         //「count」が5のとき方向3に移動
  {
   left ;
   Wait(150);
   Off(OUT_A+OUT_C);
   direction=9 ;
  }
    if(count<7)               //「count」が6のとき方向2に移動
  {
   left ;
   Wait(180);
   Off(OUT_A+OUT_C);
   direction=9  ;
  }
    if(count<8)                  //「count」が7のとき方向1に移動
  {
   left ;
   Wait(210);
   Off(OUT_A+OUT_C);
   direction=9 ;
  }
     else
  {
   left ;
   Wait(240);
   Off(OUT_A+OUT_C);
   direction=9 ;
  }
while(direction<10)        //「direction」が9のときブロックを投げる
{
OnFwd(OUT_C);
Off(OUT_A+OUT_C) ;
}
}
}
光2.jpg

ロボットを中心に方向を8分割し、一つづつ光量を確認していく。
ひとつ前の方向と現在の方向における光量を比較し、より明るい方角をロボットに覚えさせた。
8つの方向を調べ終わると8つの方向で最も明るい方向に戻り、ブロックを投げる。

<例1>
 ロボットの明るさが上の図より
 1>2>3>4>5>6>7>8
 のとき、ロボットは方向1を最大値に設定し方向8の時点で「count」の値が「8」となり45×7°左周りに回転し光源の方向を向く

<例2>
 ロボットの明るさが上の図より

 6>8>7>5>4>3>2>1

 のとき、
 ロボットは方向5の時点で方向5を最大値として認識。「count」の値は「5」。

 方向6が方向5よりも明るいことを知ると「count」の値を「0」にリセット。~
 その後、方向7、8を調べるごとに「count」の値を+1加算していく。~

 そうしてすべての方向を調べ終わった時点で「count」の値は「2」。  したがって、ロボットは45×2°左に回転して方向6で停止→ブロックを投げる。  

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

#define THRESHOLD 60      //闘値を設定
task main ()
{
SetSensor(SENSOR_1,SENSOR_LIGHT);
SetSensor(SENSOR_3,SENSOR_LIGHT);
while(true){
   if(SENSOR_1 > THRESHOLD){   //左センサーの光が強く
   if(SENSOR_3 > THRESHOLD){   //かつ右センサーの光が強い
             Off(OUT_A);        // 回転を止め
             Wait(30);
               OnFwd(OUT_C);     //球を投げる
             Wait(80);
             Off(OUT_C);       
 } else {                      //右の光が弱く、かつ左の光が強い
         OnFwd(OUT_A);          //左周りに回転する
         Wait(20);
             }
 } else {    //左の光が弱く
   if(SENSOR_3 > THRESHOLD){     //かつ右の光が強い
            OnRev(OUT_A);
            Wait(20);
 }else{                          //それ以外(右と左ともに光が弱い)のとき
             Off(OUT_A);     
               }                     
              }
             }
            }

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

#define THRESHOLD  70                                                //光度「70」を定義        
int run_count;                                                      //変数「count」を定義
task main ()
 {
      SetSensor(SENSOR_1,SENSOR_LIGHT);                              //センサー1に光センサーをセット              
      SetSensor(SENSOR_3,SENSOR_LIGHT);                              //センサー2に光センサーをセット              
      SetPower(OUT_A,7);                                         //モーターの出力を7とする
      SetPower(OUT_C,7);
   count = 0 ;                                                       //前進の回数を数える    
   while(run_count <= 3)
   {             //前進が3回以下のとき   
             if(SENSOR_1 > THRESHOLD)
            {   
                     if(SENSOR_3 > THRESHOLD)
                    {                                                     //センサー1、3が閾値以上;前方に光源;前進
                           OnFwd(OUT_C);   
                           Wait(30);
                           OnRev(OUT_C);
                           Wait(30);
                           count += 1;                                  //現在の「count」の値+1
                    } 
                     else 
                    {
                       OnFwd(OUT_C);                                //右へ曲がる
                       run_count  = 0;                                //「count」の値を0の戻す
                    }
             } 
                         else 
                           {
                             if(SENSOR_3 > THRESHOLD)
                                      { 
                                       OnRev(OUT_C);                          //左へ曲がる
                                      }
                                       else
                                         {
                                          Off(OUT_C);                         //停止
                                          run_count = 0;                           //「count」の値を0に戻す            
                                          }
                  }
   }
                                
while(run_count > 3)                                                  //「count」の値が3よりも大きいとき
{
      if(SENSOR_1 < X)              
            {   
               if(SENSOR_3 < X)                                //両方の光センサーが閾値以下のとき(50センチ以上の距離があるとき)
                  {
                    Off(OUT_C);                                        //停止する 
                    Wait(100);                                           
                    OnFwd(OUT_A);                      //ブロックを光源に向かって投げる
                    Wait(80);   
                    Off(OUT_A);                                        //発射装置の動作を停止する。
                   }
             }
       else                                    //両方の光センサー閾値以上の時(50センチよりも近い位置にいる時)
            {
             OnFwd(OUT_C);
             Wait(170);                                                     //180度方向転換する
             OnFwd(OUT_C);   
             Wait(30);                                 //前進
             OnRev(OUT_C);
             Wait(30);
             OnFwd(OUT_C);
             Wait(170);                                                //再度180度方向転換する
           }                         
 }

その他

製作する過程ででたアイデアを紹介する。

製作初期の発射台

TS3H0081.JPG

モータに棒状のブロックを付け、引っかけるようにしてブロックを投げる発射台である。
しかし、うまい具合に次弾を装填できずに廃案となった。
この発射台は上記の発射台の原型となっており、これをもとに様々な改良が加えらた。

ダルマ落としを利用した発射台

rensya1.JPG
rensya2.JPG

ダルマ落としを参考に考えた発射台である。
3つのブロックを貫くようにシャフトを差し込むことで
一番下のブロックを打ち出すと上から次のブロックが落ちてくる仕組みである。
これによってスムーズに4連射することができた。

現状での欠点はモーターの回転速度の調整がきわめて難しいということだ。
また、一度でも詰まると継続は困難である。

コメント

お気付きの点、アドバイスをお願いします


ロボット、プログラムともとても良くできています。
課題1で相対的に最も明るい方向を探すことができるプログラムにすれば、より良い評価になります。I


添付ファイル: file光2.jpg 357件 [詳細] filerensya2.JPG 364件 [詳細] filerensya1.JPG 358件 [詳細] fileTS3H0096001.JPG 373件 [詳細] file光.JPG 352件 [詳細] fileTS3H0097.JPG 350件 [詳細] fileディファレンンシャルギア.JPG 411件 [詳細] fileTS3H0081.JPG 364件 [詳細] fileTS3H0095.JPG 375件 [詳細]

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2008-08-12 (火) 03:07:10