2017a/Member

課題2
17T2037H 押見 洋土

 

課題2

 課題2

2017a-mission2.png

 私の担当ルートは上図の番号順になる

ロボット

 今回の課題においてEV3の弱点は車輪幅の大きさであった。カーブを曲がる際等に細かい調整を必要とする面が今回EV3を使用するメンバーを相当に苦労させた。

DSC_0528.JPG

 私達の班はその弱点を最小限にとどめるために、二つのモータを密着させ、車輪幅を可能な限り小さくした。

DSC_0529.JPG
DSC_0527.JPG

プログラム

#!/usr/bin/python3
# -*- coding:utf-8 -*-
import ev3dev.ev3 as ev3
import time
mR=ev3.LargeMotor('outA')
mL=ev3.LargeMotor('outB')
t0=time.time()#一方向のカーブ時間
t1=time.time()#交差点判定の最低時間間隔を保つための時間
t2=time.time()#交差点での動作を司る時間
cs=ev3.ColorSensor('in3')
tsR=ev3.TouchSensor('in1')
tsL=ev3.TouchSensor('in2')
modeA = 0#カーブの方向を決定する型
modeB = 1#modeAに前回のカーブの方向をフィードバックする変数
modeC = 0#交差点の番号をカウントする変数

 変数の定義とモータ、センサの導入

mL.run_timed(time_sp=2000,duty_cycle_sp=50,speed_sp=100,stop_action='brake')
mR.run_timed(time_sp=2000,duty_cycle_sp=50,speed_sp=100,stop_action='brake')    
time.sleep(2)

 初めのスタート地点から無条件で前進する。このスタートをしないと白い地点と判断してぐるぐる回ってしまう。

