目次
ピッチャーロボットとバッターロボットが所定の位置まで移動してピンポン球を投げて打つ
ピッチャーロボットはA地点をスタートしM地点まで移動する
バッターロボットはC地点をスタートしB地点まで移動する
スタート時はそれぞれA地点B地点の枠内に収まること(高さの制限はなし)
M地点、B地点では接地している部分が枠内に入っていること
ピッチャーロボットはスタート時にピンポン球を5個まで保持できる
ピッチャーロボットが投げたピンポン球をバッターロボットは3秒以上保持してはならない
移動の途中で目標(ゴール)に接触してはならない
目標は5個あり、それぞれに書かれている点数を合計する。ただし同じ目標に2個以上のピンポン玉が入った場合は2個目以降の得点は1個目の半分とする。
打つことができたにもかかわらずどの目標にも入らなかった場合には1点とする
以下の動作の精度・スピード・確実性などを含めた技術的な工夫や芸術性について他の全てのチームが20点満点で採点し、その平均点を求める。
スタートしてから目的地点まで移動する速さ、正確さ (3点)
ピンポン玉を投げる動作 (3点)
ピンポン玉を打つ動作 (3点)
2台のロボットの連携の良さ (3点)
自立型のロボットとしての形や動作の美しさ、斬新さ (3点)
ロボコン出場ロボットとしての完成度 (3点)
その他 (2点)
今回私たちはピッチャーの担当のためピッチャーをメインとして書く。プログラムもピッチャーのものである。
バッターは前のコの字型の部分でピンポン玉を受け止め、方向転換して打ち出すようになっている。また、入口が大きく球を受け止めやすくなっている。前には向き合うために必要な光センサーが設置してある。
二つの車輪で動き、前の長いブロックをレールにしている。ピンポン玉がその上を通りそのままバッターへ転がるようになっている。レールは地面ぎりぎりまで伸ばしてあり、コントロールし易いようになっている。
レールのすぐ横にタッチセンサーがついている。これは本体の上にブロックを置いたため、スタートボタンが押しづらくなっているので、代わりにこのセンサーをスタートボタンにしている。
ピンポン玉が上に積み重なっており、横のギアを動かすことで中の二本のブロックがピンポン玉一つを前に押し出す仕組みになっている。ピンポン玉が意図せずに前へ出ないようにグレー色のブロックが設置してある。
反対側には回転センサーがついており、一回転だけするようになっている。これにより球が出ないことや出すぎることがないようになっている。
#define GO OnFwd(OUT_AC); //前に進む #define BACK OnRev(OUT_AC); //後ろに進む #define CURVE_LEFT OnFwd(OUT_C); //左に曲がる #define TURN_RIGHT OnFwd(OUT_A);OnRev(OUT_C); //右に旋回 #define TURN_LEFT OnFwd(OUT_C);OnRev(OUT_A); //左に旋回 #define PUSH_BALL OnFwd(OUT_B); //球を押し出す #define NUMMBER1 111 //ピッチャーがバッターに送る値 #define NUMMBER2 222 //バッターがピッチャーに送る値 #define kaiten_time 120 //バッターを捜す時間 int light=0; //光センサーがとる値 int n=0; //投げる回数を数える値
sub THROW() { SetSensor(SENSOR_2,SENSOR_ROTATION); //回転センサー ClearSensor(SENSOR_2); //センサー2の値をリセット until(SENSOR_2>=16){ //一回転するまで回転 PUSH_BALL; //ボールを押し出す } Off(OUT_B); //止まる
M地点についた後バッターとピッチャーが向き合うために光センサーを使っている。光センサーの光は弱いため感知することが難しい。そのためバッターがピッチャーに近づいてお互い向き合ってから距離をとるようになっている。
M地点で右旋回しながら明るさの最大値を計測し、ある時間経過後に左旋回して最も明るい場所まで戻る仕組みになっている。
sub FACE() { SetSensor(SENSOR_3,SENSOR_LIGHT); //光センサー ClearTimer(0); //センサー3の値をリセット light=SENSOR_3; //センサー3の値をlightに置き換える while(FastTimer(0)<kaiten_time){ //定義で定めた時間より短いとき if(light<SENSOR_3){ //センサー3の値よりlightの値が小さいとき light=SENSOR_3; //センサー3の値をlightに置き換える if(light>=SENSOR_3){ //センサー3の値よりlightの値が大きいとき TURN_RIGHT; //右旋回を行う } } Off(OUT_AC); //停止する until(light<=SENSOR_3){ //センサー3が一番明るい数値以上になるまで TURN_LEFT; //左旋回する } Off(OUT_AC); //止まる Wait(300); //待機時間 }
task main() { SetSensor(SENSOR_1,SENSOR_TOUCH); //タッチセンサー until(SENSOR_1==1){ //タッチセンサーが押されるまで Off(OUT_AC); //待機 } CURVE_LEFT; //左に曲がる。 Wait(110); GO(OUT_AC); //AからMに向かう Wait(520); Off(OUT_AC); //止まる Wait(1500); //バッターが位置につくまで待機
サブルーチンのFACEを繰り返して通信ができる向きにする。もし一回で向き合うことが出来ない場合、その場で一秒待機して0.4秒右旋回を行う。これは最初の光センサーの値が最大値のとき、同じ場所を計測し続けてしまうためである。最後は右旋回を0.07秒することで調整をしている。
ClearTimer(1); //タイマー1の値をリセット ClearMessage(); //メッセージの値をリセット until(Message()==NUMMBER2){ //メッセージを受け取るまで if(FastTimer(1)>100){ //1秒よりも長い場合 TURN_RIGHT; //右旋回 Wait(40); FACE(); //バッターの方向を向く SendMessage(NUMMBER1); //メッセージを送る ClearTimer(1); //タイマー1の値をリセット } } TURN_RIGHT; //右旋回 Wait(7); Off(OUT_AC); //止まる
PlaySound(SOUND_UP); //音をならす Wait(143); THROW(); //ボールを押し出す ClearTimer(2); //タイマー2をリセット while(n<4){ //nが4よりも小さいとき if(FastTimer(2)>200){ //タイマー2が2秒(待機時間)より大きいなら PlaySound(SOUND_UP); //音をならす THROW(); //球を投げる ClearTimer(2); //タイマー2をリセット n++; //nの値に1を足す } } Off(OUT_AC); //止まる }
一回目、4点が一つ、バッターが打ち返せた球が一つ、6点が一つの計11点がとれた。また、他のチームからの判定で技術点が平均13.5点になり、合わせて24.5点の結果になった。
二回目は球を打ち返せてないため技術点のみの7.3点なった。
一回目の点数のおかげで1位をとることができた。しかし、このとき機体が紙を巻き込む事故がおきており、手で修正を行ったため成功とは言えないだろう。
今回は2機の連携が重要な鍵となる課題でした。時間で動くようにプログラミングしてしまうと電池のボルトが低下したときに再調整が必要になり、誤差が起きやすくなってしまう。そのためお互いに通信をして調整がしやすいようにプログラミングをしました。しかし、実際に動かしてみると機体の構造により通信が難しくなっていました。結果的には機体やプログラムを変えることで何とかできましたが、連携することがこんなにも難しいとは思いませんでした。何度もプログラムを実行して確実性を高めていく大切さが身にしみた課題だと思います。