[[2018b/Member]] #contents *課題3の内容 [#z8284252] *ロボットの紹介 [#m31fda23] 前回のロボットを改良して、カラーセンサーと超音波センサーが真ん中に来るようにした。 ボールを掴むのではなくベルトコンベアを使って掬い上げるようにした。こうすることによって、ボールを2つ保持することができるので、s字カーブを通らなくて済むようになった。 また、ベルトコンベアにすることによってボールを掴む動作に使用するモーターを一つだけにすることができた。 今回はジャイロセンサーを利用していて、車体の回転した角度を測っている。 ベルトコンベアのプロセスは以下の画像の通りである。 **このロボットに至った経緯 [#w113020a] 最初はUFOキャッチャーのようにボールを掴むロボットを考えていたが、課題一の反省からモーターによってモーターを動かすと車体のバランスが悪くなったり、ケーブルに引っ張る力が加わって正確に動かないと思ったので、ベルトコンベア式にした。 *プログラム [#ce923e86] **ライントレース [#mff91215] 基本的に課題2と変化は無い。(課題2: http://yakushi.shinshu-u.ac.jp/robotics/?2018b%2FMember%2FKisuke%2FMission2) def linetrace_rin(): c1=cs.value() while c1>13: c1=cs.value() x=(abs(c1-10)/70)*100 if x>100: x=100 l=(x/100)*210-30 r=150-l ml.run_forever(speed_sp=l,stop_action='brake') mr.run_forever(speed_sp=r,stop_action='brake') stop() def linetrace_lin(): c1=cs.value() while c1>13: c1=cs.value() x=abs((c1-10)/70)*100 if x>100: x=100 r=(x/100)*210-30 l=150-r ml.run_forever(speed_sp=l,stop_action='brake') mr.run_forever(speed_sp=r,stop_action='brake') stop() def linetrace_rout(): c1=cs.value() while c1<40: c1=cs.value() x=(abs(c1-10)/70)*100 if x>100: x=100 l=(x/100)*120-40 r=40-l ml.run_forever(speed_sp=l,stop_action='brake') mr.run_forever(speed_sp=r,stop_action='brake') stop() def linetrace_lout(): c1=cs.value() while c1<40: c1=cs.value() x=(abs(c1-10)/70)*100 if x>100: x=100 r=(x/100)*120-40 l=40-r ml.run_forever(speed_sp=l,stop_action='brake') mr.run_forever(speed_sp=r,stop_action='brake') stop() 赤ボールを缶5,6に乗せる際に、設定した時間で終了するライントレースを作成した。 def linetrace_ltime(j): c1=cs.value() t1=time.time() #プログラムがスタートした時刻を定義 t2=time.time() #プログラムの経過時間を定義 while t2-t1<j: #j秒経った時に止まる。 c1=cs.value() t2=time.time() x=abs((c1-10)/70)*100 if x>100: x=100 r=(x/100)*210-30 l=150-r ml.run_forever(speed_sp=l,stop_action='brake') mr.run_forever(speed_sp=r,stop_action='brake') stop() **ベルトコンベアのプログラム [#vf39220f] def roll(s): ma.run_to_rel_pos(position_sp=s,speed_sp=80,stop_action='hold') time.sleep(3) モーターを回すだけのシンプルなプログラムになっている。基本的に220度ずつ回している。 **ボール射出のプログラム [#x7b1a3d4] 課題2ではタイヤの回転角度で車体の角度を測っていたが、それだと車体のバッテリー残量で回転角度が変わっていたので、ジャイロセンサーを利用して改善した。 def discover_l(s,t): #左回りの場合 u1=us.value() #超音波センサーの値を先に定義する g1=gs.value() #プログラムスタート時の角度を定義 g2=gs.value() #プログラムの途中経過の角度をあらかじめ定義 while g1-g2<s: #g1-g2は回った角度を表していて、それがs度に達した時プログラムが終了する u2=us.value() #プログラムの進行中に逐次超音波センサーの値を保存する ml.run_forever(speed_sp=-70,stop_action='hold') mr.run_forever(speed_sp=70,stop_action='hold') #車体を左回転させる g2=gs.value() #ジャイロセンサーの値を逐次更新する if u2<u1: #超音波センサーを更新した時、その値が最小値だった場合はその値をu1に保存しておく u1=u2 g3=gs.value() #その時の角度もg3に保存しておく g4=gs.value() #缶発見後に右回転する時のスタート地点の角度を定義 g5=gs.value() #右回転している時の角度を定義 if u1<=t: #指定した範囲内に缶が存在していた場合 while g5-g4<g3-g2-6: #缶の位置に到達するまで右回りする mr.run_forever(speed_sp=-70,stop_action='hold') ml.run_forever(speed_sp=70,stop_action='hold') g5=gs.value() stop() u3=us.value() #超音波センサーの値をあらかじめ定義 t1=time.time() #この時の時間を保存 while u3<2550: #※1 ml.run_forever(speed_sp=100,stop_action='hold') mr.run_forever(speed_sp=100,stop_action='hold') #缶に近づくために進む u3=us.value() #超音波センサーの値を更新していく t2=time.time() #進んだ経過時間を測定する stop() roll(220) #ベルトコンベアを回してボールを射出する ml.run_timed(speed_sp=-100,time_sp=(t2-t1)*1000,stop_action='hold') mr.run_timed(speed_sp=-100,time_sp=(t2-t1)*1000,stop_action='hold') #缶に近づくために進んだ分だけ後退する time.sleep(t2-t1) #後退している間プログラムを一時停止する g6=gs.value() #初期位置に戻るためのスタートの時間を定義 g7=gs.value() #初期位置に戻る時の経過時間をあらかじめ定義 while g7-g6<=g1-g3-6: #初期位置に戻るまでループする mr.run_forever(speed_sp=-70,stop_action='hold') ml.run_forever(speed_sp=70,stop_action='hold') #右回転 g7=gs.value() stop() else: #測定した範囲内で缶が見つからなかった場合 while g5-g4<g1-g2: #測り始めた位置まで戻る mr.run_forever(speed_sp=-70,stop_action='hold') ml.run_forever(speed_sp=70,stop_action='hold') g5=gs.value() stop() def discover_r(s,t): #右回転の場合 左回転の時とさほど変わらないので省略 u1=us.value() g1=gs.value() g2=gs.value() while g2-g1<s: u2=us.value() ml.run_forever(speed_sp=70,stop_action='hold') mr.run_forever(speed_sp=-70,stop_action='hold') g2=gs.value() if u2<u1: u1=u2 g3=gs.value() g4=gs.value() g5=gs.value() if u1<=t: while g4-g5<g2-g3-6: mr.run_forever(speed_sp=70,stop_action='hold') ml.run_forever(speed_sp=-70,stop_action='hold') g5=gs.value() stop() u3=us.value() t1=time.time() while u3<2550: ml.run_forever(speed_sp=100,stop_action='hold') mr.run_forever(speed_sp=100,stop_action='hold') u3=us.value() t2=time.time() stop() roll(220) ml.run_timed(speed_sp=-100,time_sp=(t2-t1)*1000,stop_action='hold') mr.run_timed(speed_sp=-100,time_sp=(t2-t1)*1000,stop_action='hold') time.sleep(t2-t1) g6=gs.value() g7=gs.value() while g6-g7<=g3-g1-6: mr.run_forever(speed_sp=70,stop_action='hold') ml.run_forever(speed_sp=-70,stop_action='hold') g7=gs.value() stop() else: while g4-g5<90: mr.run_forever(speed_sp=70,stop_action='hold') ml.run_forever(speed_sp=-70,stop_action='hold') g5=gs.value() stop() ※1 超音波センサーの値が2550を示した時にwhile関数を抜ける。ここで言う2550というのは2550だけの距離があるということではなく、超音波センサーと缶の距離が限りなく近いことを表している。超音波センサーは2つのスピーカーから発せられた超音波の干渉縞を計測しているのではないかと思う。なので超音波センサーに缶を限りなく近づけた時、干渉縞が形成されずセンサーが自身の測れる距離の限界である2550ではないかと勘違いをする。それを利用して超音波センサーが缶に限りなく近づいた(センサーの値が2550)時、whileのループを抜けるようにした。 分かりづらいので画像を載せておく。 **プログラム全体 [#l6526719] #!/usr/bin/env python3 from ev3dev.ev3 import * import time ml=LargeMotor('outA') mr=LargeMotor('outD') ma=LargeMotor('outB') cs=ColorSensor('in3') us=UltrasonicSensor('in4') gs=GyroSensor('in1') def stop(): ml.stop() mr.stop() def linetrace_rin(): c1=cs.value() while c1>13: c1=cs.value() x=(abs(c1-10)/70)*100 if x>100: x=100 l=(x/100)*210-30 r=150-l ml.run_forever(speed_sp=l,stop_action='brake') mr.run_forever(speed_sp=r,stop_action='brake') stop() def linetrace_lin(): c1=cs.value() while c1>13: c1=cs.value() x=abs((c1-10)/70)*100 if x>100: x=100 r=(x/100)*210-30 l=150-r ml.run_forever(speed_sp=l,stop_action='brake') mr.run_forever(speed_sp=r,stop_action='brake') stop() def linetrace_rout(): c1=cs.value() while c1<40: c1=cs.value() x=(abs(c1-10)/70)*100 if x>100: x=100 l=(x/100)*120-40 r=40-l ml.run_forever(speed_sp=l,stop_action='brake') mr.run_forever(speed_sp=r,stop_action='brake') stop() def linetrace_lout(): c1=cs.value() while c1<40: c1=cs.value() x=(abs(c1-10)/70)*100 if x>100: x=100 r=(x/100)*120-40 l=40-r ml.run_forever(speed_sp=l,stop_action='brake') mr.run_forever(speed_sp=r,stop_action='brake') stop() def linetrace_ltime(j): c1=cs.value() t1=time.time() t2=time.time() while t2-t1<j: c1=cs.value() t2=time.time() x=abs((c1-10)/70)*100 if x>100: x=100 r=(x/100)*210-30 l=150-r ml.run_forever(speed_sp=l,stop_action='brake') mr.run_forever(speed_sp=r,stop_action='brake') stop() def runtime(l,r): ml.run_timed(time_sp=l*1000,speed_sp=70,stop_action='brake') mr.run_timed(time_sp=r*1000,speed_sp=70,stop_action='brake') time.sleep((l+r)/2) def angle(l,r,t): ml.run_to_rel_pos(position_sp=l,speed_sp=115,stop_action='hold') mr.run_to_rel_pos(position_sp=r,speed_sp=115,stop_action='hold') time.sleep(t) def kaiten_r(s,t): g1=gs.value() g2=gs.value() while g2-g1<s: ml.run_forever(speed_sp=t,stop_action='hold') mr.run_forever(speed_sp=-t,stop_action='hold') g2=gs.value() stop() def kaiten_l(s,t): g1=gs.value() g2=gs.value() while g1-g2<s: ml.run_forever(speed_sp=-t,stop_action='hold') mr.run_forever(speed_sp=t,stop_action='hold') g2=gs.value() stop() def roll(s): ma.run_to_rel_pos(position_sp=s,speed_sp=80,stop_action='hold') time.sleep(3) def discover_l(s,t): u1=us.value() g1=gs.value() g2=gs.value() while g1-g2<s: u2=us.value() ml.run_forever(speed_sp=-70,stop_action='hold') mr.run_forever(speed_sp=70,stop_action='hold') g2=gs.value() if u2<u1: u1=u2 g3=gs.value() g4=gs.value() g5=gs.value() if u1<=t: while g5-g4<g3-g2-6: mr.run_forever(speed_sp=-70,stop_action='hold') ml.run_forever(speed_sp=70,stop_action='hold') g5=gs.value() stop() u3=us.value() t1=time.time() while u3<2550: ml.run_forever(speed_sp=100,stop_action='hold') mr.run_forever(speed_sp=100,stop_action='hold') u3=us.value() t2=time.time() stop() roll(220) ml.run_timed(speed_sp=-100,time_sp=(t2-t1)*1000,stop_action='hold') mr.run_timed(speed_sp=-100,time_sp=(t2-t1)*1000,stop_action='hold') time.sleep(t2-t1) g6=gs.value() g7=gs.value() while g7-g6<=g1-g3-6: mr.run_forever(speed_sp=-70,stop_action='hold') ml.run_forever(speed_sp=70,stop_action='hold') g7=gs.value() stop() else: while g5-g4<90: mr.run_forever(speed_sp=-70,stop_action='hold') ml.run_forever(speed_sp=70,stop_action='hold') g5=gs.value() stop() def discover_r(s,t): u1=us.value() g1=gs.value() g2=gs.value() while g2-g1<s: u2=us.value() ml.run_forever(speed_sp=70,stop_action='hold') mr.run_forever(speed_sp=-70,stop_action='hold') g2=gs.value() if u2<u1: u1=u2 g3=gs.value() g4=gs.value() g5=gs.value() if u1<=t: while g4-g5<g2-g3-6: mr.run_forever(speed_sp=70,stop_action='hold') ml.run_forever(speed_sp=-70,stop_action='hold') g5=gs.value() stop() u3=us.value() t1=time.time() while u3<2550: ml.run_forever(speed_sp=100,stop_action='hold') mr.run_forever(speed_sp=100,stop_action='hold') u3=us.value() t2=time.time() stop() roll(220) ml.run_timed(speed_sp=-100,time_sp=(t2-t1)*1000,stop_action='hold') mr.run_timed(speed_sp=-100,time_sp=(t2-t1)*1000,stop_action='hold') time.sleep(t2-t1) g6=gs.value() g7=gs.value() while g6-g7<=g3-g1-6: mr.run_forever(speed_sp=70,stop_action='hold') ml.run_forever(speed_sp=-70,stop_action='hold') g7=gs.value() stop() else: while g4-g5<90: mr.run_forever(speed_sp=70,stop_action='hold') ml.run_forever(speed_sp=-70,stop_action='hold') g5=gs.value() def Redball(): #スタートから赤ボールを取りに行くプログラム angle(250,250,3) #赤ボールの位置まで進む kaiten_r(180,110) #ボールを掬う部分は車体の後ろにあるので180度回転する roll(220) #ボールを掬う kaiten_r(195,110) #車体の向きを戻す ライントレースの条件に引っかからないようにすこし余分に回っておく linetrace_lin() #ライントレースをする def Blueball(): 青ボールを取りに行くまでのプログラム angle(-20,160,2) #Gの交差点をまたぐために位置を調整する linetrace_lin() angle(-35,-35,1.5) #Hの交差点を認識したら車体を回転した際、ボールとぶつからないように少し下がる kaiten_r(175,110) #車体を180度回転させる roll(220) #ボールを掬う def move(): 青ボールを拾った後、Eの交差点に行くまでのプログラム kaiten_r(190,110) #車体の向きを元に戻す angle(-50,-50,1) #ライントレースが安定するように少し下がる linetrace_lin() linetrace_lout() linetrace_lin() linetrace_lout() linetrace_lin() def BlueZone(): #赤ボールを缶に乗せて分岐から帰ってきた後、青ボールを乗せに行くプログラム linetrace_rin() linetrace_rout() linetrace_rin() angle(70,0,1) #交差点を跨ぐ linetrace_rin() def discover2(): #青ボールを射出するプログラム kaiten_l(60,100) #角度を調整しておく discover_r(90,500) def start(): r=int(input("insert numbera")) #赤は番号の場合分けが容易だったため、赤のみダミーを避けるために分岐を設けた。その際に缶に番号を入力する。 Redball() Blueball() move() if r<=2: #缶1缶2に置く時 Eの位置で缶を探し始める kaiten_l(90,110) discover_l(90,250) kaiten_l(95,100) if r==3: #缶3に置く時 Dまで進んで缶3がある範囲のみ探す angle(-40,180,2) linetrace_lin() discover_r(60,250) angle(-150,-150,2) kaiten_l(195,110) linetrace_rin() angle(230,-40,2) if r==4: #缶4に置く時 Dまで進んで缶4がある範囲のみ探す angle(-40,180,2) linetrace_lin() discover_l(60,250) kaiten_l(195,110) linetrace_rin() angle(230,-40,2) if 5<=r: #缶5缶6に置く時 Uターンの手前まで進み、缶がある範囲を探す angle(-40,180,2) linetrace_lin() linetrace_lout() linetrace_ltime(3) discover_l(60,190) angle(-130,-130,3) kaiten_l(180,110) linetrace_rin() linetrace_rout() linetrace_rin() angle(230,-40,2) BlueZone() discover2() start() *ロボコンの結果と反省 [#da4ce272] ロボコンでは無事に優勝することができた。しかし、青ボールを缶に乗せることが出来なかった。本番で失敗したところの1つは赤いボールを掬う時である。これはジャイロセンサーの調子がEV3を起動した時に少しだけ変化するため、180度回転したつもりが、行き過ぎたり足りなかったりするのが原因だ。2つ目は赤ボールを乗せた後、交差点Iに侵入する時にライントレースがうまく作動しなかったことだ。これはロボットを作動した時の外部の環境によってカラーセンサーの値が少し変化したのではないかと思われる。 *振り返り [#cc8408b6] 課題3では課題1や課題2の反省点を生かしたロボットができたのではないかと思った。このゼミを受ける前はロボットを動かすために、いかに良いプログラムを作れるかが課題だと思っていたが、実際に取り組んでみるとロボット自体のハードの大切さに気づかされた。与えられた課題に適したロボットを作り、それに合ったプログラムを作ることが大事である。