*黒い線に沿って動くロボット [#e9227f4e]
*&size(25){パターン1}; [#h361a1d8]
光センサ2個の場合(モーター2個使用)
 //    作成者:山崎 畠山
 //    作成日:2005-11-21
  task main()
  {
      SetSensor(SENSOR_1,SENSOR_LIGHT);  //センサの宣言
      SetSensor(SENSOR_3,SENSOR_LIGHT);  //センサの宣言
      
      while(true)  //無限に繰り返す
      {            //センサ1、センサ2共に黒線上にあるとき前進する
           if(SENSOR_1<40)
           {
              OnRev(OUT_C);
              
           }else{
                   OnFwd(OUT_C);  //センサ1が黒線上をはずれると左折
                }
           
           if(SENSOR_3<40)
           {
              OnRev(OUT_A);
                     
           }else{
                   OnFwd(OUT_A);  //センサ2が黒線上をはずれると右折
                }
      }
  }

*&size(25){パターン2}; [#y21254fc]
モータを1つ、光センサを1つ使用しました。
#ref(dscn2320_Medium.jpg)
右折と左折を繰り返しながら前進中です。後ろのタイヤは引きずられるのでゴムを付けていません。

#ref(dscn2322_Medium.jpg)
おっと。ここから先は企業秘密ですぜ旦那。(まだ製作中のグループもあるからね。)

モータ1つでは右折と左折のジグザグ走行で動きます。
 //    作成者:山崎 畠山
 //    作成日:2005-11-28
 
 #define THRESHOLD 40
 
 task main ()
 {
    SetSensor(SENSOR_1, SENSOR_LIGHT);
    while (true) {
            OnFwd(OUT_A); //左折します。
            ClearTimer (0);
            until ((SENSOR_1 > THRESHOLD) && (Timer(0)>5));//ラインからはみでて、左折開始から0.5秒後まで
            OnRev (OUT_A); //右折します。
            ClearTimer (0);
            until ((SENSOR_1 < THRESHOLD) && (Timer(0)>5));//ラインに戻り、右折開始から0.5秒後まで
    }
 }
*&size(25){パターン3}; [#j599fd00]
モータを2つ、光センサを1つ使用しました。高速に移動できるようなプログラムを考えてみました。
 //    作成者:山崎 畠山
 //    作成日:2005-11-28
 int i; //どのサブルーチンを行うかを決める変数です。
 
 //右折から試すサブルーチン(i==0のとき)
 sub right_first()
 {
 while (i==0) {
              OnFwd(OUT_A+OUT_C);//前進
                   
              if (SENSOR_2 > 40){ //ラインから外れたら
                                       
                       ClearTimer(0);//右折時間を計るタイマースタート
                                       
                       OnFwd(OUT_C);
                       OnRev(OUT_A);//右折
                       until((SENSOR_2 < 40) || ((Timer(0)>2) && (SENSOR_2 > 40)));
                       //センサーがラインに戻る または 0.2秒してもラインに戻らないと右折終了
                                       
                       if ((Timer(0)>2) && (SENSOR_2 > 40)){  
                                                            //0.2秒してもラインに戻らないときは
                                                            ClearTimer(0);
                                                            OnFwd(OUT_A);
                                                            OnRev(OUT_C);//左折
                                                            until((SENSOR_2 < 40) || ((Timer(0)>4) && (SENSOR_2 > 40)));
                                                            i=1;
                                                            
                                                            if ((Timer(0)>4) && (SENSOR_2 > 40)){
                                                            //0.4秒してもラインに戻らないときは
                                                            OnFwd(OUT_C);
                                                            OnRev(OUT_A);//再び右折
                                                            until(SENSOR_2 < 40);
                                                            i=0;}
                                                                           }
                                                          } 
                         
                               } 
             }
 
 //左折から試すサブルーチン(i==1のとき)
 sub left_first()
 { 
 while (i==1) {
              OnFwd(OUT_A+OUT_C);//前進
                   
              if (SENSOR_2 > 40){ //ラインから外れたら
                                       
                       ClearTimer(0);//左折時間を計るタイマースタート
                                       
                       OnFwd(OUT_A);
                       OnRev(OUT_C);//左折
                       until((SENSOR_2 < 40) || ((Timer(0)>2) && (SENSOR_2 > 40)));
                       //センサーがラインに戻る または 0.2秒してもラインに戻らないと左折終了
                                       
                       if ((Timer(0)>2) && (SENSOR_2 > 40)){  
                                                            //0.2秒してもラインに戻らないときは
                                                            ClearTimer(0);
                                                            OnFwd(OUT_C);
                                                            OnRev(OUT_A);//右折
                                                            until((SENSOR_2 < 40) || ((Timer(0)>4) && (SENSOR_2 > 40)));
                                                            i=0;
                                                            
                                                            if ((Timer(0)>4) && (SENSOR_2 > 40)){
                                                            //0.4秒してもラインに戻らないときは
                                                            OnFwd(OUT_A);
                                                            OnRev(OUT_C);//再び左折
                                                            until(SENSOR_2 < 40);
                                                            i=1;}
                                                                           }
                                                           } 
                         
              } 
 }
            
 task main ()
 {
   i = 0;
   SetSensor(SENSOR_2, SENSOR_LIGHT);
 
   while (true){
                 right_first();//右折から試すサブルーチンをします。
                 left_first();();//左折から試すサブルーチンをします。
               }
 }
このプログラムはわかりづらいので、だいたいの流れをまとめてみました。(実際は精度をよくするため、どちらに曲がるか決定する作業を右、左、また右と、曲がれないときは3回試します。)
#ref(説明.jpg)
-カーブでは連続で右折または左折の一方を行います。そこで、一度右折(左折)すると次も右折(左折)から試すようにし、右、左どちらのカーブも高速で曲がれるようにしました。
*&size(25){難しかった点}; [#b0c538f1]
-モータ1つでの移動方法を考えるのが苦労した。
-ギアが多くなり、ギア比を考えるのが大変だった。
*&size(25){工夫した点}; [#fba1df2f]
-モータ1つでのプログラムは0.5秒以上ずつタイヤが動くので確実に前進できます。
-センサー1つのときでも、左右どちらのカーブも速く曲がれるようプログラムしました。
*&size(25){反省点}; [#e33ec352]
-パターン1の場合において、急なカーブを曲がるときに曲がりきることはできるが無駄な動きが多かった。
-モーター1つで動くロボットにおいて、モーターからの動力を受けないタイヤのゴムが摩擦をうみ動力が弱まった。
-ギアの都合上タイヤの位置が左右でずれてしまった。
*&size(25){感想}; [#sc3bfd89]
-苦労した甲斐があって課題が早く済みました。
-すべて順調です。
*&size(20){コメントはこちらまで}; [#a5cd97d1]
-タイマを有効に活用していますね。あと、どうでもいいコメントで申し訳ありませんが、最初に左折するサブルーチンの名前は left_fast より left_first のほうがいいかも。 -- [[松本(教員)]] &new{2005-11-30 (水) 09:47:20};
-しまったぁぁぁ!!すぐ直します。 -- [[山崎]] &new{2005-11-30 (水) 17:10:48};
-素晴らしい!!プログラムだけでなく、このページ全体が他人からも理解しやすいように工夫されていますね。 -- [[かとりーぬ(TA)]] &new{2005-12-09 (金) 18:54:28};

#comment
[[戻る>2005/C6]]
RIGHT:
tya&counter(today);
&counter(yesterday);
&counter(all);
//11月28より

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