【Raspberry Pi Mouse】Raspberry Pi Mouseをxboxコントローラで自由に動かしました。

はじめに

こんにちは、がんがんです。
以前Raspberry Pi Mouseのセットアップを行いました。
gangannikki.hatenadiary.jp

そして、xboxコントローラの実験も行いました。
gangannikki.hatenadiary.jp


今回はxboxコントローラで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

理想はアナログスティックによる操作ですが、とりあえずは動作すればよかったのでLTRTで動作させます。

コード

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目線の映像を見ながら操作できて楽しいです。現在はローカルネットワークでしか動作しないので、今後グローバルネットワークからでも見られるようにしていきます。


まとめ

今回は今までの総まとめとして、コントローラでRaspberry Pi Mouseを操作させました。
コントローラの入力コマンドの解析やラズパイによる制御など、いろいろと楽しいお盆の自由研究となりました。

今後はEdge TPUを搭載して物体検出をしたり、外部ネットワークからカメラ映像を視聴出来るように設定を行っていきます。