''&size(30){目次};''
#contents


*メンバー [#cfd15b69]
きたざわ

ユウジ


*課題 [#q18badd5]
**課題内容 [#bb224d10]
今回の課題は「ライントレーサー兼空き缶運びロボット」です。詳しい課題内容は[[課題2:http://yakushi.shinshu-u.ac.jp/robotics/?2010a%2F%CE%FD%BD%AC%CC%E4%C2%EA#kadai1]]をご覧ください。
**それぞれの課題について [#o14b966c]
空き缶の移動のさせ方がそれぞれ違います。

・きたざわ→空き缶を次の交差点まで運んで行き、その交差点に空き缶を残してさらにコースに沿って進む。

・ユウジ→空き缶をコース上に戻して再びコースに戻って進む。
 


*ロボットの紹介 [#be3525e9]

**ロボット全体図 [#p48b74b4]
完成したロボットがこちらです。

&ref(2010a/A8/課題2左/ロボ全体.JPG,ロボ全体);

&ref(2010a/A8/課題2左/横_改.JPG,横);

&ref(2010a/A8/課題2左/前_改.JPG,前);
&ref(2010a/A8/課題2左/後ろ_改.JPG,後ろ);

前のパーツを簡単に取り外すことができないので、外す必要が無くなるようNQCのCPUをわざと反対向きに取り付けました。↑

CPU前部に、CPUにプログラムを送るためのセンサーがあるためです。

**空き缶を掴む流れ [#tb5aca9e]
走行中、後述するタッチセンサーのバンパーに空き缶が当たると、左右のアームが閉じ、空き缶を掴みます。

&ref(2010a/A8/課題2左/掴む流れ.png,掴む流れ);

&ref(2010a/A8/課題2左/ロボ全体(アーム開きver).JPG,ロボ全体(アーム開きver));
&ref(2010a/A8/課題2左/ロボ全体(空き缶持ちver).JPG,ロボ全体(空き缶持ちver));

**ライントレースの流れ [#y59e599b]
光センサーを2つ付け、その間に線をはさんで走行します。また、公差点で道が途絶えているところにはT字路があり、そこで両方のセンサーが反応したら、線を無視して直進し、離れた線まで進みます。

&ref(2010a/A8/課題2左/下_改.JPG,下);
&ref(2010a/A8/課題2左/課題コース_3.jpg,課題コース);

**工夫したところ [#of92371a]

***ギア部分 [#yb25b4b4]
3つだけしかモーターを使えないので、配分は、タイヤに2つ、ハサミ(空き缶を掴む部分)に1つ、ということになります。1つのモーターでハサミを動かすために、次の写真のような仕組みを考えました。

&ref(2010a/A8/課題2左/ギヤ部分.JPG,ギア部分);
&ref(2010a/A8/課題2左/ギヤ部分_装着.JPG,ギア部分_装着);

回す軸を左右に伸ばし、同じ仕組みのギアの仕組みを左右に付けることにより、同時に動き、なおかつそれぞれが逆に動くので、ハサミにぴったりな動きをさせることができました。

***タッチセンサーをどう使うのか [#c9f229ff]
1つのタッチセンサーで広範囲をカバーするため、以下の写真の仕組みにしました。オレンジの方向に力が加わると、センサーが反応するようになっています。

&ref(2010a/A8/課題2左/タッチセンサー.JPG,タッチセンサー);

***バンパーの工夫 [#y239dc9a]
空き缶がぶつかったことを感知するためにタッチセンサーを付けるのですが、ハサミの開閉に影響がでないよう、バンパーの位置をハサミの間にしています。

&ref(2010a/A8/課題2左/バンパーの位置.JPG,バンパーの位置);
&ref(2010a/A8/課題2左/しっかり閉じます.JPG,しっかり閉じます);

また、ちょうど真ん中の高さにバンパーがあるので、空き缶に当たったときに、しっかりと反応します。

&ref(2010a/A8/課題2左/空き缶に当てるバンパーの高さ.JPG,空き缶に当てるバンパーの高さ);

***ハサミパーツの固定 [#ua631b50]
ハサミパーツを作る上で、軸を縦方向にしたいために、レゴブロックを横向きに使う必要がありました。

&ref(2010a/A8/課題2左/レゴ.png,ブロックの使い方);

このパーツを固定するために、始めは同じ向きで固定して使用する光センサーのブロックとだけ固定されていました。(赤丸内のところ)

&ref(2010a/A8/課題2左/危険.JPG,いっしょに固定されていた部分);
&ref(2010a/A8/課題2左/初代ハサミ.JPG,初代ハサミ);

しかし固定している部分が少なすぎたため、モーターを動かした瞬間にハサミパーツは外れました。

そこで本体上部とハサミパーツを連結させました。

&ref(2010a/A8/課題2左/固定用パーツ装着.JPG,固定用パーツ装着);
&ref(2010a/A8/課題2左/実際に固定.JPG,実際に固定);

***走行中の安定性向上 [#r0559d3a]
走行するときに、ライントレースの特性上、発進→方向転換(ほぼ急ブレーキ)、を繰り返すため、ロボがつんのめってしまい、タッチセンサーの誤作動が起きてしまいました。

&ref(2010a/A8/課題2左/つんのめる.JPG,つんのめる);

そこでロボ前方に支えを作ることにしました。光センサーと地面との隙間を無くし、安定して走るようにしたのが下の写真です。

改善前
&ref(2010a/A8/課題2左/隙間あり.JPG,隙間あり);
改前後
&ref(2010a/A8/課題2左/隙間なし.JPG,隙間なし);

***タッチセンサーのバー自体の揺れ [#ufe566f7]

先ほど述べたように、ライントレース走行の勢いにより、タッチセンサーのバーが大きく揺れ、その反動によりタッチセンサーが誤作動することがたびたび起きました。

&ref(2010a/A8/課題2左/揺れ防止棒_説明図.png,タッチセンサーの誤動作の図);

そこで軸パーツを使い、バーが前方へ動くことを防ぐことで、大きな揺れが起こることを防ぎました。

&ref(2010a/A8/課題2左/揺れ防止棒.JPG,大きな揺れを防止);



*プログラム [#w2702e18]

**きたざわ [#ia70bfea]
&ref(2010a/A8/課題2左/行うこと_2.jpg,行うこと);

図の流れで動かします。

 #define go OnFwd(OUT_A+OUT_C);          //まっすぐ進む
 #define back OnRev(OUT_A+OUT_C);                  //まっすぐ下がる
 #define stoping Off(OUT_A+OUT_C);                 //動きを止める
 #define spin_r OnFwd(OUT_C);OnRev(OUT_A);         //右旋回
 #define spin_l OnFwd(OUT_A);OnRev(OUT_C);         //左旋回 
 #define open OnFwd(OUT_B);Wait(30);Off(OUT_B);    //アームを開く
 #define close SetPower(OUT_B,0);OnRev(OUT_B);     //アームを弱い力で閉じ続ける(空き缶を持って移動中、アームが開いてしまわないように)
 #define eye_r SENSOR_1                            //SENSOR_1の名称をeye_rと定義
 #define eye_l SENSOR_3                            //SENSOR_2の名称をeye_lと定義
 #define boundary_r 42                             //右光センサーの黒白判断の境目の値(部屋の明るさで大きく左右されるので、すぐ訂正できるよう定義しておく)
 #define boundary_l 50                             //左光センサーの黒白判断の境目の値(部屋の明るさで大きく左右されるので、すぐ訂正できるよう定義しておく)
 
 
 task line_run() {                    //ライントレース用のタスクです
      SetSensor(eye_r,SENSOR_LIGHT);  //eye_rは光センサーと定義
      SetSensor(eye_l,SENSOR_LIGHT);  //eye_lも光センサーと定義
 
      while(true) {
         go;                          //普段はライントレースしながら進む
 
         if(eye_r<boundary_r) {       //もし右光センサーが線に当たったら
            spin_r;                   //右旋回
            until((eye_r>boundary_r)||((eye_r<boundary_r)&&(eye_l<boundary_l)));  //右光センサーが線を離れるか、両方のセンサーが反応するまで(T字路)
          }
 
         if(eye_l<boundary_l) {       //もし左光センサーが当たったら
            spin_l;                   //左旋回
            until((eye_l>boundary_l)||((eye_r<boundary_r)&&(eye_l<boundary_l)));  //左光センサーが線を離れるか、両方のセンサーが反応するまで(T字路)
          }
 
         if((eye_r<boundary_r)&&(eye_l<boundary_l)) {  //もし両方のセンサーが反応したら(T字路に到着)
            PlaySound(SOUND_DOUBLE_BEEP);              //まず音を出す(わかりやすいように)
            stoping;Wait(200);                         //課題の通り2秒間停止
            go;Wait(100);                              //まっすぐ進み向かい側の線へ
          }
       }
 }
 
 
 task main() {
      SetSensor(SENSOR_2,SENSOR_TOUCH);  //SENSOR_2をタッチセンサーと定義
      ClearTimer(0);                     //タイマーで時間を計り始める
 
      start line_run;                    //走る
      until(SENSOR_2==1);                //タッチセンサーが反応するまで(1つめの空き缶と接触)
      stoping;                           //一度止まる
      stop line_run;                     
  
      close;                             //空き缶をつかむ
 
      start line_run;                    //再び走る
      until((eye_r<boundary_r)&&(eye_l<boundary_l));  //両方の光センサーが反応するまで(T字路到着)
      PlaySound(SOUND_DOUBLE_BEEP);      //わかりやすいように音
      stoping;                           //止まって
      stop line_run;                     //ライントレースのタスクを一度止めます
 
      go;Wait(180);        //少し進んで
      spin_r;Wait(164);    //180度回転
      open;                //空き缶を線の上に置きます
 
      back;Wait(60);       //下がって
      spin_r;Wait(100);     //方向を修正(ここで線の上に復帰)
 
      start line_run;      //再び走る
      until(SENSOR_2==1);  //タッチセンサーが反応するまで(2つめの空き缶と接触)
      stoping;             //止まる
      stop line_run;
 
      close;               //空き缶つかむ
 
      start line_run;      //再び走る
      until((eye_r<boundary_r)&&(eye_l<boundary_l));  //両方の光センサーが反応するまで(T字路到着)
      PlaySound(SOUND_DOUBLE_BEEP);       //わかりやすいように音
      stoping;                            //止まって
      stop line_run;                      //ライントレースのタスクを一度止めます
 
      go;Wait(150);        //少し進んで               
      spin_r;Wait(164);    //反転
      open;                //空き缶を置く
 
      back;Wait(60);       //下がって
      spin_r;Wait(70);     //方向修正
      go;Wait(30);         //少し進む(ここで線の上に復帰)
      stoping;             
 
      while(FastTimer(0)<=5200) {  //タイマーが52秒以上になるまで
      start line_run;Wait(100);      //1秒間ライントレースを繰り返す
      stoping;
      stop line_run;                       
      }
 }   

空き缶を置いた後に進む道2つがかなり異なっていたため、復帰するためのプログラムが別々なものになり、全体的にかなり長いプログラムになってしまい残念でした。

一周して止まるのに使った最後のプログラムでは、止まるべき時間から最大1秒近くの誤差ができてしまいます。センサーを使って停止するなど、もう少し正確に停止できればよかったと思います。


**ユウジ [#v70d4801]
 #define Turn_R OnRev(OUT_A);      //右タイヤを後退
 #define Turn_L OnRev(OUT_C);      //左タイヤを後退
 #define Light_R  40               //右の光センサーの閾値
 #define Light_L  50               //左の光センサーの閾値
 #define Tomare Off(OUT_A+OUT_C);  //停止
 #define go OnFwd(OUT_A+OUT_C);    //前進
 #define Eye_R SENSOR_1        //右の光センサ
 #define Eye_L SENSOR_3        //左の光センサ
 #define BUMPER SENSOR_2       //バンパーを定義
 #define Get OnRev(OUT_B);Wait(30);Off(OUT_B);  
 #define carry OnRev(OUT_A);OnFwd(OUT_C);Wait(190);OnFwd(OUT_A);Wait(20);Off(OUT_A+OUT_C);
 #define carry2 OnFwd(OUT_B);Wait(30);Off(OUT_B);
 #define fin OnRev(OUT_A+OUT_C);Wait(80);OnFwd(OUT_C);Wait(195);OnRev(OUT_C);Wait(80);Off(OUT_A+OUT_C);
 #define RUN_TIME 660        //時間を定義
 
 task main()  {                                           //メインのタスク
      SetPriority(1);                                     //優先順位を設定
      SetSensor(BUMPER,SENSOR_TOUCH);                     //タッチセンサーを定義
      SetSensor(Eye_R, SENSOR_LIGHT);                     //右の光センサーを定義
      SetSensor(Eye_L, SENSOR_LIGHT);                     //左の光センサーを定義
 
       ClearTimer(0);                                     //タイマーをリセット                        
 
      while( Timer(0) <= RUN_TIME )  {                    //定義した時間を越えるまで続ける         
      start follow_line;                                  //もう一つのtaskを使用          
 
      until (BUMPER == 1);                                //タッチセンサが反応するまで
       acquire(ACQUIRE_OUT_A+ACQUIRE_OUT_C){
       Get;Wait(35);carry;Wait(35);carry2;Wait(35);fin;Wait(35);   //缶を運ぶ一連の動作
       Tomare; }  
         } 
       Tomare;
      }
 
 
 task follow_line()                                     //有線順位の低いtask(光センサー専用タスク)
 {    SetPriority(2);                                   //優先順位を設定
 
      while ( Timer(0) <= RUN_TIME ) {acquire(ACQUIRE_OUT_A+ACQUIRE_OUT_C){
 
        if ((Eye_R < Light_R)&&(Eye_L > Light_L))           //右の光センサが反応したら
    {     Turn_R;
          Wait(15);
          Tomare;    }
 else if ((Eye_L < Light_L)&&(Eye_R > Light_R))       //左の光センサが反応したら
 
 {     Turn_L;
          Wait(15);
          Tomare;      }
 
 else if ((Eye_R < Light_R)&&(Eye_L < Light_L))       //両方同時に反応したら
     {      Tomare;Wait(50);
            go;Wait(100);Tomare;   }
          
         else{ 
           go;}
          Wait(1);}      } Tomare;}
         


*感想 [#x4c3a5cf]

**きたざわ [#w30dd056]
組み立てたロボットを実際に動かしてみて、初めて発覚する問題点がかなりありました。
ロボの問題点を克服させる作業が大変でしたが、楽しい部分でもありました。


**ユウジ [#f8a581ba]
 最初taskを複数使いこなせず、大変苦労しました。また、ロボットを動かしている時に本体が揺れてしまい勝手にタッチセンサーが反応してうまく行かないときもありました。しかし自分たちで工夫して問題点をクリアすることができ、とてもやりがいのある課題でした。

*コメント [#q08cf274]
このページについてコメントをよろしくお願いします。
- イラストと写真を使い、わかりやすく説明されています -- [[TAKA]] &new{2010-07-09 (金) 17:33:25};
- イラストと写真を使い、わかりやすく説明されています。プログラムについても工夫した点を説明するとさらによいと思います -- [[TAKA]] &new{2010-07-09 (金) 17:33:25};

#comment

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS