*課題2〜ライントレースロボット〜 [#f4eb807a]

目次
#contents

**ルール [#r3e8ddea]
黒い線のコースを1周半してゴールに到達したときに停止する。

**コース説明 [#zcae88b2]
-交差点:2箇所
-直角カーブ(クランク):1箇所
-ヘアピンカーブ:1箇所
-線の太さは15〜20mm(場所によって太さが異なる)

//写真
  &ref(2012a/A3/Hexa/M2/コース.jpg,50%,コース);

**車体 [#x4ecb3f0]
 車体はセンサ部分以外は説明書どうりに組み立ました。

//写真
  &ref(2012a/A3/Hexa/M2/車体.JPG,30%,車体);

**プログラム [#x68327c0]
***ライントレースの仕組み [#cc6b52e6]
 私の車体はセンサを1つしか使っていないので白と黒の境界をトレースする感じでプログラムを作成しました。

�.札鵐気�白に反応しているとき

  &ref(2012a/A3/Hexa/M2/白のとき.jpg,50%,センサ反応��);

 丸い赤いやつをセンサだとするとセンサが白に反応しているとき、黒いラインにセンサが反応するまで左のタイヤを正回転させ右タイヤを停止させます。

�▲札鵐気�黒に反応しているとき

  &ref(2012a/A3/Hexa/M2/黒のとき.jpg,50%,センサ反応��);

 センサが黒に反応したとき、白に反応するまで右タイヤを正回転させ左タイヤを停止させます。

このように�,鉢△魴�り返してトレースさせています。

***工夫した点 [#f56eb684]
-しきい値

 私は白のしきい値を「60」、黒のしきい値を「43」とし黒のしきい値を高く設定しました。黒のしきい値を高くした理由は、ラインの太さやコースの状況によってトレース状況が変わってしまい黒いラインを読み飛ばして進んでしまうという現象が出てしましました。それを防ぐために、黒のしきい値を高めにとっておくことで黒いラインを反応させやすくしました。また、白と黒のあいだ、つまり境界周辺をセンサが読み取ったら直進するというプログラムを書きました。

-直角カーブ(クランク)
 クランクをどう通過するか悩みました。クランクは通常のトレースで通過できるのですが動きに無駄がると思いました。そこで次のようにクランクの動作を4段階に分けました。

�ゞ覆�り角に来るまで

  &ref(2012a/A3/Hexa/M2/通常トレース.jpg,50%,通常トレース);

 境界が切れるまで通常トレースを行います。

��曲がり角を越えたら

  &ref(2012a/A3/Hexa/M2/境界が切れたら.jpg,50%,境界が切れたら);
  &ref(2012a/A3/Hexa/M2/境界が切れたとき.jpg,50%,境界が切れたら);

 境界が切れたら右のタイヤを停止させ、左のタイヤを正回転させて右旋回を行います。

��しばらく白色だったら

  &ref(2012a/A3/Hexa/M2/境界が切れたら2.jpg,50%,境界が切れたら2);
  &ref(2012a/A3/Hexa/M2/境界が切れたとき2.jpg,50%,境界が切れたら2);

 �△瞭虻遒鬚靴个蕕�(だいたい350ms前後)の間センサの反応が白を検知していたら右モータを逆回転させます。

�す�い線を検知するまで

  &ref(2012a/A3/Hexa/M2/フッキ.jpg,50%,フッキ);

 黒い線を検出するまで��の動作をし、黒い線を検出したら通常とレースをします。


-脱出方法

 脱出方法は、トレースする位置を変えることです。まず1周半してないときは�,里曚Δ鬟肇譟璽垢靴討い�ます。そして一周半したときゴールのT字路の直前でわざと黒いラインを飛び越えて�△里曚Δ妊肇譟璽垢靴謄粥璽襪妨�かう方法をとりました。また�△砲Δ弔辰浸�の駆動方法が黒いT字路を曲がりやすいように、黒いラインを「30ms」以上反応し続ける時は内側のタイヤを逆回転させて曲がる角度を直角に近いようにしました。

  &ref(2012a/A3/Hexa/M2/工夫.jpg,50%,コース);

***ソース [#vbca9525]
 /*------------------------------------------------------------
 		ライントレースロボット
 						2012/6/26
 						trace.nxc
 ------------------------------------------------------------*/
 
 /*-----------------------------------------------------------
 			定数
 ------------------------------------------------------------*/
 #define TH_B		43		//黒のしきい値
 #define TH_W		60		//白のしきい値
 
 #define DUTY		50		//PWMデューティ設定(%)
 
 #define T_TIM		480		//コースをトレースする時間(T秒×10)
 #define T2		1000		//コースからゴールへ行く時間(T秒×100)
 
 /*-----------------------------------------------------------
 			グローバル変数
 ------------------------------------------------------------*/
 int iNum1;			//LCDに表示するための値を入れる変数
 int iNum2;			//LCDに表示するための値を入れる変数
 int cnt1;			//時間換算のカウント
 
 
 /*-----------------------------------------------------------
 			サブ関数
 ------------------------------------------------------------*/
 //LCD表示用関数
 task put_lcd()
 {
 	NumOut(0,LCD_LINE1,iNum1);			//センサ値表示
 	NumOut(0,LCD_LINE2,iNum2);			//時間表示
 	Wait(1000);					//1000ms待つ
 	ResetScreen();					//LCDクリア
 	Wait(100);					//100ms待つ
 }
 
 //コースをトレースするときのモータ出力関数1
 void trace(int sens)
 {
 	if(sens > TH_W){			//白に反応したら
 		OnFwd(OUT_C,DUTY);
 		Off(OUT_A);
 		cnt1++;
 		if(cnt1 > 70){			//白に反応してる時間が70を超えたら
 			OnRev(OUT_A,DUTY);
 		}
 	}
 	else if(sens < TH_B){			//黒に反応したら
 		OnFwd(OUT_A,DUTY);
 		Off(OUT_C);
 		cnt1 = 0;
 	}
 	else{					//白と黒の境界にきたら
 		OnFwdSync(OUT_AC,70,0);
 		cnt1 = 0;
 	}
 } 
 
 //コースを脱出するときのモータ出力関数2
 void trace2(int sens)
 {
 	if(sens > TH_W){		//白に反応したら
 		OnFwd(OUT_A,DUTY);
 		Off(OUT_C);
 		cnt1 = 0;
 	}
 	else{				//黒に反応したら
 		OnFwd(OUT_C,DUTY);
 		Off(OUT_A);
 		cnt1++;
 		if(cnt1 > 30){		//黒に反応してる時間が30を超えたら
 			OnRev(OUT_A,DUTY);
 		}
 	}
 	
 }
 	
 /*-----------------------------------------------------------
 			メイン関数
 ------------------------------------------------------------*/
 task main()
 {
 	long old_time1,time2=0;
 	/* センサの初期設定 */
 	SetSensor(SENSOR_1,SENSOR_LIGHT);
 	SetSensorLight(IN_1);
 	
 	old_time1 = CurrentTick();						//ここまでの時間を取得
 	
 	while(iNum2 <= T_TIM){
 		start put_lcd;							//LCD表示スタート
 		
 		iNum1 = SENSOR_1;						//センサ値代入
 		iNum2 = (CurrentTick() - old_time1)/100;			//時間計測
 				
 		trace(iNum1);							//モータ出力関数1
 		
 		Wait(5);							//センサの読み取り速度を調整(5ms)
 	}
 	
 	/* トレースする境界を変える(脱出モードへ) */
 	Off(OUT_AC);
 	Wait(100);
 	OnRev(OUT_A,DUTY);
 	Wait(100);
 	Off(OUT_AC);
 	Wait(100);
 	
 	/* コースを脱出する(脱出モード) */
 	while(time2 < (T2*10)){
 		iNum1 = SENSOR_1;		//センサ値代入
 		trace2(iNum1);			//モータ出力関数2
 		time2++;
 		Wait(1);			//センサ読み取り速度調整(1ms)
 	}
 	
 	
 	Off(OUT_AC);				//停止
 }
 
 
**動画 [#m944e6ca]
完走した動画がこちらです。

リンク:http://www.youtube.com/watch?v=K2CUb7D1okM 


**反省感想 [#wd3abcc4]
 今回の課題はラインをトレースするのにすごく時間がかかりました。特にこだわったのは黒と白のしきい値です。この値がちょっとでもずれてしまうとラインをトレースしなくなってしまします。一番難しかったのは1周半コースをトレースしたあとのゴール地点に行く動作でした。

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