[[2019a/Member]]
#contents
*課題3:ボール運搬ロボット [#w05fb60a]
ピンポン玉または青と赤のボールを運搬して、所定の容器の中に入れる。
#ref(2019a/Member/www/Mission3/ko-su'.jpg,40%)

**フィールドの説明 [#i12fef37]

-フィールドは課題2で使用した紙を使用する。
-生協のお弁当の四角いプラ容器2つをそれぞれ円内に置き、片方に玉を2個入れる。
-残りの2個の玉は課題2と同じ位置に置く。その際、ゴムタイヤやプレートの上に置いてもよい。
-プラ容器には色をつけたり文字や記号を書いてもよい。
-プラ容器は両面テープ等でフィールドに固定してもよい。
-2枚の紙の境界にはそれぞれ幅1cm、合計2cmの黒線を描いてもよい。


**ルール [#p6d1295d]

-競技時間は審判が続行不能と判断するまで、あるいはリタイアするまで。
-図のA地点または(および)A'地点からスタートする。ただし接地している部分はそれぞれの領域内に収まるものとする(線上はOK)。上空部分は領域からはみ出していてもよい。
-開始の合図から5秒以内にスタートボタンを押す作業を完了すること。
-競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。
-途中でうまく動かなくなった場合、1回限り再スタートすることができる(再スタートの際に別プログラムで起動してよい)。
-競技終了後、ロボットが、ゴールのプラ容器に触れていてはいけない。
-競技終了後、もともと玉が入っていたプラ容器が、ゴールのプラ容器に触れていてはいけない。

ルールについて詳しくは[[こちら>2019a/Mission3]]。

*ロボットの説明 [#ibcf3892]
ロボットの全体像は下の写真である。前は黄色いパーツがついているほうで、RISが乗っているほうが後ろだ。
#ref(2019a/Member/www/Mission3/zentai.jpg,50%)
ロボットはアームと足回りの2つの部分に分けられる。以下でそれぞれについて説明する。

**アームの説明 [#ebc42135]
***アームの動き [#n1e9f5ca]
1.ピンポン玉の取り方
#ref(2019a/Member/www/Mission3/robo''.GIF)
2.ピンポン玉の放し方
#ref(2019a/Member/www/Mission3/robo'.GIF)

***シーソー部分 [#t49d56da]
上の動画にもあるようにアームは上下に動いてピンポン玉を取ったりはなしたりする。

アームが完全に上がったときに少し斜めになっていて、ピンポン玉をつかむための黄色い部分が上がっても、ピンポン玉が落ちないようになっている。
#ref(2019a/Member/www/Mission3/shishi.jpg,60%)
アーム部分が重たいため、パワーを出すために6枚のギアを使用した。

   &ref(2019a/Member/www/Mission3/udegia'.jpg,60%);
&ref(2019a/Member/www/Mission3/udegia_zu.jpg,40%);

***ピンポン球をキャッチする部分 [#tc4c2348]
アームの前と後ろの重さのバランスをとるために後ろにモーターを取り付けた。
#ref(2019a/Member/www/Mission3/kyatti'.jpg,60%)
後ろから動力を持ってくるために2か所で歯車を直角につけて、回転方向を変化させている。~
   &ref(2019a/Member/www/Mission3/tenogia.jpg,60%);
&ref(2019a/Member/www/Mission3/tenogia''.jpg,60%);

また、下の写真のように歯車を取り付けて、パワーが出るようにした。
#ref(2019a/Member/www/Mission3/tenogia'.jpg,60%)
下の写真の ↓ は、ピンポン玉が逃げないようにするためのものだ。
#ref(2019a/Member/www/Mission3/otete.jpg,60%)

***ベルトコンベア部分 [#fb0c816f]
ピンポン玉を拾った後、機体の上部にピンポン玉を乗せる役割をする。
#ref(2019a/Member/www/Mission3/konbea.jpg,60%)
ピンポン玉をコンベアで奥に送り、最大3つまで収納できるようになっている。
#ref(2019a/Member/www/Mission3/syunou.jpg,60%)
下の画像の ↓ の部分でコンベアをピンポン玉に押し付け、ピンポン玉が途中で止まることを防止した。
#ref(2019a/Member/www/Mission3/sutoppaa.jpg,60%)
ベルトコンベアは片方が回転すればピンポン玉が収納できるので、片方のみ回転する。~
コンベアを回転させるためのギアは、下の写真のように取り付けた。
#ref(2019a/Member/www/Mission3/konbea1.jpg,60%)


**足まわりの説明 [#qa382d2f]
#ref(2019a/Member/www/Mission3/risokiba''.jpg,70%)
上の写真のようにタイヤの上にRISを2台並べておいた。
赤外線送受信部をくっつけて通信を行えるようにした。

裏側
#ref(2019a/Member/www/Mission3/ashiura''.jpg,60%)
課題2と同様、タイヤは全部で3輪で、前輪2つが駆動輪、後輪1つは摩擦を減らすために、ゴムを外したホイールのみを取り付けた。~
光センサーは、タイヤの中心に近いところに取り付けた。

*経路の説明 [#a6325bd5]
車体が重たく、ガタガタ揺れると壊れそうだったので、極力ライントレースをしないように経路を考えた。
**1つ目のピンポン玉を入れるまでの経路 [#l050ad9c]
#ref(2019a/Member/www/Mission3/michi1.jpg,30%)
スタートしてから2本の黒い線を横切って、3本目の黒い線を認識したら、ライントレースを開始する。~
上の図にあるようにしばらく進んだら、ピンポン玉を取り、その場で90度回転してピンポン玉をリリパックの中に入れる。

**2つ目のピンポン玉を取るまでの経路 [#idf09ed4]
#ref(2019a/Member/www/Mission3/michi2.jpg,30%)
少し下がった後に90度回転し、リリパックに当たらないように移動した。~
3本の黒い線を横切り、ここでもリリパックに当たらないよう、斜めに移動。~
4本目の黒い線を横切った後、ライントレースを開始し、ピンポン玉をつかむ。

**リリパックの中のピンポン玉を取るまでの経路 [#z3e7b023]
#ref(2019a/Member/www/Mission3/michi3.jpg,30%)
アームがリリパックの端に引っ掛かり、ピンポン玉がとれなくなることを防止するため、90度回転した後、少し下がってから、ピンポン玉をつかむようにした。

**3つのピンポン玉を入れるまでの経路 [#b356303a]
#ref(2019a/Member/www/Mission3/michi4.jpg,30%)
さらに下がり、90度回転する。~
2本目の黒い線で停止、少し前進してリリパックにピンピン玉を入れる。

*プログラムの説明 [#s935091c]
**共通するプログラム [#k04979a2]
2台のRISで通信を行うために、以下のようにマクロを定義をした。
 #define signal_catch 1
 #define signal_release 2
 #define signal_end 3

**アームのプログラム [#p5ab606a]
***サブルーチン [#pf8a95cb]
-ピンポン玉を取る

 sub CATCH()
 {
     ClearMessage();
     until(Message()==signal_catch);  //signal_catchを受信するまで待機
 
     OnFwd(OUT_B);
     Wait(30);
     Off(OUT_B);
     Wait(100);         // 下がる
     SetPower(OUT_A,2);
     OnRev(OUT_A);
     Wait(90);
     Off(OUT_A);
     Wait(100);         // 掴む
     OnRev(OUT_B);
     Wait(50);
     Off(OUT_B);
     Wait(100);         //  上がる
     OnFwd(OUT_A);
     Wait(90);
     Off(OUT_A);
     Wait(100);         //  手を元に戻す
     OnFwd(OUT_C);
     Wait(200);
     Off(OUT_C);
     Wait(100);         // 奥へ送る
 
     SendMessage(signal_end);     //動作終了を足のRISに送信
 } 

SendMessage(signal_end);はアームの動作が終わってから足のプログラムを再開させるために入れた。足のプログラムにはuntil(Message()==signal_end);が入っていて、アームの動作が終わった後足の動作が再開されるようになっている。

-ピンポン玉をリリパックに入れる

 sub release()
 {
     ClearMessage();
     until(Message()==signal_release);   //signal_releaseを受信するまで待機
 
     OnFwd(OUT_B);
     Wait(30);
     Off(OUT_B);
     Wait(100);     //  下がる
     OnRev(OUT_C);
     Wait(200);
     Off(OUT_C);
     Wait(100);     // 前へ送る
     OnRev(OUT_B);
     Wait(50);
     Off(OUT_B);
     Wait(100);     //  上がる
 
     SendMessage(signal_end);    //動作終了を足のRISに送信
 } 
 
***メインプログラム [#ge4f37c2]
アームのメインプログラムは以下の通り。
 task main()
 {
     ClearMessage();
     CATCH();   //L'のピンポン玉を取る
     release();  //リリパックに入れる
     CATCH();   //Lのピンポン玉を取る
     CATCH();   //リリパック内のピンポン玉を取る(1個目)
     CATCH();   //リリパック内のピンポン玉を取る(2個目)
 
     ClearMessage();                //(※)
     until(Message()==signal_release);  
     OnFwd(OUT_B);
     Wait(30);
     Off(OUT_B);
     Wait(100);  //アームを下げる
     OnRev(OUT_C);
     Wait(200);
     Off(OUT_C);
     Wait(100);  //ピンポン玉を前へ送る
     OnRev(OUT_BC);
     Wait(50);
     Off(OUT_BC);
     Wait(100);  //アームを上げながらピンポン玉を送る
 
     SendMessage(signal_end);
 }

(※)以下のプログラムは基本的にはサブルーチンの release() と同じだが、アームを上げる際にもコンベアを動かしている。一番最後は複数のピンポン玉をリリパック内に入れる必要があるが、release() だとピンポン玉が全部箱に入る前に、動作が終わってしまう。また、先に入ったピンポン玉に邪魔をされてピンポン玉が全部出ないという問題を解決するためにアームを上げながらコンベアを動かすようにした。


**足回りのプログラム [#q4126503] 
***マクロ・グローバル変数 [#fdbdfa50]
-光センサーの値

 #define black 40    //真っ黒
 #define gray_black 44  //黒
 #define gray 47      //灰
 #define gray_white 50  //白
 #define white 60     //真っ白

-基本的な動作

 #define go_ahead OnFwd(OUT_AC);     //前に進む
 #define turn_left OnFwd(OUT_A);Off(OUT_C);  //左に曲がる
 #define turn_right OnFwd(OUT_C);Off(OUT_A);  //右に曲がる
 #define circling_left OnRev(OUT_C);OnFwd(OUT_A);   //左旋回する
 #define circling_right OnRev(OUT_A);OnFwd(OUT_C);  //右旋回する

-グローバル変数

 int t;

***サブルーチン [#yf71ea61]

下にライントレースに使用したサブルーチンを示す。

 sub follow_line()// 右側トレース
 {
     SetSensor(SENSOR_2,SENSOR_LIGHT);
     ClearTimer(0);
     while(FastTimer(0)<t)
     {
     if(SENSOR_2<black)
         {
         circling_right;
         }        //真っ黒なら右旋回せよ
     else if(SENSOR_2<gray_black)
         {
         turn_right;
         }  //黒なら右に曲がれ
     else if(SENSOR_2<gray)
         {
         go_ahead;
         }          //灰なら直進せよ
     else if(SENSOR_2<gray_white)
         {
         turn_left;
         }   //白なら左に曲がれ
     else if(SENSOR_2<white)
         {
         circling_left;
         }    //真っ白なら右旋回せよ
     }
     Off(OUT_AC);
     Wait(100);   //1秒止まれ
 } 
今回はコース取りの関係上交差点認識をする必要がないため、グローバル変数tを使って指定した秒数だけ動いて止まるようにしている。交差点認識について、詳しくは[[課題2のレポート>2019a/Member/www/Mission2]]を参照。

***メインプログラム [#p926cb48]
以下が足のメインプログラムである。
〇の中の数字は、経路の説明の図の数字に対応している。

-1つ目のピンポン玉を入れるまで

 task main()
 {
     ClearMessage();      // A'スタート
     while(SENSOR_2>gray)      //白なら進む ※1
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100);
     while(SENSOR_2<gray)      //黒なら進む
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100);
     while(SENSOR_2>gray)
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100);
     while(SENSOR_2<gray)
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100);
     while(SENSOR_2>gray)
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100); 
     t=90;follow_line();  // ※2
     Wait(100);
     SendMessage(signal_catch);  //  L'のピンポン玉を掴む命令を送る��
     ClearMessage();
     until(Message()==signal_end);      //アームの動作が終わるまで待機
     circling_left;    //左に90°旋回��
     Wait(102);
     Off(OUT_AC);
     SendMessage(signal_release);  //  1つ目のピンポン玉を箱に入れる命令を送る��
     ClearMessage();
     until(Message()==signal_end);     // ※3

-2つ目のピンポン玉を取るまで

     OnRev(OUT_AC);   //後ろに下がる
     Wait(30);
     Off(OUT_AC);
     circling_left;
     Wait(102);
     Off(OUT_AC);        //左に90°旋回��
     while(SENSOR_2>gray)
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100);        //白なら進む  ※1
     while(SENSOR_2<gray)
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100);        //黒なら進む
     while(SENSOR_2>gray)
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100);
     while(SENSOR_2<gray)
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100);
     while(SENSOR_2>gray)
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100); 
     while(SENSOR_2<gray)
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100);
     turn_right;      //右に曲がる
     Wait(100);
     while(SENSOR_2>gray)      //白なら進む  ※1
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100);
     while(SENSOR_2<gray)     //黒なら進む
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100);
     t=150;follow_line();  // ※2
     SendMessage(signal_catch);//  Lのピンポン玉を掴む命令を送る��
     ClearMessage();
     until(Message()==signal_end);  // ※3

-リリパックの中のピンポン玉を取るまで

     circling_left;  //左に90°旋回��
     Wait(102);
     Off(OUT_AC);
     OnRev(OUT_AC);  //後ろに下がる��
     Wait(23);
     Off(OUT_AC);
     SendMessage(signal_catch);  //リリパックの中のボールを掴む(1個目)��
     ClearMessage();
     until(Message()==signal_end);   // ※3
     Wait(100);
     SendMessage(signal_catch);  //リリパックの中のボールを掴む(2個目)
     ClearMessage();
     until(Message()==signal_end);   // ※3

-3つのピンポン玉を入れるまで

     OnRev(OUT_AC);      //後ろに下がる
     Wait(90);
     Off(OUT_AC);
     circling_left;       //左に90°旋回��
     Wait(102);
     Off(OUT_AC);
     while(SENSOR_2>gray)         //白なら進む  ※1
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100);
     while(SENSOR_2<gray);         //黒なら進む
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100)
     while(SENSOR_2>gray)
     {OnFwd(OUT_AC);}
     Off(OUT_AC);
     Wait(100);
     go_ahead;       //前に進む
     Wait(15);
     Off(OUT_AC);
     SendMessage(signal_release);  //ピンポン玉をリリパックに入れる命令を送る��
     ClearMessage();
     until(Message()==signal_end);   // ※3
 
     OnRev(OUT_AC);//リリパックから離れるために少し後ろに下がる
     Wait(100);
     Off(OUT_AC);  
 }

※1 光センサーを使って白と黒を感知し、while(SENSOR_2>gray){OnFwd(OUT_AC);}Off(OUT_AC); (白ければ直進せよ)、 while(SENSOR_2<gray);{OnFwd(OUT_AC);}Off(OUT_AC); (黒ければ直進せよ)という命令を任意の数並べることで、好きな黒線の手前、または、黒線を超えてからロボットを止めることができる。

※2 この後にあるピンポン玉をつかむプログラム、90°回転するプログラムが正確に機能するようにライントレースをして、ロボットを黒線となるべく平行にするためのプログラム。また、時間制御することで、ピンポン玉を取りやすい位置にロボットを移動させることができる。

※3 アームのRISから一連の動きが終わったという信号を受け取ってからプログラムを再開させるためのもので、アームが動きながら足も動くことを防ぐために入れた。


*反省・感想 [#tb6dfd41]
 ロボット自体の動きは、良かったと思う。得点も取れなかったし、紙の上に置いてあったピンポン玉もつかめなかったが、リリパックの中のピンポン玉は2つとも取ることが出来てうれしかった。
ただ、調整段階では、ピンポン玉を4つともうまく運べていたので、今回ロボットが紙に引っ掛かってしまい得点をとれなかったのに悔しさもある。自分たちの詰めの甘さが悔やまれる。~
ただ、調整段階では、ピンポン玉を4つともうまく運べていたので、今回ロボットが紙に引っ掛かってしまい得点をとれなかったのに悔しさもある。自分たちの詰めの甘さが本当に悔やまれる。~
 今回の課題は、課題1,2に比べて難しく、チームのみんなと沢山悩んだが、完成し自分たちの思い通りの動きができたときには、達成感を感じた。ロボコンは4位だったが、時間がない中、チームのメンバー4人がそれぞれの強みを生かしてロボットを作り上げることが出来たと思う。

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