- 追加された行はこの色です。
- 削除された行はこの色です。
[[2017b/Member/masato/Mission1]]
#contents
*課題2 [#o0bf25a7]
今回の課題は下図のようなコースを各チームで作成し、ミッションを遂行することである。
#ref(./2017b-mission2.png,100%,課題2)
ミッションとは指定された3つのコースのうち1つを選択し、ライントレースしながら紙コップを指定の場所まで運ぶことである。自分の場合は
Aをスタート、Bを直進、Cを直進、D地点の紙コップを取得して来たコース戻りCへ向かう、Cを左折、Fを直進、Rを左折(一時停止)、Pを直進、X地点に紙コップを置いてコースに戻る、Qを左折、Sを右折(一時停止)、Fを左折(一時停止)、Cを右折(一時停止)、D地点へ(ゴール)
(一時停止の指定がある場所は、1秒間停止すること)
*ロボットの構造 [#hf2b1920]
キットについていた説明書の基本の光センサロボットに紙コップを掴むためのアームを後ろ側に取り付けた。アームは3つ目のモーターを使って、上下に動くようになっていて、アームを下に降ろし掴むというよりは中に入れて引きずっていくようにした。
キットに載っているような基本的な3輪駆動のロボットに前側に光センサ、後ろ側の基盤と駆動輪の間にコップを掴むアームを取り付けた。アームは3つ目のモーターを使って、上下に動くようになっていて、アームを下に降ろし掴むというよりは中に入れて引きずっていくようにした。なるべく正確な値を測りライントレースさせるために光センサはできるだけ地面に近づけるようにした。
#ref(./IMG_0143.jpg,15%,ロボットの構造)
#ref(./IMG_0153.JPG,15%,ロボットの構造)
*プログラム [#s089f2e2]
**マクロ [#r522c306]
#define speed_fast 20 //直線上での速さ
#define speed_curve 25 //曲がる時の速さ
**各定義 [#k5a7f9b0]
#define speedRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL); //タイヤBを speedR%,タイヤCをspeedL%の速さでそれぞれ進ませる(+:前進,-:後進)
#define go_fwd speedRL(speed_fast,speed_fast); //前進
#define turn_right_high speedRL(-speed_curve - 5,speed_curve); //右旋回
#define turn_right_low speedRL(0,speed_curve + 10); //右折
#define turn_left_high speedRL(speed_curve ,-speed_curve - 10); //左旋回
#define turn_left_low speedRL(speed_curve + 10,0); //左折
#define turn_left_90 OnFwd(OUT_B,25); OnFwd(OUT_C,-25); Wait(1100); //左90度回転
#define turn_left_150 OnFwd(OUT_B,25); OnFwd(OUT_C,-25); Wait(2500); Off(OUT_BC); //左150 度回転
#define turn_right_150 OnFwd(OUT_B,-25); OnFwd(OUT_C,25); Wait(2500); Off(OUT_BC); //右150度回転
#define turn_left_180 OnFwd(OUT_B,25); OnFwd(OUT_C,-25); Wait(3100); Off(OUT_BC); //左180度回転
#define turn_right_180 OnFwd(OUT_B,-25); OnFwd(OUT_C,25); Wait(3100); Off(OUT_BC); //右180度回転
#define arm_down OnFwd(OUT_A,-10); Wait(1000); Off(OUT_A); // アームダウン
#define arm_up OnFwd(OUT_A,20); Wait(1000); Off(OUT_A); //アームアップ
**ライントレースサブルーチン,交差点認識 [#x706e03a]
自分のコースの場合光センサが黒線のラインと左側の白い部分の境界線上を走ることにした。ライントレースをする上で重要な明るさを5段階に分けて測り各動作を決定した。暗い順に左旋回、左折、直進、右折、右旋回するようになっている。測った結果しきい値は60になった。
#define threthold 60 //しきい値
交差点認識に関しては時間ではなく最も黒い時が連続して何回続いたかという方法を採用した。調べた結果160回が最適だと判断した。
交差点認識に関しては時間ではなく最も黒い時が連続して何回続いたかという方法を採用した。調べた結果160回が最適だと判断した。つまり光センサが最も暗いとき(値でいうと45以下の時)、を160回計測したとき、そこを交差点だと判断し、各動作を行う。そして、値が45以下でなくなった瞬間最も暗いときの回数を初期化(0回)するようにしている。
#define nMAX 160 //交差点認識のための最も黒い時の回数
sub follow_line() //ライントレース
{
SetSensorLight(S1);
int n = 0; //nは続けて黒になった回数
while(n <= nMAX){ //最も黒い時がnMAX以下のときライントレースを繰り返す
int n = 0; //nは続けてもっとも暗いときになった回数
while(n <= nMAX){ //最も暗い時がnMAX以下のときライントレースを繰り返す
if(SENSOR_1 < threthold -15 ){
turn_left_high;
n++; //回数を増やす
}else {
if (SENSOR_1 < threthold -7){
turn_left_low;
}else if (SENSOR_1 < threthold +6){
go_fwd;
}else if (SENSOR_1 < threthold +10){
turn_right_low;
}else{
turn_right_high;
}
n = 0; //最も黒い時の回数の初期化
}
}
Off(OUT_BC);
Wait(1000);
PlaySound(SOUND_CLICK); //交差点で音を鳴らす
Wait(1000);
}
ロボットが交差点だと判断したら音を鳴らして分かりやすくしている。
**交差点での行動サブルーチン [#h47071d4]
3パターンを用意した。
sub inter_left() //交差点左折
{
OnFwd(OUT_BC,25);
Wait(1000);
Off(OUT_BC);
turn_left_90;
Off(OUT_BC);
Wait(1000);
}
sub inter_straight() //交差点直進
{
OnFwd(OUT_BC,25);
Wait(500);
Off(OUT_BC);
}
通常は上記の2パターンで大丈夫だと思うが自分の場合は直角の部分が曲がりにくかったのでもうひとつ余分に作った
sub inter_left_90() //交差点を90度左折
{
OnFwd(OUT_BC,25);
Wait(600);
Off(OUT_BC);
turn_left_90;
Off(OUT_BC);
Wait(1000);
}
**EF間(急カーブ)でのライントレースサブルーチン [#m39d9563]
通常のライントレースでは急カーブがうまく行かなかったので仕方なくそれ専用のライントレースサブルーチンを作った。このサブルーチンはnMAX_EFが指定された回数になるまでライントレースを繰り返すようになっている。
通常のライントレースでは急カーブがうまく行かなかったので仕方なくそれ専用のライントレースサブルーチンを作った。このサブルーチンはnMAX_EFが指定された回数になるまでライントレースを繰り返すようになっている。通常のライントレースサブルーチンと違うのは、nの値を初期化しないところにある。
#define nMAX_EF 3800 //交差点認識のための最も黒い時の回数(EF間のみ)
sub follow_line_EF() //EF間で適用したライントレース
{
SetSensorLight(S1);
int n = 0;
while(n <= nMAX_EF){
if(SENSOR_1 < threthold -15 ){
OnFwd(OUT_B,50); OnFwd(OUT_C,-60);
n++;
}else {
if (SENSOR_1 < threthold -7){
turn_left_low;
}else if (SENSOR_1 < threthold + 6){
go_fwd;
}else if (SENSOR_1 < threthold + 10){
turn_right_low;
}else{
OnFwd(OUT_B,-30); OnFwd(OUT_C,20);
}
}
}
Off(OUT_BC);
Wait(1000);
}
**コップを掴む、離すサブルーチン [#kd0778cb]
sub catch_cup() //コップを掴む
{
turn_left_180;
Wait(500);
arm_down;
Wait(500);
turn_right_180;
}
コップを掴むときはアームを下におろしている。
sub release_cup() //コップを離す
{
turn_left_180;
Wait(500);
arm_up;
Wait(500);
turn_right_180;
}
コップを離すときはアームを上に上げている。
アームが進行方向とは後ろについているので掴む、離すときにロボットを180度回転(turn_right_180やturn_left_180)させている。
**タスクメイン [#p9ace022]
task main()
{
follow_line();
inter_straight(); //C直進
follow_line();
Off(OUT_BC);
follow_line();
inter_left_90(); //B左折
OnFwd(OUT_B,25); //微調整
Wait(500);
Off(OUT_B);
follow_line();
inter_left(); //P左折
follow_line();
inter_straight(); //Q直進
OnFwd(OUT_C,30); //微調整
Wait(1100);
Off(OUT_C);
follow_line();
inter_left(); //R左折
follow_line();
inter_left_90(); //E左折
follow_line_EF();
follow_line();
inter_left_90(); //F左折
OnFwd(OUT_B,25); //微調整
Wait(500);
Off(OUT_B);
follow_line();
catch_cup(); //コップ掴む
inter_straight(); //S直進
follow_line();
inter_straight(); //S直進
follow_line();
release_cup(); //コップ離す
inter_left(); //Q左折
OnFwd(OUT_C,30); //微調整
Wait(800);
Off(OUT_C);
follow_line();
inter_straight(); //R直進
follow_line();
inter_left(); //P左折
follow_line();
inter_left(); //B左折
OnFwd(OUT_B,25); //微調整
Wait(700);
Off(OUT_B);
follow_line();
inter_straight();
OnFwd(OUT_BC,30); //Aの中にゴール
Wait(800);
}
交差点を曲がるときに常にではないが、曲がりすぎて脱線したり、逆に曲がらな過ぎて上手くいかなかったりということが起こったのでそれらを防ぐために//微調整というものは入っている。微調整具合が各々違ったのでサブルーチンにはできなかった。
*感想、反省 [#y10f60c5]
プログラムに関してはサブルーチンやマクロを使いながら前回の課題よりは大分コンパクトに収まっていて見やすくなったので良かった。ただ実際に動かしてみると成功率は50%というところで完全性に関しては反省すべき点が多々あった。電池の残量によって変化したり、僅かな光の変化などもう少し完全性に注意すべきだった。次の課題では反省を活かせるようにしたい。