ブロック(一番太いホイール)を投げるロボットを作成し、以下の動きをするようにプログラムを作成せよ。 (重複しないように一人一つ以上のプログラムを作成すること)
ただし、モータ、光センサ、タッチセンサはそれぞれ2個まで使用可。懐中電灯の代わりに携帯のライトなどを利用してもよい。
(製作者:クノピー、ハネウマ、ネタ切れ)
駆動はディファレンシャルギアを使い、一つのモーターで移動する。
ディファレンシャレルギアの機構の上に本体を乗せ、センサーを取り付けただけの単純な機構になっている。(ディファレンシャルギア自体は決して単純な機構ではないが)
タイヤが二つでは安定しないので、前回の課題と同じように、ターンの邪魔にならないような補助輪を取り付けた。でも、それだけでは芸がないので、今回はキャスター型の補助輪を作成した。
前方の二つの光センサーが光を感知する。あまり改造はしていない。ひさしをつけるべきか悩んだが、特に何も改良せずただ取り付けただけの状態でも、プログラムを遂行してくれたのでそのままの状態でそっとしておいた。反応の仕方は(図の青い四角が光センサです。)
まず、図の1の状態では右のセンサが左のセンサより明るいを認識しているので、右折した。しかし、図の2のように、今度は左のセンサが右のセンサより明るくなってくるので、図の3のように左折を開始する。そして、それを繰り返すことによって前進する。
条件を満たすと、モーターが回転するプログラムを組んであるので、条件を満たすとブロックを投げる。
この機構では、頂点部分でモーターの回転が止まるので、そこから図の絵のように投擲をすることができる。
全方向から懐中電灯の方向を探しだし、懐中電灯に向けてブロックを投げる。懐中電灯は動かさない。
プログラム1
懐中電灯をゆっくり動かしたとき懐中電灯に向かって進む。
プログラム2
懐中電灯をゆっくり動かしたとき懐中電灯に向かって進み、懐中電灯の動きを止めればブロックを投げる。
#define TURN_TIME 225 //1周にかかるだいたいの時間 #define RUN_TIME 20 int time_max=0; // int turn_dir=0,last_turn=0; //曲がる方向turn_dirと前回の方向last_turnを定義 int i; //forループのための変数 int i_min=0,i_max=5; //iの最大値と最大値を指定 int light_max=0;
sub throw_block() { OnFwd(OUT_B); Wait(7); Off(OUT_B); }
task main(){ SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT); ClearTimer(0);OnRev(OUT_A); //タイマーをリセットして右のタイヤを中心に回転 while(FastTimer(0)<TURN_TIME){ //1周まわるまでの間 if(SENSOR_1>light_max) //最も強い光を探す { light_max=SENSOR_1; time_max=FastTimer(0); } } OnRev(OUT_A); //最初の向きをむいたので、最も強い光の場所まで再び回転 Wait(time_max); for(i=i_min; i<i_max;){ //iが1から5の間のときに繰り返す if(SENSOR_1>SENSOR_3){ //左のほうが強い光を感知したとき OnRev(OUT_A); Wait(RUN_TIME); Off(OUT_A); turn_dir=1; //左に1回(0,2秒)進み、今回の動きをしめすturn_dirという変数を1に変える if(turn_dir==last_turn){ i=0; //かつ、前回と今回の動きが同じならば、変数iを0に変える }else{ i++; //前回と異なる動きをしたならば、変数iを1増やし、前回の動きをしめすlast_turnをturn_dirの動きである1に変える last_turn=turn_dir; } }else{ //右のほうが強い光を感知したとき OnFwd(OUT_A); Wait(RUN_TIME); Off(OUT_A); turn_dir=0; //右に1回(0,2秒)進み、turn_dirという変数を0に変える if(turn_dir==last_turn){ //かつ、前回と今回の動きが同じならば、変数iを0に変える i=0; }else{ //前回と異なる動きをしたならば、変数iを1増やし、last_turnをturn_dirの0に変える i++; last_turn=turn_dir; } } } throw_block(); //iが5を越えたので、ブロックを投げて停止。 Off(OUT_A+OUT_B); }