目次
「空き缶を収集し、ゴールに空き缶をなるべく高く積み上げる」という課題である。
フィールドの説明
◦フィールドは課題2で使用した紙を使用する
◦図のピンク色の場所に350mlの空き缶を置く
◦図のライトブルーの円のいずれか一箇所に中身の入った350mlの缶を置く
◦中身の入った缶には紙をはったり図などを描いてもよい
課題の内容に関して詳しくはこちら課題3
私たちのグループは都合により8月7日の発表会に出ることができなかったため、ほかのグループより早く発表することとなった。
ロボットを組み立てる前にどのように点数を取っていくのかを考える必要があった。何段積み上げるのか、どのようなルートで行くのかを決めておかないとロボットの全体像が浮かばない。
そこで私たちは、Eの交差点の缶→Gの交差点の缶→中身の入った缶の順番で缶を積み上げていき、3段積み上げた状態でゴールに入れることができるロボットを作ることにした。
プログラムをしていくうえで中身の入った缶をとるのがとても大変なことがわかり、結果Eの交差点の缶→Gの交差点の缶→Hの交差点の缶の順で積み上げることとなった。
二台のロボットで動かすのではなく、二つのキットを一つに組み合わせたロボットを作るという方針にした。 ロボットの形状については、缶をできるだけ高く積むためにレールをつけ、アームが上下に動く形を採用した。
一番最初に作った試作機では、アーム部分に多くの部品を用いてしまったため、重くなりすぎてしまいアームを持ち上げることができないという事態が起こった。それに加えて、部品を多く使ったためレールを作る段階で部品が足りなくなってしまったため、アーム部分をまた一から作り直すこととなった。
ほかの失敗としては、ロボット本体を前後に長くしすぎてしまったため曲がるときにフィールドから出てしまうという事態が起こった。そのため、できるだけ最小限の大きさにするように心がけた。
ロボット本体を斜め上から写した画像である。
ロボット本体を横から写した画像である。
ロボット本体を前から写した画像である。
アームを本体の前側に付けるため重心がどうしても前に寄ってしまう。そのため、ロボットをコンパクトにするためと重心を安定させるためにRISの通信部分(電池が入っている本体部分)を縦に重ねることにした。
タイヤは小回りを利かせるため小さなタイヤを用いた。後ろのタイヤは動力がつながっておらず、摩擦が少ないため曲がるときには横に滑る。
光センサーは全部で3つ搭載しており、下に向く2つの光センサーはライントレース用、前を向いている光センサーは缶を識別する用である。詳しくは次の各部の説明で説明する。
私はアーム部分のプログラムを担当した。缶判別用の光センサーとアームの上下移動、アーム開閉のプログラムである。ロボット同士の通信をしなくてもゴールまで行くことができたため、通信は用いなかった。完全に独立した動きをしていたためプログラムをするのが楽だった。
//A アーム上下 //C アーム開閉 #define kan_hanbetu 26 //光センサーが缶を判別する値
缶には黒い紙を貼ることで光センサーが缶と認識できるようにした。缶判別の値は26とした。
void arm_close(int time) { OnRev(OUT_C); //アームを閉じる Wait(time); OnRev(OUT_A); //上に上がる Wait(280); Off(OUT_A); }
アームを閉じ、一番上まで上がるというvoidである。アームを閉じた後のWait時間は状況によって変わるためintを用い、引数とした。
sub arm_open() { Wait(300); OnFwd(OUT_A); //下に下がる Wait(20); Off(OUT_A); OnFwd(OUT_C); //アームを開く Wait(20); Off(OUT_AC); OnFwd(OUT_A); //下に下がる Wait(250); Off(OUT_A); }
缶を持った状態でアームが一番上にHOLDされているところから、少し下がりアームを開いて缶を重ね、アームを一番下まで下げるsubである。
task main () { while (true) { if (SENSOR_2 <= kan_hanbetu) { Wait(300); arm_close(300); Wait(100); OnRev(OUT_A); //上に上がる Wait(500); while (true) { if (SENSOR_2 <= kan_hanbetu) { arm_open(); Wait(80); arm_close(30); OnRev(OUT_A); //上に上がる Wait(500); while (true) { if (SENSOR_2 <= kan_hanbetu) { OnFwd(OUT_A); //下に下がる Wait(200); Off(OUT_A); Wait(200); OnFwd(OUT_C); //アームを開く Wait(30); Off(OUT_C); } } } } } } }
Whileとifを使うことで缶を判別したときに次のプログラムに進むようになっている。
光センサーが缶を直前ではなく少し前の段階で判別してしまうため、ifの後にはWaitを入れ、調節している。
その他のWaitは次の缶の場所に移動するときや、ゴールまで運んでいるときのWaitである。
#define senkai_left OnRev(OUT_C);OnFwd(OUT_A);//左旋回 #define senkai_right OnFwd(OUT_C);OnRev(OUT_A); //右旋回 #define turn_left Off(OUT_C);OnFwd(OUT_A);//左折 #define turn_right OnFwd(OUT_C);Off(OUT_A);//右折 #define fwd OnFwd(OUT_AC);//直進 void go_fwd(int time) { fwd; Wait(time); Off(OUT_AC); } sub usetu() { turn_right; Wait(230); Off(OUT_C); senkai_right; Wait(50); Off(OUT_AC); OnRev(OUT_AC); Wait(30); Off(OUT_AC); } sub sasetu() { turn_left; Wait(190); Off(OUT_A); senkai_left; Wait(40); Off(OUT_AC); } sub naname_usetu() { OnFwd(OUT_C); Off(OUT_A); Wait(200); Off(OUT_C); OnRev(OUT_AC); Wait(40); Off(OUT_AC); } sub owari() { turn_right; Wait(70); Off(OUT_AC); Wait(450); OnRev(OUT_AC); Wait(200); Off(OUT_AC); } sub line_trace() { SetSensor(SENSOR_1, SENSOR_LIGHT); //右 SetSensor(SENSOR_3, SENSOR_LIGHT); //左 ClearTimer(0); PlaySound(SOUND_CLICK); while(FastTimer(0)<11){ if(SENSOR_1>=49&&SENSOR_3>=55){ fwd; ClearTimer(0); }else if(SENSOR_3>=50){ turn_right; ClearTimer(0); }else if(SENSOR_1>=40){ turn_left; ClearTimer(0); }else if(SENSOR_3>=48){ senkai_right; ClearTimer(0); }else if(SENSOR_1>=38){ senkai_left; ClearTimer(0); }else if(SENSOR_1>=30){ Off(OUT_AC); PlaySound(SOUND_LOW_BEEP); }else if(SENSOR_3>=30){ Off(OUT_AC); PlaySound(SOUND_LOW_BEEP); }else{ fwd; Wait(30); Off(OUT_AC); } } Off(OUT_AC); PlaySound(SOUND_CLICK); } void line_trace_2(int time) { SetSensor(SENSOR_1, SENSOR_LIGHT); //右 SetSensor(SENSOR_3, SENSOR_LIGHT); //左 ClearTimer(0); ClearTimer(1); PlaySound(SOUND_CLICK); while(FastTimer(0)<11&&FastTimer(1)<time){ if(SENSOR_1>=49&&SENSOR_3>=55){ fwd; ClearTimer(0); }else if(SENSOR_3>=50){ turn_right; ClearTimer(0); }else if(SENSOR_1>=40){ turn_left; ClearTimer(0); }else if(SENSOR_3>=48){ senkai_right; ClearTimer(0); }else if(SENSOR_1>=38){ senkai_left; ClearTimer(0); }else if(SENSOR_1>=30){ Off(OUT_AC); PlaySound(SOUND_LOW_BEEP); }else if(SENSOR_3>=30){ Off(OUT_AC); PlaySound(SOUND_LOW_BEEP); }else{ fwd; Wait(30); Off(OUT_AC); } } Off(OUT_AC); } task main() { go_fwd(50); line_trace(); usetu(); repeat(2){ line_trace(); Wait(50); naname_usetu(); Wait(50); } line_trace_2(230); Wait(500); senkai_left; Wait(200); Off(OUT_AC); go_fwd(30); line_trace(); Wait(450); sasetu(); line_trace(); owari(); }
タイヤ側のプログラムはrockが担当したため詳しい解説はこちらのページを見ていただきたい。 rockのmisson3
結果は中身の入っていない缶3つを積み上げたため3+6+9で18点であった。
実際に動かした動画はこちらmisson3動画
今回のmission3では多くの失敗を繰り返した。ロボットを作るうえでも、プログラムを作るうえでもうまくいかないことが多く、そのたびに一からやり直すということがあった。ほかの人よりも発表が早いこともあってか、最後の詰めの部分が甘くなってしまったかもしれない。ロボットの完成度は高かったため、もう少し時間があれば缶を4つ積んだり、中身の入った缶を回収することも可能だったのではないかと思う。
しかし、多くの時間をかけたため完成した時の喜びは大きかった。グループで集まるときにはちゃんと4人集まって作ることが多かったので、意見を出し合うことができ、良いチームワークだったと思う。
ロボティクスを通じて自ら研究・探求する力を身に付けることができたと思う。チームのみんなに感謝しつつ、これからも探求心を持ち続けていきたい。
訪問者合計1179