for loop in range(100000):
   if tsR.value()==1 or tsL.value()==1:
       break

 for文で動作をループさせ、タッチセンサに反応があると緊急停止するようにしている。

   if cs.value()>55 and cs.value()<=60:
       mL.run_forever(duty_cycle_sp=50,speed_sp=120)
       mR.run_forever(duty_cycle_sp=50,speed_sp=120)
       t0=time.time()
       t2=time.time() 

 閾値を設定して、走行の角度を4パターン用意した。必要なところは走行区画(modeC)によって左右の反転をしている。カラーセンサの値が(55,60]の時は直進

   elif cs.value()>37 and cs.value()<=55:

 カラーセンサ(37,55]の時

       if modeC==3 or modeC==2:
           mL.run_forever(duty_cycle_sp=50,speed_sp=60)
           mR.run_forever(duty_cycle_sp=50,speed_sp=100)
           t0=time.time()
           t2=time.time()

 チェックポイント↓の時、左に小さく軌道を修正

       elif modeC!=2 and modeC!=3:
           mL.run_forever(duty_cycle_sp=50,speed_sp=100)
           mR.run_forever(duty_cycle_sp=50,speed_sp=60)
           t0=time.time()
           t2=time.time()

 ↓0奮阿如右に小さく軌道を修正

   elif cs.value()>26 and cs.value()<=37:

 カラーセンサ(26,37]の時

       if modeC==3 or modeC==2:
           mL.run_forever(duty_cycle_sp=50,speed_sp=0)
           mR.run_forever(duty_cycle_sp=50,speed_sp=100)
           t0=time.time()
           t2=time.time()

 チェックポイント↓の時、左に旋回

       elif modeC!=2 and modeC!=3:
           mL.run_forever(duty_cycle_sp=50,speed_sp=100)
           mR.run_forever(duty_cycle_sp=50,speed_sp=0)
           t0=time.time()
           t2=time.time()

 ↓0奮阿了、右に旋回

   elif cs.value()>14 and cs.value()<=26:

 カラーセンサ(14,26]の時

       if modeC==3 or modeC==2:
           mL.run_forever(duty_cycle_sp=50,speed_sp=-70)
           mR.run_forever(duty_cycle_sp=50,speed_sp=100)
           t0=time.time()
           t2=time.time()

 チェックポイント↓の時、左に急旋回

       elif modeC!=2 and modeC!=3:
           mL.run_forever(duty_cycle_sp=50,speed_sp=100)
           mR.run_forever(duty_cycle_sp=50,speed_sp=-70)
           t0=time.time()
           t2=time.time()

 ↓0奮阿了、右に急旋回

   if time.time()-t0<=1.8:
       modeA=modeB#フィードバック
       if modeA==0 and cs.value()>60 and modeC!=3 and modeC!=2:
           mL.run_forever(duty_cycle_sp=50,speed_sp=100)
           mR.run_forever(duty_cycle_sp=50,speed_sp=25)#白検知 右向きに軌道修正
           modeB=0
       elif modeA==1 and cs.value()>60 and modeC!=3 and modeC!=2:
           mL.run_forever(duty_cycle_sp=50,speed_sp=25)
           mR.run_forever(duty_cycle_sp=50,speed_sp=100)#白検知 左向きに軌道修正
           modeB=1
       elif modeA==0 and cs.value()>60:
           if modeC==2 or modeC==3:
               mL.run_forever(duty_cycle_sp=50,speed_sp=100)
               mR.run_forever(duty_cycle_sp=50,speed_sp=25)#白検知 右向きに軌道修正
               modeB=0

 白い地点にいるとき、一定時間内は黒線を探知するまで旋回。同じ方向に曲がり続けるためmodeBはmodeAと同じにして、フィードバックでmodeAの値は一定時間内は変わらないようにしている。

       elif cs.value()<=60 and cs.value()>17 and time.time()-t0>0.9:
           ev3.Sound.play('tyokkaku.wav')
           mR.stop()
           mL.stop()
           time.sleep(1)
           modeC+=1
       t2=time.time()

 設定した時間範囲内に2回黒線上に乗ったとき直角と判断する。

   elif cs.value()>60:
       if modeA==1:
           mL.run_forever(duty_cycle_sp=50,speed_sp=100)
           mR.run_forever(duty_cycle_sp=50,speed_sp=0)#白検知 右向きに旋回
           modeB=0
       elif modeA==0:
           mL.run_forever(duty_cycle_sp=50,speed_sp=0)
           mR.run_forever(duty_cycle_sp=50,speed_sp=100)#白検知 左向きに旋回
           modeB=1
       t2=time.time()

 白の旋回が一定時間を超えると逆向きに旋回する。こちらはmodeBはmodeAと逆の値にして、次回の白の旋回の方向を決定する。ここではmodeAは決定済みで、modeBに関係なく旋回するためフィードバックはない。

   if cs.value()<=14 and time.time()-t1>3:
       while time.time()-t2<=1:
           mL.stop()
           mR.stop()
       modeC += 1

 交差点と判断すると各チェックポイントでカウント用変数(modeC)を1増加させ、一度ストップさせる。

       while time.time()-t2>1 and time.time()-t2<=3:
           if modeC==1:#
               ev3.Sound.play('tziro.wav')
               mL.run_timed(time_sp=210,duty_cycle_sp=50,speed_sp=170,stop_action='brake')
               mR.run_timed(time_sp=210,duty_cycle_sp=50,speed_sp=-80,stop_action='brake')

 ポイント,瞭虻遏ПΔ膨廠僂剖覆る

           elif modeC==2 or modeC==7:↓                
               ev3.Sound.play('tziro.wav')
               mL.run_timed(time_sp=400,duty_cycle_sp=50,speed_sp=-50,stop_action='brake')
               mR.run_timed(time_sp=400,duty_cycle_sp=50,speed_sp=110,stop_action='brake')

 ポイント↓Г瞭虻遏Ш犬帽線を横切ってサークルの左側へ移動

           elif modeC==3 or modeC==8:
               ev3.Sound.play('tziro.wav')
               mL.run_timed(time_sp=400,duty_cycle_sp=50,speed_sp=165,stop_action='brake')
               mR.run_timed(time_sp=400,duty_cycle_sp=50,speed_sp=70,stop_action='brake')
               while time.time()-t2>2 and cs.value()>70:
                   mL.run_forever(duty_cycle_sp=50,speed_sp=140)
                   mR.run_forever(duty_cycle_sp=50,speed_sp=50)

 ポイント┐瞭虻遏Д櫂ぅ鵐箸旅線を通り抜け、右側に方向を曲げる

           elif modeC==4 or modeC==9:き
               ev3.Sound.play('tziro.wav')
               mL.run_timed(time_sp=800,duty_cycle_sp=50,speed_sp=40,stop_action='brake')
               mR.run_timed(time_sp=800,duty_cycle_sp=50,speed_sp=150,stop_action='brake')

 ポイントきの動作:ポイントの黒線を通り抜け、左側に直角に曲がる

           elif modeC==5 or modeC==6 or modeC==10:キΝ            
               ev3.Sound.play('kousaten.wav')
               mL.run_timed(time_sp=500,duty_cycle_sp=50,speed_sp=100,stop_action='brake')
               mR.run_timed(time_sp=500,duty_cycle_sp=50,speed_sp=100,stop_action='brake')
           t0=time.time()
           t1=time.time()

 ポイントキΝの動作:ポイントの黒線を通り抜ける。

