[[2019a/Member]]
目次
#contents
*課題3 [#t72907f8]
ピンポン玉または青と赤のボールを運搬して、所定の容器の中に入れる。
#ref(2019a/Member/Mars/Mission3/00854202-255E-4386-8774-8D8AAAB8C309.png)
**フィールドの説明 [#j32d2c70]
フィールドは課題2で使用した紙を使用する。
生協のお弁当の四角いプラ容器2つをそれぞれ円内に置き、片方に玉を2個入れる。
残りの2個の玉は課題2と同じ位置に置く。その際、ゴムタイヤやプレートの上に置いてもよい。
プラ容器には色をつけたり文字や記号を書いてもよい。
プラ容器は両面テープ等でフィールドに固定してもよい。
2枚の紙の境界にはそれぞれ幅1cm、合計2cmの黒線を描いてもよい。
**ルール [#e3308788]
基本ルール
競技時間は審判が続行不能と判断するまで、あるいはリタイアするまで。
図のA地点または(および)A'地点からスタートする。ただし接地している部分はそれぞれの領域内に収まるものとする(線上はOK)。上空部分は領域からはみ出していてもよい。
開始の合図から5秒以内にスタートボタンを押す作業を完了すること。
競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。
途中でうまく動かなくなった場合、1回限り再スタートすることができる(再スタートの際に別プログラムで起動してよい)。
競技終了後、ロボットが、ゴールのプラ容器に触れていてはいけない。
競技終了後、もともと玉が入っていたプラ容器が、ゴールのプラ容器に触れていてはいけない。
基本得点の計算方法
プラ容器内の玉を1個運べば8点。二つとも運べば20点。
L地点とL'地点の玉をどちらか1個運べば4点、2個とも運べば12点。
競技終了後、ゴールのプラ容器が完全に円から出しまった場合、もとの基本点の1/4を減点。
競技終了後、ゴールのプラ容器の半分以上が円から出ていれば、もとの基本点の3/4を減点。
競技終了後、ゴールのプラ容器にもとのプラ容器が触れていれば、もとの基本点の1/2を減点。
競技終了後、ゴールのプラ容器にもとのプラ容器が触れていれば、もとの基本点の1/2を減点。
競技終了後、ゴールのプラ容器にロボットが触れていれば、もとの基本点の1/4を減点。
*ロボットの説明 [#k12b4e61]
ロボット全体は以下の通り。
#ref(2019a/Member/Mars/Mission3/074B2B56-AE1C-4DBE-9FDE-F43F6940384B.jpeg)
#ref(2019a/Member/Mars/Mission3/8636463F-C236-49AA-8DD4-1B6E0033E123.jpeg)
一度にボールを複数運ぶロボットにしたため、ロボットが大きくなってしまった。
**アーム部分について [#v5cc31ed]
アーム全体は以下の写真の通り。
#ref(2019a/Member/Mars/Mission3/21EC3F04-0EA2-4B53-9644-179C16CA4EE5.jpeg)
黄色の部分でボールを掴む。コンベアーでボールを後ろに送ることで保持し、前に送ることでボールを離す。
***ボールを掴む部分 [#j361ba38]
#ref(2019a/Member/Mars/Mission3/482E6D1D-CAEC-4229-9ECF-C1F4FE06075A.jpeg)
オレンジの丸で囲ってある部分で掴む。青い丸で囲ってある部分は、オレンジの丸の部分の動力源で、アーム全体のバランスを保つために掴む部分とは反対側に配置してある。
***コンベアーの部分 [#bfa3916d]
#ref(2019a/Member/Mars/Mission3/7A39F883-2AC1-49DF-BB38-1099CF99BE2F.jpeg)
写真の中央の少し薄い黒のベルトの部分がコンベアーになっている。モーターを回すことでベルトが回り、ボールが後ろへ運ばれる。
***シーソーの部分 [#dcd5dce3]
#ref(2019a/Member/Mars/Mission3/DAF2C478-176D-4F08-8E8A-638D7A4B1B62.jpeg)
上図のように、アームが上下する。そうすることで箱の中のボール、紙に置いてあるボール2つを掴むことができるようになっている。
アーム全体として重たいため、上下させるためにギアを挟んでパワーを上げた。ギアの図は以下の写真の通り。
#ref(2019a/Member/Mars/Mission3/28ACEA38-09AE-4586-A565-45AEAB90FF81.jpeg)
*ロボットの動くルート [#rcc5ed31]
ロボットが大きく、たくさん揺れた時に壊れてしまうのを防ぐため、できる限りライントレースをしないルートを通ることにした。以下の4枚の写真の通りに動く。
#ref(2019a/Member/Mars/Mission3/F2796329-1E3D-4168-85C4-F82EEC730AB8.png)
#ref(2019a/Member/Mars/Mission3/9DFF484E-E2E1-4A89-92DA-E8CFC89A7D75.png)
#ref(2019a/Member/Mars/Mission3/6EFAFAF3-2F71-499E-9132-55569433CDBB.png)
#ref(2019a/Member/Mars/Mission3/B5EED354-2D51-47F6-893D-7389E5C9F896.png)
先程ライントレースを少なくすると書いたが、ライントレースの部分がどこであるかを説明する。ライントレースは、黒線の手前で止まってから、点K、および点K'にあるボールを掴むまでの間に行っている。ロボットを黒線と平行にし、そのあとの動きを正確に、かつ簡単にするためにそうしてある。
*プログラムの説明 [#g27c194d]
アームと足、それぞれ1つずつのメインプログラムを使って、RIS間で通信しながら動かしていく。
それぞれのマクロやサブルーチン、メインプログラムは以下で説明する。
**マクロについて [#k3085013]
アームのプログラムには以下の3つのマクロしか使っていないが、足のプログラムには、他のマクロも使われている。そのマクロについては足のプログラムとともに説明する。
以下に用いたマクロを記す。
#define signal_catch 1
#define signal_release 2
#define signal_end 3
**アームのプログラム [#b21f2e93]
アームで行う動作は、主に「ボールを掴む」、「ボールを箱に入れる」の2つ。それぞれ名前を「CATCH」、「release」とした。
***サブルーチンについて[#g66fe8e0]
ボールを一度に運ぶこともあるため、同時に複数個のボールを持てるように、プログラムを組んだ。
ボールを掴むサブルーチンは以下の通り。
sub CATCH()
{
ClearMessage();
until(Message()==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);
}
SendMessage(signal_end);は一連の動作が終わってから足のプログラムを再開するために入れた。そのため、足のプログラムにはuntil(Message()==signal_end);が入っていて、アームの動作が終わってから足のプログラムの続きから再開出来るようになっている。
ボールを箱に入れるサブルーチンは以下の通り。
sub release()
{
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_B);Wait(50);Off(OUT_B);Wait(100);// 上がる
SendMessage(signal_end);
}
これもボールを掴むサブルーチンと同様の理由でSendMessage(signal_end);が入っている。
***アームのメインプログラムについて [#n747be98]
ロボットの進路の関係で以下のようにサブルーチンを並べてメインプログラムを構成している。
task main()
{
ClearMessage();
CATCH();
release();
CATCH();
CATCH();
CATCH();
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);
}
CATCH();3連続のあとの部分について。1文目と2文目はサブルーチン「release」と同じである。3文目の「上がりながら送る」の部分が違っている。ボールを複数個同時に箱に入れる場合、サブルーチン「release」を使うと、全てのボールを箱に入れる前に動作が終わってしまう。それを防ぐため、最後はアームをあげる時に、同時にコンベアーも動かす。こうすることで掴んだボールは全て箱に入る。
**足のプログラム [#nbe130d1]
足のプログラムは、ロボットの動く道順に従う。それぞれの動作をある程度正確に行えるように、全ての動作を時間で制御するのではなく、大部分に光センサーを用いている。
***マクロについて [#s8e786c1]
上で記したものの他には以下のものがある。
#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);
go_aheadは前に進む、turn_rightは右側のタイヤを固定して右回転する、turn_leftは左側のタイヤを固定して左回転する、circling
***サブルーチンについて [#y3ad9eaa]
用いたのはライントレースするサブルーチンのみである。以下にそのサブルーチンを示す。
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);
}
最後のWait(100);は挙動を見やすくするために入れてある。
ライントレースの仕組みはMission2の時と同じだが、コース取りの関係で、交差点を判別する必要がない。そのため、グローバル変数tを使って、指定した秒数動いて止まるようになっている。
***足のメインプログラムについて [#pce59bde]
以下に足のメインプログラムを示す。グローバル変数tはint t;で指定している。
task main()
{
ClearMessage();
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);
t=90;follow_line();//��
Wait(100);
SendMessage(signal_catch);// L'のボールを掴む命令を送る
ClearMessage();
until(Message()==signal_end);//☆
circling_left;Wait(102);Off(OUT_AC);// 90°その場で左回転
SendMessage(signal_release);// ボールを1個箱に入れる命令を送る
ClearMessage();
until(Message()==signal_end);
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);// 白なら進む
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){OnFwd(OUT_AC);}Off(OUT_AC);Wait(100);// 白なら進む
while(SENSOR_2<gray){OnFwd(OUT_AC);}Off(OUT_AC);Wait(100);// 黒なら進む
t=150;follow_line();//��
SendMessage(signal_catch);// L掴む
ClearMessage();
until(Message()==signal_end);
circling_left;Wait(102);Off(OUT_AC);// その場で左回転
OnRev(OUT_AC);Wait(23);Off(OUT_AC);// 後ろに下がる
SendMessage(signal_catch);// 箱の中のボールを掴む(1つ目)
ClearMessage();
until(Message()==signal_end);
Wait(100);
SendMessage(signal_catch);// 箱の中のボールを掴む(2つ目)
ClearMessage();
until(Message()==signal_end);
OnRev(OUT_AC);Wait(90);Off(OUT_AC);// 後ろに下がる
circling_left;Wait(102);Off(OUT_AC);// その場で左回転
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);
go_ahead;Wait(15);Off(OUT_AC);// 前に進む
SendMessage(signal_release);//
ClearMessage();
until(Message()==signal_end);
OnRev(OUT_AC);Wait(100);Off(OUT_AC);//��
}
度々出てくるwhile(SENSOR_2>gray){OnFwd(OUT_AC);}Off(OUT_AC);は、「光センサーが白を感知している間直進する」、while(SENSOR_2<gray){OnFwd(OUT_AC);}Off(OUT_AC);は「光センサーが黒を感知している間直進する」を命令している。この2つを並べることで、黒線の手前で止めたり、黒線を越えて止めたりすることを可能にしている。
☆について。これはアームのサブルーチンのところでも説明した通り、アームを制御しているRISから、「一連の動作が終わった」という信号を受け取ってからプログラムを再開するために入れてある。これがないと、アームが動きながら足も動く、というような想定外の動きをしてしまう。
�,砲弔い董�2つのfollow_lineのあとには、ボールを掴むプログラム、90°回転するプログラムがあるため、できる限り黒線とロボットが平行であって欲しい。そのため、ライントレースをすることによって、ロボットを、ボールを掴める位置に移動させながら黒線に平行にしている。
�△砲弔い董�ルールにある通り、終わった時にロボットが箱に触れていたら減点なので、それを防ぐために、後ろに下がるようにしている。
*反省・感想 [#k350497f]
ロボットの動き自体はかなり上手くいっていた。ボールを上手く掴むことが出来ずに惜しくも得点とはならなかった。調整段階で4つのボール全て運ぶことが出来ていただけに悔しい。