空き缶を分別して所定の場所に運ぶ。
ロボットを2個に分けると連携が難しいと思ったので、1個の大きいロボットにした。2個のRISを移動とアームの動きに分けて使った。缶をつかむのをアーム型にすることで、少し位置がずれてもしっかりと缶をつかんでくれた。缶をつかむアームは、缶を持ち上げても滑り落ちないようにタイヤをつけて滑り止めにした。また、缶3個を積み上げたまま移動できるように、縦に高い囲いをつけた。
アームを上にあげると重力で自然に下がってしまうので、上にあげるときはモーターを回し続けて勝手に落ちないようにした。その時に、ロボットが壊れないように白色の「とりき」をつけた。
ロボットの高い位置に重いモーターをつけてアームを上下するときによくロボットが壊れてしまったので、補強をした。外側と内側に長い棒をピンでとめることで壊れることはなくなった。
後輪にモーターをつけた。前輪にもタイヤをつけたら摩擦や内輪差の違いなどで上手く回転ができなかったので、タイヤの代わりに丸い支えをつけた。ライトセンサーを前輪の前につけると、缶のある円に入ると丁度缶とアームの位置が合うようにしている。
大まかな動きとして、Xにある缶を一度外に出す。2段目をXに戻す。3段目を外に出す。1段目と3段目をYに持っていく。
#define arm_ueageru OnFwd(OUT_AC);Wait(120);Off(OUT_AC); //アームを一定時間上げる #define arm_sageru OnRev(OUT_C); //アームを下げ続ける #define kan_tukamu OnRev(OUT_A); //アームを掴み続ける #define arm_ageru OnFwd(OUT_C); //アームを上げ続ける #define kan_hanasu OnFwd(OUT_A);Wait(30);Off(OUT_AC); //缶をアームから放す #define STOP Off(OUT_AC); //一時停止 #define kan_temae_toutyaku 10 //本体が缶が手前まで到着したことをアームに伝える #define kan_sanko_motu 11 //アームが缶を3個持ったことを本体に伝える #define kan_sanko_motte_senkaisita 12 //本体が3個の缶を持って左に旋回したことをアームに伝える #define kan_niko_motta 13 //アームが缶を2個持ったことを本体に伝える #define kan_niko_motte_senkaisita 14 //本体が2個の缶を持って元のXの位置に右旋回してついたことをアームに伝える #define kan_ikko_motta 15 //アームが缶を1個持ったことを本体に伝える #define kan_ikko_motte_senkaisita 16 //本体が1個の缶を持って左に旋回して前に置いた1個の缶の上に到着したことをアームに伝える #define kan_okiowatta 17 //アームが1個の缶をもう一個の缶の上に置いたことを本体に伝える #define kan_futatabi_modoru 18 //本体が2個の缶の前に再び戻ってきたことをアームに伝える #define kan_futatabi_motta 19 //アームが2個の缶を持ったことを本体に伝える #define y_toutyaku 20 //本体がYに到着したことをアームに伝える
sub ueno_kan_tukamu() { arm_ueageru; Wait(10); arm_sageru; Wait(5); kan_tukamu; Wait(5); arm_ageru; }
缶が3個積みあがっているので、それを順番に下ろしていくサブルーチンを考えた。アームが3段目の缶まで届かないので2段目の缶を順番に下ろしていくことにした。缶の上下に紙を貼ると、2個以上の缶を一緒に運ぶときに缶が崩れてしまうので、缶に紙を貼らなかった。紙を貼らないと2段目の缶を横に移動するときに、1段目の缶が倒れてしまう。なので、2段目の缶を少し持ち上げる必要がある。そこで、缶をつかんで少し持ち上げる一連の動作をサブルーチンにした。
task main () { ClearMessage(); until(Message() == kan_temae_toutyaku); //Xに着くまで待つ kan_tukamu; Wait(50); SendMessage(kan_sanko_motu); ClearMessage(); //缶3個掴んだことを伝える until(Message() == kan_sanko_motte_senkaisita); //缶を3個持って旋回してもらうまで待つ Wait(100); STOP; kan_hanasu; //缶を3個横に移動 ueno_kan_tukamu(); ClearMessage(); Wait(100); SendMessage(kan_niko_motta); //缶2個持ち上げたことを伝える ClearMessage(); until(Message() == kan_niko_motte_senkaisita); //もう一つのロボに旋回してもらう Wait(100); Off(OUT_C); //缶が下りるのを待つ Wait(800);
2段目の缶を持ち上げて移動させて下ろそうとしても、缶を持ち上げているので地面と少し距離がある。このときアームを開くと缶が落下の勢いで上手く立つことができなかったので、アームを開く前に長い時間をとった。長い時間をとると、缶の重力で勝手に下りてきて、缶が地面に着く。
kan_hanasu; //缶を1個2個に分ける ueno_kan_tukamu(); Wait(100); ClearMessage(); SendMessage(kan_ikko_motta); //缶を一個持ったことを相手に伝える ClearMessage(); until(Message() == kan_ikko_motte_senkaisita); //ロボットが旋回するまでまつ STOP; Wait(800); //缶が下がるのを待つ kan_hanasu; //缶を2個1個に分けた OnFwd(OUT_A); //アームを開き続ける arm_ueageru; //アームを上げる SendMessage(kan_okiowatta); //缶からアームを完全に放したことを伝える until(Message() == kan_futatabi_modoru); //再び缶の手前まで戻ってきたことを伝える kan_tukamu; //缶を掴む SendMessage(kan_futatabi_motta); //缶を掴んだことを伝える until(Message() == y_toutyaku); //缶を持ってYに到着してもらうまで待つ kan_hanasu; //缶を放す }
#define go_straight(t) OnFwd(OUT_AC);Wait(t);Off(OUT_AC); //前進 #define go_back(t) OnRev(OUT_AC);Wait(t);Off(OUT_AC); //交代 #define TURN_RIGHT(t) OnFwd(OUT_A);OnRev(OUT_C);Wait(t);Off(OUT_AC); //右旋回 #define TURN_LEFT(t) OnFwd(OUT_C);OnRev(OUT_A);Wait(t);Off(OUT_AC); //左旋回 #define cross_stop Off(OUT_AC);Wait(100); //一時停止 #define kan_temae_toutyaku 10 #define kan_sanko_motu 11 #define kan_sanko_motte_senkaisita 12 #define kan_niko_motta 13 #define kan_niko_motte_senkaisita 14 #define kan_ikko_motta 15 #define kan_ikko_motte_senkaisita 16 #define kan_okiowwata 17 #define kan_futatabi_modoru 18 #define kan_futatabi_motta 19 #define y_touchaku 20
Aからスタート。Xが正面に来るようにロボットをセット。
task main() { SetSensor(SENSOR_3,SENSOR_LIGHT); go_straight(100); OnFwd(OUT_AC); until(SENSOR_3<=46); Off(OUT_AC); //Xの円の黒まで直進 SendMessage(kan_temae_toutyaku); ClearMessage(); until (Message()==kan_sanko_motu); //缶3個をつかむ TURN_LEFT(90); //左旋回 Off(OUT_AC); SendMessage(kan_sanko_motte_senkaisita); ClearMessage(); until (Message()==kan_niko_motta); //上の缶2個を持ち上げる TURN_RIGHT(140); //右旋回 Off(OUT_AC); SendMessage(kan_niko_motte_senkaisita); ClearMessage(); until (Message()==kan_ikko_motta); //上の缶を持ち上げる go_back(45); //後退 TURN_LEFT(97); //左旋回 Off(OUT_AC); go_back(10); //後退 SendMessage(kan_ikko_motte_senkaisita); ClearMessage(); until (Message()==kan_okiowwata); //アームを開く go_back(150); //後退 Wait(100); go_straight(150); //直進 Off(OUT_AC); SendMessage(kan_futatabi_modoru ); ClearMessage(); until (Message()==kan_futatabi_motta); //アームを閉じる go_straight(400); //直進 TURN_RIGHT(130); //右旋回 Off(OUT_AC); go_straight(10); //直進 Wait(100); SendMessage(y_touchaku); //アームを開く Off(OUT_AC); }
今回はロボットを作るのも、プログラムを考えるのもどちらとも難しかった。缶を置いて、その缶をつかもうとしたら位置がずれてしまうことが大変だった。回転センサーを使おうとしたが、時間もなく上手くつけることができなかった。また、今回は1個の大きいロボットをつくったが、2個のロボットで協力していくのも良いと思った。どの課題も大変だったが、達成感がありプログラミングの基礎を学ぶことができたのが良い経験となった。