今回は各地点に置かれた紙コップを重ね、指定された場所に置くロボットのプログラミングと作成であった。
また、今回はロボコンを行うため全員の前で初めて発表する事となった。
課題3では、EV3班はA,B,Cの三カ所に3個ずつ紙コップを置き、その紙コップを交差点Qのある○の中に運ぶというものであった。
大まかなルールについて
・重ねずに運んだだけでも点数は入る
・各地点にある紙コップを交互に重ねると重ねるごとに点数が上がる
・コップは決してたっている必要はない
・スタート地点はどこからでも良い
ということであった
その他の細かいルールについては
http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMission3
にまとまっているのでこちらを見ていただきたい。
・紙コップを運ぶロボット
全体像
つかむ機構
ミディアムモーターを用いてギアをかませてモーター1つで稼働させた。 この部分に赤外線センサー、カラーセンサーもついている。
背部
ミディアムモーターはかなり後ろの方についてしまっている。 ロボットを改良してもっと前の方につければつかむ機構の稼働がさらに安定したと考えられる。
・紙コップを積むロボット
詳しい説明は下部URL先を参照していただきたい。2つのキャタピラーで紙コップを挟み込み、積むような機構にした。
http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMember%2FKAIYMB%2FMission3
全体像
はじめの大きな問題として、ロボットを何台使うかということが問題となった。
私が最初に出した案としては1台でコップを運び、重ねるという作業をやらせるという案ものであったのだが、私たちの班で前項からも分かるとおり 運ぶロボットと重ねるロボットを分ける2台体制でクリアを目指すことにした。
・紙コップを運ぶロボット
#!/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')
プログラミングで動かすパーツについて上記のように略称を定義した。
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)
C地点に集めた紙コップをつかみ、ライントレースをして紙コップをQ地点の円の中まで運ぶ。
・紙コップを重ねるロボットについて
私は紙コップを運ぶロボットのプログラミングしか書いていないので、紙コップを重ねるプログラミングの詳細については下記URL先を参照していただきたい。
http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMember%2FKAIYMB%2FMission3
私たちの班は結局本番では紙コップを1つも運ぶことはできなかった。 原因として最も大きなものは、紙コップを運ぶロボットにつけた赤外線センサーの感知できる範囲を甘く見ていたことだ。 赤外線センサーでは本当に紙コップが正面にあるときにしか反応しないので、例えば前のアームのところに2本動かないアームのようなものをつけて 紙コップを赤外線センサーの正面に無理矢理固定できるようにすれば運べる確率は格段に上がったと容易に想像できる。 実際にうまくいったときは(少なくとも2個は)うまく運べていたので詰めが甘かったというのが正直なところだ。 課題に取り組んでいた終盤はロボットのことはあまり気にせずプログラミングのことばかり考えてしまっていたのでそこも多きな原因だと思う。
最後の課題なだけあってプログラミングなどは割とスムーズに進んだが、本体の改良と運ぶためのアイデアが私たちには足りなかった。 最後の課題なので完成させたかったが、残念であった。 課題に取り組んでいるときは辛いこともあったが、今思えばとって良かったと思える授業であった。