目次
課題2で作成したコース上にランダムに置いたテニスボール(3個)をロータリーの中央部分に置いたランタンに向かって
1. 転がす 2. 最短距離で運ぶ
ロボットを作成せよ。ただし、1の場合はテニスボールの置いてある場所から直接転がし、 2の場合はその場所から最短距離で運ぶこと。ボールを探す際にはラインに沿っても沿わなくてもよい。
使用するコースはこちら。
●全体図
かなり大柄なロボットになった。
タッチセンサーにつながったアームに入り込んだボールを、回転する灰色の板で押さえ、逆に回すことでそれを蹴りだすこともできる、というアイデア。
以下では、それぞれの部分を細かく説明していく。
●車体
モーターに接続された二輪とキャスターで動く。ボールを押さえる板が車体の前にあり、四輪をすべて駆動させたままでは非常に不安定だった。
こうすることで、非常に安定性が高まっている。
●タッチセンサーとアーム
マインドストームの説明書にあった一つのタッチセンサーを用いるバンパーを少し改造したもの。
車体とも関係のある話だが、キャスターが少し高く、ロボット全体がわずかに前向きに傾いているため、アームがタッチセンサーに触れにくい(テニスボールが触れれば、もちろん十分に押し込まれる)。つまり、振動による誤作動が少なくなっている。
●ボールを押さえる部分
前述のようにロボットの前方に重さが集中しているため、ボールを押さえる板を動かすモーターをできるだけ後ろにもってきたかった。
回転数の異なるギアを組み合わせることで、ボールを押さえる板の回転が遅くなっている。その分、正確さとパワーが増している。
以上のギアの組み合わせにより、車体後部のモーターの回転が、ボールを押さえる板を動かす動力となっている。
使用したトルクギアは、一定以上の負荷がかかると空回りするギア。ボールを押さえすぎた場合でもその過剰な回転を緩衝することができる。
task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); //ランタン探索用 SetSensor(SENSOR_2,SENSOR_TOUCH); SetSensor(SENSOR_3,SENSOR_LIGHT); //ライントレース用 while(SENSOR_2==0) //ボールに触れていない状態での挙動 { if (SENSOR_3 < 40) { OnFwd(OUT_A); Off(OUT_C); } else { Off(OUT_A); OnFwd(OUT_C); } } Off(OUT_A+OUT_C); //触れた場合は停止し OnRev(OUT_B); //板を閉じる Wait(120); Off(OUT_B); ClearTimer(0); //回転し続ける間 int light_max; //明るさの最大値を light_max=0; //記録しつづける while(FastTimer(0)<400) { OnFwd(OUT_A); OnRev(OUT_C); if(SENSOR_1 > light_max) {light_max=SENSOR_1;} } OnFwd(OUT_A); //先ほどの OnRev(OUT_C); //最大値のところまで until(SENSOR_1>=light_max); //回転し OnFwd(OUT_A+OUT_C); //直進 until(SENSOR_1>=62); //既定の明るさまで近づいたら Off(OUT_A+OUT_C); //停止 }
#define THRESHOLD 45 //ライントレースで使用する閾値。 #define T 360 //周回に要する時間。 task main() { SetSensor(SENSOR_1, SENSOR_LIGHT);//センサー1を光センサーに。ランタン捜索用。 SetSensor(SENSOR_2, SENSOR_TOUCH);//センサー2をタッチセンサーに。 SetSensor(SENSOR_3, SENSOR_LIGHT);//センサー3を光センサーに。ライントレース用。 int i; //テニスボールは3つなので、3回繰り返す。 int i_min=1,i_max=3; //iの初期値を1、最大値を3とする。 for (i=i_min; i<=i_max; i++) //繰り返す度にiを1増やし、iが3になるまで繰り返す。 { while (SENSOR_2==0) //タッチセンサーが反応するまで。 { if (SENSOR_3 < THRESHOLD)//ライントレース用のセンサーが黒線を感知している場合 { OnFwd(OUT_A); Off(OUT_C); //右に進む } else //そうでなければ { Off(OUT_A); OnFwd(OUT_C); //左に進む } } //ライントレース用のセンサーが1つしか使えないため、ギザギザ進んでトレースする。 Off(OUT_A+OUT_C); OnRev(OUT_B);Wait(120); //ボールを押さえる板を下ろす。 Off(OUT_B); int l_max; l_max=0; int t_max; t_max=0; //l_maxとt_maxという関数を定義。 ClearTimer(0); //タイマーをセット。 while(FastTimer(0)<=T) { OnRev(OUT_A);OnFwd(OUT_C);//Tで定めた一周回転するのに必要な時間、回転。 if(SENSOR_1>l_max) { l_max=SENSOR_1; t_max=FastTimer(0); //この間、感知した光の最大値を常にl_maxとして更新。かかった時間をt_maxとする。 } } OnFwd(OUT_A);OnRev(OUT_C);Wait(T-t_max);//先ほどと逆に(T-t_max)回転することで、ランタンの方向を向く。 Off(OUT_A+OUT_C); OnFwd(OUT_B);Wait(360);Off(OUT_B); //ボールを蹴り出す。 OnFwd(OUT_A);OnRev(OUT_C); Wait(t_max);Off(OUT_A+OUT_C); //もとの向きへ戻る。 } }