目次
いずれの方法もカラーセンサによってラインを検知している
PID制御とは“比例と積分と微分を使った制御”のことであり、P制御では現在の状況に対して操作量を決定する(カーブをどのぐらい曲がるのかを操作する)、I制御では過去の状況に対して操作量を決定する(カーブが終わり際に発生するP制御の誤差を修正する)、D制御は未来の状況を予測して操作量を決定する(カーブに差し掛かかった際にロボットが曲がり始めるようにする)今回はこの制御を断念したため、使用していない。よって詳しい説明は割愛する。
今回ロボット本体の設計を行ったのはbeingさんであり、前回の課題から流用しているパーツも多いため、比較的すぐに完成した
EV3 Lモーター ×2 (税込4,644円/個)
EV3カラーセンサー
EV3超音波センサー
EV3 Mモーター ×1(税込3,780円)
#!/usr/bin/env python3 # python3でプログラムを作成する from ev3dev.ev3 import * import ev3dev.ev3 as ev3 import time arm = ev3.MediumMotor('outA') #ボールを保持するアームをMidiumMotorで制御する mr = ev3.LargeMotor('outB') #mr : 右駆動輪 ml = ev3.LargeMotor('outC') #ml : 左駆動輪 us = ev3.UltrasonicSensor('in1') #us : 超音波センサ gy = ev3.GyroSensor('in2') #gy : ジャイロセンサ(今回は使用しない) cs = ev3.ColorSensor('in3') #カラーセンサ(反射光の強さモード)5~80の値が返ってくる x = 0 #x : 交差点のカウントに用いる lfr = 200 #lfr :右駆動輪の出力値 (line follow right) lfl = 80 #lfl : 左駆動輪の出力値 (line follow left)
###ライントレース### def line_follow(): while cs.value() >= 50: #カラーセンサが白を検知した時、右に曲がる mr.run_forever(speed_sp=lfr) ml.run_forever(speed_sp=-lfl) t0 = time.time() while cs.value() < 50: #カラーセンサが黒を検知した時、左に曲がる mr.run_forever(speed_sp=-lfl) ml.run_forever(speed_sp=lfr)
###交差点について(何も指定しない場合、交差点を右折する)### #ライントレース時にカラーセンサが黒色を認識している時間が一定以上になった時に交差点と判断する
#交差点を直進 def go_straight(): #交差点と認識するとロボットを目的の進行方向に向け、直進する。 mr.run_forever(speed_sp=lfl) #このあと直進時の交差点の誤検知を防ぐ措置をとる(後述) ml.run_forever(speed_sp=-lfr) time.sleep(1.2) mr.run_forever(speed_sp=200) ml.run_forever(speed_sp=210) time.sleep(0.5) if cs.value() >= 50: #white while cs.value() >= 50: mr.run_forever(speed_sp=lfr) ml.run_forever(speed_sp=-lfl) t0 = time.time() else: #black mr.run_forever(speed_sp=-lfl) ml.run_forever(speed_sp=lfr) t0 = time.time #交差点を左折 def turn_left(): mr.run_forever(speed_sp=lfl) ml.run_forever(speed_sp=-lfr) time.sleep(elapsed_time) mr.run_forever(speed_sp=lfr) ml.run_forever(speed_sp=-lfl) time.sleep(elapsed_time)
###ボールに対する動作### def ball_catch(): #アームを上げる arm.run_forever(speed_sp=-60) time.sleep(2) arm.stop() def shoot(): #ゴールを狙う mr.run_forever(speed_sp=lfl) ml.run_forever(speed_sp=-lfr) time.sleep(1.4) mr.stop() ml.stop() time.sleep(1) #助走をするためゴールとの距離を少し開ける mr.run_forever(speed_sp=-100) ml.run_forever(speed_sp=-100) time.sleep(0.6) #ボールを設置する arm.run_forever(speed_sp=60) time.sleep(1) mr.stop() ml.stop() time.sleep(1) arm.stop() mr.run_forever(speed_sp=-100) ml.run_forever(speed_sp=-100) time.sleep(1) arm.run_forever(speed_sp=-60) time.sleep(2) arm.stop() #助走する mr.run_forever(speed_sp=300) ml.run_forever(speed_sp=300) time.sleep(1) mr.stop() ml.stop() #射出する arm.run_forever(speed_sp=300) time.sleep(0.6) arm.stop()
shoot()の動作(「ボールを設置する」 からの動作)
###今回の流れ############################################# # B -> R(go_straight) -> P(turn_R) -> Q(go_straight) -> ball_catch # -> Q(go_straight) -> R(turn_R) -> P(go_straight) -> S(turn_R) -> shoot ####################################################### Sound.play('start.wav') #音声ファイルを再生 time.sleep(1) mr.run_forever(speed_sp=220) ml.run_forever(speed_sp=220) time.sleep(1) ###直進時の交差点の誤検知を防ぐ措置### if cs.value() >= 50: #カラーセンサが白を検知した時、右に曲がる while cs.value() >= 50: #カラーセンサが黒を検知するまで続ける mr.run_forever(speed_sp=lfr) ml.run_forever(speed_sp=-lfl) t0 = time.time() else: #カラーセンサが黒を検知した時、左に曲がる mr.run_forever(speed_sp=-lfl) ml.run_forever(speed_sp=lfr) t0 = time.time() #これによって交差点と認識させないようにしている #########################
直進時の交差点の誤検知を防ぐ措置を取らない場合
while True: t0 = time.time() line_follow() elapsed_time = time.time() - t0 #elapsed_time:カラーセンサが黒を検知している間の経過時間 ######交差点の判定###### if elapsed_time > 1.18: #elapsed_timeが1、18秒以上のとき現在位置を交差点と認識する x += 1 #交差点の数を数える mr.stop() ml.stop() Sound.play('kousatendesu.wav') #音声ファイルを再生する time.sleep(1.2) ########交差点での動作################ if x == 1 or x == 3 or x == 4 or x == 6: #交差点R,Q,Q(2回目),P(2回目)では直進する go_straight() if x == 3: #交差点Qを通過した時、超音波センサを起動しボールをさがす while True: ###超音波センサの誤検知を防ぐ措置### us1 = us.value() #稀に一瞬ボール以外のものを検知することもあるため3回計測し、その平均値によって判断している us2 = us.value() us3 = us.value() ############################### line_follow() if (us1 + us2 + us3)/3 < 85: #ボールを検知した時、停止してボールを掴む break mr.stop() ml.stop() ball_catch() elif x == 8: #ゴールにたどり着いた時、ゴールにボールをシュートする time.sleep(1) Sound.play('neraimasu.wav') #音声ファイルを再生する shoot() #ボールをシュートする Sound.play('unicorn.wav') #音声ファイルを再生する break #動作を終了する
対処法
対処法
今回の課題ではライトセンサ2個とPID制御によるライントレースを計画していたが、ライトセンサが1個しかなかったため計画を変更した。また、余裕を持ってプログラムを作成することができたため成功率を非常に高めることができた。交差点の判断にはモーターの角度制御を用いたかったが、作成時にはうまく動作しなかったため時間を計ることによって行った。次の課題では、角度制御やジャイロセンサなど、ev3の性能を活用していきたいと思う