- 追加された行はこの色です。
- 削除された行はこの色です。
[[2019a/Member]]
*目次 [#ie15bf3a]
#contents
*課題 [#m1dc624d]
ボール運搬ロボットの作成
ピンポン玉または青と赤のボールを運搬して、所定の容器の中に入れる。
#ref(2019a/Member/yuka/Mission3/順路,15%,順路)
**フィールドの説明 [#z2643552]
-フィールドは課題2で使用した紙を使用する。-
-生協のお弁当の四角いプラ容器2つをそれぞれ円内に置き、片方に玉を2個入れる。-
-残りの2個の玉は課題2と同じ位置に置く。その際、ゴムタイヤやプレートの上に置いてもよい。-
-プラ容器には色をつけたり文字や記号を書いてもよい。-
-プラ容器は両面テープ等でフィールドに固定してもよい。-
-2枚の紙の境界にはそれぞれ幅1cm、合計2cmの黒線を描いてもよい。-
*基本ルール [#dcf13771]
-競技時間は審判が続行不能と判断するまで、あるいはリタイアするまで。
-図のA地点または(および)A'地点からスタートする。ただし接地している部分はそれぞれの領域内に収まるものとする(線上はOK)。上空部分は領域からはみ出していてもよい。
-開始の合図から5秒以内にスタートボタンを押す作業を完了すること。
-競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。
-途中でうまく動かなくなった場合、1回限り再スタートすることができる(再スタートの際に別プログラムで起動してよい)。
-競技終了後、ロボットが、ゴールのプラ容器に触れていてはいけない。
-競技終了後、もともと玉が入っていたプラ容器が、ゴールのプラ容器に触れていてはいけない。
※さらに詳しいルールは課題3を参照にしてください。
*ロボットの構造 [#b7853832]
**床に落ちているボールを拾うロボット [#d1444c92]
--床に落ちているボールは以下ような順路で拾っていく。
#ref(2019a/Member/yuka/Mission3/床(順路).jpg,15%,床(順路))
--床に落ちているボールは輪ゴムの弾性力を使ってアームが床に着いた時ボールがアームに張った輪ゴムの上に乗ることでボールを拾う仕組みをとった。
--輪ゴムを4本張ることで、安定してボールが取れるようにした。
#ref(2019a/Member/yuka/Mission3/アーム1,15%,アーム1)
#ref(2019a/Member/yuka/Mission3/アーム2,15%,アーム2)
#ref(2019a/Member/yuka/Mission3/アーム3,15%,アーム3)
#ref(2019a/Member/yuka/Mission3/アーム4,15%,アーム4,)
--部品は以下のようなものを使った。
#ref(2019a/Member/yuka/Mission3/床部品,15%,床部品)
**容器の中に入っているボールを拾うロボット [#n6160315]
#ref(2019a/Member/yuka/Mission3/容器(順路),15%,容器(順路))
--容器に入っているボールは上図のような順路で、容器ごと持ち上げて、2つのボールを一度に転がして入れる方法にした。
#ref(2019a/Member/yuka/Mission3/容器1,15%,容器1)
#ref(2019a/Member/yuka/Mission3/容器2,15%,容器2)
#ref(2019a/Member/yuka/Mission3/容器3,15%,容器3)
--本体に容器を持ち上げるために長いアームを付けて容器ごとと持ち上げる
#ref(2019a/Member/yuka/Mission3/容器ロボット,15%,容器ロボット)
*プログラム [#x48edfa4]
**床に落ちているボールを拾うロボット [#lff4a0a1]
***定義したこと [#z004855b]
-define MOVE_TIME 250 // ライントレースする時間
-define SPEED_H 35
-define SPEED_L 20
-define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL) // 右の車輪と左の車輪を違うスピードで動かす。
-define go_straight OnRL(SPEED_H,SPEED_H) // 直進
-define rot_r OnRL(-SPEED_L,SPEED_L) // 右に旋回
-define turn_r OnRL(0,SPEED_L) // 右に曲がる
-define rot_l OnRL(SPEED_L,-SPEED_L) // 左に旋回
-define turn_l OnRL(SPEED_L,0) // 左に曲がる
-define B1 43 // ラインの真ん中の閾値
-define G 53 // ラインの境界の閾値
-define W1 59 //ラインから近いところの閾値
-define W2 61 // ラインから遠いところの閾値
-define BACK OnRL(-SPEED_H,-SPEED_H) // 後進
-sub follow_line_l() // ライントレース
{
SetSensorLight(S2);
long t0=CurrentTick();
while(CurrentTick()-t0<MOVE_TIME){
if(SENSOR_2>W1){
rot_r;t0=CurrentTick();
}
else if(SENSOR_2>W2){
turn_r;t0=CurrentTick();
}
else if(SENSOR_2>G){
go_straight;t0=CurrentTick();
}
else if(SENSOR_2>B1){
turn_l;t0=CurrentTick();
}
else{
rot_l;
}
}
}
-sub follow_line_r() // 交差点を見分ける
{
SetSensorLight(S2);
long t0=CurrentTick();
while(CurrentTick()-t0<MOVE_TIME){
if(SENSOR_2>W1){
rot_l;t0=CurrentTick();
}
else if(SENSOR_2>W2){
turn_l;t0=CurrentTick();
}
else if(SENSOR_2>G){
go_straight;t0=CurrentTick();
}
else if(SENSOR_2>B1){
turn_r;t0=CurrentTick();
}
else{
rot_r;
}
}
}
-sub short_break() // 小休止
{
Off(OUT_BC);
Wait(1000);
}
-sub arm_down() // 床に落ちているボールを取るときにアームを下げる
{
OnFwd(OUT_A,70);
Wait(600);
Off(OUT_A);
Wait(500);
OnRev(OUT_A,50);
Wait(500);
Off(OUT_A);
}
-sub shoot() // ボールを容器の中に入れる
{
OnRev(OUT_A,60);
Wait(700);
Off(OUT_A);
OnFwd(OUT_A,55);
Wait(500);
Off(OUT_A);
}
-sub back(long t) // 後進する時間
{
BACK;
Wait(t);
Off(OUT_BC);
}
***全体のプログラム [#q7bbb65f]
{
Off(OUT_A);
go_straight;
Wait(1000);
Off(OUT_BC);
follow_line_l();
short_break();
rot_r;
Wait(400);
Off(OUT_BC);
go_straight;
Wait(800);
Off(OUT_BC);
arm_down();
turn_r;
Wait(3500);
Off(OUT_BC);
shoot();
Wait(1000);
rot_r;
Wait(3800);
Off(OUT_BC);
go_straight;
Wait(6600);
Off(OUT_BC);
arm_down();
back(3000);
OnRL(0,-SPEED_L);
Wait(300);
Off(OUT_BC);
shoot();
}
**容器の中に入っているボールを拾うロボット [#ud80dfb1]
-define MOVE_TIME 250 //ライントレースする時間
-define SPEED_H 35
-define SPEED_L 20
-define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL) //その場で回る
-define go_straight OnRL(SPEED_H,SPEED_H) //直進
-define rot_r OnRL(-SPEED_L,SPEED_L) // 右に旋回
-define turn_r OnRL(0,SPEED_L) // 右に回る
-define rot_l OnRL(SPEED_L,-SPEED_L) // 左に旋回
-define turn_l OnRL(SPEED_L,0) //左に回る
-define B1 43 // ラインの真ん中の閾値
-define G 53 // ラインの境界の閾値
-define W1 59 // ラインに近いところ
-define W2 61 // ラインより遠いところ
-define BACK OnRL(-SPEED_H,-SPEED_H) //後進
-sub follow_line_l() // ラインの左側をトレース
{
SetSensorLight(S2);
long t0=CurrentTick();
while(CurrentTick()-t0<MOVE_TIME){
if(SENSOR_2>W1){
rot_r;t0=CurrentTick();
}
else if(SENSOR_2>W2){
turn_r;t0=CurrentTick();
}
else if(SENSOR_2>G){
go_straight;t0=CurrentTick();
}
else if(SENSOR_2>B1){
turn_l;t0=CurrentTick();
}
else{
rot_l;
}
}
}
- sub follow_line_r() // 右側をトレース
SetSensorLight(S2);
long t0=CurrentTick();
while(CurrentTick()-t0<MOVE_TIME){
if(SENSOR_2>W1){
rot_l;t0=CurrentTick();
}
else if(SENSOR_2>W2){
turn_l;t0=CurrentTick();
}
else if(SENSOR_2>G){
go_straight;t0=CurrentTick();
}
else if(SENSOR_2>B1){
turn_r;t0=CurrentTick();
}
else{
rot_r;
}
}
}
- sub cross_line_1() // 交差点を見分ける。左に回る
{
while(SENSOR_2<W1){
go_straight;
}
while(SENSOR_2>G){
turn_l;
}
Off(OUT_BC);
}
-sub cross_line_2() // 交差点を見分ける。左に旋回する。
{
while(SENSOR_2<W1){
go_straight;
}
while(SENSOR_2>G){
rot_l;
}
Off(OUT_BC);
}
-sub short_break() // 小休止
{
Off(OUT_BC);
Wait(1000);
}
-sub arm_down() // アームを下げる
{
OnFwd(OUT_A,50);
Wait(500);
Off(OUT_A);
Wait(500);
OnRev(OUT_A,50);
Wait(500);
Off(OUT_A);
}
-sub shoot() // 容器をひっくり返してボールを入れる
{
OnRev(OUT_A,60);
Wait(600);
Off(OUT_A);
OnFwd(OUT_A,90);
Wait(800);
Off(OUT_A);
}
-sub back(long t) // 後進
{
BACK;
Wait(t);
}
***全体のプログラム [#u8e13c65]
{
go_straight;
Wait(1000);
Off(OUT_BC);
rot_l;
Wait(2800);
Off(OUT_BC);
go_straight;
Wait(3000);
Off(OUT_BC);
rot_l;
Wait(4500);
Off(OUT_BC);
go_straight;
Wait(3000);
turn_l;
Wait(8700);
Off(OUT_BC);
Wait(27000);
OnFwd(OUT_A,50);
Wait(700);
OnRev(OUT_BC,60);
Wait(700);
Off(OUT_BC);
shoot();
}
* 感想 [#mb3262f3]
-少しの条件の変化、例えば電池の残量や起動時間、床の条件なのでロボットの動きが変わってしまったのでボールは確実に取れることはなかった。 [#rc6e2182]
-普段使っているロボットがいかに汎用性が高く、環境に左右されないんだなと思った。