[[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]
 今回の課題で最も難関となるのが、交差点の判断です。私は、光センサが黒を連続で認識し続けた時間で交差点と判断しました。判断する時間は0.1秒より大きい値としました。しかし、この時間では走行途中、特にカーブでも交差点と判断してしまいます。これを避けるためには、判断する時間を延ばすことが挙げられますが、時間を延ばしてしまうと、交差点で止まる際に車体が斜めに傾いた状態で止まってしまいます。これはあまり好ましくないと思ったので、ライントレースの走行時間も併せて、交差点の判断に使いました。そうすることで、カーブの途中で止まることなく、ライントレースすることができます。

**コースの道順 [#k16928ad]
 課題のコースをうまく走行するために、通常のライントレースを2パターンに分けました。

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

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

 この動きを続けることで、交差点を直進することを除き、課題の通りにライントレースすることができます。交差点での直進は、その場から0.3秒間前進することで、実現しています。

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

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

 この動きを続けることで、課題の通りにライントレースすることができます。

 2パターンに分けた理由は、上図ので橙色の丸の部分をトレースした際に、誤って交差点と判断してしまうことがあり、右側走行が難しかったからです。そういう事なので、スタートから左側走行にすれば良いと考えると思いますが、Q地点右折が上手くいかないということから、始めは右側走行、P地点右折後には左側走行というふうにしました。

*プログラム [#d4fb4ffe]
**マクロ定義 [#hac9f964]
〇閾値
 #define THRESHOLD 39
〇A地点からスタートする動作・・・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増やす・・・課題の条件にある交差点で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]
 このプログラムでは、主にwhile文とif文を使っています。

 ライントレース中の動きはwhile文を使っています。条件式は、交差点を判断するタイマーかつ交差点の通過回数で、2つの条件式を同時に満たしているときには、ライントレースを行い、2つの条件のどちらかを満たさない場合、交差点に差し掛かったと判断します。

 交差点での動きはif文を使っています。条件式は、走行時間かつ交差点の通過回数で、2つの条件を同時に満たした時、その交差点ですべき動作を行います。交差点で停止する度に、カウンター(初期値0)が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)) //A地点からP地点右折前までのライントレース
		  {
		     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)) //P地点右折後からB地点までのライントレース
					    {
					        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)) //P地点直進
										      {
										       crossing();
										       PQ_ST;
										       ClearTimer(0);
										      }
										       else
										        {
										            ClearTimer(0);
										        }
										      
										     if((FastTimer(1)>2100)&&(c_point==1)) //Q地点直進
										      {
										         crossing();
										         CCW;
										         PQ_ST;
										         ClearTimer(0);
										      }
										        
										     if((FastTimer(1)>2800)&&(c_point==2)) //Q地点右折
										      {
										        crossing();
										        ClearTimer(0);
										        ClearTimer(1);
										      }
										     
										     if((FastTimer(1)>500)&&(c_point==3)) //P地点右折
										      {
										         crossing();
										         PQ_ST;
										         ClearTimer(0);
										         ClearTimer(1);
										      }
										      
										     if((FastTimer(1)>2300)&&(c_point==4)) //Q地点左折
										      {
										         crossing();
										         ClearTimer(0);
										         ClearTimer(1);
										      }
										      
										     if((FastTimer(1)>500)&&(c_point==5)) //P地点左折
										      {
										        crossing();
										        ClearTimer(0);
										      }
										      
										     if((FastTimer(1)>1300)&&(c_point==6)) //B地点
										      {
										        crossing();
										        GOAL;
										        Off(OUT_AC);
										        Wait(50);
										        music();
										        Off(OUT_AC);
										        Wait(10000);
										      }       
   }
 }
*結果・課題点 [#ja36522e]
 課題の通りにライントレースすることはできました。ですが、直進やカーブをする際に車体がジグザグに進んでいて、不格好に見えました。このような無駄な動きが多くあり、早くゴールすることは難しかったです。直進やカーブを滑らかに走行することが、今回の課題であると思います。これを解決するには、5段階に分けたライントレースをより細かく設定することや、モーターのパワーをカーブに合うように設定することが考えられます。
*反省・感想 [#c72d73f0]
今回の課題はプログラムを考えることが、非常に難しかったと思います。課題に取り掛かかり始めたころは、通常のライントレースすることすら、ままならない状態で混乱していました。そういった問題をチームの人と考え、解決していくことで、徐々にプログラムを完成させていきました。チームメンバーがいなければ、今回の課題は達成できていなかったと思います。
 今回の課題はプログラムを考えることが、非常に難しかったと思います。課題に取り掛かかり始めたころは、通常のライントレースすることすら、ままならない状態で混乱していました。そういった問題をチームの人と考え、解決していくことで、徐々にプログラムを完成させていきました。チームメンバーがいなければ、今回の課題は達成できていなかったと思います。

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