2012a/A4/Tnakano/M2
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
[[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]
今回はライントレースロボットを制作した。コースも最初はシンプルにしたつもりだったが、直角コーナーから交差点までの距離が短すぎて、切り替えに苦労した。また、コースの線が太くなりすぎてしまったため、交差点を横切るときにスピードを上げるだけでは上手く行かなかった。そのためトレースを無視するプログラムを入れなければ上手く走らなかった。トレースの方法を工夫して、スピードを上げることができたのはよかったと思う。次回からはロボコンの準備なので今回の経験を活かして、頑張りたいと思います。
終了行:
[[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]
今回はライントレースロボットを制作した。コースも最初はシンプルにしたつもりだったが、直角コーナーから交差点までの距離が短すぎて、切り替えに苦労した。また、コースの線が太くなりすぎてしまったため、交差点を横切るときにスピードを上げるだけでは上手く行かなかった。そのためトレースを無視するプログラムを入れなければ上手く走らなかった。トレースの方法を工夫して、スピードを上げることができたのはよかったと思う。次回からはロボコンの準備なので今回の経験を活かして、頑張りたいと思います。
ページ名: