#contents *はじめに [#j9c2c091] 今回は前回よりは早く始めることができ、かなりの余裕を持って機体、ロボット共々完成させることができた。とはいえ、今回も一筋縄ではいかなかった。~ 結局、最新のev3dev(2016-10-17版)にアップグレードし、pythonのバージョンをpython3に変更し、windows10からはteraterm、linux mintからは端末からアクセスし、nanoを使ってプログラミングした。~ また、下書き用にPyCharmのCommunity Editionを利用した。&size(7){相変わらず大学のWifi経由だと不安定で使いにくい。あと、PyCharmほんとに便利・・・}; *課題2について [#pb1a32ef] 今回の課題は簡単に言えばライントレース+ピンポン玉の確保&シュートである。&size(7){前期より複雑になってる・・・};~ 自分はAスタートであるため、“ Aスタート → P直進 → Q直進 → (ピンポン玉をキャッチ) → Q直進 → R右折 → P直進 → S左折 → Dへシュート”である。 今回も機体製作は私、プログラムの雛形はペアのbickyである。 *コースについて [#q45eaa78] *今回の機体について [#bd46a54a] **本体 [#a427fead] 今回の機体で重視したのはコンパクトさである。(写真は見やすさのためにケーブルを取り外してある)~ 超音波センサー側に進むのだがもともとは反対方向へ進むように作っていたが、これでは車輪とアームの位置が離れてしまう(ライントレース中の機体の左右の揺れが大きくなってしまい、ピンポン玉をはじいてしまう)という指摘を受けたため急遽、逆向きにした&size(15){そのため、後ろ側のほうがいろいろつけられる構造になっており、前側の拡張性が低く苦労した。};~ **センサーについて [#q663c934] 使用しているセンサーは超音波センサー、カラーセンサー(赤色発光反射率モード)&size(7){値が条件にも依るが3〜92程度の範囲で返ってくるため、そのまま利用した};ジャイロセンサー(積算モード?)である。 ***この課題においての各センサーの特徴 [#i56f3286] 超音波センサーは、超音波を発してその超音波が帰ってくるまでの時間から対象との距離を測るセンサーである。今回は機体に地面と水平に取り付け、また値を三回取得し平均を取ることで外的要因や電圧の影響を受けにくくなっている。~ 地面と水平に設置することで地面に向けて設置した場合と比べて、ライントレース中の機体のがたつきに影響されることなく、値がおかしくなってゴーストを検知してしまうことがなくなった。~ 今回の課題の場合対象物が球形であるため反射波が&size(7){ステルス機に当たったレーダー波のように};拡散されてしまう影響か、値が突然大きくなってしまうという現象が散見された。~ われわれの機体は取り付け位置のおかげか特にそのような現象には悩まされなかった。~ ~ カラーセンサーは、もともと光の三原色を発して色を判定し、その値を色ごとのコードで返してくるものであるが、今回はモードを変更して赤色に発光させ反射率を測定し0〜100で返すモードを使った。&size(7){モードの変更方法は後に記述};~ ~ ジャイロセンサーは本来角速度を検知するものであるため、自分の向いている向きを相対的に&size(7){積分を始めたときの向きが起点として};知るためにはこれを積分しなくてはならず処理速度が一定とはいいがたいEV3で角度を知るのは困難であると思っていた。~ しかし、実際に使ってみるとセンサーの内部で積分しているらしかなり正確な角度を知ることができたが結局自分が最後にほんの少しだけ使うにとどまった。&size(7){たぶんこのセンサーと時間制御のみで今回の課題はクリアできる};~ **ピンポン玉関連の機構について [#xc3cbf14] 今回の機体を製作するにあたっていろいろな機構を考えたものの、ピンポン玉を確保し打ち出すという動作をするのに適切な形を求めていった結果このようになった。~ ***ピンポン玉の確保について [#h4dacc8d] 今回の機体はアーム部を上げたまま移動し、Qを通過後に超音波センサーがピンポン玉を検知するとアームを下ろすという非常にシンプルなものになっている。アーム動作用のモーターはev3本体に直接ついている。~ 機体は反時計回りに進んでいるため、超音波センサーと降りてきたアーム、機体側のバーによって囲まれることで確保される。このときアームを下ろし過ぎないように物理的にリミッターを取り付けてある。 ***ピンポン玉の打ち出しについて [#sdea9034] ピンポン玉の打ち出し手順はシンプルであり、ゴールに到着すると機体の向きを整え、アームを上げてからゆっくりと下がりアームを下げ、前進しながら全力でアームを上げることで打ち出す、という特に難しくもない方式である。~ この方式の課題は、機体がピンポン玉を離しているあいだに何処かへ行ってしまうということと、打ち出すときにアームがピンポン玉と接しておらず打ち出せないときがあることと、変にアームがピンポン玉に当たると意図しない方向に飛んでいってしまうことである。~ これは外的要因によるものであるため動かないようにすることは困難である。 この問題に対応するためたとえピンポン玉が動いてもシュートできるように機体を改造した。~ 簡単に言えばガイドレールの設置とピンポン玉を機体に押し付けることである。ピンポン玉が動いてしまうとはいえそこまで早くは移動しないため多少の時間はあるのでその間にアームを下げ、その状態で前進することにより超音波センサーから伸びているレールとアームから伸びているレールではさみ、機体が前進することでアームとピンポン玉が離れないようにし、安定した打ち出しができるようになった。 **機体の分解について [#ndf053b9] 今回の機体は前回の機体のフレームを立てて、ev3を取り付けたような構造である。今回もゆがまないように、また特定のパーツにだけ負荷がかからないようにした。~ 箱にしまえる大きさまで分解するとモーター2個とジャイロセンサーがついたフレーム、アーム、超音波センサー部、ev3の4パーツである。今回は左右対称には作れなかったが、走行中に歪まず、部品が外れず、分解しやすい機体になっていると思う。 *プログラムについて [#n0984797] **ball.py [#cddcab06] #!/usr/bin/env python3 import ev3dev.ev3 as ev3 import time arm = ev3.MediumMotor('outA') mr = ev3.LargeMotor('outB') ml = ev3.LargeMotor('outC') #behave of ball def ball_catch(): arm.run_forever(speed_sp=-60) time.sleep(4) arm.stop() def shoot(): cs = ev3.ColorSensor('in3') #5~80 gy = ev3.GyroSensor('in2') gy_old = gy.value() while abs(gy.value() - gy_old) < 90: mr.run_forever(speed_sp=100) ml.run_forever(speed_sp=-100) mr.run_forever(speed_sp=-100) ml.run_forever(speed_sp=-100) time.sleep(1) while cs.value() >= 40: #white mr.run_forever(speed_sp=100) ml.run_forever(speed_sp=100) while cs.value() < 40: mr.run_forever(speed_sp=0) ml.run_forever(speed_sp=-60) mr.stop() ml.stop() arm.run_forever(speed_sp=60) time.sleep(1) arm.stop() time.sleep(1) mr.run_forever(speed_sp=-200) ml.run_forever(speed_sp=-200) time.sleep(2)#adjust mr.stop() ml.stop() arm.run_forever(speed_sp=-500) time.sleep(0.5) arm.stop() mr.run_forever(speed_sp=150) ml.run_forever(speed_sp=150) time.sleep(3.2) arm.run_forever(speed_sp=1050) mr.stop() ml.stop() time.sleep(0.5) arm.stop() **linetrace.py [#fa484292] #!/usr/bin/env python3 import ev3dev.ev3 as ev3 import time mr = ev3.LargeMotor('outB') ml = ev3.LargeMotor('outC') cs = ev3.ColorSensor('in3') #5~80 GoPw = -120 linepowerS = -150 linepowerL= -60 target = 40 power = 100 KP = 4.0 #def line_follow():#with P # while cs.value() >= 70: #white # mr.run_forever(speed_sp=-GoPw) # ml.run_forever(speed_sp=GoPw) # t0 = time.time() # while cs.value() >= 20 and cs.value() < 70: #gray?#P # turn = KP*(cs.value() - target) # pwl = power - turn # pwr = power + turn # mr.run_forever(speed_sp=pwr) # ml.run_forever(speed_sp=pwl) # while cs.value() < 20: #black # mr.run_forever(speed_sp=Gopw) # ml.run_forever(speed_sp=-GoPw*2) def line_follow(): while cs.value() >= 50: #white mr.run_forever(speed_sp=-linepowerS) ml.run_forever(speed_sp=linepowerL) t0 = time.time() while cs.value() < 50: #black mr.run_forever(speed_sp=linepowerL) ml.run_forever(speed_sp=-linepowerS) #behave at intersection(normal:turn_right) def go_straight(): mr.run_forever(speed_sp=-GoPw) ml.run_forever(speed_sp=GoPw/3*2) time.sleep(2.5) ml.stop() mr.stop() while cs.value() >= 50: #find line mr.run_forever(speed_sp=200) while cs.value() < 70: #Adjust direction mr.run_forever(speed_sp=-100) ml.run_forever(speed_sp=200) while cs.value() >= 40: mr.run_forever(speed_sp=200) ml.run_forever(speed_sp=-100) #for last intersection def turn_left(): mr.run_forever(speed_sp=200) ml.run_forever(speed_sp=-150) time.sleep(2) while cs.value() >= 30: #find line mr.run_forever(speed_sp=200) def start(): mr.run_forever(speed_sp=220)#Get out of Zone A ml.run_forever(speed_sp=220) time.sleep(1) mr.stop() ml.stop() time.sleep(1) if cs.value() >= 50: while cs.value() >= 50: #find line mr.run_forever(speed_sp=200) else: while cs.value() < 50: #Adjust direction mr.run_forever(speed_sp=-200) ml.run_forever(speed_sp=200) **li-S.py [#af5a8604] #!/usr/bin/env python3 from ev3dev.ev3 import * import ev3dev.ev3 as ev3 import time import linetrace as move import ball as catch #A to D arm = ev3.MediumMotor('outA') mr = ev3.LargeMotor('outB') ml = ev3.LargeMotor('outC') us = ev3.UltrasonicSensor('in1') cs = ev3.ColorSensor('in3') #5~80 x = 0 Itime = 1.6 # A -> P(go_straight) x=1 -> Q(go_straight) x=2 -> ball_catch # -> Q(go_straight) x=3 -> R(turn_R) -> P(go_straight) -> S(turn_L) -> shoot # ev3.Sound.speak('start!') Sound.play('start.wav') time.sleep(1) move.start() while True: t0 = time.time() move.line_follow() elapsed_time = time.time() - t0 print(elapsed_time, cs.value(),us.value()) if elapsed_time > Itime: x += 1 #count of intersection print('count = ', x) mr.stop() ml.stop() ev3.Sound.play('kousatendesu.wav') time.sleep(1.2) if x == 1 or x == 2 or x == 3 or x == 5: #A to D move.go_straight() if x == 2: while True: us1 = us.value() us2 = us.value() us3 = us.value() print(us1,us2,us3) move.line_follow() if (us1 + us2 + us3) / 3 < 70: mr.stop() ml.stop() break catch.ball_catch() elif x == 6: move.turn_left() elif x == 7: ev3.Sound.play('neraimasu.wav') catch.shoot() break