[[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] -普段使っているロボットがいかに汎用性が高く、環境に左右されないんだなと思った。