[[2017a/Member]] *目次 [#g516ec1b] #contents *課題内容 [#p5f4db28] &ref(2017a/Member/irin/Mission2/マップ.png,60%,コース); -課題内容は次の経路に沿ってライントレースをするロボットを製作することである。 --E直進 --F(SOUND_UP) --Q一時停止(SOUND_DOWN)&左折 --R直進(SOUND_UP) --S左折(SOUND_UP) --G(SOUND_UP) --H(SOUND_UP) --T一時停止(SOUND_DOWN)&直進 --T一時停止(SOUND_DOWN)&直進 --R一時停止(SOUND_DOWN)&左折 --S直進(SOUND_UP) --P左折(SOUND_UP) --E一時停止(SOUND_DOWN)&左折 --A停止(SOUND_DOWN) *ロボットの説明 [#p20a4c3a] **実際に動いているところ [#be8fa4b8] https://www.youtube.com/watch?v=xUq5ioWZRWA **本体について [#xec12109] &ref(2017a/Member/irin/Mission2/俯瞰1.JPG,60%,EV3上部); 今回のロボット製作で注意したことの一つとして、車輪の幅が挙げられる。 というのも、現在の車輪幅に至る前に、現在より広い車輪幅で製作していたところ小回りが 効きにくく、安定性に欠けることが判明したからである。 そこで、車輪幅を狭くし、小回りが効くようにすることで、急カーブを安定して回れるように改善した。 **カラーセンサーの位置 [#f05101c9] &ref(2017a/Member/irin/Mission2/securedownload.jpg,60%,EV3裏面); 当初、色センサーの位置をタイヤの近くに設置していたが、直角カーブを検知できず、現在の位置に落ち着いた。タイヤと色センサーは適度に離した方が、タイヤの動きが小さくても、色センサーの動きが大きくなって安定することがわかった。 *プログラムの説明 [#z712b286] **インスタンスの作成 [#h79ad080] #!/usr/bin/python3 # -*- coding: utf-8 -*- import ev3dev.ev3 as ev3 import time mr = ev3.LargeMotor("outA") # MotorRight ml = ev3.LargeMotor("outB") # MotorLeft ts = ev3.TouchSensor("in1") #TouchSensor cs= ev3.ColorSensor("in2") #ColorSensor 補足として、MotorRightはロボット右側のモーターであり、これだけを動作させると左折する。MotorLeftはこの逆である。 **今回設定した関数 [#k79d8f30] def LineTrace(T) while 1: if ts.value() == 1: break if cs.value() >= 38: #白のとき ml.run_forever(duty_cycle_sp=60,speed_sp=60) mr.run_forever(duty_cycle_sp=60,speed_sp=-20) t_1 = time.time() elif cs.value() < 38 and cs.value() >= 23 : #白灰のとき mr.stop() ml.run_forever(duty_cycle_sp=60,speed_sp=60) t_1 = time.time() elif cs.value() < 23 and cs.value() >= 17: #灰色のとき mr.run_forever(duty_cycle_sp=60,speed_sp=80) ml.run_forever(duty_cycle_sp=60,speed_sp=80) t_1 = time.time() elif cs.value() < 17 and cs.value() >= 10: #黒灰のとき ml.stop() mr.run_forever(duty_cycle_sp=60,speed_sp=60) t_1 = time.time() elif cs.value() < 10: #黒のとき mr.run_forever(duty_cycle_sp=60,speed_sp=60) ml.run_forever(duty_cycle_sp=60,speed_sp=-20) if time.time() - t_1 >= T: break この関数は、ロボットがライントレースを行うための関数である。しかし、実際にたどっているのはラインの左側である。授業で紹介されたように5段階で制御している。というのも、当初、白色、灰色、黒色の3段階で試してみたがうまくいかなかったからである。また、この関数にはライントレースだけではなく、黒色の上に任意の実数T(>0)秒間以上センサーがあった場合、break文を実行してwhileループを抜ける機能が実装されている。 def WhiteTrace(A) while 1: if ts.value() == 1: break if cs.value() >= 38: #白のとき ml.run_forever(duty_cycle_sp=60,speed_sp=60) mr.run_forever(duty_cycle_sp=60,speed_sp=-20) if time.time() - t_1 >= T: break elif cs.value() < 38 and cs.value() >= 23 : #白灰のとき mr.stop() ml.run_forever(duty_cycle_sp=60,speed_sp=60) t_1 = time.time() elif cs.value() < 23 and cs.value() >= 17: #灰色のとき mr.run_forever(duty_cycle_sp=60,speed_sp=80) ml.run_forever(duty_cycle_sp=60,speed_sp=80) t_1 = time.time() elif cs.value() < 17 and cs.value() >= 10: #黒灰のとき ml.stop() mr.run_forever(duty_cycle_sp=60,speed_sp=60) t_1 = time.time() elif cs.value() < 10: #黒のとき mr.run_forever(duty_cycle_sp=60,speed_sp=60) ml.run_forever(duty_cycle_sp=60,speed_sp=-20) t_1 = time.time() この関数はライントレースを行い、一個目の関数とほぼ同じである。異なっている点は、黒色の上にある時間を検知してbreak文を実行するのではなく、白色の上に任意の時間A(>0)以上あった時break文を実行することである。 この関数を設定した理由としては、直角カーブ(主にH,G)で色センサーがラインをはみ出し、白色しか検知できなかったからである。 **プログラム本体 [#c2ce1ad6] #F LineTrace(0.3) ev3.Sound.speak("F") ml.stop() while cs.value() <= 30: mr.run_forever(duty_cycle_sp=60,speed_sp=30) ml.run_forever(duty_cycle_sp=60,speed_sp=-10) #Q LineTrace(0.4) ev3.Sound.speak("Q") mr.stop() ml.stop() time.sleep(1) while cs.value() <= 30: mr.run_forever(duty_cycle_sp=60,speed_sp=30) ml.run_forever(duty_cycle_sp=60,speed_sp=-10) #R LineTrace(0.3) ev3.Sound.speak("R") mr.stop() ml.stop() time.sleep(1) while cs.value() <= 30: mr.run_forever(duty_cycle_sp=60,speed_sp=30) #T1 LineTrace(0.5) ev3.Sound.speak("T1") mr.stop() ml.stop() time.sleep(1) while cs.value() <= 35: mr.run_forever(duty_cycle_sp=60,speed_sp=10) ml.run_forever(duty_cycle_sp=60,speed_sp=30) #T2 LineTrace(0.4) ev3.Sound.speak("T2") mr.stop() ml.stop() time.sleep(1) while cs.value() <= 20: mr.run_forever(duty_cycle_sp=60,speed_sp=30) ml.run_forever(duty_cycle_sp=60,speed_sp=10) #H WhiteTrace(0.2) ev3.Sound.speak("H") #急カーブ LineTrace(1) while cs.value() <= 30: mr.run_forever(duty_cycle_sp=60,speed_sp=30) ml.run_forever(duty_cycle_sp=60,speed_sp=-60) #G WhiteTrace(0.8) mr.stop() while cs.value() >= 25: ml.run_forever(duty_cycle_sp=60,speed_sp=30) WhiteTrace(0.8) ev3.Sound.speak("G") #S LineTrace(0.6) ev3.Sound.speak("S") ml.stop() while cs.value() <=25: mr.run_forever(duty_cycle_sp=60,speed_sp=30) #P LineTrace(0.3) ev3.Sound.speak("P") ml.stop() while cs.value() <= 35: mr.run_forever(duty_cycle_sp=60,speed_sp=30) #E LineTrace(0.5) ev3.Sound.speak("E") mr.stop() ml.stop() time.sleep(1) while cs.value() <= 35: mr.run_forever(duty_cycle_sp=60,speed_sp=30) #A LineTrace(0.5) while cs.value() <30: mr.run_forever(duty_cycle_sp=60,speed_sp=30) ml.run_forever(duty_cycle_sp=60,speed_sp=30) ev3.Sound.speak("A") mr.stop() ml.stop() コードのところどころに記述されているLineTrace関数やWhiteTrace関数以外のモーターに関わる命令はロボットの位置調整のために用いられている。 -コードのところどころに記述されているLineTrace関数やWhiteTrace関数以外のモーターに関わる命令はロボットの位置調整のために用いられている。 例えば#Qのような一時停止する場合、黒色の上で停止するので次のライントレースを実行する前に灰色あたりにずらさないと、うまく次のライントレースが実行されない。 また、他の例については、#急カーブが挙げられる。今回製作したロボットは、Hのすぐ後に控える急カーブの内側をトレースする。しかしながら、LineTrace関数ではうまくいかなかった。改善策として灰色以下のとき急旋回を行うコードを継ぎ足した。 補足として、AやPなど名前のある地点に到達した場合、その場所の名前をロボットが音声として出力する。 --実際には、交差点や直角カーブの違いを判断しておらず、LineTrace→F地点での作業→LineTrace→Q地点での作業....といった流れで処理している。 --補足として、AやPなど名前のある地点に到達した場合、その場所の名前をロボットが音声として出力する。 *今回の課題を振り返って [#h02a0443] 今回の課題を振り返ってみて一番大変だったのは、締め切りが迫ってきている中、T地点付近のトレースがうまくいかず、見直した結果、車輪の幅が広すぎるという結論に至り、ロボットを改造したことである。改造自体はすぐに終わったが、車輪の幅が変わったせいでプログラムに大きな影響が出ていた。というのも、ライントレースの値を見直したり、黒色検知の時間を見直す必要があったあったからである。完成一歩手前での出来事だったのですごく辛かった。一度終えた作業をもう一度、一から行うというののはなかなかのものであった。それもあり、完成した時はとてもうれしかった。 次は、こんなことにならないよう、もっと見通しを立てて製作していかなければならないと思った。