空き缶を分別して所定の場所に運ぶ。
二台に分けないタイプのロボット。アームの開閉運動及びアームの上下移動が可能。
アームの開閉にモーター一つと歯車を、上下移動にモーター二つをしようしている。タイヤ間に設置された光センサーによりライントレースを行う...はずだった(後述)。
見ての通りのアームの重量で光センサーが地面すれすれになった。そこで缶運搬の安定とアームの高さあげを兼ねてコの字状の部品を装着。
ただし先端部分はしっかり浮いているためスタートラインからはみ出ることはない(重要)
ロボット完成後に光センサー二つ使ったライントレースのほうがよいのではないか、超音波センサーを使って缶を探したらどうかなどの議論があったが実装されるに至らなかった。
缶を掴む能力に関しては、上図のように小タイヤが滑り止めの役割を果たしており、割と安定して上げ下げができる。
ただし缶を置く時にはアームの上下移動の下限により、ある程度の高さから落とす必要があるため注意が必要である。
ロボットの動きに関して、左右のタイヤを同出力にした場合曲がってしまうなど直進運動が苦手である。
また、上図では白缶を置いた後黒缶を戻しているが、逆の動きがプログラムされているにも関わらずしばしばズレをきたした。
ライントレース時もタイヤが動かなくなるなど安心させてくれることを知らないロボットである。
Aをスタートし、Yで積んだ二つをXに押し込んで確実に点を取る。これが完成して余裕があれば、押し出したほうの缶も積んでYに運ぶ予定だったが。。。
ロボコン前日に、あとはG通って押し込むだけだし今日はここまでと切り上げる。
ロボコン当日の朝前日の続きをする前に試運転。こっちのルートのほうがL周辺の曲がりがなくてよいのではと急遽変更。
(A-H-Iの左トレースをA-B-Jの右トレースにするだけだし大丈夫でしょみたいな感じ)
そして思い通り動かなくなる、Bの曲がりがうまくいかない。(前日までのプログラムは上書され再現不可)
さらにプログラムを書いていていたPCの不具合により作業中断、時間大幅ロス。
時間がもうない!Bで曲がれないなら直接いくしかない。ライントレースをせず直進して掴んでXへ押し入れるルートへ
これは以下のプログラムに共通する動きである。缶の掴む動作、上下移動を表す。
task main(){ OnRev(OUT_BC,30); OnRev(OUT_A,10); Wait(8000); }
task main(){ OnFwd(OUT_A,20); Wait(1000); Off(OUT_A); }
task main(){ OnFwd(OUT_BC,20); Wait(600); Off(OUT_BC); }
task main(){ OnRev(OUT_A,20); Wait(1000); }
マスター側のプログラム。作戦遷移2,3のプログラムを紹介する。(1は上記の理由、また冒頭部が右トレースである2と考えていただければ)
#define CONN 1//スレーブの番号を割り振り
#define AGERU RemoteStartProgram(CONN,"ageru.rxe");Wait(4500); //アームの上げるのを定義
#define SAGERU RemoteStartProgram(CONN,"sageru.rxe");Wait(3000); //アームの下げるのを定義
#define TUKAMU RemoteStartProgram(CONN,"tukamu.rxe");Wait(3500); //アームで掴むのを定義
#define HANASU RemoteStartProgram(CONN,"hanasu.rxe");Wait(3000); //アームで放すのを定義
#define MODOSU RemoteStartProgram(CONN,"modosu.rxe");Wait(3000); //アームを開きもとに戻す
#define KUZUSU TUKAMU;AGERU;OnRev(OUT_BC,10);Wait(1000);Off(OUT_BC);OnFwd(OUT_B,15);OnRev(OUT_C,15);Wait(1500);Off(OUT_BC);OnFwd(OUT_BC,10);Wait(1000);Off(OUT_BC);Wait(3000);SAGERU;HANASU;TUKAMU;AGERU;OnRev(OUT_BC,10);Wait(1000);Off(OUT_BC);OnFwd(OUT_C,15);OnRev(OUT_B,15);Wait(1600);Off(OUT_BC);OnFwd(OUT_BC,10);Wait(1300);Off(OUT_BC);Wait(1000);SAGERU;HANASU;
#define BLACK 40
#define LITTLE_BLACK 47
#define LITTLE_WHITE 53
#define WHITE 65
#define LEFT OnFwd(OUT_B,30);OnRev(OUT_C,30);Wait(1);Off(OUT_BC);
#define LITTLE_LEFT OnFwd(OUT_B,35);OnFwd(OUT_C,20);Wait(1);Off(OUT_BC);
#define LITTLE_RIGHT OnFwd(OUT_B,20);OnFwd(OUT_C,35);Wait(1);Off(OUT_BC);
#define RIGHT OnFwd(OUT_C,30);OnRev(OUT_B,30);Wait(1);Off(OUT_BC);
#define FRONT OnFwd(OUT_BC,25);Wait(1);Off(OUT_AC);
#define LINE_LEFT if (SENSOR_1 < BLACK) {LEFT;KAZU += 3;} else if (SENSOR_1 < LITTLE_BLACK) {LITTLE_LEFT;KAZU += 1;} else if (SENSOR_1 > WHITE) {RIGHT;KAZU -= 1;} else if (SENSOR_1 > LITTLE_WHITE) {LITTLE_RIGHT;KAZU -= 3;} else {FRONT;KAZU *= 0;}
#define LINE_RIGHT if (SENSOR_1 < BLACK) {RIGHT;KAZU += 3;} else if (SENSOR_1 < LITTLE_BLACK) {LITTLE_RIGHT;KAZU += 1;} else if (SENSOR_1 > WHITE) {LEFT;KAZU -= 1;}else if (SENSOR_1 > LITTLE_WHITE) {LITTLE_LEFT;KAZU -= 3;} else {FRONT;KAZU *= 0;}
task main() {
SetSensorLight(S1); //光センサを定義 int KAZU=0; int n = 0; long t0 = CurrentTick();
RemotePlayTone(1,440,1000);Wait(1500); //最初に音を鳴らす
MODOSU; //最初に念のため開いておく
while(n < 1){
if (SENSOR_1 < BLACK){OnFwd(OUT_C,25);OnFwd(OUT_B,20);Wait(700);Off(OUT_BC);n++;Off(OUT_BC);Wait(1);} else {OnFwd(OUT_BC,20);Wait(1);Off(OUT_BC);} }
n = 0; //黒を感知するまで進む//線を超えるために進む
while(n < 1){
if (SENSOR_1 < LITTLE_WHITE){OnFwd(OUT_C,35);OnFwd(OUT_B,20);Wait(100);Off(OUT_BC);n++;Off(OUT_BC);Wait(1);} else {OnFwd(OUT_B,40);OnFwd(OUT_C,20);Wait(1);Off(OUT_BC);} }
n = 0; //黒を感知するまで曲がる
repeat(2000){LINE_RIGHT;};KAZU *= 0; while(KAZU < 300){LINE_RIGHT;}; PlaySound(SOUND_DOUBLE_BEEP); //十字の交差点を感知
OnFwd(OUT_C,30);OnRev(OUT_B,30);Wait(1200); //右に曲がる OnFwd(OUT_BC,15);Wait(300);Off(OUT_BC);
repeat(2000){LINE_RIGHT;};KAZU *= 0; while(KAZU < 200){LINE_RIGHT;}; PlaySound(SOUND_DOUBLE_BEEP); //円との交差点を感知
KUZUSU; //缶を崩す
OnFwd(OUT_BC,15);Wait(200);Off(OUT_BC); OnRev(OUT_BC,15);Wait(200);Off(OUT_BC); OnFwd(OUT_C,15);OnRev(OUT_B,30);Wait(200);Off(OUT_BC); OnFwd(OUT_B,15);OnRev(OUT_C,15);Wait(200);Off(OUT_BC); //ぐちゃぐちゃやって積んだ缶を整える
Wait(1000);
SAGERU;TUKAMU; //引きずるために掴む
Wait(2000);
OnFwd(OUT_B,40);OnFwd(OUT_C,30);Wait(3000);Off(OUT_BC); //円を超えるために進む
repeat(3000){LINE_RIGHT};KAZU *= 0; while(KAZU < 200){LINE_RIGHT}; PlaySound(SOUND_DOUBLE_BEEP); //十字の交差点を感知
/* OnFwd(OUT_C,20);OnRev(OUT_B,20);//右に曲がる Wait(2500); Off(OUT_BC);
repeat(1500){LINE_RIGHT}; KAZU *= 0; while(KAZU < 100){LINE_RIGHT}; PlaySound(SOUND_DOUBLE_BEEP);//十字の交差点を感知
while(n < 1){
if (SENSOR_1 < BLACK){OnFwd(OUT_BC,20);Wait(1);Off(OUT_BC);} else{n++;Off(OUT_BC);Wait(1);}
} n = 0; //白を感知するまで進む OnFwd(OUT_BC,25); Wait(700); Off(OUT_BC); MODOSU;*/
/*TUKAMU;AGERU; OnRev(OUT_BC,20);Wait(2000);Off(OUT_BC); OnFwd(OUT_B,30);OnRev(OUT_C,30); Wait(1000); Off(OUT_BC); OnFwd(OUT_BC,20);Wait(2000);Off(OUT_BC); SAGERU;HANASU; TUKAMU;AGERU; OnRev(OUT_BC,20);Wait(2000);Off(OUT_BC); OnFwd(OUT_C,30);OnRev(OUT_B,30); Wait(1000); Off(OUT_BC); OnFwd(OUT_BC,20);Wait(2000);Off(OUT_BC); SAGERU;HANASU;MODOSU;*/
/*repeat(1000){LINE_RIGHT}; KAZU *= 0; while(KAZU < 100){LINE_RIGHT}; PlaySound(SOUND_DOUBLE_BEEP);//円との交差点を感知 /
はなす } task main(){ OnFwd(OUT_A,1c0); Wait(500); Off(OUT_A); }
#define CONN 1//スレーブの番号を割り振り
#define AGERU RemoteStartProgram(CONN,"ageru.rxe");Wait(4500); //アームの上げるのを定義
#define SAGERU RemoteStartProgram(CONN,"sageru.rxe");Wait(3000); //アームの下げるのを定義
#define TUKAMU RemoteStartProgram(CONN,"tukamu.rxe");Wait(3500); //アームで掴むのを定義
#define HANASU RemoteStartProgram(CONN,"hanasu.rxe");Wait(3000); //アームで放すのを定義
#define MODOSU RemoteStartProgram(CONN,"modosu.rxe");Wait(3000); //アームを開きもとに戻す
#define KUZUSU TUKAMU;AGERU;OnRev(OUT_BC,30);Wait(1000);Off(OUT_BC);OnFwd(OUT_B,30);OnRev(OUT_C,30);Wait(1500);Off(OUT_BC);OnFwd(OUT_BC,30);Wait(1000);Off(OUT_BC);Wait(3000);SAGERU;HANASU;TUKAMU;AGERU;OnRev(OUT_BC,30);Wait(1000);Off(OUT_BC);OnFwd(OUT_C,30);OnRev(OUT_B,30);Wait(2000);Off(OUT_BC);OnFwd(OUT_BC,30);Wait(1300);Off(OUT_BC);Wait(1000);SAGERU;
task main() { MODOSU; RemotePlayTone(1,440,1000);Wait(1500); //最初に音を鳴らす
OnFwd(OUT_BC,30); Wait(4000); Off(OUT_BC);//缶へ直行
KUZUSU; //缶を崩す
OnFwd(OUT_BC,15);Wait(200);Off(OUT_BC); OnRev(OUT_BC,15);Wait(200);Off(OUT_BC); OnFwd(OUT_C,15);OnRev(OUT_B,30);Wait(200);Off(OUT_BC); OnFwd(OUT_B,15);OnRev(OUT_C,15);Wait(200);Off(OUT_BC); //ぐちゃぐちゃやって整える
SAGERU;TUKAMU; //引きずるために掴む
OnFwd(OUT_B,30); OnFwd(OUT_C,35); Wait(4000); Off(OUT_BC);// 缶を運ぶ
OnFwd(OUT_C,30); Wait(500); Off(OUT_C);//もとからある缶を押し出す
HANASU; MODOSU; }
光センサー2つと超音波センサーを使いたかった。使えばもう少し正確な移動ができたかと。
また、時間が圧倒的に足りなかったロボコン前の土日では電池、集中力、時間の消費が著しかった。
もう少し余裕を持った日程を組めたら2のプログラムは完成できたように思う。
また、ロボコンでは見せれなかったが積み上げだけは満足できる動きができたように思う