半径1m以内にある懐中電灯を探し出し懐中電灯にピンポン玉を当てるロボットを作る。
光の最大値が変わっていくため次々と更新していかなければならず、時間も計らなくてはならない。また最後にロボットがピンポン玉をシュートし懐中電灯にあてなくてはならないためシュートをまっすぐに飛ばさなくてはならない。
基本的な部分は課題2で製作したロボットと変わりはないが2つ変更点があり、1つは光センサーの位置。もう1つはアームの可動域である。そのためここでは光センサー、アームの変更点について説明する。
光センサーは下向きだと懐中電灯の光を感知しないため、上の写真の位置に前方に向けて設置した。
今回の課題3はピンポン玉をはじめから持った状態でスタートするためアームの可動域はあまり関係がないが、前回の課題2の欠点であった部分の改善に成功したためここで載せておく。課題2の時よりもアームを大きく開けることができるようになった。
#define kaiten360 345
このロボットが360度旋回するのにかかった時間は約3.45秒であった。
#define KAITEN OnFwd(OUT_A); OnRev(OUT_C);//回転のプログラム #define shoot OnRev(OUT_B);Wait(20);Off(OUT_B);SetPower(OUT_AC,7);OnFwd(OUT_AC);Wait(60);OnRev(OUT_AC);Wait(60);Off(OUT_AC);//ピンポン玉をシュートするプログラム
このロボットのシュート方法はアームを開いて前進することでピンポン玉を前に押し出す形でシュートする。少しでも威力を上げるためパワーを上げている。
sub SAGASU() { ClearTimer(0); KAITEN;
タイマーをスタートさせ旋回させる
while(FastTimer(0) < kaiten360) {
3.45秒になるまで旋回させる
if(SENSOR_1>max) { int max = SENSOR_1; //光センサーの値の最大値を記録 int zikan = FastTimer(0); //最大値が更新された時の時間を記録 }
実際に動かしたプログラムではないがグローバル変数はややこしくなるらしいのでローカル変数に修正した。光センサーの値が更新されたらその時の光センサーの値とそれまでにかかった時間を記録するようにする。
} OnRev(OUT_A);OnFwd(OUT_C);Wait(kaiten360 - zikan); Off(OUT_AC);Wait(50); }
光が一番強かった方へ向くようにする。このとき旋回する方向を逆にし、約360度旋回する時間から記録した時間を引くことによりkaiten360の値で正確に360度回らなくてもその誤差を修正することができる。
task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); SAGASU;
センサーをセットし光センサーの最大値を記録する整数値とその時の時間を記録する整数値をセットし懐中電灯を探す
Off(OUT_AC);Wait(50); OnFwd(OUT_AC);Wait(100);Off(OUT_AC);
このときロボットは懐中電灯の方を向いているはずなので懐中電灯の方へ進む
SAGASU;
前に進んだことでロボットの向きが懐中電灯からずれてしまってはいけないから念のためもう一度懐中電灯を探す。これをすることで他よりも精度が少し上がる。
shoot; }
ボールを懐中電灯の向きに押し出してシュートする
ロボットを課題2のものをベースにすることができたため、機動性に優れ安定したマシーンを短時間で用意することができた。ロボットは前回の反省を生かして改善点を直すことができた。プログラムではサブルーチンや定義を使うことで比較的見やすいプログラムにできたと思う。今回覚えるべき数が光センサーの最大値とそこに至るまでの時間の2つあってどちらもリアルタイムで計測しながら記憶するプログラムを作らなくてはならなかったが、なんとか目標に近いプログラムが作成できたと思う。
シュート方法が毎回押し出し式で芸がないとは思ったがコンパクトな車体を保ちつつシュートを決められる構造が思いつかなかった。押し出し式ではやはりシュートの安定にかけるため別の方法ももっと考えるべきだったかもしれない。