[[2017b/Member]] *課題2 [#g41334c3] **コース説明 [#u4a587d5] 今回の課題は2通りのコースを分担して走行して紙コップを取り、更に走行したのちにコップを離す。そして完走する、というものになっている。 &ref(2017b/Member/Reici/Mission2/2017b-mission2.png,100%,コース図); +Dに機体を置く +Cを直進 +Bを左折 +Pを左折(一時停止) +Qを直進 +Rを左折 +Fを左折 +Sを直進(一時停止) +Y地点の紙コップを取得 +Sを直進(一時停止) +Qを左折(一時停止) +Rを直進 +X地点に紙コップを置く +Pを左折 +B を左折(一時停止) +A地点へ となっている。 EからヘアピンカーブでFに向かう箇所が難しそうだと感じた。 **機体説明 [#x455ca09] &ref(2017b/Member/Reici/Mission2/001.jpg,100%,ロボ機体); &ref(2017b/Member/Reici/Mission2/001.jpg,25%,ロボ機体); 今回の機体である。Lモータ2つで移動、Mモータでコップをキャッチ&リリースする。 [写真仮置き2] &ref(2017b/Member/Reici/Mission2/002.jpg,25%,CS設置場所); Lモータの駆動軸よりやや前にカラーセンサ(以下CS)を置く。かなり地面に近くなっているので、微妙な数値で制御を変更できる。本当は駆動軸と同じくらいの箇所に置きたかったが、CSに繋ぐケーブルと本体Boxが干渉するので妥協した。 [写真仮置き3] &ref(2017b/Member/Reici/Mission2/003.jpg,25%,コップ掴むところ); コップはこのように上から囲って移動させる。移動中に機体が左右に振れてもコップを取りこぼさないよう、覆いこむ構造にした。 [写真仮置き4] &ref(2017b/Member/Reici/Mission2/004.jpg,25%,ロボ分解図、ケーブル付); 今回の機体は上図のように簡単に分解できる。またMモータとの干渉を避けるためにケーブルを本体Boxの下を通している。 **プログラミング説明/設定とか [#a134abe4] mA=LargeMotor('outA') mD=LargeMotor('outD') mB=MediumMotor('outB') cs=ColorSensor('in1') 各モータ、センサの定義 **プログラミング説明/基礎部分 [#jd03cc98] ライントレース用の基本プログラムについて説明する。 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) このプログラムでライントレースを行う。 ***ピンカーブ用に調整したもの [#v54e65ab] 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() 途中でカーブが急で曲がり切れずに停止してしまう。なのでちょっと回転させて再びライントレースに戻るというだけの雑な仕掛けだが、上手くトレース出来た。 **プログラミング説明/追加部分 [#g115fc3c] 上記のプログラムでは交差点が感知しない場合があったので、その分析と対策について説明する。 -直線から円へ進む場合 -逆に円周から交差点に合流する場合 具体的な箇所としては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) このプログラムではロボットはラインの左縁をジグザグ進む。交差点の検知は&size(20){ロボットが左折する時間};の長さで決まるといっていい。なのでD端子側のモータだけ強く曲がらせることで左折の時間を長く取れるようにした。なおこれでも打率は6割5分だった…。 **プログラミング説明/その他 [#rebd243a] 交差点でのバック、コップの保持、音等 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) 上述したように、このプログラムでは交差点の検知はすべて左折時に行う。一旦交差点で元に戻って、そのまま直進する用。 右折するプログラムも定義したはいいが全く使わなかったので割愛。定義したものは以上となる。 **プログラミング説明/まとめ [#z0ad1d93] 全部書いただけです。アルファベットは上図参照。 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() 以上でライントレース用のプログラムは終わりです。