【Raspberry Pi Mouse】Raspberry Pi Mouseをxboxコントローラで自由に動かしました。
はじめに
こんにちは、がんがんです。
以前Raspberry Pi Mouseのセットアップを行いました。
gangannikki.hatenadiary.jp
そして、xboxコントローラの実験も行いました。
gangannikki.hatenadiary.jp
今回はxboxコントローラでRaspberry Pi Mouseを動かすことが出来たのでまとめておきます。
目的
- Raspberry Pi Mouseをxoboxコントローラで操作
- mjpg-streamerでRaspberry Pi Mouseの映像を見る
操作方法
操作方法は以下の通りです。
コマンド | 動作 |
---|---|
LT | 前進 or 後進 |
LB | 前進と後進の切り替え |
RT | 右回転 or 左回転 |
RB | 左右回転の切り替え |
メニュー | プログラムの終了 |
A | LED0のON・OFF |
B | LED1のON・OFF |
X | LED2のON・OFF |
Y | LED3のON・OFF |
理想はアナログスティックによる操作ですが、とりあえずは動作すればよかったのでLT
とRT
で動作させます。
コード
import struct import subprocess import time device_path = "/dev/input/js0" rt_cmd = [] EVENT_FORMAT = "LhBB"; EVENT_SIZE = struct.calcsize(EVENT_FORMAT) speed = 500 def main(): straight = True curbe = False try: with open(device_path, "rb") as device: event = device.read(EVENT_SIZE) while event: (xbox_time, xbox_val, xbox_type, xbox_num) = struct.unpack(EVENT_FORMAT, event) if xbox_type == 1 and xbox_val == 1: # Aボタンの入力 if xbox_num == 0: subprocess.call(["echo 1 > /dev/rtled0"], shell=True) # Bボタンの入力 elif xbox_num == 1: subprocess.call(["echo 1 > /dev/rtled1"], shell=True) # Xボタンの入力 elif xbox_num == 2: subprocess.call(["echo 1 > /dev/rtled2"], shell=True) # Yボタンの入力 elif xbox_num == 3: subprocess.call(["echo 1 > /dev/rtled3"], shell=True) # ブザーON elif xbox_num == 4: straight = not straight curbe = False subprocess.call(["echo 440 > /dev/rtbuzzer0"], shell=True) elif xbox_num == 5: curbe = not curbe straight = True subprocess.call(["echo 523 > /dev/rtbuzzer0"], shell=True) # 終了フェーズ elif xbox_num == 7: break elif xbox_type == 1 and xbox_val == 0: # Aボタンの入力 if xbox_num == 0: subprocess.call(["echo 0 > /dev/rtled0"], shell=True) # Bボタンの入力 elif xbox_num == 1: subprocess.call(["echo 0 > /dev/rtled1"], shell=True) # Xボタンの入力 elif xbox_num == 2: subprocess.call(["echo 0 > /dev/rtled2"], shell=True) # Yボタンの入力 elif xbox_num == 3: subprocess.call(["echo 0 > /dev/rtled3"], shell=True) # ブザーOFF elif xbox_num == 4: subprocess.call(["echo 0 > /dev/rtbuzzer0"], shell=True) elif xbox_type == 2: subprocess.call(["echo 1 > /dev/rtmotoren0"], shell=True) num = round(xbox_val / 32767 * 255) if xbox_num == 1: pass # 前進(現状の最善) elif xbox_num == 2: if straight: subprocess.call(["echo {} > /dev/rtmotor_raw_r0".format(speed)], shell=True) subprocess.call(["echo {} > /dev/rtmotor_raw_l0".format(speed)], shell=True) # 後進 else: subprocess.call(["echo -{} > /dev/rtmotor_raw_r0".format(speed)], shell=True) subprocess.call(["echo -{} > /dev/rtmotor_raw_l0".format(speed)], shell=True) # 左正転 elif xbox_num == 5: if curbe: subprocess.call(["echo {} > /dev/rtmotor_raw_r0".format(speed)], shell=True) subprocess.call(["echo -{} > /dev/rtmotor_raw_l0".format(speed)], shell=True) # 右正転 else: subprocess.call(["echo -{} > /dev/rtmotor_raw_r0".format(speed)], shell=True) subprocess.call(["echo {} > /dev/rtmotor_raw_l0".format(speed)], shell=True) # 矢印キー入力 elif xbox_num == 6: # 矢印(左):左回転 if xbox_val < 0: subprocess.call(["echo {} > /dev/rtmotor_raw_r0".format(speed)], shell=True) subprocess.call(["echo -{} > /dev/rtmotor_raw_l0".format(speed)], shell=True) # 矢印(右):右回転 elif xbox_val > 0: subprocess.call(["echo -{} > /dev/rtmotor_raw_r0".format(speed)], shell=True) subprocess.call(["echo {} > /dev/rtmotor_raw_l0".format(speed)], shell=True) elif xbox_num == 7: # 矢印(上):前進 if xbox_val < 0: subprocess.call(["echo {} > /dev/rtmotor_raw_r0".format(speed)], shell=True) subprocess.call(["echo {} > /dev/rtmotor_raw_l0".format(speed)], shell=True) elif xbox_val > 0: # 矢印(下):後進 subprocess.call(["echo -{} > /dev/rtmotor_raw_r0".format(speed)], shell=True) subprocess.call(["echo -{} > /dev/rtmotor_raw_l0".format(speed)], shell=True) else: subprocess.call(["echo 0 > /dev/rtmotor_raw_r0"], shell=True) subprocess.call(["echo 0 > /dev/rtmotor_raw_l0"], shell=True) subprocess.call(["echo 0 > /dev/rtmotoren0"], shell=True) # print( "{0}, {1}, {2}, {3}".format(xbox_time, xbox_val, xbox_type, xbox_num) ) event = device.read(EVENT_SIZE) except IOError: print("再起動") subprocess.run(["sudo", "reboot"]) finally: pass if __name__ == "__main__": main()
mjpg-streamerも実行する場合
mjpg-streamerを実行する場合は前回の記事で作成したshellスクリプトを実行します。
$ sh Document/start_server.sh
きちんと実行させることが出来ると、mouse目線の映像を見ながら操作できて楽しいです。現在はローカルネットワークでしか動作しないので、今後グローバルネットワークからでも見られるようにしていきます。
お盆休みの成果!
— GANGAN(技術用) (@gangan_nikki) 2019年8月16日
これにEdge TPUぶっ指して遊んでいくぞ~☺️
ここからが本番感o(^o^)o pic.twitter.com/dgEdHcBj50
まとめ
今回は今までの総まとめとして、コントローラでRaspberry Pi Mouseを操作させました。
コントローラの入力コマンドの解析やラズパイによる制御など、いろいろと楽しいお盆の自由研究となりました。
今後はEdge TPUを搭載して物体検出をしたり、外部ネットワークからカメラ映像を視聴出来るように設定を行っていきます。