[[2012a/MemberOnly/進行状況A]]

[[2012a/Member]]

[[2012a/A4]]

[[2012a/A4/Tnakano]]

目次

#contents

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

-白の画用紙に書かれた黒い線のコースをトレースするロボットを作成する。

***ルール [#ie6d3ba5]
-コースは交差点2ヶ所以上、ヘアピンカーブ、直角コーナーそれぞれ1ヶ所以上。
-線の幅15〜20mm。
-ひとりにつき一つ以上のプログラムを作成すること。(コースの逆まわり)

**ハードウェア [#tc475b09]
今回制作したロボットは、ロボット全体をできるだけコンパクトにして、小回りが利くようにした。下図が外観図である。
#ref(IMG_0321.JPG,left,nowrap,外観図)

***工夫した点 [#t3301dab]
工夫した点は、センサーとタイヤの距離をできるだけ狭くしたことである。センサーをタイヤに近づけることでセンサー値の変化に対するタイヤの応答速度が速まり、ヘアピンカーブや直角コーナーをきれいに曲がることができます。
#ref(IMG_0320_a.jpg,left,nowrap,センサーとタイヤの距離について)


**プログラム [#de7b6cb9]
***ライントレースについて [#ob465523]
ライントレースは精度の違う2種類を使い分けている。
1つ目は、緩やかなカーブや直線を速く走るためのトレースである。センサーを黒から白に動かしたとき、値が約23から63まで変化したことを利用して、その時のセンサー値−23を行うことで0から40まで変化することになる。この値を変数に代入し右(または左)の出力に2倍して代入するとモータへの出力を0〜80%まで、センサー値に応じて連続的に変化させることができる。左(または右)には80−(センサー値−23)を出力することで右の時とは逆の出力を行うことができる。(下図参照)ただしセンサー値−23を行うとき、0より小さくなってしまう時と63より大きくなってしまう時は、正しい計算を行うことができないので、if文を用いて、上限(63)下限(0)を定めている。
もう1つはヘアピンカーブ、直角コーナー、入り口、出口等を曲がるためのトレースである。1つ目のトレースと同様にセンサー値の変化23から63を0から40に変換する。そして、配列を用いて0から40のセンサー値に応じて、モーターの出力を-20から60%まで変化させようとした。そうするとカーブは曲がるが直線がパワー不足で進まなくなってしまった。センサー値が中心の20になったときモータへの出力は、両方20パーセントだが、電池が少なくなったり、2周目になったりすると動かなかった。この失敗から配列を組み替え出力を−20、25、40%の3種類にして走行した。そうすると、動きはぎこちなくなってしまったが、各種カーブも直線も走るようになった。

#ref(モータ出力図.png,left,nowrap,モータ出力図)

***プログラムの流れ [#v8456d70]
基本的に、switch case文をwhile文の永久ループで囲んでプログラムを進めている。交差点や直角コーナー、ヘアピンカーブ等の検出は、nxtのタコメータを使用し、スタートからの距離を測定しながら大まかな検討をつけ、トレースの精度を変えながら走行した。プログラムの重複を避けるため、何度も使うcaseでフラグ変数にカウントしながら、caseの切り替えを行った。

***コースについて [#la14724d]
#ref(IMG_0318_b.jpg,left,nowrap,コース)
上図の順に走行した。ヘアピンも直角もアウトコースから通ったほうが安全だったため、直前の交差点で、アウトコースへトレースを切り替えた。交差点でラインを無視して直進するところやコースのインコースからアウトコースに交代するところ、スピードupするところ、直角コーナー、ヘアピンカーブ等、各ポイントでcaseを変更し走行した。

***プログラムリスト [#n5a3b9e1]
 /*****************************************************************/
 /*		nxtプログラム kadai2				*/
 /*****************************************************************/
 
 //定義文
 #define	thr1_dis	400            //交差点1距離
 #define	thr3_dis	4900            //交差点3距離
 #define	cr1_dis 	5600            //直角コーナー距離
 #define	thr4_dis	7200            //交差点4距離
 #define	thr5_dis	7700            //交差点5距離
 #define	thr6_dis	9000            //交差点6距離
 
 //メイン関数
 task main(void){
	unsigned int mode,thr_f=0,cr_f=0,distance_r;
	int power_b[]={
		/*-20,-18,-16,-14,-12,-10,-8,-6,-4,-2,0,2,4,6,8,10,12,14,16,18,20,
		22,24,26,28,30,32,34,36,38,4,42,44,46,48,50,52,54,56,58,60*/
                 -20,-20,-20,-20,-20,-20,-20,-20,-20,-20,-20,-20,-20,-20,-20,25,25,25,25,25,
		25,25,25,25,25,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40
		};
	int power_c[]={
		/*60,58,56,54,52,50,48,46,44,42,40,38,36,34,32,30,28,26,24,22,20,
		18,16,14,12,10,8,6,4,2,0,-2,-4,-6,-8,-10,-12,-14,-16,-18,-20*/
		40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,25,25,25,25,25,
                 25,25,25,25,25,-20,-20,-20,-20,-20,-20,-20,-20,-20,-20,-20,-20,-20,-20,-20,
		};
	int power;
	unsigned int power_bs,power_cs;
	
	SetSensorLight(IN_3);          //センサーセット
 
	ResetTachoCount(OUT_B);         //タコメータリセット
 
	mode=1;                 //初期モードセット
 
	while(1){
							
		distance_r=MotorTachoCount(OUT_B);
 
		TextOut(0,LCD_LINE1,"LightSensor =");
		NumOut(85,LCD_LINE1,Sensor(IN_3));            //センサー値表示
 
		TextOut(0,LCD_LINE2,"TachoCout_R");
		NumOut(0,LCD_LINE3,distance_r);               //距離表示
				
		NumOut(0,LCD_LINE4,mode);                     //case表示
 
		switch(mode){
 
			case 1:
				power=Sensor(IN_3)-23;
				if(power<=0){
					power=0;
				}else if(power>=40){
					power=40;
				}
			
				CoastEx(OUT_BC,0);			//モータBCフリー
				OnFwdEx(OUT_C,power_c[power],0);
				OnFwdEx(OUT_B,power_b[power],0);
				Wait(1);
				
				if(distance_r>thr1_dis && thr_f==0){
					mode=2;
				}
 
				if(distance_r>thr4_dis && thr_f==2){
					mode=2;
				} 
				
				if(distance_r>thr5_dis && thr_f==3){
					mode=6;
				} 
 
				break;
				
			case 2:
			
				PlayTone(TONE_G4,100);
				RotateMotor(OUT_BC,40,130);		
				
				
				if(thr_f==0){
					mode=3;
					thr_f++;
				}
				
				if(distance_r>thr3_dis && thr_f==1){
					mode=4;
					thr_f++;
				}
 
				if(distance_r>thr4_dis && thr_f==2){
					mode=1;
					thr_f++;
				}
				
				if(distance_r>thr6_dis && thr_f==3){
					mode=4;
					thr_f++;
				}
 
				break;
				
			case 3:
				
				power=Sensor(IN_3)-23;
				if(power<=0){
					power=0;
				}else if(power>=40){
					power=40;
				}
				
				power_bs=power*2;
				power_cs=80-power*2;
			
				CoastEx(OUT_BC,0);			//モータBCフリー
				OnFwdEx(OUT_C,power_cs,0);
				OnFwdEx(OUT_B,power_bs,0);
				Wait(1);
				
				if(distance_r>thr3_dis && thr_f==1){
					mode=2;
				} 
 
				break;
				
			case 4:
				power=Sensor(IN_3)-23;
				if(power<=0){
					power=0;
				}else if(power>=40){
					power=40;
				}
			
				CoastEx(OUT_BC,0);			//モータBCフリー
				OnFwdEx(OUT_C,power_b[power],0);
				OnFwdEx(OUT_B,power_c[power],0);
				Wait(1);
				
				if(distance_r>/*cr1_dis*/5600 && cr_f==0){
					cr_f++;
					mode=5;
				}
				
				break;
			
			case 5:
			
				PlayTone(TONE_G4,100);
				CoastEx(OUT_BC,0);
				RotateMotor(OUT_C,40,150);
				RotateMotor(OUT_BC,40,130);		
				mode=1;
				break;
				
			case 6:
			
				PlayTone(TONE_G4,100);
				CoastEx(OUT_BC,0);
				RotateMotor(OUT_B,40,250);
				RotateMotor(OUT_BC,40,130);		
				mode=7;
				break;
				
			case 7:
				power=Sensor(IN_3)-23;
				if(power<=0){
					power=0;
				}else if(power>=40){
					power=40;
				}
				
				power_bs=power*2;
				power_cs=80-power*2;
			
				CoastEx(OUT_BC,0);			//モータBCフリー
				OnFwdEx(OUT_C,power_bs,0);
				OnFwdEx(OUT_B,power_cs,0);
				Wait(1);
				
				if(distance_r>thr6_dis){
					mode=2;
				} 
 
				break;
		}
	}
 }

**反省・感想 [#k4bc4d6d]
今回はライントレースロボットを制作した。コースも最初はシンプルにしたつもりだったが、直角コーナーから交差点までの距離が短すぎて、切り替えに苦労した。また、コースの線が太くなりすぎてしまったため、交差点を横切るときにスピードを上げるだけでは上手く行かなかった。そのためトレースを無視するプログラムを入れなければ上手く走らなかった。トレースの方法を工夫して、スピードを上げることができたのはよかったと思う。次回からはロボコンの準備なので今回の経験を活かして、頑張りたいと思います。

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