- 追加された行はこの色です。
- 削除された行はこの色です。
#contents
*課題2の内容 [#fb0bb097]
今回の課題はライントレースで決められた場所を走らせ、その途中で空き缶を認知し缶に向かってボールを投げさせるロボットを作成するというものであった。コースは2つあり、その内容や経路は経路は以下に表す通りである。
第1コース
#ref(2018b/Member/prague/Mission2/robo street1.png,100%,経路1);
ロボットを長方形X内におき、Aをスタート
1,Bを右折
2,Kで一時停止して左折
3,Jを直進
4,Iを直進
5,Hを左折
6,Gで一時停止して左折
7,Eで一時停止して右折
8,Lを経て正方形Y内に入って停止
(一時停止の指定がある場所は、1秒間停止すること)
ボールはロボットが弧KJIH上にある時にQ地点の空き缶に当てる。
第2コース
#ref(2018b/Member/prague/Mission2/robo street2.png,100%,経路2);
ロボットを正方形Y内におき、Lをスタート
1,Eを一時停止して直進
2,Iを一時停止して左折
3,Hを直進
4,Kを直進
5,Jを左折
6,Cを一時停止して右折
7,Eを一時停止して直進
8,Gを一時停止して直進
長方形X内に入って停止
(一時停止の指定がある場所は、1秒間停止すること)
ボールはロボットが弧IHKJ上にある時にP地点の空き缶に当てる。
*機体について [#ga36b92c]
**機体の全体図[#n28e5578]
#ref(2018b/Member/prague/Mission2/robobo.png,10%,機体の全体像)
#ref(2018b/Member/prague/Mission2/robo zentaizu .png,10%,機体の全体像〜後ろから〜)
**機体の特徴 [#fb1be886]
***車体部分 [#z82b9af6]
今回はライントレースということで色を読み取って機体を黒線に合わせながら進んでいくこと、さらに缶の位置を検知してボールを投げることが課題に挙げられているため超音波センサーとカラーセンサーをロボットに組み込まなければならない。ここでいうセンサはそれぞれ以下のようなものである。
***放出部分 [#z5a87b02]
このロボットではボールを転がす形で投げるような設計にした。
*プログラミング [#t681e04a]
#!/usr/bin/env python3
from ev3dev.ev3 import *
from time import sleep
mL = LargeMotor('outA') #左タイヤの出力の定義
mR = LargeMotor('outB') #右タイヤの出力の定義
mi = MediumMotor('outD') #放出部分の出力の定義
s1 = TouchSensor('in3') #タッチセンサの出力の定義
s2 = ColorSensor('in4') #カラーセンサの出力の定義
U1 = UltrasonicSensor('in2') #超音波センサの出力の定義
def laf(t): #left and forwardの略
mL.run_timed(time_sp=30,speed_sp=120+20*t,stop_action='brake')
mR.run_timed(time_sp=30,speed_sp=120-20*t,stop_action='brake')
def raf(t): #right and forwardの略
mL.run_timed(time_sp=30,speed_sp=120-20*t,stop_action='brake')
mR.run_timed(time_sp=30,speed_sp=120+20*t,stop_action='brake')
def tl(t): #turn leftの略
mL.run_timed(time_sp=20,speed_sp=-150*t,stop_action='brake')
mR.run_timed(time_sp=20,speed_sp=150*t,stop_action='brake')
def tr(t): #turn lightの略
mL.run_timed(time_sp=20,speed_sp=100*t,stop_action='brake')
mR.run_timed(time_sp=20,speed_sp=-100*t,stop_action='brake')
def fd():
mL.run_timed(time_sp=20,speed_sp=150,stop_action='brake')
mR.run_timed(time_sp=20,speed_sp=150,stop_action='brake')
def roll(t,s):
mL.run_to_rel_pos(position_sp=t,speed_sp=150,stop_action='brake')
mR.run_to_rel_pos(position_sp=s,speed_sp=150,stop_action='brake')
基本的なロボットの動かし方は以下のとおりである。
#ref(2018b/Member/prague/Mission2/sikumi.png,100%,トレースの仕組み);
以下はボールを投げる際に利用した定義である。
def throwing(s,t): #ボールを投げる際につかわれる定義
mi.run_timed(time_sp=s,speed_sp=t,stop_action='brake')
def turn(s,t):
mL.run_timed(time_sp=s,speed_sp=t,stop_action='brake')
mR.run_timed(time_sp=s,speed_sp=-t,stop_action='brake')
ここからは実際にロボットを動かすプログラミングである。
roll(150,150) #前にロボットを動かす
sleep(3) #3秒止まる
w=0 #変数wの定義
b=0 #変数bの定義
i=0 #変数iの定義
while s1.value() == 0: #タッチセンサーが押されていないときに命令を実行させる。
t0 = time.time()
if i == 0: #i=0の時の数える時間
s=0.2
elif i == 3:
s=1.0
elif i == 6:
s=3
elif i == 7:
s=1.1
elif i == 8:
s=6.5
elif i == 9:
s=0.7
else:
s=0.8
while i <= 9:
if time.time()-t0 <= 7*s:
b=0
if 65 < s2.value(): #道から大きく外れたときの命令
tl(-1)
w=w+1
b=0
if 55 < s2.value() <= 65: #道から少し外れたときの命令
laf(1)
w=w+1
b=0
if 50 < s2.value() <= 55: #黒と白のちょうど境界線を走るときの命令
fd()
w=0
b=0
if 40 < s2.value() <= 50:
if 40 < s2.value() <= 50: #道の中に少しだけ入り込んだときに実行する命令
raf(1)
b=b+0.6
if s2.value() <= 40:
if s2.value() <= 40: #道に深く入り込んだ時の命令
tr(-1)
b=b+1
w=0
elif b>33:
i=i+1
print(i)
break
if i == 1:
sleep(2)
b=b+1 #変数bに1を足す
w=0 #変数wを0に戻す
elif b>33: #交差点を認識した時の命令
i=i+1 #iに1を足す
print(i) #コマンドプロンプトにiの値を表示させる
break #命令を終わらせる
if i == 1: #iが1の時の命令
sleep(2) #2秒休み
roll(30,-30)
sleep(1)
sleep(1) #1秒休み
roll(50,50)
sleep(2)
if i == 3:
sleep(2) #2秒休み
if i == 3: #iが3の時の命令
roll(200,0)
sleep(2)
sleep(2) #2秒休み
I=0
while s1.value()==0:
u = 100000
while s1.value()==0: #ここから缶を見つけてボールを投げる命令が始まる。
u = 100000
t0=time.time()
print(I)
turn(12000,70)
while time.time()-t0<= 12:
while time.time()-t0<= 12: #命令を実行する際の条件
if u >=U1.value():
u = U1.value()
t1 = time.time()
print(u)
else:
continue
sleep(0.5)
t2=time.time()
sleep(1)
sleep(0.5) #0.5秒休み
t2=time.time() #t2の定義
sleep(1) #1秒休み
print(t1)
print(t2)
t3=t2-t1
print(t3)
turn(t3*(1040+10*i),-70)
sleep(t3*1.2)
sleep(t3*1.2) #t3の1.2倍だけ秒休み
if u+20>U1.value():
throwing(1000,50)
sleep(3)
sleep(3) #3秒休み
throwing(1000,-50)
break
elif I == 3:
throwing(1000,50)
sleep(3)
sleep(3) #3秒休み
throwing(1000,-50)
break
else:
I=I+2
sleep(2)
sleep(2) #2秒休み
roll(-30,-30)
sleep(3)
if i == 4:
sleep(3) #3秒休み
if i == 4: #iが4の時の命令
roll(200,0)
sleep(2)
if i == 6:
sleep(2) #2秒休み
if i == 6: #iが6の時の命令
roll(-10,-10)
sleep(2)
sleep(2) #2秒休み
roll(420,-20)
sleep(6)
if 8 <= i <= 9:
sleep(6) #6秒休み
if 8 <= i <= 9: #iが8,9の時の命令
roll(30,-30)
sleep(1)
sleep(1) #1秒休み
roll(70,70)
sleep(2)
if i == 10:
sleep(2) #2秒休み
if i == 10: #iが10の時の命令
roll(50,-50)
sleep(1)
sleep(1) #1秒休み
roll(250,250)
break
break #実行を終了させる
ここで変数w,b,iというものが存在しているが、これは順に白の検知数、黒の検知数、交差点の検知数を表すものであり、白と黒をを認識した数を数えさせることで今ロボットが動いている場所が交差点であるのかということや、今いる交差点は何回目のものであるのかを数えてそれにより実行する命令を変えさせるために用意した。
またsという変数は時間を表す。このsは交差点を認知した瞬間から計られ、この時間の範囲内はbの値が常に0となり普通の道を間違えて交差点だと検知しないように設定されている。
*考察と反省 [#m4a19783]
今回ライントレースをやってみて、一番難しいと感じたところは交差点を認識する部分だった。この交差点を認識する条件が厳しいと認識せずに進んでいってしまうし、逆に条件が易しすぎると交差点でない普通の直線やカーブを認識してしまった。