俺より強い奴に会いに行く!? アケコンでIoT大作戦 その1

皆さんこんにちは。
UEQareer Advent Calendar 2016 21日目の記事です。
いよいよラスト5記事に突入しました。

さて、突然ですが、皆さんの手に最も馴染む「入力インタフェース」ってなんでしょうか?

テレビのリモコン?

マウスとキーボード?

おそらく最も多くの人の手に馴染むのはこの「アケコン」だと思います。

このアケコンをIoT化して、様々なことに応用することを目指します。

  • 波動拳を入力すると部屋の電気が点く
  • 昇竜拳を入力するとテレビのチャンネルが変わる
  • 玄関前にアケコンを設置して、難しいコンボを決めないと鍵が開かないようにする

などなど…。
日々の生活が楽しくなること間違い無しですね。

まずはRaspberry Piに繋いでみる

まず前提ですが、今回はIoTと親和性の高いRaspberry Piにアケコンを繋いでいます。
この記事で使用しているのはRaspberry Pi 3 (Raspbian Jessie)です。

[bash gutter=”false”] [5222599.744305] usb 1-1.3: new full-speed USB device number 5 using dwc_otg
[5222599.852287] usb 1-1.3: New USB device found, idVendor=0f0d, idProduct=0027
[5222599.852310] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[5222599.852323] usb 1-1.3: Product: FIGHTING STICK V3
[5222599.852335] usb 1-1.3: Manufacturer: HORI CO.,LTD.
[5222599.860523] input: HORI CO.,LTD. FIGHTING STICK V3 as /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3/1-1.3:1.0/0003:0F0D:0027.0001/input/input0
[5222599.860814] hid-generic 0003:0F0D:0027.0001: input,hidraw0: USB HID v1.11 Gamepad [HORI CO.,LTD. FIGHTING STICK V3] on usb-3f980000.usb-1.3/input0
[/bash]

とりあえず繋いでみて、dmesgを叩くとこんなメッセージが出ていました。
また、lsusbの結果はこんな感じ。

[shell gutter=”false”] Bus 001 Device 005: ID 0f0d:0027 Hori Co., Ltd
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
[/shell]

HORIのゲームパッドとしてきちんと認識されています。
意外とすんなり行きました。

アケコンをPythonで認識してみる

当然ですが、繋いだだけでは何も起こりません。
波動拳も昇竜拳も出ません。

どうやら、evdevいうPythonのライブラリでアケコンの入力を拾うことが出来るようなので、今回はこれを使うことにします。
pygamesというライブラリでもジョイスティック入力が取れるそうなのですが、GUIが必須のようだったので今回はevdevを使いました。(pygameのほうが日本語の情報は多く見つかったのですが…)

evdevはpipからインストールが可能です。

[shell gutter=”false”] $ sudo pip install evdev
[/shell]

無事にインストールが出来たら、Pythonからもジョイスティックが認識出来るかを確認します。

[python] #!/usr/bin/python
#coding: utf-8

import evdev

def main():
# 使えるデバイスを確認
devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()] for device in devices:
print(device.fn, device.name, device.phys)

if __name__ == ‘__main__’:
main()
[/python]

結果は、こんな感じ。

[shell gutter=”false”] $ python akekon.py
(‘/dev/input/event1’, ‘HORI CO.,LTD. REAL ARCADE Pro.V3’, ‘usb-3f980000.usb-1.2/input0’)
(‘/dev/input/event0’, ‘HORI CO.,LTD. FIGHTING STICK V3’, ‘usb-3f980000.usb-1.3/input0’)
[/shell]

無事に認識されています。(アケコンを2つ繋いで実行してみました。)

アケコンの入力を読んでみる

次は、アケコンの入力を検知してみます。

[python] #!/usr/bin/python
#coding: utf-8

import evdev

def main():
# デバイスのインスタンスを作成
device = evdev.InputDevice(‘/dev/input/event0’)
print(device)
# デバイスのイベントを読む
for event in device.read_loop():
print(event)

if __name__ == ‘__main__’:
main()
[/python] これを実行してみると、こんな感じに。

[shell gutter=”false”] $ python akekon.py
device /dev/input/event0, name "HORI CO.,LTD. FIGHTING STICK V3", phys "usb-3f980000.usb-1.3/input0"
event at 1482263365.665763, code 04, type 04, val 589825
event at 1482263365.665763, code 304, type 01, val 01
event at 1482263365.665763, code 00, type 00, val 00
event at 1482263365.753774, code 04, type 04, val 589825
event at 1482263365.753774, code 304, type 01, val 00
event at 1482263365.753774, code 00, type 00, val 00[/shell]

codeやtypeなどの意味はまだわかりませんが、
アケコンのボタンを押したり、スティックを動かしたりすると、そのイベントをきちんと検知出来ています。

また、このevdevライブラリには、デバイスの入力をモニタリングするコマンドラインツールが付属しています。
これを使って、波動拳の入力をモニタリングした結果は以下の通りです。

[shell gutter=”false”] $ python -m evdev.evtest
ID Device Name Phys
—————————————————————————————-
0 /dev/input/event0 HORI CO.,LTD. FIGHTING STICK V3 usb-3f980000.usb-1.3/input0
1 /dev/input/event1 HORI CO.,LTD. REAL ARCADE Pro.V3 usb-3f980000.usb-1.2/input0

Select devices [0-1]: 0
Listening for events (press ctrl-c to exit) …
time 1482263038.77 type 3 (EV_ABS), code 17 (ABS_HAT0Y), value 1    # 2を入力(スティック)
time 1482263038.77 ——— SYN_REPORT ——–
time 1482263039.86 type 3 (EV_ABS), code 16 (ABS_HAT0X), value 1 # 3を入力
time 1482263039.86 ——— SYN_REPORT ——–
time 1482263040.94 type 3 (EV_ABS), code 17 (ABS_HAT0Y), value 0 # 6を入力
time 1482263040.94 ——— SYN_REPORT ——–
time 1482263042.0 type 4 (EV_MSC), code 4 (MSC_SCAN), value 589825
time 1482263042.0 type 1 (EV_KEY), code 304 ([‘BTN_A’, ‘BTN_GAMEPAD’, ‘BTN_SOUTH’]), value 1 # 弱Pボタン押下
time 1482263042.0 ——— SYN_REPORT ——–
time 1482263042.18 type 4 (EV_MSC), code 4 (MSC_SCAN), value 589825
time 1482263042.18 type 1 (EV_KEY), code 304 ([‘BTN_A’, ‘BTN_GAMEPAD’, ‘BTN_SOUTH’]), value 0    # 弱Pボタン離す
time 1482263042.18 ——— SYN_REPORT ——–
[/shell]

おわりに

無事にRaspberry Piでアケコンの入力を取れたところで、今回はここまでです。
次回は、入力を解析して波動拳や昇竜拳を出すところまでやってみようと思います。

また、今回掲載したコードは、evdevのドキュメントのQuick Startをほぼそのままなぞったものです。
よかったら公式ドキュメントもご覧になってください。(英語ですが)