[[2016b/Member]]

#contents

* 概要 [#a20e41ad]
今回の[[課題:http://yakushi.shinshu-u.ac.jp/robotics/?2016b%2FMission2]]はライントレースである.

"AからC"のコースと"BからD"のコースが選べるので,私は"AからC"のコースを選択した.

* ハードウェアについて [#d88ec1ce]
今回のローバーは,mindstorm付属のテキストに紹介されている基本的なローバーロボットを改良(小型化及び部品点数の削減)し,

- 光センサー
- ボール捕獲用アーム

をフロントにセットした.

NXT本体,ボール捕獲用アームがそれぞれタイヤ駆動用モーター,前輪上にあるので安定している.

** 光センサー [#g31ebbe2]
光センサーは紙面すれすれに設置することもできたが,紙面との間に隙間を設けたほうがより安定した動作をすることが判明したため,あえて紙面から離している.

黒線の,左側の境界をなぞっていくので,光センサーはフロント左側に設置した.

** ボール捕獲用アーム [#d15a2b06]
フロント部分にモーターユニットを設置する余裕がなかったので,最初はモーターをローバーの上部分に設置するつもりだったが,そうするとNXTを設置する場所がなくなってしまう.そこで,モーターを縦方向に設置した.重心が上がってしまうが,上記の通り前輪上に重心があるため特に問題はなかった.

むしろ,前輪のグリップ力が上がることで,他のチームにあった「駆動輪が浮いてしまう」現象をある程度防ぐことができたようである.

* ソフトウェアについて [#k387a557]

** ライントレース [#o5fd7a41]
今回は光センサーを"ひとつだけ"使用してライントレースを行う必要がある.そのため,黒線の左側の境界を利用する.

もしセンサーが"黒線上"と判断した時は,進行方向を左に修正する.一方センサーが"黒線上でない"と判断した時は,進行方向を右に修正する.センサーが"黒線との境界"と判断した時には直進する.

ただしこの方法では交差点を検出できない(左屈折と判断して左折してしまう).

** 交差点の判断 [#rf03b1a4]
しかし,光センサーが交差点を通過するとき,光センサーは一定時間以上"黒線上"と判断し続けるはずである.そこで,光センサーがX秒以上"黒線上"と判断し続けた場合に限って,カーブではなく交差点であると判断するようにする.

 /*
 OUT_A -> ハンドル制御
 OUT_B -> タイヤ(右)
 OUT_C -> タイヤ(左)
 SNS_4 -> 光センサー(ライントレース)
 */
 
 #define SPEED 30
 #define go_forward OnFwd(OUT_BC, SPEED);
 #define l_turn OnFwd(OUT_B, SPEED); Off(OUT_C);
 #define r_turn OnFwd(OUT_C, SPEED); Off(OUT_B);
 #define timer_r t0 = CurrentTick();
 
 //交差点直進
 sub CROSS_GO()
 {
 	RotateMotor(OUT_B, SPEED, -150);
 	go_forward; Wait(500);
 }
 
 //交差点右折
 sub CROSS_R()
 {
 	RotateMotor(OUT_B, SPEED, -300);
 	go_forward; Wait(900);
 }
 
 //ボールを捕獲
 sub BALLGET()
 {
 	go_forward; Wait(700);
 	Off(OUT_BC); Wait(500);
 	RotateMotor(OUT_A, SPEED, -50);
 	Off(OUT_ABC); Wait(500);
 }
 
 //ボールを射出
 sub BALLTHROW()
 {
 	RotateMotor(OUT_B, SPEED, -170);
 	RotateMotor(OUT_A, SPEED, 50);
 	Off(OUT_ABC); Wait(500);
 	OnFwd(OUT_BC, SPEED + 30); Wait(200); Off(OUT_BC);
 }
 
 task main()
 {
 	SetSensorLight(S4);
 
 	long t0 = CurrentTick();
 	//交差点を数える
 	int cross = 0;
 
 	while(cross <= 7)
 	{
 		if (CurrentTick() - t0 < 2000)
 		{
 			if(SENSOR_4 > 48)
 			{
 				r_turn; timer_r;
 			}
 			
 			else if(SENSOR_4 > 42)
 			{
 				go_forward; timer_r;
 			}
 			
 			else
 			{
 				l_turn;
 			}
 		}
 
 		//交差点とゴール
 		else
 		{
 			Off(OUT_BC); Wait(1000); 
 
 			if ((cross == 0) || (cross == 2) || (cross == 5))
 			{
 				/* 交差点を直進 */
 				CROSS_GO(); cross ++;
 			}
 
 			else if (cross == 1)
 			{
 				CROSS_GO(); BALLGET(); cross ++;
 			}
 
 			else if (cross == 3)
 			{
 				/* ヘアピンカーブ */
 				RotateMotor(OUT_B, SPEED, 100); cross ++;
 			}
 
 			else if ((cross == 4) || (cross == 6))
 			{
 				/* 交差点右折 */
 				CROSS_R(); cross ++;
 			}
 
 			else if (cross == 7)
 			{
 				/* ボール射出 */
 				BALLTHROW(); cross ++;
 			}
 
 			timer_r;
 		}
 	}
 }

以下に詳細を説明する.

** モーターとセンサーの説明 [#cabe6d7b]

 /*
 OUT_A -> ハンドル制御
 OUT_B -> タイヤ(右)
 OUT_C -> タイヤ(左)
 SNS_4 -> 光センサー(ライントレース)
 */

これは,それぞれのモーターの出力とセンサーの対応を示している(コメント).

** モーターのトルク,移動等の定義 [#m5248ead]

 #define SPEED 30
 #define go_forward OnFwd(OUT_BC, SPEED);
 #define l_turn OnFwd(OUT_B, SPEED); Off(OUT_C);
 #define r_turn OnFwd(OUT_C, SPEED); Off(OUT_B);
 #define timer_r t0 = CurrentTick();

- SPEEDはモーターのトルクの定義
- go_forwardは前進
- l_turnは進路を左方向に調整
- r_turnは進路を右方向に調整
- timer_rはタイマーをリセットする(交差点の判断に利用)

これ以外の複雑な動作(交差点の進行,ボールの捕獲・射出など)はsubroutineを利用した.

** 各種動作の定義 [#k08685fe]

 //交差点直進
 sub CROSS_GO()
 {
 	RotateMotor(OUT_B, SPEED, -150);
 	go_forward; Wait(500);
 }
 
 //交差点右折
 sub CROSS_R()
 {
 	RotateMotor(OUT_B, SPEED, -300);
 	go_forward; Wait(900);
 }
 
 //ボールを捕獲
 sub BALLGET()
 {
 	go_forward; Wait(700);
 	Off(OUT_BC); Wait(500);
 	RotateMotor(OUT_A, SPEED, -50);
 	Off(OUT_ABC); Wait(500);
 }
 
 //ボールを射出
 sub BALLTHROW()
 {
 	RotateMotor(OUT_B, SPEED, -170);
 	RotateMotor(OUT_A, SPEED, 50);
 	Off(OUT_ABC); Wait(500);
 	OnFwd(OUT_BC, SPEED + 30); Wait(200); Off(OUT_BC);
 }

*** 交差点直進・右折 [#w52bdcb4]
ライントレースを一旦中止し,進行方向を修正し,ある程度直進する.その後またライントレースを再開する.

*** ボールを捕獲・射出 [#p23e7d13]
ボールは交差点Qの10cm先にあるので,10cm進んでから,アームをおろす.
射出時は進行方向を修正し,アームをあげて,ローバーを急発進させ,その勢いでボールを射出する.

** task main() [#v84e643e]

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