今回の課題は2通りのコースを分担して走行して紙コップを取り、更に走行したのちにコップを離す。そして完走する、というものになっている。
となっている。
EからヘアピンカーブでFに向かう箇所が難しそうだと感じた。
今回の機体である。Lモータ2つで移動、Mモータでコップをキャッチ&リリースする。
Lモータの駆動軸よりやや前にカラーセンサ(以下CS)を置く。かなり地面に近くなっているので、微妙な数値で制御を変更できる。本当は駆動軸と同じくらいの箇所に置きたかったが、CSに繋ぐケーブルと本体Boxが干渉するので妥協した。
コップはこのように上から囲って移動させる。移動中に機体が左右に振れてもコップを取りこぼさないよう、覆いこむ構造にした。
今回の機体は上図のように簡単に分解できる。またMモータとの干渉を避けるためにケーブルを本体Boxの下を通している。
mA=LargeMotor('outA') mD=LargeMotor('outD') mB=MediumMotor('outB') cs=ColorSensor('in1')
各モータ、センサの定義
ライントレース用の基本プログラムについて説明する。
def line_follow(): t0 = time.time() t1 = time.time() while t0 - t1 < 0.5: #この場合、0.5秒以上同じ行動をとると停止する t1=time.time() if cs.value() >= 15: #CSの値が15以上で白にいると定義、この場合左折する。 while cs.value() >= 15: #CSが15以下になるまで mA.run_forever(speed_sp= 450) mD.run_forever(speed_sp= -80) t0=time.time() elif cs.value() < 15: #CSの値が15以下は黒。この場合右折。 while cs.value() <=15: mA.run_forever(speed_sp= -80) mD.run_forever(speed_sp= 450) t0=time.time() mA.stop() mD.stop() sleep(2)
このプログラムでライントレースを行う。
def pinC_follow(): line_follow() mA.run_timed(time_sp=500, speed_sp=200, stop_action='brake') mD.run_timed(time_sp=500, speed_sp=-80, stop_action='brake') line_follow()
途中でカーブが急で曲がり切れずに停止してしまう。なのでちょっと回転させて再びライントレースに戻るというだけの雑な仕掛けだが、上手くトレース出来た。
上記のプログラムでは交差点が感知しない場合があったので、その分析と対策について説明する。
具体的な箇所としてはP,Q,Rの三か所だが、上記のline_follow()では交差点と認識してくれず、そのまま一切止まらずに動き続ける。while t0 - t1 <0.5 の時間を短くする(0.45,0.475,0.49と試してみた)と今度は円の途中で止まる。止まる箇所が定位置なら誤魔化すことも出来るのだが全く安定しない。
なので、円を曲がるときだけ別にプログラムをつくる必要があった。以下そのプログラム
def line_C(): t0 = time.time() t1 = time.time() while t0 - t1 < 0.45: #この数値が一番打率が高かった t1=time.time() if cs.value() >= 15: while cs.value() >= 15: mA.run_forever(speed_sp= 250) #変更箇所 mD.run_forever(speed_sp= -80) t0=time.time() elif cs.value() < 15: while cs.value() <=15: mA.run_forever(speed_sp= -80) mD.run_forever(speed_sp= 450) #変更箇所 t0=time.time() mA.stop() mD.stop() sleep(2)
このプログラムではロボットはラインの左縁をジグザグ進む。交差点の検知はロボットが左折する時間の長さで決まるといっていい。なのでD端子側のモータだけ強く曲がらせることで左折の時間を長く取れるようにした。なおこれでも打率は6割5分だった…。
交差点でのバック、コップの保持、音等
def S(): Sound.tone(440,100) #音がピッってなる sleep(500/1000)
わざわざ定義する必要ある?と思われるかもしれないが、道中のデバック用に何かと便利で頻繁に使用するので定義した。EV3は英語音声も流せるのだが、いまいち好みじゃなかったので没。「S()」はずっとシフトキー押したまま打てるので楽だった。そういった作る時のことを考えていきたいなと思った次第。
def get_cop(): mB.run_timed(time_sp=400, speed_sp=-200, stop_action='brake')
コップを掴む?為にアームを下すだけのプログラム。安定して動作するよう、予めアームは垂直にした上で開始する。コップを離す rel_cop()もあるが、speedを逆にしただけなので省略。
def F(): mA.run_timed(time_sp=200, speed_sp=-200, stop_action='brake') S() mA.run_timed(time_sp=200, speed_sp=400, stop_action='brake') mD.run_timed(time_sp=200, speed_sp=400, stop_action='brake') sleep(100/1000)
上述したように、このプログラムでは交差点の検知はすべて左折時に行う。一旦交差点で元に戻って、そのまま直進する用。
右折するプログラムも定義したはいいが全く使わなかったので割愛。定義したものは以上となる。
全部書いただけです。アルファベットは上図参照。
line_follow() S() #C地点で停止 F() #交差点直進 line_follow() S() #B地点で停止 line_C() S() #P地点で停止 line_C() S() #Q地点で停止 F() #交差点直進 line_C() S() #R地点で停止 line_follow() S() #E地点で停止 pinC_follow() S() #F地点で停止 line_follow() S() #S地点で停止 F() #交差点直進 line_C() mA.run_timed(time_sp=200, speed_sp=-200, stop_action='brake') #コップを掴むための位置調整 S() mA.run_timed(time_sp=250, speed_sp=100, stop_action='brake') #前 mD.run_timed(time_sp=180, speed_sp=100, stop_action='brake') #進 get_cop() mA.run_timed(time_sp=80, speed_sp=400, stop_action='brake') F() #S地点に戻ってくる line_C() S() line_C() S() #再びQ地点 F() line_C() S() mA.run_timed(time_sp=480, speed_sp=-200, stop_action='brake') rel_cop() mA.run_timed(time_sp=480, speed_sp=200, stop_action='brake') S() line_follow() S() #再びB地点で停止、最後の交差点 line_follow() S()
以上でライントレース用のプログラムは終わりです。