[[2018a/Member]]
#contents
*課題 [#s8d00e43]
空き缶を分別して所定の場所に運ぶ。
#ref(./2018a-mission3.png,50%,課題3のコース)

フィールドの説明&br;
・フィールドは課題2で使用した紙を使用する。&br;
・2種類の空き缶(Aタイプ,Bタイプ)をそれぞれ3個づつ用意し、円XにABA、円YにBABとなるように3段づつ積み上げる。&br;
・空き缶には色をつけたり文字や記号を書いてもよい。あるいは周囲に紙を張ってもよい。
#br
ルール&br;
・競技時間は審判が続行不能と判断するまで、あるいはリタイアするまで。&br;
・図のA地点または(および)A'地点からスタートする。ただし接地している部分はそれぞれの領域内に収まるものとする(線上はOK)。上空部分は領域からはみ出していてもよい。&br;
・Aタイプの空き缶を円Y内に、Bタイプの空き缶を円X内に運ぶ。&br;
・開始の合図から5秒以内にスタートボタンを押す作業を完了すること。&br;
・競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。&br;
・途中でうまく動かなくなった場合、1回限り再スタートすることができる(再スタートの際に別プログラムで起動してよい)。&br;
*ロボットについて [#rc44acab]
**全体像 [#a1ca0261]
#ref(./Image_060a1c4.jpg,50%,全体図)
アームを制御するRISとロボットの移動を制御するRISを取り付け、2つのRISでメッセージの送受信を行わさせることで課題を解決しようとした。
**アーム [#m1fe2543]
#ref(./課題3 アーム.jpg,50%,アーム)
缶を挟む機構をつかみたい缶の中央まで移動させ、1缶ずつ運びたかったが、ロボットの高さとアームの可動範囲の問題により、挟む機構を高く移動できても下から2缶目が限界であった。そのため、複数の缶を同時に運ぶ必要性が出てきた。そこで、挟む機構を縦に3つ設け、それを棒状のもので接続し、缶を複数挟んでもある程度は安定するようにした。
**タイヤ [#a20077f7]
#ref(./課題3タイヤ.jpg,50%,タイヤ)
当初は前後どちらもタイヤを用いていたが、ライントレースができなかったため、前の部分を回転するブロックに変えた。そうすることで、重量のあるロボットでもスムーズにライントレースできた。
*プログラム [#jfabbe82]
**流れ [#m7204d5b]
��A`からXに向かう
#ref(./課題3��.jpg,50%,��)
��X内の缶3つを円外に移動させる
#ref(./IMG_8277.jpg,50%,��)
���△念榮阿気擦心未両紕欧弔�X内に戻す
#ref(./IMG_8279.jpg,50%,��)
�き�で移動させた上の缶を円外にある缶に重ねる
#ref(./IMG_8286.jpg,50%,��)
�キい能鼎佑殖牡未�Yに運ぶ
#ref(./IMG_8290.jpg,50%,��)
**本体の移動 [#r236a115]
***定義 [#f8a1f40d]
最初の5行はロボットの移動に関わる定義で、それ以降はロボット本体とアームの送受信に関わる定義である
   #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                                   //アームが缶を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に到着したことをアームに伝える
***メインプログラム [#hde208ce]
流れ�◆↓�、�い脇韻験囘抂榮阿気擦襪燭瓠⇒�屈的には旋回の秒数は等しくあるべきだが、アームの操作の最中に本体自体が軽く動いてしまうため、旋回の秒数を少しずつ変えた。しかし、生じる誤差が毎回同じであるわけでないため、成功率的に低いものになった。また、光センサで検出される高度はその場所の明るさに大きく左右されたため、使う場所の明るさに合わせて、値を変化させた。
  task main()
 {
    SetSensor(SENSOR_3,SENSOR_LIGHT);
    go_straight(100);                            //前に直進
    OnFwd(OUT_AC);
    until(SENSOR_3<=46);                         //Xの円の前で止まるようにする.明るさは場所(教室)によって変わる
    Off(OUT_AC);
    SendMessage(kan_temae_toutyaku);             //本体が缶の手前まできたことをアームに伝える
    ClearMessage();
    until (Message()==kan_sanko_motu);           //アームが3個の缶を持つのを待つ
    TURN_LEFT(90);                               //3個の缶を持ち左旋回
    Off(OUT_AC);
    SendMessage(kan_sanko_motte_senkaisita);     //3個の缶を持って左に旋回したことをアームに伝える
    ClearMessage();
    until (Message()==kan_niko_motta);           //アームが缶を2個持つまで待つ
    TURN_RIGHT(140);                             //缶を持ち右に旋回
    Off(OUT_AC);
    SendMessage(kan_niko_motte_senkaisita);      //アームに缶を2個持って右旋回(Xの位置に戻る)したことを伝える
    ClearMessage();
    until (Message()==kan_ikko_motta);           //アームが缶を1個持つまで待つ
    go_back(45);                                 //後退(この時アームは上にあがり続けて缶もつかみ続けている)
    TURN_LEFT(97);                               //左旋回
    Off(OUT_AC);
    go_back(10);                                 //後退
    SendMessage(kan_ikko_motte_senkaisita);      //持っている1個の缶が置いてある1個の缶の上に来たことを伝える
    ClearMessage();
    until (Message()==kan_okiowwata);            //アームが置いてある1個の缶の上に持っていた1個の缶を置くまで待つ
    go_back(150);                                //後退
    Wait(100);
    go_straight(150);                            //後退した分直進
    Off(OUT_AC);
    SendMessage(kan_futatabi_modoru);           //本体が先程いた2個の缶の手前まで来たことをアームに伝える
    ClearMessage();
    until (Message()==kan_futatabi_motta);       //アームが2個の缶を再び持つまで待つ
    go_straight(400);                            //直進
    TURN_RIGHT(130);                             //右旋回
    Off(OUT_AC);
    go_straight(10);                             //直進
    Wait(100);
    SendMessage(y_touchaku);                     //Yに到着したことをアームに伝える
    Off(OUT_AC);
 }
**アーム [#ya3b2c9a]
***定義 [#c1cbcaa1]
最初の6行はロボットの移動に関わる定義で、それ以降はロボット本体とアームの送受信に関わる定義である。
   #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に到着したことをアームに伝える
***サブルーチン [#kd46c955]
下から2番目の缶をつかむサブルーチンである。缶を持ち上げる際、缶のふちが引っかからないように軽く持ち上げてから移動させた。
   sub ueno_kan_tukamu()
  {
     arm_ueageru;              //アームを最大まであげる
     Wait(10);  
     arm_sageru;               //アームを少し下げる
     Wait(5);
     kan_tukamu;               //缶をつかむ
     Wait(5);
     arm_ageru;                //缶をつかんだままアームをあげ続ける
  }
***メインプログラム [#r9ebd473]
缶を放すときに、Waitのプログラムを入れることで、缶が倒れることなく地面に着地した。
   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);
     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;                                           //缶を放す    
 }
*まとめ [#f1df4472]
**課題 [#d1e632dc]
・アームで缶を挟むためにロボットの高さが必要となり、ブロックで高さを出した結果、不安定なものになり、さらにブロックで補強したため、重量のあるロボットになってしまった。&br;
・RISのバッテリー等に大きく左右されてしまったため、成功率が低くなった。&br;
・ルールをしっかり把握し、作戦を練るべきであった。&br;
・ライントレースをせず時間でプログラムを作ったことから、少しの誤差が命取りになった。&br;
・光センサの設置位置が良くなかったのか、その場所の明るさに大きく左右された。
**感想 [#v78b3398]
今までの学びを総結集させて、今回の課題に取り組んだため、今までの学びを深めることができた。楽しく、プログラミングの基礎が学べて、良かったです。

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS