目次
#contents

*課題2:黒い線上を動くロボット [#s2a9e895]
次のような周回コース(黒い線)を動くロボットを作成せよ。

-通常の交差点が2箇所以上ある
-ロータリー型の交差点が1箇所以上ある (ロータリーでは反時計まわりに進む)
-直角に曲がるコーナーおよびそのコーナーをショートカットするコース(点線)が存在する
-急なヘアピンカーブが1箇所以上ある
-スタート地点に目印がある
-黒い線の幅は15〜20mm程度

センサー、モーターはいくつ使ってもよい。プログラムは次の2つを作成すること。

 1. 直角のコーナーを通る
 2. 直角のコーナーを通らない(近道する)

ただし互いに逆方向に周回すること。

*メンバー紹介 [#qf933802]
-イシイ(近道担当)
-ゆきち(直角コーナー担当)

*課題 [#q735ffe3]
**コースについて [#e3f78d38]
#ref(course.jpg)
-イシイのコース
#ref(course_ishii.jpg)
-ゆきちのコース
#ref(course_yukichi.JPG)
**ロボットについて [#ic2a75be]
**問題点について [#t0bab1b1]

*プログラム [#o770212f]
**イシイ [#d645274a]
 #define go(t) OnFwd(OUT_A+OUT_C);Wait(t);Off(OUT_A+OUT_C);             //直進
 #define turn_r(t) OnFwd(OUT_A);OnRev(OUT_C);Wait(t);Off(OUT_A+OUT_C);  //右旋回
 #define turn_l(t) OnFwd(OUT_C);OnRev(OUT_A);Wait(t);Off(OUT_A+OUT_C);  //左旋回
 #define THRESHOLD 45                                                   //閾値
 
 task main()
 {
   SetSensor(SENSOR_1,SENSOR_LIGHT);
   SetSensor(SENSOR_3,SENSOR_LIGHT);
  
   ClearTimer(0);
   while(FastTimer(0)<=500)
   ClearTimer(0);                     //タイマーをリセット
   while(FastTimer(0)<=500)           //5秒後まで繰り返し
   {
     OnFwd(OUT_A+OUT_C);
     if(SENSOR_1<THRESHOLD)
     {
       turn_l(10);
       turn_l(10);                    //センサー1が反応したら0.1秒左旋回
     }
     if(SENSOR_3<THRESHOLD)
     {
       go(20);
       go(20);                        //センサー3が反応したら0.2秒直進
     }
   }
   ClearTimer(0);
   while(FastTimer(0)<=800)
   ClearTimer(0);                     //タイマーをリセット
   while(FastTimer(0)<=800)           //8秒後まで繰り返し
   {
     OnFwd(OUT_A+OUT_C);
     if(SENSOR_3<THRESHOLD)
     {
       turn_r(10);
       turn_r(10);                    //センサー3が反応したら0.1秒右旋回
     }
     if(SENSOR_1<THRESHOLD)
     {
       go(20);
       go(20);                        //センサー1が反応したら0.2秒直進
     }
   }
   ClearTimer(0);
   while(FastTimer(0)<=150)
   ClearTimer(0);                     //タイマーをリセット
   while(FastTimer(0)<=150)           //1.5秒後まで繰り返し
   {
     OnFwd(OUT_A+OUT_C);
     if(SENSOR_3<THRESHOLD)
     {
       turn_r(10)
     }
     if(SENSOR_1<THRESHOLD)
     {
       go(50);
       turn_r(70);
     }
   }
   ClearTimer(0);
   while(FastTimer(0)<=350)
                                      //1回目のロータリー
   ClearTimer(0);                     //タイマーをリセット
   while(FastTimer(0)<=350)           //3.5秒後まで繰り返し
   {
     OnFwd(OUT_A+OUT_C);
     if(SENSOR_1<THRESHOLD)
     {
       turn_l(10)
       turn_l(10)                     //センサー1が反応したら0.1秒左旋回
     }
   }
   ClearTimer(0);
   while(FastTimer(0)<=250)
   ClearTimer(0);                     //タイマーをリセット
   while(FastTimer(0)<=250)           //2.5秒後まで繰り返し
   {
     OnFwd(OUT_A+OUT_C);
     if(SENSOR_1<THRESHOLD)
     {
       turn_l(10);
       turn_l(10);                    //センサー1が反応したら0.1秒左旋回
     }
     if(SENSOR_3<THRESHOLD)
     {
       go(50)
       turn_r(60);
       turn_r(60);                    //センサー3が反応したら
     }
   }
   ClearTimer(0);
   while(FastTimer(0)<=550)
   ClearTimer(0);                     //タイマーをリセット
   while(FastTimer(0)<=550)           //5.5秒後まで繰り返し
   {
     OnFwd(OUT_A+OUT_C);
     if(SENSOR_3<THRESHOLD)
     {
       turn_r(20);
     }
   }
   ClearTimer(0);
   while(FastTimer(0)<=300)
   ClearTimer(0);                     //タイマーをリセット
   while(FastTimer(0)<=300)           //3秒後まで繰り返し
   {
     OnFwd(OUT_A+OUT_C);
     if(SENSOR_3<=THRESHOLD)
     {
       turn_r(10);
     }
     if(SENSOR_1<=THRESHOLD)
     {
       go(50);
       turn_r(80);
     }
   }
   ClearTimer(0);
   while(FastTimer(0)<=350)
   ClearTimer(0);                     //タイマーをリセット
   while(FastTimer(0)<=350)           //3.5秒後まで繰り返し
   {
     OnFwd(OUT_A+OUT_C);
     if(SENSOR_1<THRESHOLD)
     {
       turn_l(10)
     }
   }
   ClearTimer(0);
   while(FastTimer(0)<=250)
   ClearTimer(0);                     //タイマーをリセット
   while(FastTimer(0)<=250)           //2.5秒後まで繰り返し
   {
     OnFwd(OUT_A+OUT_C);
     if(SENSOR_1<THRESHOLD)
     {
       turn_l(10);
     }
     if(SENSOR_3<THRESHOLD)
     {
       go(50)
       turn_r(100);
     }
   }
   ClearTimer(0);
   while(FastTimer(0)<=400)
   ClearTimer(0);                     //タイマーをリセット
   while(FastTimer(0)<=400)           //4秒後まで繰り返し
   {
     OnFwd(OUT_A+OUT_C);
     if(SENSOR_3<=THRESHOLD)
     {
       turn_r(10);
     }
     if(SENSOR_1<=THRESHOLD)
     {
       go(25);
       OnFwd(OUT_A);
       Wait(20);
       Off(OUT_A);
     }
   }
   ClearTimer(0);
   while(FastTimer(0)<=600)
   ClearTimer(0);                     //タイマーをリセット
   while(FastTimer(0)<=600)           //6秒後まで繰り返し
   {
     OnFwd(OUT_A+OUT_C);
     if(SENSOR_3<=THRESHOLD)
     {
       OnRev(OUT_A+OUT_C);
       Wait(10);
       Off(OUT_A+OUT_C);
       turn_r(20);
     }
   }
   ClearTimer(0);
   while(FastTimer(0)<=400)
   ClearTimer(0);                     //タイマーをリセット
   while(FastTimer(0)<=400)           //4秒後まで繰り返し
   {
     OnFwd(OUT_A+OUT_C);
     if(SENSOR_1<THRESHOLD)
     {
       turn_l(10);
     }
     if(SENSOR_3<THRESHOLD)
     {
       go(25);
     }
   }
   while(SENSOR_3<THRESHOLD)
   while(SENSOR_3<THRESHOLD)          //センサー3が反応するまで繰り返し
   {
     OnFwd(OUT_A+OUT_C);
     if(SENSOR_1<THRESHOLD)
     {
       turn_l(10);
     }
   }
   Off(OUT_A+OUT_C);
 } 


**ゆきち [#i0f9386d]
 #define GO(t) OnFwd(OUT_A+OUT_C);Wait(t);Off(OUT_A+OUT_C); //前にt秒進む
 #define THRESHOLD 45  //閾値
 #define THRESHOLD 45  //明かりを判定する基準値。
 
 
 sub RIGHT_CURVE()
   {
         if (SENSOR_3>THRESHOLD)
 sub RIGHT_CURVE()              //コースが右にカーブしているときのプログラム
   {                  //右側のセンサー3のみを考慮します。
         if (SENSOR_3>THRESHOLD)//センサーに反応がなければ直進。
           {
             OnFwd(OUT_A+OUT_C);
           }
         if (SENSOR_3<THRESHOLD)
         if (SENSOR_3<THRESHOLD)//センサーに反応があれば、右にカーブします。
           {
             Off(OUT_C);
             OnFwd(OUT_A);
           }
    }
 sub LEFT_CURVE()
   {
         if (SENSOR_1>THRESHOLD)
 sub LEFT_CURVE()               //コースが左にカーブしているときのプログラム
   {                  //左側のセンサー1のみを考慮します。
         if (SENSOR_1>THRESHOLD)//センサーに反応がなければ直進。
           {
             OnFwd(OUT_A+OUT_C);
           }
         if (SENSOR_1<THRESHOLD)
         if (SENSOR_1<THRESHOLD)//センサーに反応があれば、左にカーブします。
           {
             Off(OUT_A);
             OnFwd(OUT_C);
           }
   }
 
 sub ROTARY()                //ロータリーのプログラム。
  {                       //ロータリーに入った時点から、このプログラムを使用します。
    GO(35);
    OnFwd(OUT_A);OnRev(OUT_C);Wait(20)//ロボットの回転の中心がロータリーの黒線上に来るように移動。
    
   while(SENSOR_1>THRESHOLD)          
      {
    OnFwd(OUT_A);
    OnRev(OUT_C);
          } 
     Off(OUT_A+OUT_C);                 
 
     OnFwd(OUT_A+OUT_C);         //この時点で、ロータリーの黒線が二つのセンサーの間にあります。
 
     ClearTimer(0);
 
   while(FastTimer(0)<400)        //4秒という時間は、一つ目の分岐を通りすぎるのに十分な時間です。
     {
            LEFT_CURVE();              //その間、ロータリーを左カーブとみなすことができます。
     }
 
   while(SENSOR_3>THRESHOLD)       //4秒以降に3センサーが黒線を感知するとき、ロータリーの出口に達したことになります。
     {
             LEFT_CURVE();        //それまでは、ロータリーを左カーブとみなします。
     } 
 
    Off(OUT_A+OUT_C);GO(35);
    OnFwd(OUT_A);OnRev(OUT_C);Wait(20);//入ったときと同様に、ロボットの回転の中心がロータリーの黒線上にあるように移動します。
    
   while(SENSOR_1>THRESHOLD)
      {
    OnFwd(OUT_A);OnRev(OUT_C);
          }                    //この時点でロータリーの黒線は二つのセンサーの間にあります。
  }                           //ロータリーを抜けました。
 
 
 task main()
 {
     SetSensor(SENSOR_1,SENSOR_LIGHT);
     SetSensor(SENSOR_3,SENSOR_LIGHT);
     SetSensor(SENSOR_3,SENSOR_LIGHT);//センサー1、3を光センサーと定義。
 
     ClearTimer(0);
 
    while(FastTimer(0)<=330)
    while(FastTimer(0)<=330)      //最初はなだらかな右カーブ。
       {
          RIGHT_CURVE();
        }
 
    while(FastTimer(0)<=850)
    while(FastTimer(0)<=850)                  //ここは左の急カーブなので、別のプログラムを使います。
        {
         if ((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD))
           {
             OnFwd(OUT_A+OUT_C);
           }
         if ((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD))
         if ((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD)) //反対のタイヤを逆回転させることで、急カーブを回りきります。
           {
             OnRev(OUT_A);
             OnFwd(OUT_C);
           }
        }
 
    while(FastTimer(0)<=1100)
    while(FastTimer(0)<=1100)   //緩やかな左カーブ
       {
             LEFT_CURVE();
     }
 
   while(SENSOR_3>THRESHOLD)
   while(SENSOR_3>THRESHOLD)    //ロータリーまで、左カーブが続きます。
      {
            LEFT_CURVE();
          }
 
    Off(OUT_A+OUT_C);Wait(50);GO(35);
    OnFwd(OUT_A);OnRev(OUT_C);Wait(20);
    
   while(SENSOR_1>THRESHOLD)
      {
    OnFwd(OUT_A);
    OnRev(OUT_C);
          } 
     Off(OUT_A+OUT_C);
    Off(OUT_A+OUT_C);        //ロータリー入り口で停止。
 
     OnFwd(OUT_A+OUT_C);
   while(SENSOR_3>THRESHOLD)
     {
            LEFT_CURVE();
     }
    ROTARY;
 
   Off(OUT_A);OnFwd(OUT_C);Wait(15);
 
   while(SENSOR_3>THRESHOLD)
     {
             LEFT_CURVE();
     } 
 
    Off(OUT_A+OUT_C);Wait(50);GO(35);
    OnFwd(OUT_A);OnRev(OUT_C);Wait(20);
    
   while(SENSOR_1>THRESHOLD)
      {
    OnFwd(OUT_A);OnRev(OUT_C);
          } 
 
    ClearTimer(0);
 
   while(FastTimer(0)<300)
     {
        LEFT_CURVE();
     }
 
   GO(50);
   GO(50);               //近道を無視します。
 
   while(FastTimer(0)<700||SENSOR_1>THRESHOLD||SENSOR_3>THRESHOLD)
     {
   while(FastTimer(0)<700||SENSOR_1>THRESHOLD||SENSOR_3>THRESHOLD)//直角カーブを回るため、急カーブのときと同じプログラムを使用。
     {                                      //ロータリーを感知するまでこのプログラムを継続します。
        if ((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD))
          {
            OnFwd(OUT_A+OUT_C);
          }
        if ((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD))
          {
            OnRev(OUT_A);
            OnFwd(OUT_C);
          }
    }
 
    Off(OUT_A+OUT_C);Wait(50);GO(35);
    OnFwd(OUT_A);OnRev(OUT_C);Wait(20);
    
   while(SENSOR_1>THRESHOLD)
      {
    OnFwd(OUT_A);
    OnRev(OUT_C);
          } 
     Off(OUT_A+OUT_C);
    Off(OUT_A+OUT_C);           //ロータリー入り口。
 
     OnFwd(OUT_A+OUT_C);
   while(SENSOR_3>THRESHOLD)
     {
            LEFT_CURVE();
     }
    ROTARY;
 
   Off(OUT_A);OnFwd(OUT_C);Wait(15);
    ClearTimer(0);
 
   while(SENSOR_3>THRESHOLD)
     {
             LEFT_CURVE();
     } 
 
    Off(OUT_A+OUT_C);Wait(50);GO(35);
    OnFwd(OUT_A);OnRev(OUT_C);Wait(20);
    
   while(SENSOR_1>THRESHOLD)
      {
    OnFwd(OUT_A);OnRev(OUT_C);
          } 
 
 
    OnFwd(OUT_A+OUT_C);
 
     ClearTimer(0);
 
   while(SENSOR_1>THRESHOLD||SENSOR_3>THRESHOLD)
     {
            LEFT_CURVE();    
     }
 
   GO(15);
   GO(15);                 //交差点を無視して進みます。
 
   while(SENSOR_1>THRESHOLD||SENSOR_3>THRESHOLD)
     {
            LEFT_CURVE();    
     }
 
   GO(10);
   GO(10);                       //交差点を無視。
 
   while(SENSOR_1>THRESHOLD||SENSOR_3>THRESHOLD)
   while(SENSOR_1>THRESHOLD||SENSOR_3>THRESHOLD)//「どちらかが白である間、継続」つまり「ゴールの黒線を感知するまで継続」
     {
        if ((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD))
       Off(OUT_A);OnFwd(OUT_C);   {
        {
            OnFwd(OUT_A+OUT_C);
          }
        if ((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD))
          {
            OnRev(OUT_A);OnFwd(OUT_C);
          } 
        if ((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD))
          {
            OnRev(OUT_C);OnFwd(OUT_A);
          } 
     } 
   Off(OUT_A+OUT_C);
     }
 
   Off(OUT_A+OUT_C);      //ゴール
 }

*感想 [#m39f9cd2]
-イシイ~
タイマーを上手く利用して動かすことができたが、時間の調整がとても大変だった。
-ゆきち~


*コメントをどうぞ [#d155cfe7]
*コメントをお願いします [#d155cfe7]
#comment


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS