ボール運搬ロボット
ボールを所定の位置から運び出し、決められた、ゴールに入れる。
ボールをそれぞれ向きの違う棒に挟まれた状態から運びだし、4箇所あるゴールの箱に入れる。
競技時間は審判が続行不能と判断するまで、あるいはリタイアするまで。 4隅のコーナー(半径30cmの1/4円)のいずれかからスタートする。 スタート時のロボットは2個を越えないこと (スタート後はいくつに分裂してもかまわない)。
開始の合図から5秒以内にRCXのスタートボタンを押す作業を完了すること。 競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。 途中でうまく動かなくなった場合、1回限り再スタートすることができる。
基本得点の計算方法
半分以上箱に入ったボールだけを得点の対象とする。
横から入れるゴールについてはボール1個2点、上から入れるゴールについては1個4点で計算する。ただし同じ箱に3個のボールを入れた場合には、その箱に限り点数を倍にする。
技術点の計算方法 以下の動作の精度・スピード・確実性などを含めた技術的な工夫や芸術性について他の全てのチーム(9チーム+TAor教員)が20点満点で採点し、その平均点を求める。
得点の目安:
ボールを取り出す動作 (3点)
ボールを運ぶ動作 (3点)
ボールを紙パックに押し込む動作 (3点)
2台以上のロボット、あるいは単体のロボットの場合は2台のRCXの連携の良さ(3点) 自立型のロボットとしての形や動作の美しさ、斬新さ(3点)
その他 (5点)
#define ROTATION_GET 60 #define ROTATION_PUT 10 #define ROTATION_KICK 500 #define ROTATION_GIVE 130 #define FRONT 1 #define BACK 2 #define DEGREE_OF_LIGHT 53 // ロボットの腕を動く関数 // iRotation : 腕を動く角度の変数 // iDirection : 腕を動く方向 void move_arm ( int iRotation, int iDirection ) { int iTime = iRotation; ClearSensor ( SENSOR_2 ); if ( iDirection == FRONT ) { OnFwd ( OUT_B ); } else { OnRev ( OUT_B ); } Wait ( iRotation ); Off ( OUT_B ); } // ロボットを前進する関数 // iTime : 前進する時間 void go ( int iTime ) { OnFwd ( OUT_A ); OnFwd ( OUT_C ); Wait ( iTime ); Off ( OUT_A + OUT_C ); } // ロボットを後進する関数 // iTime : 後進する時間 void back ( int iTime ) { OnRev ( OUT_A ); OnRev ( OUT_C ); Wait ( iTime ); Off ( OUT_A + OUT_C ); } // ロボットを左に曲がる関数 void left ( ) { OnRev ( OUT_A ); OnFwd ( OUT_C ); Wait ( 46 ); Off ( OUT_A + OUT_C ); } // ロボットを右に曲がる関数 void right () { OnFwd ( OUT_A ); OnRev ( OUT_C ); Wait ( 46 ); Off ( OUT_A + OUT_C ); } task main() { SetSensor ( SENSOR_2, SENSOR_LIGHT ); SetSensor ( SENSOR_3, SENSOR_LIGHT ); SetSensor ( SENSOR_1, SENSOR_TOUCH ); go ( 145 ); left ( ); go ( 60 ); move_arm ( ROTATION_GET, FRONT ); back ( 20 ); right ( ); go ( 150 ); left (); go ( 200 ); move_arm ( ROTATION_GIVE, FRONT ); move_arm ( ROTATION_GIVE, BACK ); Wait ( 30 ); move_arm ( ROTATION_GIVE, FRONT ); move_arm ( ROTATION_GIVE, BACK ); back (90 ); right ( ); go (70 ); move_arm ( ROTATION_GET, FRONT ); back ( 30 ); left ( ); go ( 130 ); move_arm ( ROTATION_GIVE, FRONT ); move_arm ( ROTATION_GIVE, BACK ); Wait ( 30 ); move_arm ( ROTATION_GIVE, FRONT ); move_arm ( ROTATION_GIVE, BACK ); back ( 90 ); right (); go (70 ); move_arm(ROTATION_KICK, BACK ); go ( 30 ); move_arm(ROTATION_KICK, BACK ); go (30 ); move_arm(ROTATION_KICK, BACK ); }
フィールドの端から上に穴のあいた箱の前まで行き、
もうひとつのロボットがボールをいれるの待ってから、箱にボールを入れるプログラムです。本番までにロボット等を完璧に作成できなかったため、このプログラムを作りました。
この動作に関しては問題なく動きましたが、まっすぐ進まないといったロボット側の問題はありました。
また本番に待つ時間を間違えるというミスもあり、本番ではうまくいきませんでした。
task main(){ OnFwd(OUT_A+OUT_C); //箱の前まで直進 Wait(575); Off(OUT_A+OUT_C); Wait(1600); //ボールが乗るまで待機 OnRev(OUT_B); Wait(30); Off(OUT_B); OnFwd(OUT_B); //ボールを箱にいれる Wait(30); Off(OUT_B);}
(作成者:三澤)
こちらが最初に計画していたプログラムで、外側の楕円をライントレースしながら箱にボールをいれる、というプログラムです。
外側の楕円を時計回りに進み、ライントレースはロボット本体の左側についている光センサー1つで行います。
ボールの受け渡しは外側の楕円と8の字が合流する部分で行います。両側の光センサーが黒を感知したら止まります。
ボールを受け取ったら、上に穴の開いた箱の前に行くのですが、箱と黒い線が完全にくっついているため、ここで悩みました。
タッチセンサーをつけ、箱を感知したらうまくよけて、箱の横に着くようにしてみましたが、これでうまくいくかは確認できてません。
また、通信機能を使い、ボールの受け渡し地点まで来たら、ボールを運ぶロボットのほうにそれを伝えるようにしてみました。
#define BLACKLINE 45 #define SIGNAL_A 11 #define SIGNAL_B 12 task main () { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_2,SENSOR_TOUCH); SetSensor(SENSOR_3,SENSOR_LIGHT); while (true) { if(SENSOR_1 < BLACKLINE){ //左側の光センサーが黒線上なら直進 OnFwd(OUT_A+OUT_C); そうでない場合は右折 } else { OnFwd(OUT_A); Off(OUT_C);} if((SENSOR_1 < BLACKLINE) && (SENSOR_3 < BLACKLINE)){ //両側の光センサーが黒線上なら停止する Off(OUT_A+OUT_C); ClearMessage(); while(Message() == 1){ //もう1つのロボットから返信があるまで、自分がボール受け渡し地点まで来たことを通信で伝える SendMessage(SIGNAL_A);} if(Message() == 1){ //返信が来たら、音を鳴らす PlaySound(SOUND_CLICK); ClearMessage();} } if(Message() == SIGNAL_B){ //相手から「ボールを乗せた」と通信があったら再びライントレースを始める SendMessage(2); OnFwd(OUT_A+OUT_C);} if(SENSOR_2 == 1){ //タッチセンサーが箱に触ったら箱を回避して横付けする OnRev(OUT_A+OUT_C); Wait(100); Off(OUT_C); OnFwd(OUT_A); Wait(190); OnFwd(OUT_A+OUT_C); Wait(50); Off(OUT_A); OnFwd(OUT_C); OnFwd(OUT_A+OUT_C); Wait(300); Off(OUT_A+OUT_C); OnFwd(OUT_B); //ボールを箱にいれる Wait(30); Off(OUT_B); OnFwd(OUT_A+OUT_C);} } }
(作成者:三澤)