この記事では、Pythonを使ってPS4コントローラーをEV3に接続していろいろ取得します。
DUALSHOCK 4を前提にコードを書いていますが、別のコントローラーにも応用が利くと思います。
コード
PS4コントローラーを検出し、コントローラーの入力に基づいてEV3ロボットのモーターを制御します。
#!/usr/bin/env python3
import evdev
import ev3dev.auto as ev3
import threading
def scale_stick(value):
return (value / 255) * 2000 - 1000
def dc_clamp(value):
return max(min(1000, value), -1000)
# PS4コントローラーの検出
print("Finding PS4 controller...")
devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
ps4dev = devices[0].fn
gamepad = evdev.InputDevice(ps4dev)
# モータースレッドクラス
class MotorThread(threading.Thread):
def __init__(self):
self.left_motor = ev3.LargeMotor(ev3.OUTPUT_B)
self.right_motor = ev3.LargeMotor(ev3.OUTPUT_C)
threading.Thread.__init__(self)
def run(self):
while True:
self.left_motor.run_forever(speed_sp=dc_clamp(forward_speed - turn_speed))
self.right_motor.run_forever(speed_sp=dc_clamp(-forward_speed - turn_speed))
motor_thread = MotorThread()
motor_thread.setDaemon(True)
motor_thread.start()
# コントローラー入力の処理
forward_speed = 0
turn_speed = 0
for event in gamepad.read_loop():
if event.type == 3: # スティックの移動
if event.code == 1: # 左スティックのY軸
forward_speed = scale_stick(event.value)
if event.code == 3: # 右スティックのX軸
turn_speed = scale_stick(event.value)
解説
import evdev
evdev
はあまり聞き覚えがないですがコントローラーからの入力を処理するために使っています。
print("Finding PS4 controller...")
devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
ps4dev = devices[0].fn
gamepad = evdev.InputDevice(ps4dev)
接続されたデバイスからコントローラーを見つけています。
for event in gamepad.read_loop():
if event.type == 3: # スティックの移動
if event.code == 1: # 左スティックのY軸
forward_speed = scale_stick(event.value)
if event.code == 3: # 右スティックのX軸
turn_speed = scale_stick(event.value)
スティックの入力値は-1000から1000の範囲で提供されます。ちょうどモーターの速度も-1000から1000なのでちょうどいいですね。
event.type
とevent.code
それぞれイベントの値は以下のサイトを参考にするといいと思います。
https://github.com/codeadamca/ev3-python-ps4
ただサイトによって書いてある値がまちまちだったり、間違っていたりするので実際にコードを組んて動かしてみるのが安全です。
私の方で検証できたら、まとめます。
参考文献