#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]
今回ライントレースをやってみて、一番難しいと感じたところは交差点を認識する部分だった。この交差点を認識する条件が厳しいと認識せずに進んでいってしまうし、逆に条件が易しすぎると交差点でない普通の直線やカーブを認識してしまった。


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS