目次
次のような周回コース(黒い線)を動くロボットを作成せよ。
センサー、モーターはいくつ使ってもよい。プログラムは次の2つを作成すること。
1. 直角のコーナーを通る 2. 直角のコーナーを通らない(近道する)
ただし互いに逆方向に周回すること。
先生が例として挙げたコースとほとんど同じコースを作った。 コースの線の幅は15mmで統一した。
●コースの概要
以下は、メンバーのロボットがたどるコース。
●イシイ(近道担当)のコース
●ゆきち(直角コーナー担当)のコース
ロボットは四輪の車体に光センサーを取り付けたシンプルな作りになった。
●全体
●光センサー
シンプル、と言っても、光センサーの取り付け方には注意した。
3センチという幅は組み立ての際に偶然たどり着いた値だが、広すぎず狭すぎない幅だった。広すぎればラインに対する反応が遅れ、カーブを曲がりきれない。また、狭すぎればロボットがコースの曲線に過剰に反応してしまい、一周を回るのにかかる時間が長くなると予想できる。
もう一点、光センサーとロボットを旋回させたときの回転軸との距離に注意した。
この距離が長ければ、わずかに旋回しただけでも光センサーが大きく動くことになってしまい、急カーブでラインを追いかけることが難しくなると考えた。その点を意識してロボットを作った。
#define go(t) OnFwd(OUT_A+OUT_C);Wait(t);Off(OUT_A+OUT_C); //直進 #define turn_r(t) OnFwd(OUT_A);OnRev(OUT_C);Wait(t);Off(OUT_A+OUT_C); //右旋回 #define turn_l(t) OnFwd(OUT_C);OnRev(OUT_A);Wait(t);Off(OUT_A+OUT_C); //左旋回 #define THRESHOLD 45 //閾値 task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT); ClearTimer(0); //タイマーをリセット while(FastTimer(0)<=500) //5秒後まで繰り返し { OnFwd(OUT_A+OUT_C); //前進 if(SENSOR_1<THRESHOLD) { turn_l(10); //センサー1が反応したら0.1秒左旋回 } if(SENSOR_3<THRESHOLD) { go(20); //センサー3が反応したら0.2秒直進 } } ClearTimer(0); //タイマーをリセット while(FastTimer(0)<=800) //8秒後まで繰り返し { OnFwd(OUT_A+OUT_C); //前進 if(SENSOR_3<THRESHOLD) { turn_r(10); //センサー3が反応したら0.1秒右旋回 } if(SENSOR_1<THRESHOLD) { go(20); //センサー1が反応したら0.2秒直進 } } ClearTimer(0); //タイマーをリセット while(FastTimer(0)<=150) //1.5秒後まで繰り返し { OnFwd(OUT_A+OUT_C); //前進 if(SENSOR_3<THRESHOLD) { turn_r(10) //センサー3が反応したら0.1秒右旋回 } if(SENSOR_1<THRESHOLD) { go(50); turn_r(70); //センサー1が反応したら0.5秒直進し、0.7秒右旋回 } } //1回目のロータリー ClearTimer(0); //タイマーをリセット while(FastTimer(0)<=350) //3.5秒後まで繰り返し { OnFwd(OUT_A+OUT_C); //前進 if(SENSOR_1<THRESHOLD) { turn_l(10) //センサー1が反応したら0.1秒左旋回 } } ClearTimer(0); //タイマーをリセット while(FastTimer(0)<=250) //2.5秒後まで繰り返し { OnFwd(OUT_A+OUT_C); //前進 if(SENSOR_1<THRESHOLD) { turn_l(10); //センサー1が反応したら0.1秒左旋回 } if(SENSOR_3<THRESHOLD) { go(50) turn_r(60); //センサー3が反応したら0.5秒直進し、0.6秒右旋回 } } ClearTimer(0); //タイマーをリセット while(FastTimer(0)<=550) //5.5秒後まで繰り返し { OnFwd(OUT_A+OUT_C); //前進 if(SENSOR_3<THRESHOLD) { turn_r(20); センサー3が反応したら0.2秒右旋回 } } ClearTimer(0); //タイマーをリセット while(FastTimer(0)<=300) //3秒後まで繰り返し { OnFwd(OUT_A+OUT_C); //前進 if(SENSOR_3<=THRESHOLD) { turn_r(10); //センサー3が反応したら0.1秒右旋回 } if(SENSOR_1<=THRESHOLD) { go(50); turn_r(80); //センサー1が反応したら0.5秒直進し、0.8秒右旋回 } } //2回目のロータリー ClearTimer(0); //タイマーをリセット while(FastTimer(0)<=350) //3.5秒後まで繰り返し { OnFwd(OUT_A+OUT_C); //前進 if(SENSOR_1<THRESHOLD) { turn_l(10) //センサー1が反応したら0.1秒左旋回 } } ClearTimer(0); //タイマーをリセット while(FastTimer(0)<=250) //2.5秒後まで繰り返し { OnFwd(OUT_A+OUT_C); //前進 if(SENSOR_1<THRESHOLD) { turn_l(10); //センサー1が反応したら0.1秒左旋回 } if(SENSOR_3<THRESHOLD) { go(50) turn_r(100); //センサー3が反応したら0.5秒直進し、1秒右旋回 } } ClearTimer(0); //タイマーをリセット while(FastTimer(0)<=400) //4秒後まで繰り返し { OnFwd(OUT_A+OUT_C); //前進 if(SENSOR_3<=THRESHOLD) { turn_r(10); //センサー3が反応したら0.1秒右旋回 } if(SENSOR_1<=THRESHOLD) { go(25); OnFwd(OUT_A); Wait(20); Off(OUT_A); センサー1が反応したら0.25秒直進し、0.2秒左車輪のみ前進 } } //ヘアピンカーブ ClearTimer(0); //タイマーをリセット while(FastTimer(0)<=600) //6秒後まで繰り返し { OnFwd(OUT_A+OUT_C); //前進 if(SENSOR_3<=THRESHOLD) { OnRev(OUT_A+OUT_C); Wait(10); Off(OUT_A+OUT_C); turn_r(20); //センサー3が反応したら0.1秒後退し、0.2秒右旋回 } } ClearTimer(0); //タイマーをリセット while(FastTimer(0)<=400) //4秒後まで繰り返し { OnFwd(OUT_A+OUT_C); //前進 if(SENSOR_1<THRESHOLD) { turn_l(10); //センサー1が反応したら0.1秒左旋回 } if(SENSOR_3<THRESHOLD) { go(25); //センサー3が反応したら0.25秒直進 } } while(SENSOR_3<THRESHOLD) //センサー3が反応するまで繰り返し { OnFwd(OUT_A+OUT_C); //前進 if(SENSOR_1<THRESHOLD) { turn_l(10); //センサー1が反応したら0.1秒左旋回 } } Off(OUT_A+OUT_C); }
#define GO(t) OnFwd(OUT_A+OUT_C);Wait(t);Off(OUT_A+OUT_C); //前にt秒進む #define THRESHOLD 45 //明るさを判定する基準値。 sub RIGHT_CURVE() //コースが右にカーブしているときのプログラム { //右側のセンサー3のみを考慮します。 if (SENSOR_3>THRESHOLD)//センサーに反応がなければ直進。 { OnFwd(OUT_A+OUT_C); } if (SENSOR_3<THRESHOLD)//センサーに反応があれば、右にカーブします。 { Off(OUT_C); OnFwd(OUT_A); } } sub LEFT_CURVE() //コースが左にカーブしているときのプログラム { //左側のセンサー1のみを考慮します。 if (SENSOR_1>THRESHOLD) //センサーに反応がなければ直進。 { OnFwd(OUT_A+OUT_C); } if (SENSOR_1<THRESHOLD) //センサーに反応があれば、左にカーブします。 { Off(OUT_A); OnFwd(OUT_C); } } sub ROTARY() //ロータリーのプログラム。 { //ロータリーに入った時点から、このプログラムを使用します。 GO(35); OnFwd(OUT_A);OnRev(OUT_C);Wait(20) //ロボットの回転の中心がロータリーの黒線上に来るように移動。 while(SENSOR_1>THRESHOLD) { OnFwd(OUT_A); OnRev(OUT_C); } Off(OUT_A+OUT_C); OnFwd(OUT_A+OUT_C); //この時点で、ロータリーの黒線が二つのセンサーの間にあります。 ClearTimer(0); while(FastTimer(0)<400) //4秒という時間は、一つ目の分岐を通りすぎるのに十分な時間です。 { LEFT_CURVE(); //その間、ロータリーを左カーブとみなすことができます。 } while(SENSOR_3>THRESHOLD) //4秒以降に3センサーが黒線を感知するとき、ロータリーの出口に達したことになります。 { LEFT_CURVE(); //それまでは、ロータリーを左カーブとみなします。 } Off(OUT_A+OUT_C);GO(35); OnFwd(OUT_A);OnRev(OUT_C);Wait(20); //入ったときと同様に、ロボットの回転の中心がロータリーの黒線上にあるように移動します。 while(SENSOR_1>THRESHOLD) { OnFwd(OUT_A);OnRev(OUT_C); } //この時点でロータリーから伸びる黒線が二つのセンサーの間にあります。 } //ロータリーを抜けました。 task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT); //センサー1、3を光センサーと定義。 ClearTimer(0); while(FastTimer(0)<=330) //最初はなだらかな右カーブ。 { RIGHT_CURVE(); } while(FastTimer(0)<=850) //ここは左の急カーブなので、別のプログラムを使います。 { if ((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD)) { OnFwd(OUT_A+OUT_C); } if ((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD)) //反対のタイヤを逆回転させることで、急カーブを回りきります。 { OnRev(OUT_A); OnFwd(OUT_C); } } while(FastTimer(0)<=1100) //緩やかな左カーブ { LEFT_CURVE(); } while(SENSOR_3>THRESHOLD) //ロータリーまで、左カーブが続きます。 { LEFT_CURVE(); } Off(OUT_A+OUT_C); //ロータリー入り口で停止。 ROTARY; ClearTimer(0); while(FastTimer(0)<300) { LEFT_CURVE(); } GO(50); //近道を無視します。 while(FastTimer(0)<700||SENSOR_1>THRESHOLD||SENSOR_3>THRESHOLD) //直角カーブを回るため、急カーブのときと同じプログラムを使用。 { //ロータリーを感知するまでこのプログラムを継続します。 if ((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD)) { OnFwd(OUT_A+OUT_C); } if ((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD)) { OnRev(OUT_A); OnFwd(OUT_C); } } Off(OUT_A+OUT_C); //ロータリー入り口。 ROTARY; ClearTimer(0); while(SENSOR_1>THRESHOLD||SENSOR_3>THRESHOLD) { LEFT_CURVE(); } GO(15); //交差点を無視して進みます。 while(SENSOR_1>THRESHOLD||SENSOR_3>THRESHOLD) { LEFT_CURVE(); } GO(10); //交差点を無視。 while(SENSOR_1>THRESHOLD||SENSOR_3>THRESHOLD) //「どちらかが白である間、継続」つまり「ゴールの黒線を感知するまで継続」 { if ((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD)) { OnFwd(OUT_A+OUT_C); } if ((SENSOR_1<THRESHOLD)&&(SENSOR_3>THRESHOLD)) { OnRev(OUT_A);OnFwd(OUT_C); } if ((SENSOR_1>THRESHOLD)&&(SENSOR_3<THRESHOLD)) { OnRev(OUT_C);OnFwd(OUT_A); } } Off(OUT_A+OUT_C); //ゴール }