目次
課題はこちらを参照
自分はE地点直進コースを制作した。
今回のライントレースのコースには半径の小さい円が存在し、大型ロボットではラインに沿って正しく進むことが困難になる。そこで小さいタイヤを2つ使い、タイヤの相互の距離を短くした小型ロボットにすることによって小回りを可能にし、よりラインに沿いやすくした。また、光センサーをタイヤの近くにつけることで、曲線で光センサーがラインから外れにくくなるようにした。なお、小型ロボットのため、準備及び片付けにほとんど時間を要さず、すぐにライントレースを行うことができる。
比較的多めに定義を作成した。
多くなりすぎると複雑になってしまうため、しきい値については定義で示さなかった。
以下にすべての定義を記載する。
#define senkai_right OnFwd(OUT_A); OnRev(OUT_C); //右に旋回 #define senkai_left OnFwd(OUT_C); OnRev(OUT_A); //左に旋回 #define turn_right OnFwd(OUT_A); Off(OUT_C); //右に曲がる #define turn_left OnFwd(OUT_C); Off(OUT_A); //左に曲がる #define chokushin OnFwd(OUT_AC); //前進 #define koutai OnRev(OUT_AC); //後退 #define teishi Off(OUT_AC); Wait(100); //1秒間停止 #define oto_up PlaySound(SOUND_UP); //低→高の音を鳴らす #define oto_down PlaySound(SOUND_DOWN); //高→低の音を鳴らす
上記の9つはなるべくわかりやすい名前を利用して定義をした。
#define kuro_kanchi_left if(SENSOR_2>46){senkai_right; ClearTimer(0);} else if(SENSOR_2>44){turn_right; ClearTimer(0);}\ else if(SENSOR_2>40){chokushin; ClearTimer(0);} else if(SENSOR_2>38){turn_left; ClearTimer(0);}\ else{senkai_left;} //黒線の左側をライントレースし、しきい値が38未満の時タイマー0をリセットしない #define kuro_kanchi_right if(SENSOR_2>46){senkai_left; ClearTimer(0);} else if(SENSOR_2>44){turn_left; ClearTimer(0);}\ else if(SENSOR_2>40){chokushin; ClearTimer(0);} else if(SENSOR_2>38){turn_right; ClearTimer(0);}\ else{senkai_right;} //黒線の右側をライントレースし、しきい値が38未満の時タイマー0をリセットしない #define kuro_kanchi_left_noreset if(SENSOR_2>46){senkai_right;} else if(SENSOR_2>44){turn_right;} else if(SENSOR_2>40){chokushin;} \ else if(SENSOR_2>38){turn_left;} else{senkai_left;} //黒線の左側をライントレース #define kuro_kanchi_right_noreset if(SENSOR_2>46){senkai_left;} else if(SENSOR_2>44){turn_left;} else if(SENSOR_2>40){chokushin;}\ else if(SENSOR_2>38){turn_right;} else{senkai_right;} //黒線の右側をライントレース
上記の4つの定義は下記の図のようにライントレースする。
(黒線左側をライントレースする場合は、しきい値の47-100と0-37あるいは44-46と38-39の役割が逆になる。)
なお、黒線の右側左側でそれぞれ2つずつ定義を設けているのは、次項のサブルーチンで詳しく説明をするが、Timer0をリセットする必要のない場面とある場面とを区別をするためである。
task mainをできるだけシンプルにするために、サブルーチンはRISが使用できる最大の8つを用いた。
それぞれのサブルーチンの名前は、linetrace_の後にtask mainで命令を実行したい順に英語の数字を振っている。これは、プログラムを制作・修正するときにどこを直したら良いのかわかりやすくするためである。(数字の小さい順に並んでいな箇所が一部あるが、これはサブルーチンを繰り返し使用しているためである。)
以下にすべてのサブルーチンと、その説明を記載する。
sub linetrace_one() { ClearTimer(0); int time_kuro=18; while(FastTimer(0) < time_kuro) {kuro_kanchi_left;}//しきい値0-37を感知する連続時間がtime未満の時ライントレースをする oto_up; //角を感知したので音を鳴らす Off(OUT_AC); }
コースのA-E-F区間を走るためのサブルーチンである。
黒いコーナーを感知して音を鳴らす。
sub linetrace_two() { ClearTimer(1); int time_kuro=18; while(FastTimer(1) < 100){kuro_kanchi_left_noreset;}//1秒間ライントレースのみする ClearTimer(0); while(FastTimer(0) < time_kuro){kuro_kanchi_left;}//しきい値0-37を感知する連続時間がtime未満の時ライントレースをする oto_down; //交差点を感知したので音を鳴らす teishi; //1秒間停止 }
コースのF-Q区間とT-R区間とP-E区間を走るためのサブルーチンである。
交差点を感知して音を鳴らす。
sub linetrace_three() { ClearTimer(1); int time_kuro=13; while(FastTimer(1) < 150){kuro_kanchi_left_noreset;}//1.5秒間ライントレースのみする ClearTimer(0); while(FastTimer(0) < time_kuro){kuro_kanchi_left;}//しきい値0-37を感知する連続時間がtime未満の時ライントレースをする oto_up; //角を感知したので音を鳴らす turn_right;//位置調整 Wait(45); // ↓ chokushin; // ↓ Wait(20); // ↓ ClearTimer(1); while(FastTimer(1) < 150){kuro_kanchi_left_noreset;}//1.5秒間ライントレースのみする ClearTimer(0); while(FastTimer(0) < time_kuro){kuro_kanchi_left;}//しきい値0-37を感知する連続時間がtime未満の時ライントレースをする oto_up; //角を感知したので音を鳴らす Off(OUT_AC); }
コースのQ-R-S区間とR-S-P区間を走るためのサブルーチンである。
途中、黒線をまたぐときに光センサーが誤作動を起こさないように位置調整をするプログラムを入れてある。
sub linetrace_four() { ClearTimer(1); int time_kuro=18; while(FastTimer(1) < 200){kuro_kanchi_left_noreset}//2秒間ライントレースのみする ClearTimer(0); while(FastTimer(0) < time_kuro){kuro_kanchi_left}//しきい値0-37を感知する連続時間がtime未満の時ライントレースをする oto_up;//角を感知したので音を鳴らす Off(OUT_AC); }
コースのS-G区間を走るためのサブルーチンである。
基本はlinetrace_oneと変わらないが、角を曲がるときに黒を感知しすぎて誤作動を起こさないように2秒間ライントレースのみするプログラムを入れてある。
sub linetrace_five() { ClearTimer(1); int time_kuro=18; while(FastTimer(1) < 1500){kuro_kanchi_left_noreset}//15秒間ライントレースのみする ClearTimer(0); while(FastTimer(0) < time_kuro){kuro_kanchi_left;}//しきい値0-37を感知する連続時間がtime未満の時ライントレースをする oto_up; //角を感知したので音を鳴らす chokushin; //黒線をまたぐ Wait(40); // ↓ senkai_left;// ↓ Wait(40); // ↓ Off(OUT_AC); }
コースのG-H区間を走るためのサブルーチンである。
linetrace_fourと同じように誤作動防止プログラムを入れている。さらに、この次からのライントレースの精度を高めるために、黒線をまたぐプログラムを入れてある。
sub linetrace_six() { ClearTimer(0); int time_kuro=15; while(FastTimer(0) <time_kuro){kuro_kanchi_right;}//しきい値0-37を感知する連続時間がtime未満の時ライントレースをする oto_down; //交差点を感知したので音を鳴らす teishi; //1秒間停止 chokushin;//黒線をまたぐ Wait(40); // ↓ Off(OUT_AC); }
コースのH-T区間を走るためのサブルーチンである。
黒線をまたぐプログラムが入れてある。
sub linetrace_seven() { ClearTimer(1); int time_kuro=18; while(FastTimer(1) < 1000){kuro_kanchi_right_noreset;}//10秒間ライントレースのみする ClearTimer(0); while(FastTimer(0) < time_kuro){kuro_kanchi_right;}//しきい値0-37を感知する連続時間がtime未満の時ライントレースをする oto_down; //交差点を感知したので音を鳴らす teishi; //1秒間停止 turn_left; //位置調整 Wait(50); // ↓ chokushin; // ↓ Wait(30); // ↓ Off(OUT_AC); }
コースのT-T区間を走るためのサブルーチンである。
誤作動防止と位置調整のプログラムが入れてある。
sub linetrace_eight() { ClearTimer(1); int time_kuro=20; while(FastTimer(1) < 200){kuro_kanchi_left_noreset}//2秒間ライントレースのみする ClearTimer(0); while(FastTimer(0) < time_kuro){kuro_kanchi_left;}//しきい値0-37を感知する連続時間がtime未満の時ライントレースをする chokushin; //終了のエリアへもっていく Wait(100); // ↓ oto_down; Off(OUT_AC); }
コースのE-A区間を走るためのサブルーチンである。
基本的にlinetrace_twoと同じだが、ゴールをするためのプログラムを入れてある。
〜Timerと係数について〜
サブルーチンの中にTimerを二つ用いているが、これはそれぞれ使う場面が違うため、プログラムがわかりやすくなるように分けている。
係数timeの定義は、それぞれ誤作動を起こさずかつ最短になるようにしているため、サブルーチンによってばらばらとなっている。
サブルーチンを複雑にしたおかげで、task mainは光センサーの定義とモーターのパワー設定、サブルーチンの実行の三つの要素だけで済み、非常にシンプルなプログラムになった。
なお、モーターのパワー設定を最小にしたのは、そのままのパワーでライントレースをすると、光センサーのしきい値の測定がロボットの速さについていかなくなってしまうためである。
task main() { SetSensor(SENSOR_2, SENSOR_LIGHT);//光センサーをセット SetPower(OUT_AC ,0 ); //モーターのパワーを最小にする linetrace_one(); //A-E-F linetrace_two(); //F-Q linetrace_three(); //Q-R-S linetrace_four(); //S-G linetrace_five(); //G-H linetrace_six(); //H-T linetrace_seven(); //T-T linetrace_two(); //T-R linetrace_three(); //R-S-P linetrace_two(); //P-E linetrace_eight(); //E-A }
形状がほぼ同じ箇所が2つあるため、そこではサブルーチンの使い回しをした。(linetrace_twoとlinetrace_three)
最初は、自分にライントレースするロボットが作れるかどうかとても心配で、実際、前回の課題1で制作した単純なプログラムとは違って、とても複雑なプログラムを制作しなければならず、途中で何度も挫折しかけた。しかし、考えれば考えるほど良いプログラムを思いつくことができ、何とか課題を完成させることができてほっとした。
今回学んだことや反省点を生かし、最終課題に精一杯取り組んでいきたいと思う。