#contents

* 相方 [#c9dd7a2a]

 gamigami

*ロボット本体の説明 [#k08fa481]
#ref(./IMG_1667.JPG,10%,ご尊顔)
今回作ったロボット。講義にて渡されたマニュアル通りに作ったドライブベースに少し手を加えた物だ。光センサーを付け、大きなタイヤを前輪としている。タイヤの前後を入れ替えたのはロボットの回転する軸を光センサーに近づける為である。

実は元々私が作っていたのは、ここから後輪を抜き光センサーを固定したものだった。しかし途中で
相方と同じ構造で走らせなければいけないと知り、泣く泣くお互いに妥協点を探し歩み寄った改造をした結果がこの機体である。

#ref(./IMG_1668.JPG,10%,光センサー)
手を加えた光センサー位置。本来のドライブベースよりもさらにタイヤに近づけることで、左右に振られる距離を小さくしている。これによって細かい動きが可能になりヘアピンカーブもなんのそのである。プログラムを変えてライントレースを改善出来ない場合でも、光センサーの位置を変えることで簡単に問題を解消することが出来る。
#ref(./kakudo.jpg,60%,説明図)
機体と光センサーの距離の図。黄色い四角形が機体、黄色い四角形から伸びた線の先にある青い四角形がセンサーを示している。センサーが乗っている曲線は機体を旋回させた際の軌跡である。
#ref(./sensor.jpg,60%,説明図)
光センサー位置の重要さの図。左右の図で機体のタイヤ軸から光センサーへの距離を変え、タイヤ軸を中心に時計回り30度右旋回している。光センサーが振れる大きさは光センサーとタイヤ軸との距離に比例するので、センサーの位置が遠すぎるとその分センサーは大きく動くこととなる。この違いはラインへの進入角で成否が決まるカーブのライントレースや交差点の判別で特に重要である。光センサーの距離が遠いと交差点を曲がった後の機体とラインの距離が離れるし、カーブを曲がる際にはセンサーがラインから離れすぎてしまったりセンサーがラインを越えてしまうことがある。

#ref(./IMG_1669.JPG,10%,網振り後)
ピンポン玉捕獲用の機構作動後の姿。モーターに直結した棒をそのまま振るという見た目も頭も悪い機構である。適当に作った物だが、ピンポン玉を捕まえるには不便がなかったのでそのままにしている。この機構ではモーターにプーリーを介して直接繋いでおり、モーターに負荷がかかる上に動きが早くなりすぎるので、本来ならギアを噛ませて速度を落としつつパワーを確保するべきである。


*プログラムと説明 [#m43c75fb]

 #define set_power_L SetPower(OUT_A,2);SetPower(OUT_C,1);
 #define set_power_H SetPower(OUT_A,5);SetPower(OUT_C,4);
モーターの回転速度を調整する為に定義した。

 /*以下前進後退のパーツ*/
 #define go_forward set_power_H;OnFwd(OUT_AC);//直進
 #define turn_right0 set_power_L;OnFwd(OUT_A);OnRev(OUT_C);//右旋回
 #define turn_right1 set_power_L;OnFwd(OUT_A);Off(OUT_C);//右折
 #define turn_left1 set_power_L;Off(OUT_A);OnFwd(OUT_C);//左折
 #define turn_left0 set_power_L;OnRev(OUT_A);OnFwd(OUT_C);//左旋回
これらの動きを光センサーの値に応じて切り替えることで、ライントレースを行う。


 #define STEP 1//一動作にかける時間
 #define nMAX 10//ライントレースから他のプログラムに切り替える条件となる値
 #define supan 1//何回交差点を通過すればピンポン玉を捕まえるプログラムを動かすかの条件となる値
 #define short_break Off(OUT_AC);Wait(20);//プログラムの切り替えを見て分かりやすくする為の停止のプログラム
 #define CROSS_TIME 50 //交差点通過にかける時間
 #define cross_line set_power_L;OnFwd(OUT_AC);Wait(CROSS_TIME);//交差点横断に使うプログラム

補足
"STEP"
ライントレースの動作一つにかける時間。何度か弄ったが、最終的に在るがままが一番良いという結論に至り"1"のままである。

"nMAX"
ライントレース中に直角カーブ・交差点を判断する為の値。具体的には何回連続でセンサーの値が黒を示したら、while文のループを抜けるかを決める値である。

"CROSS_TIME"
交差点横断に使う時間を決めている値。ロボの構造の変化やプログラムの打ち直しにあたって結構な回数弄っていたりする。


ここからがプログラムの本体である。
猶このプログラムはラインの右側境界を認識するよう作られています。

 task main(){
      SetSensor(SENSOR_2,SENSOR_LIGHT);//本体のポート2に繋がっているのが光センサーであると宣言する
      int nOnline=0;//交差点判別に使用するカウンタ
      int THRESHOLD=SENSOR_2;//プログラムを走らせ始めた時点でのセンサー値を閾値にする
      int cross=0;//交差点通過回数を数えるカウンタ
      OnFwd(OUT_AC);Wait(50);//ロボが開始地点から外に出る為の直進
光センサー・交差点判別の為の整数を設定すると同時に閾値も決められている。この閾値を開始時点のセンサー値から取るのがとても便利で、おかげで明るさの変化による閾値の調整をする手間が省けた。タッチセンサーをスイッチのように使って、白と黒両方とるのがよりスマートであると言われたが、如何せん物臭なので改良はしなかった。


      while(cross<supan){//一回交差点を通過するまで以下のプログラム
"cross"が"supan"以上、つまりは1になった時点で以下の{}内のプログラムのループを終了し、次のプログラムに移行する。

      /*黒を続けてnMAX回繰り返すまで、ライントレースを続ける*/
 		while(nOnline<nMAX){//nOnlineがnMAXになるまでライントレース
 			if(SENSOR_2<THRESHOLD-7){
 				turn_right0;
 				nOnline++;
 			}else{
 				if(SENSOR_2<THRESHOLD-5){
 					turn_right1;
 				}else if(SENSOR_2<THRESHOLD-3){
 				      go_forward;
 				}else if(SENSOR_2<THRESHOLD-1){
 				      turn_left1;
 				}else{
 					turn_left0;
 				}
 				nOnline=0;
 			}
			Wait(STEP);
 		}
"THRESHOLD-7"の条件を満たしている、つまりは光センサーが黒であると認識した時のみ"nOnline"が1増え、それ以外では0に戻されるプログラムである。そして"nOnline"が"nMAX"以上の値をとるまで、このプログラムはループを続けるようになっている。このプログラムでは光センサーが黒と認識した場合右旋回を行うので、"nMAX"の値を調整することで普通のカーブと直角カーブ・交差点の判断が出来る。そして"Wait(STEP)"でライントレース一回の動作を"STEP"で決められた時間だけ持続させている。

 	short_break;//小休止
 	turn_left0;Wait(100*STEP);
 	go_forward;Wait(20*STEP);
 	if(SENSOR_2<THRESHOLD-7){
 		PlaySound(SOUND_UP);
 		set_power_H;OnRev(OUT_AC);Wait(30*STEP);
 		turn_right0;Wait(60*STEP);
 		cross_line;
 		cross++;
 	}else{
 		OnRev(OUT_AC);Wait(30*STEP);
 		turn_right0;Wait(120*STEP);
 		OnFwd(OUT_AC);Wait(10);
 	}
 	nOnline=0;
 	}
ライントレースのループを抜ける条件が直角カーブか交差点に入ることであり、このプログラムはそのラインが直角と交差点のどちらなのかを認識させる物である。交差点か直角カーブに入った際に右側境界から左側境界に光センサーを移動させる。そこで光センサーが黒と判断すればロボは交差点を横断するように動き、白であると判断すれば右折をするように動く。
交差点であると判断した際には"cross"の値が1増え、ライントレースと交差点判断のループから外れて次のプログラムに移行する。なお、最後の"nOnline=0"によって値をリセットし、再びライントレースに使えるようにしている。

 	Off(OUT_AC);//交差点通過後停止
 	OnFwd(OUT_B);Wait(18);//網を振る
 	Off(OUT_B);
一度目の交差点を通過した後、網を振りピンポン玉を捕まえる。

以下、再びライントレースのプログラム。新たに"sh"という交差点通過回数カウンタ用の整数が追加される。"cross"を再利用しても良かったのだが、プログラムを打つ際に混乱してしまいそうだったので止めた。

 	int sh=0;
 	while(sh<3){
 		while(nOnline<7){
交差点を三回通過するまでライントレース。
ピンポン捕獲前より交差点判断へ移行する条件が"nOnline<7"となり緩くなっている。こうした方がライントレースが安定したためである。以下、ライントレースのプログラムに特筆する変化はない。
 			if(SENSOR_2<THRESHOLD-7){
 				turn_right0;
 				nOnline++;
 			}else{
 				if(SENSOR_2<THRESHOLD-5){
 					turn_right1;
 				}else if(SENSOR_2<THRESHOLD-3){
 				      go_forward;
 				}else if(SENSOR_2<THRESHOLD-1){
 				      turn_left1;
 				}else{
 					turn_left0;
 				}
 				nOnline=0;
 			}
 			Wait(STEP);
 		}
 	short_break;
 	turn_left0;Wait(100*STEP);
 	go_forward;Wait(20*STEP);
 	if(SENSOR_2<THRESHOLD-7){
 		PlaySound(SOUND_UP);
 		set_power_H;OnRev(OUT_AC);Wait(30*STEP);
 		turn_right0;Wait(60*STEP);
 		cross_line;
 		sh++;
 	}else{
 		OnRev(OUT_AC);Wait(30*STEP);
 		turn_right0;Wait(120*STEP);
 		OnFwd(OUT_AC);Wait(10);
 	}
 	nOnline=0;
 }
 OnFwd(OUT_AC);Wait(5);Off(OUT_AC);
 OnRev(OUT_B);Wait(30);Off(OUT_B);
 }
交差点を三回通過した後に本体を直進させて、慣性で動くピンポン玉をゴールに入れる。


*反省 [#g2674a15]
何よりも相方と機体の構造を一致させて作らなかったことが問題であった。機体の改造にもプログラムの打ち直しにも時間がかかるし、何より相手に申し訳ない。もう少し意思疎通を図るべきだったか。

あとは私のプログラムに関しての反省点が一つ。ピンポン玉の捕獲前と後のライントレースに殆ど変化が無いのだから同じようなプログラムを増やすのではなく、値を変えるとかでより綺麗で小さなプログラムに出来なかったのかと思う。

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