今回は各地点に置かれた紙コップを指定された場所へと運び、その紙コップを積み重ねるというロボットのプログラミング、機構の制作であった。また、今回はロボコンを行うため全員の前での発表であった。
・基本ルール
◦紙コップは上下どちらにおいてもかまわない
◦紙コップを重ねる場所は、必ずしも目的地点の輪の中でなくてもかまわない
◦最終的に紙コップが自力で立っていること、またロボットが紙コップに触れていないこと、ただしスタート時と上下逆になっていてもかまわない
◦競技時間はすべてのコップを重ね終わるまで、あるいは審判が続行不能と判断するまで。
◦審判の合図の後、5秒以内にロボットをスタートさせ、それ以降はロボットや紙コップに触ってはいけない
◦EV3のチームはA,B,Cにそれぞれマークした紙コップをそれぞれ3個置く
◦EV3のチームはA,B,C,Dのどこからスタートしてもよいが、別の地点にある合計9個の紙コップを運ぶこと
◦紙コップに色を塗ったり文字や絵をかいてもよいが、穴を開けたり故意に変形させてはいけない
◦光センサは2セット合わせて2つまで使って良い、その他のセンサや部品はキットに含まれているものだけを使用すること
・基本得点の計算方法
◦EV3は1段目のAのカップ2点、2段目のBのカップ4点、3段目のCのカップ6点、4段目のAのカップ8点、5段目のBのカップ10点、6段目のCのカップ12点、7段目のAのカップ14点、8段目のBのカップ16点、9段目のCのカップ18点、それ以外は0点
MediumMortorを用いて紙コップをつかむはさみの部分をギアを噛ませることにより作った。これで紙コップをつかみ、運搬をする。はさみを制作する際、ギアの部分の重みにより水平にはさみが開閉しにくかった。そこで、ev3本体の下でしっかりと固定するように部品をつなげた。
紙コップを認知するように前面に赤外線センサーを取り付けた。また、課題2のコースを用いるため、ライントレースを利用するために前回同様に地面から1cmほど浮かしたところにカラーセンサーを取り付けた。
前から見たロボットである。中央に取り付けた赤外線センサーで紙コップを検出し、写真右のコンベアーが回り、紙コップを持ち上げる仕様になっている。何度も実験を行い、赤外線センサーがうまく作動するように紙コップは黒く塗りつぶした。
下から見た写真である。土台を安定させようと重心を下に持ってくるように部品を取り付けた。
ただ、上に伸ばしすぎたため上部の安定性に欠けてしまった。紙コップをまっすぐに持ち上げようとしたために上に伸びすぎたと思う。また、紙コップをあげる際に支点が二個しかないために安定してコップを持ち上げることが難しかった。
ev3の班が全て参加したので一番最初にロボットを何台使うかということが問題となった。
出てきた意見としては、
1.二台を使って紙コップを運び、もう一台を使って積み上げる案
2.一台で紙コップを運び、もう一台で紙コップを積み上げる案 である
私たちは2の意見を採用することにした。1の案ではフィールド上に三台のロボットがあることになりロボット同士がぶつかってしまうことを考えたためである。
#!/usr/bin/python
2行目以降の内容を/usr/bin/pythonへの入力として取り扱う。
import ev3dev.ev3 as ev3 import time
ev3dev.ev3をev3として導入、またtimeという関数を導入する。
ml = ev3.LargeMotor('outB') mr = ev3.LargeMotor('outA') mm = ev3.MediumMotor('outC') cs = ev3.ColorSensor('in1') de = ev3.InfraredSensor('in2')
右モーターをmr、左モーターをml、はさみの開閉に用いるモーターをmm、カラーセンサーをcs、赤外線センサーをdeとした。
def catch(): while de.value() < 50: if de.value() < 10: ml.run_forever(duty_cycle_sp=0) mr.run_forever(duty_cycle_sp=0) mm.run_forever(duty_cycle_sp=50) time.sleep(4) mm.run_forever(duty_cycle_sp=0) ml.run_forever(duty_cycle_sp=-20) mr.run_forever(duty_cycle_sp=-20) time.sleep(1.5) ml.run_forever(duty_cycle_sp=0) mr.run_forever(duty_cycle_sp=0) ml.run_forever(duty_cycle_sp=-50) mr.run_forever(duty_cycle_sp=50) time.sleep(1.6) ml.run_forever(duty_cycle_sp=0) mr.run_forever(duty_cycle_sp=0) else: ml.run_forever(duty_cycle_sp=15) mr.run_forever(duty_cycle_sp=15)
赤外線センサーが紙コップを感知したら紙コップに近づいて紙コップをつかむ動きを上記のように定義した。
赤外線センサーと紙コップの距離が5cm以下になったとき、距離が1cm以下になるまではEV3は直進し、1cm以下になったときEV3は停止して紙コップをつかむようになっている。
def lineright(): t0 = time.time() while time.time() - t0 < 0.35: if cs.value () > 50 : mr.run_forever(duty_cycle_sp=60) ml.run_forever(duty_cycle_sp=-30) t0 = time.time() else: mr.run_forever(duty_cycle_sp=-30) ml.run_forever(duty_cycle_sp=60)
交差点で右折する場合のライントレースの動きを上記のように定義した
def lineleft(): t0 = time.time() while time.time() - t0 < 0.35: if cs.value () > 50 : mr.run_forever(duty_cycle_sp=-30) ml.run_forever(duty_cycle_sp=60) t0 = time.time() else: mr.run_forever(duty_cycle_sp=60) ml.run_forever(duty_cycle_sp=-30)
交差点で左折する場合のライントレースの動きを定義した。
def cross(t,dl,dr): mr.run_forever(duty_cycle_sp=dr) ml.run_forever(duty_cycle_sp=dl) time.sleep(t/1000) ml.stop() mr.stop()
上記の定義では、 cross(動作時間、左輪のパワー、右輪のパワー) とおいている。 動作時間は1/1000秒単位となっている。
ライントレースのプログラミングについては前回の課題2を利用している。 def toa():
lineright() cross(1000,-20,20) cross(1000,13,13) lineright() cross(1000,0,0) cross(1000,-18,18) cross(1000,0,0) catch() cross(1400,30,-30) lineright() cross(1000,0,0) cross(1000,-20,20) cross(1000,10,10) lineright() cross(1000,0,0) cross(1000,-25,25) mm.run_forever(duty_cycle_sp=-50) time.sleep(3) mm.run_forever(duty_cycle_sp=0) cross(1000,-30,-30) cross(2000,-40,40)
C地点からD地点へ向かい、紙コップをつかんでD地点に戻るプログラミングを上記のように「toa()」と定義した
def tob(): lineleft() cross(1000,-10,10) lineright() cross(1000,-20,20) cross(1000,13,13) lineright() cross(1000,-20,20) cross(1000,13,13) lineright() cross(1000,0,0) cross(1000,-17,17) cross(1000,0,0) catch() lineleft() cross(1000,20,-20) cross(1000,13,13) lineleft() cross(1000,20,-20) cross(1000,40,13) lineright() cross(1000,0,0) cross(1000,36,-36) lineright() cross(1000,0,0) cross(1000,-20,20) mm.run_forever(duty_cycle_sp=-50) time.sleep(3) mm.run_forever(duty_cycle_sp=0) cross(1000,-30,-30) cross(1000,-13,13)
CからBに向かい、紙コップをつかんでC地点に戻るプログラミングを上記のように「tob()」と定義した
def toc(): lineright() cross(1000,-17,17) cross(1000,30,-30) cross(1000,10,10) lineright() cross(1000,-20,20) cross(1000,13,13) lineright() cross(1000,-20,20) cross(1000,13,13) catch() lineright() cross(1000,0,0) cross(1000,17,-17) cross(1000,13,13) lineright() cross(1000,0,0) cross(1000,-22,22) cross(1000,0,0) lineright() cross(1000,0,0) cross(1000,-25,25) mm.run_forever(duty_cycle_sp=-50) time.sleep(3) mm.run_forever(duty_cycle_sp=0) cross(1000,-30,-30) cross(1500,-50,50)
CからAに向かい、紙コップをつかんでC地点に戻るプログラミングを上記のように「toc()」と定義した
ここからは上記の定義を用いて実際に動かしたプログラミングとなります。
mm.run_forever(duty_cycle_sp=-50) time.sleep(3.5) mm.run_forever(duty_cycle_sp=0)
コップを挟む部分を開く
toa() tob() toc() toa() tob() toc() toa() tob() toc()
上記にある定義の通り、A・B・D地点までライントレースをしながら進み、紙コップをC地点に集めてくる。
time.sleep(30) lineleft() cross(1000,20,-20) cross(1000,13,13) lineleft() cross(1000,20,-20) cross(1000,13,13) cross(1000,-30,-30) ml.run_forever(duty_cycle_sp=25) mr.run_forever(duty_cycle_sp=20) time.sleep(1) ml.run_forever(duty_cycle_sp=0) mr.run_forever(duty_cycle_sp=0)
#!/usr/bin/python
2行目以降の内容を/usr/bin/pythonへの入力として取り扱う。
import ev3dev.ev3 as ev3 import time
ev3dev.ev3をev3として導入、またtimeという関数を導入する。
m1 = ev3.LargeMotor('outA') m2 = ev3.MediumMotor('outB') m3 = ev3.MediumMotor('outC') m4 = ev3.LargeMotor('outD') us = ev3.UltrasonicSensor('in1')
置かれた紙コップを認識する。
def search(p): t0 = time.time() while time.time() - t0 < 0.001: if us.value() > p: m4.run_forever(duty_cycle_sp=50) t0 = time.time() else: m4.stop()
置かれた紙コップの元まで近寄る、元の位置に戻る
def bring(x,y): m4.run_forever(duty_cycle_sp=x) time.sleep(y) m4.stop()
コンベアーを張る
def close(): m1.run_forever(duty_cycle_sp=-37.5) time.sleep(0.32) m1.stop()
コンベアーを動かし紙コップを持ち上げる
def up(): m3.run_forever(duty_cycle_sp=-50) m2.run_forever(duty_cycle_sp=50) time.sleep(2.25) m2.stop() m3.stop()
同様に紙コップを降ろす
def down(): m3.run_forever(duty_cycle_sp=50) m2.run_forever(duty_cycle_sp=-50) time.sleep(1.5) m2.stop() m3.stop()
コンベアーの張りを弱くし紙コップを落とす
def open(a,b): m1.run_forever(duty_cycle_sp=a) time.sleep(b) m1.stop()
紙コップを探し、両側のコンベアーの間に紙コップが入るようにする。紙コップが入ったことを感知した、コンベアーをあげ、紙コップを積み上げる。
search(60) bring(45,0.2) close() up() search(60) open(20,0.275) bring(45,0.2) down() open(27.5,0.325) bring(-40,7.5)
正確に紙コップを運び、積み上げることが出来なかった。そのため、基本点0点であった。
私たちの班がうまく紙コップを運ぶことが出来なかったのはロボットに頼りすぎているからだと思った。どういうことかというと、たとえば、紙コップを運ぶロボットにつけた赤外線センサーは設定した範囲に紙コップがあればつかんでくれると思っていた。しかし、赤外線センサーが反応するのはちょうど正面に紙コップがあるときだけで少しでもずれているとセンサーが反応せずにロボットは走り続けてしまう。また、紙コップを積み上げるにしろ、二本のコンベアーの間に紙コップを入れ込まなければならず、成功したのは稀であった。毎回少しずつ、誤差が生まれうまくいかないことが多かった。私たちはプログラミングに頼りすぎていた部分があった。もっとおおざっぱにロボットが移動してもいいようにロボット本体の機構を作り上げる必要があったと思う。