[[2015b/Member]]

目次
#contents
*課題内容 [#kfaf69dd]
#ref(./2015b-mission2.png,65%,ロボット全体図)
 課題は上図の黒線にそって動くライントレースロボットを制作するというものです。ライントレースをする際には、光センサを1つ用います。

 A地点またはB地点からスタートし、ライントレースしていきます。私は、A地点からスタートすることにしました。 ここで条件があり、A地点→P直進→Q直進→Q右折→P右折→Q左折→P左折→B地点というような動きをするロボットにしなければなりません。また、P地点,Q地点は交差点と判断し、そこで1秒間停止してから、次の行動に移るようにしなければなりません。そして、なるべく早く動くロボットするというのが条件になります。

*ライントレースとは? [#he44cd7b]
 ライントレースとは、床面に描かれた線をロボットがセンサで読み取り、線に沿って動くことを言います。

*ライントレースロボット [#of50aded]
**ロボット全体図 [#ya86efcb]
#ref(./DSC_0221.JPG,40%,ロボット全体図)
 上の写真のものが、今回の課題で制作したライントレースロボットの全体像になります。特徴として、急なカーブも曲がり切り、小回りが利くよう車体を小さくしています。

**光センサについて [#icca71bd]
#ref(./DSC_0222.JPG,40%,センサ位置)
 上の写真の赤丸で囲ってあるものが光センサになります。光センサは、ライントレースする際に白か黒(明暗)かの判断をするためにあります。このロボットは光センサとモーターを近くにしてます。そうすることで、光センサの判断がされてからすぐにモーターが動き、誤動作が少なくなると考えたからです。

*ライントレースをする方法[#gb308690]
 ロボットが走行するために、モーターを2つ使用しています。それぞれが独立して動作するので、直進や回転させることができます。端子Aに接続しているモーターを左、端子Cに接続しているモーターを右とします。

 今回のライントレースは光センサが1つだけということもあり、黒線に沿って動くよりも、白と黒の中間に沿って動くロボットの方が効率が良いので、そのように動くようにしました。

**基本動作 [#a7686e7d]
 基本となるライントレース中のロボットの動作は、光センサが白,黒のどちらかを認識した際に、モーターのパワー,回転方向を変え、常に白と黒の中間を走行するようになっています。私は、最も白い,少し白い,中間色(閾値),少し黒い,最も黒いというように、5段階に分けて判断するようにしました。

**交差点の判断 [#jec4bdca]
今回の課題で最も難関となるのが、交差点の判断です。
**コースの道順 [#k16928ad]
 課題のコースをうまく走行するために、通常のライントレースを2パターンに分けました。

 A地点からP地点右折までのライントレース(右側走行)
#ref(./line_trace1.png,50%,道順1)
 上図の赤線が1つ目に行うライントレースの道順です。

 このライントレースでの、光センサの白黒の判断に対するモーターの動きは、・最も白いとき→左回転・少し白いとき→左のモーターを止め、右のモーターのみを前進させる・中間色→直進運動・少し黒いとき→右のモーターを止め、左のモーターのみを前進させる・最も黒いとき→右回転となっています。

 この動きを続けることで、交差点を直進することを除き、課題の通りにライントレースします。交差点での直進は、通常のライントレースをするプログラムとは別に、光センサの白黒の判断なしに直進することで乗り越えています。

 P地点右折からB地点までのライントレース(左側走行)
#ref(./line_trace2.png,45%,道順1)
 上図の青線が2つ目に行うライントレースの道順です。

 このライントレースでの、光センサの白黒の判断に対するモーターの動きは、・最も白いとき→右回転・少し白いとき→右のモーターを止め、左のモーターのみを前進させる・中間色→直進運動・少し黒いとき→左のモーターを止め、右のモーターのみを前進させる・最も黒いとき→左回転となっています。

 2パターンに分けた理由は、上図ので橙色の丸の部分をトレースしないようにするためです。その点をトレースした際に誤って交差点と判断してしまうことが多くあったため、A地点からB地点まで、右側走行を続けるのではなく、左側走行もするようにしました。
 

*プログラム [#d4fb4ffe]
**定義 [#hac9f964]
閾値
 #define THRESHOLD 39
A地点からスタートする動作
 #define START SetPower(OUT_A,7);SetPower(OUT_C,7);OnFwd(OUT_AC);Wait(120);
ライントレース中の直進運動
 #define ST SetPower(OUT_A,5);SetPower(OUT_C,5);Off(OUT_AC);OnFwd(OUT_AC);Wait(1);
A地点からP地点右折までの左右運動
 #define TR SetPower(OUT_A,1);SetPower(OUT_C,1);Off(OUT_AC);OnFwd(OUT_A);Wait(1);OnRev(OUT_C);Wait(1);
 #define TL SetPower(OUT_A,2);SetPower(OUT_C,2);Off(OUT_AC);OnFwd(OUT_C);Wait(1);OnRev(OUT_A);Wait(1);
 #define TRL SetPower(OUT_A,1);Off(OUT_AC);OnFwd(OUT_A);Wait(1);
 #define TLL SetPower(OUT_C,2);Off(OUT_AC);OnFwd(OUT_C);Wait(1);
P地点右折からB地点までの左右運動
 #define TR2 SetPower(OUT_A,2);SetPower(OUT_C,2);Off(OUT_AC);OnFwd(OUT_A);Wait(1);OnRev(OUT_C);Wait(1);
 #define TL2 SetPower(OUT_A,1);SetPower(OUT_C,1);Off(OUT_AC);OnFwd(OUT_C);Wait(1);OnRev(OUT_A);Wait(1);
 define TRL2 SetPower(OUT_A,1);Off(OUT_AC);OnFwd(OUT_A);Wait(1);
 #define TLL2 SetPower(OUT_A,1);Off(OUT_AC);OnFwd(OUT_C);Wait(1);
交差点を直進
 #define PQ_ST SetPower(OUT_A,2);SetPower(OUT_C,2);Off(OUT_AC);OnFwd(OUT_AC);Wait(30);
左回りに車体を動かす
 #define CCW SetPower(OUT_A,4);SetPower(OUT_C,4);Off(OUT_AC);OnFwd(OUT_C);Wait(11);OnRev(OUT_A);Wait(11);
B地点にゴールする動作
 #define GOAL SetPower(OUT_AC,4);Off(OUT_AC);OnFwd(OUT_A);Wait(5);OnRev(OUT_C);Wait(5);OnFwd(OUT_AC);Wait(100);
ゴールした際に流れる音の定義
 #define Do 1047
 #define LaF 831
 #define SiF 932
 #define Si 988
交差点をカウントするための変数
 int c_point;
**サブルーチン [#h824e03e]
交差点で停止し、カウントを1増やす
 sub crossing()
 {
     Off(OUT_AC);
     Wait(100);
     c_point+=1;
 }
音を流す
 sub music()
 {
     PlayTone(Do,20);
     Wait(30);
     PlayTone(Do,20);
     Wait(30);
     PlayTone(Do,20);
     Wait(30);
     PlayTone(Do,60);
     Wait(62);
     PlayTone(LaF,60);
     Wait(62);
     PlayTone(SiF,60);
     Wait(62);
     PlayTone(Do,20);
     Wait(42);
     PlayTone(Si,20);
     Wait(22);
     PlayTone(Do,90);
     Wait(92);
 }       
**メインルーチン [#la66f077]
交差点で止まることで、カウンター(初期値0)が1足されていきます。カウンターの数で今いる交差点がどこであるか把握できるので、その交差点ですべき行動をif文を使ってあらかじめプログラムしています。

Timer(0)…交差点を判断するためのもの
Timer(1)…走行時間を計るためのもの
 task main ()
 {  
    SetSensor(SENSOR_2,SENSOR_LIGHT);
    
    START;
    
    ClearTimer(0);
    
    ClearTimer(1);
    
    c_point=0;
    
    while (true)
    {
		  while((FastTimer(0)<10)&&(c_point<=3))
		  {
		     if(SENSOR_2>THRESHOLD+8)
		      {
		              TL;
		              ClearTimer(0);
		      }        
		     else if(SENSOR_2>THRESHOLD+7)
		      {
		              TLL;
		              ClearTimer(0);
		      }
		     else if(SENSOR_2>THRESHOLD)
		      {
		              ST;
		              ClearTimer(0);
		      }
		     else if(SENSOR_2>THRESHOLD-2)
		      { 
		              TRL;
		              ClearTimer(0);
		      }
		     else
		      {     
		              TR;
		      }
		  }
    
					    while((FastTimer(0)<10)&&(c_point>=4))
					    {
					        if(SENSOR_2>THRESHOLD+8)
					         {
					                 TR2;
					                 ClearTimer(0);
					         }        
					        else if(SENSOR_2>THRESHOLD+7)
					         {
					                 TRL2;
					                 ClearTimer(0);
					         }
					        else if(SENSOR_2>THRESHOLD)
					         {
					                 ST;
					                 ClearTimer(0);
					         }
					        else if(SENSOR_2>THRESHOLD-2)
					         { 
					                 TLL2;
					                 ClearTimer(0);
					         }
					        else
					         {     
					                 TL2;
					         }
					     }
     
										     if((FastTimer(1)>1400)&&(c_point==0))
										      {
										       crossing();
										       PQ_ST;
										       ClearTimer(0);
										      }
										       else
										        {
										            ClearTimer(0);
										        }
										      
										     if((FastTimer(1)>2100)&&(c_point==1))
										      {
										         crossing();
										         CCW;
										         PQ_ST;
										         ClearTimer(0);
										      }
										        
										     if((FastTimer(1)>2800)&&(c_point==2))
										      {
										        crossing();
										        ClearTimer(0);
										        ClearTimer(1);
										      }
										     
										     if((FastTimer(1)>500)&&(c_point==3))
										      {
										         crossing();
										         PQ_ST;
										         ClearTimer(0);
										         ClearTimer(1);
										      }
										      
										     if((FastTimer(1)>2060)&&(c_point==4))
										      {
										         crossing();
										         ClearTimer(0);
										         ClearTimer(1);
										      }
										      
										     if((FastTimer(1)>500)&&(c_point==5))
										      {
										        crossing();
										        ClearTimer(0);
										      }
										      
										     if((FastTimer(1)>1300)&&(c_point==6))
										      {
										        crossing();
										        GOAL;
										        Off(OUT_AC);
										        Wait(50);
										        music();
										        Off(OUT_AC);
										        Wait(10000);
										      }       
   }
 }
*反省・感想 [#c72d73f0]

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