- 追加された行はこの色です。
- 削除された行はこの色です。
[[2019a/Member]]
*目次 [#n5474560]
#contents
*課題について [#be1acf0d]
**課題内容 [#t1388e7b]
〇下の図のようなコースを各チームで作成し、「ミッション」を遂行するためのロボットを作成する。
***コース [#sb8ba9b1]
#ref(2019a/Member/kou/Mission2/2019a-mission2.png,70%)
#ref(2019a/Member/kou/Mission2/Inked2019a-mission2_LI.jpg,70%)
***ミッション [#r26cbca0]
・A地点から出発 → B → C(直進) → D(一時停止の後、直進) → E → F → G(一時停止の後、右折) → H → I → J(右折) → K(左折) → L(ピンポン玉をつかむ) → K(直進) → M(一時停止) → シュート→ A地点に入る(ゴール)~
・交差点では1秒間停止し、丁字路では直角方向に進入する時のみ一時停止すること。
**方針 [#yb1853fd]
・ライントレースを行う際、カラーセンサーが読み取った数値によって黒と白の判別をする。今回は黒いラインと模造紙の白の境をジグザグに移動する方法を選んだ。この方法だと交差点を検知しやすいという反面、別の場所で交差点を誤認してしまうことがある。そのため誤認してしまう場所を調べロボットをその度コースに復帰させる必要がある。~
・Dの交差点では黒の検知時間が長くなることを利用して一時停止できる関数を作成した。~
・AからDまではコースの外側をライントレースさせ、Dからはコースの内側でライントレースをさせることでGからの円のライントレースを円滑に進められるようにした。これは、初めから内側でトレースしてしまうとCを交差点と誤認してしまうからである。
*ロボットについて [#sb4ba8d1]
#ref(2019a/Member/kou/Mission2/IMG_2079.JPG,10%)
ロボットの全体像である。コースが小さく、狭いためロボットの小回りはプログラミングで調整した。アーム部分はミディアムモーターと接続されており、可動域は180度である。カラーセンサーはロボット中央部分に接続されており、模造紙との距離が離れすぎてしまうと読み取る値もバラバラになってしまうので近くに固定するのが重要である。
#ref(2019a/Member/kou/Mission2/IMG_2082 (2).JPG,12%)
あらかじめアームを上に上げておくことでライントレースしやすくして、ピンポン球回収の時にだけアームを動かせばいいようにした。
スタート地点であらかじめアームを上に上げておくことでライントレースしやすくして、ピンポン球回収の時にだけアームを動かせばいいようにした。
*プログラムについて [#n25d76b3]
**モジュールのインポートとインスタンスの作成部分 [#d98c7357]
#!/usr/bin/env python3
from ev3dev.ev3 import *
from time import sleep #sleep関数をインポート
a = LargeMotor('outA') #左の車輪のモーターをa
d = LargeMotor('outD') #右の車輪のモーターをd
c = MediumMotor('outB') #アーム部分のミディアムモーターをc
cs = ColorSensor('in3')
cs.mode = 'COL-REFLECT' #光の反射値を読み取るモードである
**関数の作成部分 [#p7aa890f]
モーターをリセットする関数である。
def motor_init():
a.reset()
c.reset()
d.reset()
ロボットを前進、後退させる関数である。モーターを回転させる時間を変数tを用いた。~
例えばt=1000のときモーターは約1秒間回転する。
def move_advance(t):#前進
a.run_timed(time_sp=t, speed_sp=-100,stop_action='brake')
d.run_timed(time_sp=t, speed_sp=-100,stop_action='brake')
sleep(t/1000)
def move_back(t):#後退
a.run_timed(time_sp=t, speed_sp=100,stop_action='brake')
d.run_timed(time_sp=t, speed_sp=100,stop_action='brake')
sleep(t/1000)
ロボットを左回転、右回転させる関数である.~
モーターの回転をそれぞれ逆回転にして左右回転できるようにした。変数tについては前進、後退と一緒である。
def move_left(t):#左回転
a.run_timed(time_sp=t, speed_sp=100,stop_action='brake')
d.run_timed(time_sp=t, speed_sp=-100,stop_action='brake')
sleep(t/1000)
def move_right(t):#右回転
a.run_timed(time_sp=t, speed_sp=-100,stop_action='brake')
d.run_timed(time_sp=t, speed_sp=100,stop_action='brake')
sleep(t/1000)
ライントレースする関数である。これはAからDまでの外側をライントレースするとき、つまり黒線が右側にあるときに使用する。カラーセンサーが読み取る値の時間変数tによってwhile関数から抜けてif関数へとつながるようになっている。つまりwhile関数から抜けるときは交差点を検知していることになる。また、while関数の中でもさらに場合分けされていて、カラーセンサーが11以下(黒)の値を読み取ったら左前、11より大きく(白)なったら右前に動きジグザグに進むようになっている。
def line_follow(t):
motor_init()
t0 = time.time()
while time.time() - t0 < t:
if cs.value() <= 11:
motor_init() #モーターをリセット
t0 = time.time() #計測開始時間をt0とする
while time.time() - t0 < t: #変数tを導入
if cs.value() <= 11: #csが11以下のとき左前
a.run_forever(speed_sp=50)
d.run_forever(speed_sp=-100)
else:
else: #csが11より大きいとき右前
a.run_forever(speed_sp=-100)
d.run_forever(speed_sp=50)
t0 = time.time()
if time.time() - t0 > t:
if time.time() - t0 > t: #検知時間がtより大きくなったらなるとwhile関数から抜ける
a.stop()
d.stop()
sleep(1)
#ref(2019a/Member/kou/Mission2/タイトルなし.png,50%)
これは、内側をライントレースするとき、つまり黒線が左側にあるときに使用する。上のプログラムと車輪の回転を逆にしているだけで他は一緒である。
def line_follow2(t):
motor_init()
t0 = time.time()
while time.time() - t0 < t:
if cs.value() <= 11:
a.run_forever(speed_sp=-100)
d.run_forever(speed_sp=50)
else:
a.run_forever(speed_sp=50)
d.run_forever(speed_sp=-100)
t0 = time.time()
d.run_forever(speed_sp=-100)
if time.time() - t0 > t:
a.stop()
d.stop()
sleep(1)
#ref(2019a/Member/kou/Mission2/line.png,70%)
交差点検知の図↓
#ref(2019a/Member/kou/Mission2/交差点.png,45%)
アーム部分を上下させる関数である。回転させる角度をtとした。回転するスピードは100で安定した。
def age(t):
c.run_to_rel_pos(position_sp=t, speed_sp=100, stop_action='hold')
sleep(1)
def sage(t):
c.run_to_rel_pos(position_sp=-t, speed_sp=100, stop_action='hold')
sleep(1)
**実際のプログラム [#xe1796de]
line_follow(0.8)#交差点Dまでライントレースする
move_right(700)
line_follow(0.8) #交差点Dまでライントレースする
move_right(700) #走るコースの調整
move_advance(700)
line_follow2(1.5)
move_right(900)
line_follow2(1.5) #Gまでライントレース
move_right(900) #走るコースの調整
move_advance(600)
line_follow2(0.9)
move_left(500)
line_follow2(0.9) #Hまでライントレース
move_left(500) #走るコースの調整
move_advance(500)
line_follow2(0.7)
move_left(500)
line_follow2(0.7) #Iまでライントレース
move_left(500) #走るコースの調整
move_advance(500)
line_follow2(0.7)
move_right(300)
move_advance(300)
line_follow2(0.65)
move_advance(1500)
line_follow2(0.7) #Jまでライントレース
move_right(300) #走るコースの調整
move_advance(300)
line_follow2(0.65) #Kまでライントレース
move_advance(1500) #ピンポン球の回収
move_left(1200)
move_back(3500)
sage(140)
move_advance(1000)
age(60)
move_right(2000)
line_follow2(1.5)
*反省・感想だお☆ [#nf54a9b5]
プルコギ🎵プルコギ🎵プルコギ🎵
sage(140) #アームを下げる
move_advance(1000) #ピンポン球の下に入る
age(60) #アームを上げる
move_right(2000) #走るコースの調整
line_follow2(1.5) #KからMまでライントレース
sage(70) #シュート
*反省・感想 [#nf54a9b5]
ロボット、プログラムの作成と改めて時間のかかるものだと実感した。ライントレースでは、計測時間を10分の1単位で調整しなければならなく、とても時間がかかった。最終的なプログラムでの成功率は30%ほどとかなり低く、円のトレースがなかなか上手くいかなかったり、初める位置によっても成功率が大きく左右させられた。ピンポン球のリリースはアームを下げるだけというシュートとはほど遠いものとなった。~
良かった点としては、交差点Dの検知はほぼ確実にでき、外側ライントレースから内側ライントレースへの切り替わりをスムーズに行えた。
総計:&counter(total); 今日:&counter(today); 昨日:&counter(yesterday);