route.png

 黒線上に乗った場合に交差点と判断する。閾値でだいぶ線から離れて走行しているため、このシンプルな方法でも正確性は高い。
 各々のポイントの動作をする。似た形状のポイントは動作も同じにして問題ないため、複数のポイントをまとめて分けた。音声はゆっくりを使用した。

   elif cs.value()<=14 and time.time()-t2<=3:
       mL.run_forever(duty_cycle_sp=50,speed_sp=100)
       mR.run_forever(duty_cycle_sp=50,speed_sp=-70)
       t0=time.time()
       t2=time.time()

 チェックポイントと判断してから一定時間は次のチェックポイントはないとして、軌道を曲げる。  mR.stop()
 mL.stop()

結果

 まだ一周できていない。番号で示すとイ泙任楼貪戮世荏ってくれた。

反省

 イ泙任蝋圓辰燭、そこまでもかなり成功率は低く、調整だけでは100%は難しいようでプログラミングの構造自体に要改善点がある。
 カウント変数を用いる際にwhile文を用いると一度に複数カウントしてしまうため、いろいろと試してみるとfor文のループでは1カウントのみになることがわかった。これはEV3の処理形態とwhile,forの動作による違いだと思われる。
 pythonにおいて、for文ではシークエンスオブジェクト(オブジェクトと総称される、数値、文字で表される要素を一定の順序で並べたもの。今回のrange関数は順序を持った整数のリストとして用いた。)のすべての要素について同じプログラムが走り、1つの要素を完了することで次の要素のプログラムが始まる。while文ではtrueである間全体のプログラムを絶えず繰り返す。
 今回のfor文では黒線を感知し、run_timedで白面に出るまでの間次の要素に行かないためカウンタが増えず、while文ではそれぞれのチェックポイントの動作が始まるまで(time.time()-t2<=1まで)全体のプログラムを何度も繰り返し、カウントする条件である黒線の感知とtime.time()-t1>3(t1:チェックポイントの判断に時間間隔を置くためのタイマー)を満たすため、カウントを黒線上で複数回することになる。これによってカウンタの結果に違いが出たと考えられる。
 for文の繰り返し数が100000と多いのは、run_forever等の動作の条件についてfor文内のwhileの判断の頻度が不明だったため、1つのチェックポイントに10000程の繰り返し回数を試しに用意したためである。
 今回は次の課題があるためこれ以上の調整は難しいためここで中断したが、イ泙嚢圓辰討い燭燭畍緘召寮泙衒屬靴泙嚢圓韻丱粥璽襪任たかもしれない。相方は同じ機体でゴールしたため悔しさが残った。
 問題の原因を明確にするためにもwhileからforへの変更など、動作の比較試験をしておくべきだった。

考察

 前半のチェックポイント以外の部分をwhileで囲み、チェックポイントの動作をif文でわけ、動作をfor文のオブジェクトに対応させれば、range関数やカウント変数を用いず全体を簡潔に書けただろう。


添付ファイル: fileroute.png 87件 [詳細] file2017a-mission2.png 93件 [詳細] fileDSC_0529.JPG 80件 [詳細] fileDSC_0528.JPG 79件 [詳細] fileDSC_0527.JPG 87件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-08-14 (月) 00:42:55