半径1m以内にある懐中電灯を探して、懐中電灯にピンポン玉を当てるロボットを製作しなさい。
ただし、ピンポン玉を放つ距離は10〜30cmとする。 ロボット本体が懐中電灯に接触しない限りどこからピンポン玉を放ってもよい。
・ライトセンサーを前方に付けて本体を一回転、周囲の明るさを読み取る
・明るさの最大値を求める
・タイマーを用いて明るさの最大値の時刻を記録し使用する
本体は課題2で使用したロボットを使用。
ボールのホールドやオープンから放出も課題2で使ったままの装置を用いた。
本体やホールド機構の詳しい説明は下記URL(課題2)を参照、
http://yakushi.shinshu-u.ac.jp/robotics/?2015a%2FMember%2Fluminous%2FMission2#t490a7b6
そして、ボール取り込み装置の前方にライトセンサーを設置した。
動画は懐中電灯ではなくスマホカメラのライトをオンにし、それを光源として捉えてカメラに向かってボールを放つというものを撮ってみた。
task main() {
/*センサー2番にライトセンサーを設置 */
SetSensor(SENSOR_2,SENSOR_LIGHT);
/*それぞれのカウントを開始する*/
int turn_time = 900; //360度回転するまでの時間 int light_max = 10; //この数値は後で更新されるので0でもいいが適当においてみた int time_max; //上のライトセンサーが最大値となった時間を記録する
/*タイマーをリセット*/
ClearTimer(0);
/*タイヤの回転を抑えて精度を良くする*/
SerPower(OUT_AC,1);
/*回転しながら観測を始める*/
OnFwd(OUT_A);OnRev(OUT_C); //左旋回 while(FastTimer(0) < turn_time) //360度回転するまで以下のことを行う { if(SENSOR_2 > light_max) //明るさが最大値になった時刻を、最大値を更新していく形でタイマーで記録する。 { //最大値と時刻は回転中何度でも更新が可能である。 light_max = SENSOR_2; time_max = FastTimer(0); } }
ここでは一番明るい方向を探している。
まずセンサーで明るさを読み取り、次の瞬間読み取った数値の方が明るさの値が大きかったらその明るさと時刻を記録、小さければ何もしないという形で一番明るい時の値とその時刻を記録し残す。これを繰り返しながら一回転することで一番明るい方向がわかる。
/*観測終了*/
Off(OUT_AC);PlaySound(SOUND_CLICK);Wait(100); //小休止しモーターの蓄積エネルギーを放つ。確認音を鳴らす
/*光センサーの観測した最大値のあるところまで逆回転する*/
SetPower(OUT_AC,1); //同じパワーで動かねばならない OnFwd(OUT_C);OnRev(OUT_A); //右回転 Wait(turn_time - time_max); //360度回転した時間からライトの最大値となった時刻を引き算して光の方向まで戻る。 Off(OUT_AC);
PlaySound(SOUND_CLICK);Wait(100);
/*ホールドしているボールを押し出してシュートする*/
OnRev(OUT_B);Wait(25);Off(OUT_B); //アームを開く OnFwd(OUT_AC);Wait(80);Off(OUT_AC); //前進
PlaySound(SOUND_DOWN); //終了確認音 }
定数にすることができたものもあるが3つのカウンタを同時に使えるのが面白かった。
今回はそのまま逆回転で引き算を用いて簡単に最大値の方向を向くプログラムにしたが
一回転するための秒数は私がモーターの具合を見て勝手に与えたものなので、
ライトセンサーの最大値を用いてまずはじめに一回転を正確にするプログラムもあれば良いと思った。
上記のプログラミングができれば正確な360度が分かるのだから更に時間はかかるだろうが
逆回転を使わずに最大値の方向を向くプログラムもできるだろう。