目次
arara(自分)
2014a/Mission2に詳細が載っています
(写真左)黄色い本体を1つにすることができれば良かったのだが、 アーム部分に2つのモーターを使わないと持ち上がらないことと、 本体の同じ位置にコードを重ねて置く事ができないということから 2つの本体を使う事になった。 また、最初は平行に並べて細長いロボットになっていたが、 旋回能力の低さとモーターへの負荷が大きかった。 そのため、写真のように一方を立てる配置にすることで解決した。
(写真右)どのコードがどの部分につながるかを以下に示す。
水色:右車輪を動かすモーター 青色:左車輪を動かすモーター 黄緑:ライントレース用の光センサー 橙色:2つともアームを動かすモーター 赤色:紙コップを識別する光センサー
(写真左)立てている本体は安定しないため、ロボットのベースともうひとつの本体にビームを使って固定した。
(写真右)ロボットの下面の写真である。緑の方はライントレース用の光センサー、黄色の方は紙コップ識別用の光センサ−。紙コップ識別用の方はなるべくコップに近づけるためにアームの間からできるだけ前に出るように工夫した。
アームが一番下まで下がると、上下運動の駆動から開閉の駆動に変わり、
アームが閉まりきると、開閉運動から上下運動の駆動に変わることを使ったアームである。
閉まるときに紙コップを置くと、紙コップをはさみ持ち上げる動作を、ひとつの命令だけで行うことができる。
1の紙コップはマジックペンで黒
2の紙コップは鉛筆で黒
3の紙コップは白いまま
というように色分けをして、その明るさを区別する事で判断している。
プログラム通信の流れは次のようにしてなされている。ここではAの位置にある紙コップが1番だったと判断したときのものである。2番、3番だった時も同じように通信が行われる。かわるところは送受信メッセージの中の「1」が2や3になるのみである。
また、通信の際に受信ができない場合が起こり得るので、受信側は受信できた事を知らせるメッセージを送信側に送ってから行動をスタートする。送信側も、受信完了のメッセージが来るまで命令のメッセージを送り続け、3秒ごとに送信できたかどうかを音を鳴らす事で周囲に知らせる。
「動きに関するプログラム側」 「アームを動かすプログラミング側」
紙コップが1だと判断
↓
少しだけ後進
↓
停止したのちCUPA1を送信 → CUPA1を受信
↓
アームを下げる
↓
GOFOR受信後に前進 ← GOFOR送信
↓
ARMUPを送信 → ARMUP受信後、コップを持ち上げる
↓
GOA1受信 ← GOA1を送信
↓
1の場所に移動(識別用の光センサーが再び1番のコップを判断する)
↓
着いたら少し後進
↓
ARMDOWNを送信 → ARMDOWN受信
↓
アームを下げてコップを重ねる
↓
GOBACK受信後、後進 ← GOBACKを送信
#define CUPA1 111 #define CUPA2 112 #define CUPA3 113 #define GOFOR 200 #define GOBACK 201 #define ARMUP 202 #define ARMDOWN 203 #define GOA1 121 #define GOA2 122 #define GOA3 123 #define SKIT 45 //トレースのしきい値 #define JUDGE 45 //紙コップ判断のしきい値 #define HIGHPOWER 7 #define LOWPOWER 1 #define set_power_H SetPower(OUT_AC,HIGHPOWER);//速度を速める #define set_power_L SetPower(OUT_AC,LOWPOWER);//速度を落とす #define turn_left1 set_power_L;\ OnFwd(OUT_A); OnRev(OUT_C); //左旋回 #define turn_left0 set_power_L;\ OnFwd(OUT_A); Off(OUT_C); //左折 #define turn_right0 set_power_L;\ OnFwd(OUT_C); Off(OUT_A); //右折 #define turn_right1 set_power_L;\ OnFwd(OUT_C); OnRev(OUT_A); //右旋回 #define go_forward set_power_H; OnFwd(OUT_AC); //直進 #define go_back(s) OnRev(OUT_AC); Wait(s); Off(OUT_AC); //後進s秒間 #define STEP 1 //ライントレースの判断時間 #define noMAX 30 //右に行き過ぎた時、転回の最大回数 #define NOSTEP 200 //右に行き過ぎた時、左に戻るための時間 #define SENDTIME 300
sub line_trace(tim) { SetSensor(SENSOR_2, SENSOR_LIGHT); //ライントレース用の光センサー int nonline=0; ClearTimer(1); /*しきい値よりも6低いと左旋回 しきい値よりも3低いと左折 しきい値よりも3高いと右折 しきい値よりも6高いと右旋回するが、 右旋回をしすぎて逆方向に行きそうであれば左旋回して戻る*/ while(Timer(1) <= tim){ if (SENSOR_2 < SKIT-6){ turn_left1; } else if (SENSOR_2 < SKIT-3) { turn_left0; } else if (SENSOR_2 < SKIT+3) { go_forward; } else { if(SENSOR_2 < SKIT+6) { turn_right0; } else { while (nonline < noMAX){ turn_right1; nonline++; } turn_left1; Wait(noMAX*STEP*NOSTEP); } nonline=0; } Wait(STEP); } }
task main() { SetSensor(SENSOR_3, SENSOR_LIGHT); //紙コップ識別用の光センサー /*下のコースに行ったあとライントレースをしながらA地点に行く 紙コップが黒ければ()CUPA1 紙コップが灰色なら()CUPA2 紙コップが白ければ()CUPA3 というメッセージを送る*/ go_forward; Wait(430); line_trace(800); while(true){
Aから1の場合
if (SENSOR_3 < JUDGE-7){ Off(OUT_AC); ClearTimer(0); ClearMessage(); while((Message() != 1)||(FastTimer(0)<SENDTIME)){ SendMessage(CUPA1); } if(Message() == 1){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); } until(Message() == GOFOR); SendMessage(2); OnFwd(OUT_AC); Wait(80); ClearTimer(0); ClearMessage(); while((Message() != 3)||(FastTimer(0)<SENDTIME)){ SendMessage(ARMUP); } if(Message() == 3){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); } ClearMessage(); while(true){ if(Message() == GOA1){ SendMessage(4); OnRev(OUT_AC); Wait(100); turn_left1; Wait(30); OnFwd(OUT_AC); Wait(300); line_trace(); until(SENSOR_3 < JUDGE-7); Off(OUT_AC); go_back(100); ClearTimer(0); ClearMessage(); while((Message() != 5)||(FastTimer(0)<SENDTIME)){ SendMessage(ARMDOWN); } if(Message() == 5){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); until(Message() == GOBACK); SendMessage(6); OnFwd(OUT_AC); Wait(80); ClearTimer(0); ClearMessage(); }
Aから2の場合
else if(SENSOR_3 < JUDGE-3){ Off(OUT_AC); ClearTimer(0); ClearMessage(); while((Message() != 1)||(FastTimer(0)<SENDTIME)){ SendMessage(CUPA2); } if(Message() == 1){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); } until(Message() == GOFOR); SendMessage(2); OnFwd(OUT_AC); Wait(80); ClearTimer(0); ClearMessage(); while((Message() != 3)||(FastTimer(0)<SENDTIME)){ SendMessage(ARMUP); } if(Message() == 3){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); } ClearMessage(); while(true){ if(Message() == GOA2){ SendMessage(4); line_trace(); until(SENSOR_3 < JUDGE-2); Off(OUT_AC); go_back(100); ClearTimer(0); ClearMessage(); while((Message() != 5)||(FastTimer(0)<SENDTIME)){ SendMessage(ARMDOWN); } if(Message() == 5){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); until(Message() == GOBACK); SendMessage(6); OnFwd(OUT_AC); Wait(80); ClearTimer(0); ClearMessage(); }
Aから3の場合
else if(SENSOR_3 > JUDGE+5){ Off(OUT_AC); ClearTimer(0); ClearMessage(); while((Message() != 1)||(FastTimer(0)<SENDTIME)){ SendMessage(CUPA3); } if(Message() == 1){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); } until(Message() == GOFOR); SendMessage(2); OnFwd(OUT_AC); Wait(80); ClearTimer(0); ClearMessage(); while((Message() != 3)||(FastTimer(0)<SENDTIME)){ SendMessage(ARMUP); } if(Message() == 3){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); } ClearMessage(); while(true){ if(Message() == GOA3){ SendMessage(4); go_forward; Wait(200); turn_left0; Wait(200); line_trace(); until(SENSOR_3 > JUDGE+6); Off(OUT_AC); go_back(100); ClearTimer(0); ClearMessage(); while((Message() != 5)||(FastTimer(0)<SENDTIME)){ SendMessage(ARMDOWN); } if(Message() == 1){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); until(Message() == GOBACK); SendMessage(6); OnFwd(OUT_AC); Wait(80); ClearTimer(0); ClearMessage(); } } }
#define CUPA1 111 #define CUPA2 112 #define CUPA3 113 #define GOFOR 200 #define GOBACK 201 #define ARMUP 202 #define ARMDOWN 203 #define GOA1 121 #define GOA2 122 #define GOA3 123 #define SENDTIME 300
メインタスク
task main() { /*CUPA1が送られてきたらコップをとって1の場所へ CUPA2が送られてきたらコップをとって2の場所へ CUPA3が送られてきたらコップをとって3の場所へ*/ ClearMessage(); OnRev(OUT_AC); //1の場所に着くまで、アームを上げた状態で待機 Wait(1200); Off(OUT_AC); while(true){
Aから1の場合
if(Message() == CUPA1){ SendMessage(1); OnFwd(OUT_AC); Wait(50); ClearTimer(0); ClearMessage(); while((Message() != 2)||(FastTimer(0)<SENDTIME)){ SendMessage(GOFOR); } if(Message() == 2){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); until(Message()==ARMUP); SendMessage(3); OnRev(OUT_AC); Wait(150); ClearTimer(0); ClearMessage(); while((Message() != 4)||(FastTimer(0)<SENDTIME)){ SendMessage(GOA1); } if(Message() == 4){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } until(Message()==ARMDOWN); SendMessage(5); OnFwd(OUT_AC); Wait(150); ClearTimer(0); ClearMessage(); while((Message() != 6)||(FastTimer(0)<SENDTIME)){ SendMessage(GOBACK); } if(Message() == 6){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); until(Message()==ARMUP); SendMessage(7); OnRev(OUT_AC); Wait(150);
Aから2の場合
}else if(Message() == CUPA2){ SendMessage(1); OnFwd(OUT_AC); Wait(50); ClearTimer(0); ClearMessage(); while((Message() != 2)||(FastTimer(0)<SENDTIME)){ SendMessage(GOFOR); } if(Message() == 2){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); until(Message()==ARMUP); SendMessage(3); OnRev(OUT_AC); Wait(150); ClearTimer(0); ClearMessage(); while((Message() != 4)||(FastTimer(0)<SENDTIME)){ SendMessage(GOA2); } if(Message() == 4){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } OnRev(OUT_B); Wait(800); } until(Message()==ARMDOWN); SendMessage(5); OnFwd(OUT_AC); Wait(150); ClearTimer(0); ClearMessage(); while((Message() != 6)||(FastTimer(0)<SENDTIME)){ SendMessage(GOBACK); } if(Message() == 6){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); until(Message()==ARMUP); SendMessage(7); OnRev(OUT_AC); Wait(150);
Aから3の場合
}if(Message() == CUPA3){ SendMessage(1); OnFwd(OUT_AC); Wait(50); ClearTimer(0); ClearMessage(); while((Message() != 2)||(FastTimer(0)<SENDTIME)){ SendMessage(GOFOR); } if(Message() == 2){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); until(Message()==ARMUP); SendMessage(3); OnRev(OUT_AC); Wait(150); ClearTimer(0); ClearMessage(); while((Message() != 4)||(FastTimer(0)<SENDTIME)){ SendMessage(GOA3); } if(Message() == 4){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); until(Message()==ARMDOWN); SendMessage(5); OnFwd(OUT_AC); Wait(150); ClearTimer(0); ClearMessage(); while((Message() != 6)||(FastTimer(0)<SENDTIME)){ SendMessage(GOBACK); } if(Message() == 6){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); } Wait(50); until(Message()==ARMUP); SendMessage(7); OnRev(OUT_AC); Wait(150); } }
こちらのプログラムは、ライントレースも通信もしない、コップを重ねる事だけに重点をおいたものである
そのため、非常にシンプルかつ初歩的なプログラムとなった
さらに、Aの位置にあるコップが1番のコップであると仮定された限定的なプログラムである
定義
#define HIGHPOWER 7 //HIGHPOWERの値を7に設定 #define LOWPOWER 1 //LOWPOWERの値を1に設定 #define set_power_H SetPower(OUT_AC,HIGHPOWER);//速度を速める #define set_power_L SetPower(OUT_AC,LOWPOWER);//速度を落とす #define turn_left1(p) set_power_L;\ OnFwd(OUT_A); OnRev(OUT_C); Wait(p); //左旋回 #define turn_left0(q) set_power_L;\ OnFwd(OUT_A); Off(OUT_C); Wait(q); //左折 #define turn_right0(r) set_power_L;\ OnFwd(OUT_C); Off(OUT_A); Wait(r); //右折 #define turn_right1(s) set_power_L;\ OnFwd(OUT_C); OnRev(OUT_A); Wait(s); //右旋回 #define go_forward(t) set_power_H; OnFwd(OUT_AC); Wait(t); //直進 #define go_back(u) OnRev(OUT_AC); Wait(u); Off(OUT_AC); //後進s秒間
メインタスク
task main() { turn_right1(165); go_forward(290); turn_left1(140); go_forward(320); turn_left1(120); go_forward(310); turn_left1(30); Off(OUT_AC); Wait(100); go_forward(50); Off(OUT_AC); }
1.スタート地点から右旋回をして真下を向き、Aのコップと横並びになる位置まで前進
2.左旋回をした後、Aの位置のコップに向かって前進
3.2番と3番のコップにぶつからない位置で左旋回をしたあとに前進
4.1番のコップの手前まで来たら、コップの方向を向いて1秒間停止(このときアームを上げる)
5.そのまま0.5秒間前進して(このときアームを下げてコップを重ねる)、停止
定義
#define t1 165 #define t2 290 #define t3 140 #define t4 320 #define t5 120 #define t6 310 #define t7 30 #define UPTIME t1+t2+t3+t4+t5+t6+t7 //ロボットが1番のコップの位置につくまでの時間
メインタスク
task main() { Wait(UPTIME); OnFwd(OUT_AC); Wait(150); Off(OUT_AC); OnRev(OUT_AC); Wait(150); Off(OUT_AC); }
1.ロボットが1番のコップの手前まで来るまで待つ
2.アームを上げてAの位置から持ってきたコップをつかむ
3.アームを下げて1番のコップの上にAの位置のコップを重ねる
4人に増えた分時間はかからないと思っていたが、課題1と同じくらいか、それより多くの時間を使う事になった。今回はプログラミングを主に担当したが、時間の都合でAの位置のコップ移動をさせるものしか作れなかった。プログラミングの中で、ライントレースするものをサブルーティンとして書いたが、これを一旦とめたり、また動かしたりするプログラミングが書けなかった為、ライントレースをし続ける結果となってしまい、上手くいかなかった。
コンテストの本番には行けなかったが、チームの頑張りによってなんとか6位につけたことをうれしく思う。実際に他のチームのロボットを見てみたかった。