はじめに
コナステ版DDRやstepmaniaを頑張っている人には認知されているであろう L-Tek dance padについての記事です。
入力を読み取ってコントローラー化したい人向けの内容です。 (そんなやついるのか...?
コントローラーの入力について
pythonを使い、調べている限りだと3つの値を保有しているリストとしてコントローラーの入力が管理されている。
コントローラーの入力は、パネルを押した時と離した時に発生しており、下のような入力が発生している。
入力例:[1,2,0]
押しているペダルの管理だが、入力例のリストの真ん中の値(入力例では2)で押しているペダルを管理している。
各ペダルには数字が割り振られており、押しているペダルに紐づけられた数字の合計により押しているペダルを管理することができる。
パネルごとの数字について
左パネル:1 、右パネル:2、上パネル:4、下パネル:8
パネルと値の変動についてのイメージ
・左パネルのみを押した場合(左:1)
[1,0,0]→[1,1,0]
・左パネルを押しつつ、次に右パネルを押した場合(左:1、右:2)
[1,0,0]→[1,1,0]→[1,3,0]
左と右を踏んでいるため最終的には合計した3の値になる
・左右のパネルを踏んだ状態から、右パネル→左パネルの順に足を離した場合
[1,3,1]→[1,1,0]→[1,0,0]
・全パネルを踏んだ場合について
[1,15,0]
※1+2+4+8=15
同時に踏んだ場合について
4枚同時に踏んだら、[1,0,0]→[1,15,0]となるように思えるが、完璧に同時に踏むことは不可能であり、実際には4枚のパネルを順番に踏んでいると認識されるため、[1,0,0]→[1,2,0]→[1,3,0]→[1,11,0]→[1,15,0]というような値の変化になる。
読み取る値の更新時間のようなものを設定したら[1,0,0]→[1,15,0]のような遷移もいけるかもしれません。
ソースコードを書く前に必要なこと
今回はpythonのHIDをpipでインストールしてプログラムを作成しています。
HIDでは入力を読み取るためにデバイスのID的なやつを読み取る必要があります。
windows10だと、デバイスマネージャー→ヒューマンインターフェースデバイス→HID標準ゲームコントローラー→右クリックしてプロパティを表示→詳細→ハードウェアID という流れで調べることができます。
ハードウェアIDの一番上に表示される値を利用します。
ハードウェアIDの利用方法についてですが、筆者が実際に表示された値を使い解説します。
実際に表示された値:HID\VID_03EB&PID_8041&REV_0100&Col01
この値の 03EB(ベンダーID)と8041(プロダクトID)を利用します。
作成したプログラム
押したパネルや離したパネルに対応した数字の差分を利用して押したパネルや話したパネルを特定しています。
パネルに割り当てられている数字は2進数の値で管理されているため同時に踏まれているパネルの状態などを特定することもできます。
同時踏まれているパネルの計算例
・合計3→左と右のパネルが踏まれている
・合計11→左、右、下のパネルが踏まれている
import hid
import keyboard
# デバイスのリストを取得
for device in hid.enumerate():
print(device)
# ダンスパッドのベンダーIDとプロダクトIDを確認
vendor_id = 0x03EB # ダンスパッドのベンダーIDに変更
product_id = 0x8041 # ダンスパッドのプロダクトIDに変更
# デバイスをオープン
gamepad = hid.device()
gamepad.open(vendor_id, product_id)
# 非ブロッキングモードに設定
gamepad.set_nonblocking(True)
Last_Input=[1, 0 ,0]
# 入力を読み取る
while True:
#read(デバイスから読み取りたいデータの個数を入れる)
#l-tek padの場合は3つの値をまとめたリストで最大なので3以上の数を設定する
New_Input = gamepad.read(10)
#入力などを感知したら
if New_Input:
print(f'Report: {New_Input}')
#押された場合について
if New_Input[1]>Last_Input[1]:
#押されたパネルの特定
if New_Input[1]-Last_Input[1]==1:
#keyboard.press_and_release('a')
print("左押した")
elif New_Input[1]-Last_Input[1]==2:
#keyboard.press_and_release('b')
print("右押した")
elif New_Input[1]-Last_Input[1]==4:
#keyboard.press_and_release("c")
print("上押した")
elif New_Input[1]-Last_Input[1]==8:
#keyboard.press_and_release('d')
print("下押した")
#離した場合について
if Last_Input[1]>New_Input[1]:
#離したパネルの特定
if Last_Input[1]-New_Input[1]==1:
print("左離した")
elif Last_Input[1]-New_Input[1]==2:
print("右離した")
elif Last_Input[1]-New_Input[1]==4:
print("上離した")
elif Last_Input[1]-New_Input[1]==8:
print("下離した")
Last_Input=New_Input