- 追加された行はこの色です。
- 削除された行はこの色です。
目次
#contents
*はじめに [#neee5304]
今回はまったく余裕がなく、新しいことに多数挑戦したため自分だけの試走はともかく相方の機体との通信を伴う試走に入れたのは当日になってからだった。~
今回はev3dev(2016-10-17版)にMQTTをインストールした。前回と同様にSSH接続でプログラミングをし、下書き用にPyCharmを利用した。&size(7){今回の課題においてはWifiの安定性が非常に重要であった、ラグによって結果が変わってしまうため、別の工夫を行えばよかったと後悔している};
*課題3について [#f778acdb]
今回の課題は野球である。具体的に何を行うかといえばピッチャー、バッターに分かれて移動し、通信を行って野球盤のようなものを行う。&size(7){テスト後にこれを2人で二台は時間が圧倒的に足りない・・・};~
自分はピッチャーを作成し、プログラムを行った。
**動きについて [#u7f552fa]
今回の機体のコンセプトはロマンである。時間はなかったが使ってみたかった履帯を使ってみたかったためやってみた。履帯の弱点は精密な角度制御が難しい点であった。逆に利点は、重く重心が高い機体が安定することである。
#ref(2016b/Member/being/Mission3/第一段階.jpg,50%,第一段階)
前回ジャイロセンサーを使えるようになたため今回はジャイロセンサーで旋回角度を制御した。一番最初に期待を45度回転させる。~
次に機体後部に取り付けたカラーセンサーで黒い線の数を数える。
#ref(2016b/Member/being/Mission3/第2段階.jpg,100%,第2段階)
4本目の線を検知したら機体を止める。この時、高速で移動しているためモーターを止めた後も機体が重くとゴムがなく滑りやすい履帯のせいで暫くは滑ってしまう。これを修正するために一回低速で機体を下げ基準を合わせ、一定角度進みそこから90度旋回した後にもう一度機体を下げ、また光センサーで黒線を検知し一定角度進むことで位置を合わせる。こうすることで位置をある合わせることができる。
*機体について [#v9b964a0]
#ref(2016b/Member/being/Mission3/機体概観1.jpg,100%,機体概観1)
サイズ制限に収めるために機体は縦に長く、重心が高くなっている。今回はペアがびっくりドッキリメカを作ったため4つモーターを使っている。
#ref(2016b/Member/being/Mission3/P_20170207_170041.jpg,50%,機体後部)
機体の後部にカラーセンサーを搭載している。
#ref(2016b/Member/being/Mission3/P_20170207_170249.jpg,50%,玉設置部)
ここに玉を落とし込むと、指してあるピンによって適当な位置に玉が固定される。
#ref(2005/D7/課題1/hogehoge.jpg,50%,機体概観4)
ref(2005/D7/課題1/hogehoge.jpg,50%,機体概観4)
再装填を行う時以外は再装填アームが玉を押し上げることによって予期せぬタイミングに玉が出てしまうことを防ぐ。また、揺れ動くパーツにより再装填時に玉がはねて装填に失敗することがないようにしている。
*プログラムについて [#o32c6568]
以下のプログラムは''CC BY-SA 4.0''とします。ライセンスは[[こちら:https://creativecommons.org/licenses/by-sa/4.0/legalcode]]&size(7){htmlタグが使えないためこのように表記しておきます};
**自作関数について [#g43092a9]
*move.py [#pf33231b]
#!/usr/bin/env python3 #このプログラムはpython3で記述されている
import ev3dev.ev3 as ev3
import time
mr = ev3.LargeMotor('outB') #ここから↓
ml = ev3.LargeMotor('outC')
cs = ev3.ColorSensor('in1')
gy = ev3.GyroSensor('in2') #ここまで↑テンプレ
limen = 20 #ライトセンサーの閾値、やはり優秀で、しっかりと黒に塗られていれば一桁の値を返す。しかし、今回の会場の環境がどうなっているのかわからないので安全を見る(苦い思い出)
def move_to_Q(): #スタート地点からピッチャーマウントであるQへの移動
cs_count= 0 #カラーセンサー(反射率モード)が黒を検知した回数を格納する
gy_old = gy.value() #ジャイロセンサーのスタート時の値を格納
while abs(gy.value() - gy_old) < 45: #45度右旋回し、直線でマウントに移動する
mr.run_forever(speed_sp=200)
ml.run_forever(speed_sp=-200)
mr.stop()
ml.stop()
while cs_count < 4: #4回目の黒線でループを抜ける
print(cs.value()) #デバッグのためにPCに現在のカラーセンサーの値を表示
mr.run_forever(speed_sp=500) #大体50%の出力で前進、全開でも特に問題はない
ml.run_forever(speed_sp=500)
if cs.value() < limen: #カラーセンサーが黒線を検知したらカウンターに1を足す
cs_count = cs_count + 1
while cs.value() < limen: #カラーセンサーが黒線を抜けるまではここでとめておく、そうしないと一本の黒線でカウンタが埋まってしまう。
print(cs_count) #デバッグのためにPCに現在のカウンタの値を表示
mr.stop()
ml.stop() #出力停止
time.sleep(1) #機体が縦に大きく、重心が高いため動揺を抑える
mr.reset()
ml.reset()
#ここである程度機体を位置を修正する(画像、解説hoge)
while cs.value() > limen:
mr.run_forever(speed_sp=-200)
ml.run_forever(speed_sp=-200)
mr.stop()
ml.stop()
mr.run_to_rel_pos(position_sp=180,speed_sp=200, stop_action='hold')
ml.run_to_rel_pos(position_sp=180,speed_sp=200, stop_action='hold')
time.sleep(1)
while abs(gy.value() - gy_old) < 135:
mr.run_forever(speed_sp=200)
ml.run_forever(speed_sp=-200)
mr.stop()
ml.stop()
mr.reset()
ml.reset()
time.sleep(1)
while cs.value() > limen:
mr.run_forever(speed_sp=-200)
ml.run_forever(speed_sp=-200)
mr.run_to_rel_pos(position_sp=120, speed_sp=200, stop_action='hold')
ml.run_to_rel_pos(position_sp=120, speed_sp=200, stop_action='hold')
*test2.py [#f95ab6b9]
#!/usr/bin/env python #このプログラムはpython3で記述されている、そして最大の敵はこの文であった(後述)
import paho.mqtt.client as mqtt #paho(python用のMQTT)をインポート
from time import sleep
import ev3dev.ev3 as ev3
import time
import move as move
host = 'localhost' #こちらはpublisher兼brokerなのでローカルホストになる
port = 1883 #ポートはデフォルト
topic = 'pi/st' #トピックはpitcher/statusを略してpi/st
arm = ev3.LargeMotor('outA') #アームはアーム、ボールを打ち出すやつ(ピッチャーなのに打つとはこれは如何に)
bolthandle = ev3.MediumMotor('outD') #再装填用のアーム、役割と動きからボルトアクションを連想したためボルトハンドルとした
def reset_arm(t): #アームの位置をリセットするための関数(ミスに気がついた)
arm.run_forever(speed_sp=60)
time.sleep(t) #アームを機体側に寄せる、引数を用いて再装填時の動作と発射直後にアームを戻す動作両方に対応している
arm.stop()
arm.run_forever(speed_sp=-5) #ホームページ作成時に発見、本番に見せていたなぞの動き(なぜか一回玉を押し出しかける)の原因
time.sleep(0.5) #まず、パワーの符号を間違えていたため動作が逆になり、さらにモーターを止め忘れたため玉を押し出しかけていた
def Feuer(): #ドイツ語で発射(fire)の意味、最初作っていた時に、個々の動作を作りそれを組み合わせて一つの動作を作っていたため、個々の動作側は関数名被りを防ぐためにドイツ語を採用。
arm.run_forever(speed_sp=-600) #最初は全力の1050で動かしていた、実際に配置してみてこの程度のパワーがちょうどよいということがわかった
time.sleep(0.8)
arm.stop()
def nachladen(): #上に同じく、ドイツ語で再装填(reload)の意味
bolthandle.run_forever(speed_sp=60) #単純に一往復するだけ
time.sleep(2)
bolthandle.stop()
bolthandle.run_forever(speed_sp=-80)
time.sleep(2)
bolthandle.stop()
def throw(): #玉を投げ(撃ち)、再装填するためのひとつの動作の関数
reset_arm(2) #アームの位置を下げ
send_message(5) #投げるよーバッターにと伝え(5の数字に意味はない)
Feuer() #発射し
reset_arm(4) #アームの位置を直し
nachladen() #再装填する
def on_connect(client, userdata, flags, respons_code): #接続された時に実行される関数
print('status {0}'.format(respons_code)) #別述するが、、MQTTは接続時に状態を表すコードを返す、0が正常
client.subscribe(topic) #トピックの購読を開始
def send_message(m): #MQTTのメッセージを送信する
client.publish(topic, m) #トピックにメッセージを送信する
sleep(0.2)
client = mqtt.Client(protocol=mqtt.MQTTv311) #MQTTプロトコルのクライアントを作成
client.connect(host, port=port, keepalive=60) #brokerに接続
client.on_connect = on_connect #接続時の処理を実行
move. move_to_Q() #move.pyからmove_to_Qを実行する
for i in range(100): #100回玉を投げる(千本ノックならぬ百本ノック)
throw()
time.sleep(1.5)
client.disconnect() #接続を切る
*pub.py[#bd731158]
#テスト用のpublidherプログラム
#!/usr/bin/env python
from time import sleep
import paho.mqtt.client as mqtt
host = 'localhost'
port = 1883
topic = 'pi/st'
client = mqtt.Client(protocol=mqtt.MQTTv311)
client.connect(host, port=port, keepalive=60)
for i in range(3):
client.publish(topic, 5)
sleep(0.2)
client.disconnect()
*編集、書くことメモ [#of8b3127]
機体関係
#機体関係
モーター3つ案
MQTT関連
OSバージョン
画像作成
作り方
再装填機構
ピン
?作り方
#再装填機構
#ピン
引用
光にこでの直線だし
時刻規制