【问题标题】:How to access the joysticks of a gamepad using python evdev?如何使用 python evdev 访问游戏手柄的操纵杆?
【发布时间】:2017-12-09 14:23:04
【问题描述】:

我是 evdev 的新手,目前正在尝试使用 xbox 控制器来控制小型机器人。我对每个按钮都很成功,但我似乎无法弄清楚如何从操纵杆获得有效读数。

此代码仅适用于按钮响应。

edit:每当按下 ABXY 按钮时,也会发生 EV_ABS 事件。我不确定如何区分这些值和操纵杆的实际值。 此外,来自操纵杆运动的事件代码不一致。这是我目前正在运行的代码:

from evdev import InputDevice, categorize, ecodes
dev = InputDevice('/dev/input/event1')

print(dev)

for event in dev.read_loop():
    if event.type == ecodes.EV_KEY:
        print("button is pressed")
    elif event.type == ecodes.EV_ABS:
        print(event)

感谢任何建议!谢谢!

【问题讨论】:

  • 您将获得EV_ABS 和/或EV_REL 操纵杆事件。确切的细节取决于游戏手柄,但我周围没有 xbox :-(
  • 非常感谢您的快速回复!我试过了,但是当按下和释放按钮时,也会发生具有 EV_ABS 值的事件。我不太清楚为什么。摇杆的事件代码也很不一致。
  • 啊,但那是因为在一些游戏手柄中,一些按钮被排列成十字形(我认为它被称为d-pad)。这些有时由驱动程序映射到 hat,在 Linux 中是一对EV_ABS 轴。那些ABS_HAT* 轴通常只有三个可能的值:-MAX、0 和 +MAX,分别代表一个按钮、无按钮和另一个按钮,就像那些旧的街机数字操纵杆一样。
  • 但请注意,我说的是一些游戏手柄有时...例如,我的中国廉价游戏手柄有一个模式按钮 i> 在模拟操纵杆加上一堆按钮和数字操纵杆加上一顶帽子和更少按钮之间进行选择......
  • 返回多个事件的按钮是 ABXY 按钮。如何区分这些事件和来自实际操纵杆的事件?

标签: python linux evdev


【解决方案1】:

Python 不是我最喜欢的语言,并且可能有更好的校准方法,但我把它放在一起。希望对您有所帮助。

所有映射和最大值都是通过我的 Xbox One 无线控制器测量的,因此您可能需要根据自己的控制器试验/调整常数。

from evdev import list_devices, InputDevice, categorize, ecodes

CENTER_TOLERANCE = 350
STICK_MAX = 65536

dev = InputDevice( list_devices()[0] )
axis = {
    ecodes.ABS_X: 'ls_x', # 0 - 65,536   the middle is 32768
    ecodes.ABS_Y: 'ls_y',
    ecodes.ABS_Z: 'rs_x',
    ecodes.ABS_RZ: 'rs_y',
    ecodes.ABS_BRAKE: 'lt', # 0 - 1023
    ecodes.ABS_GAS: 'rt',

    ecodes.ABS_HAT0X: 'dpad_x', # -1 - 1
    ecodes.ABS_HAT0Y: 'dpad_y'
}

center = {
    'ls_x': STICK_MAX/2,
    'ls_y': STICK_MAX/2,
    'rs_x': STICK_MAX/2,
    'rs_y': STICK_MAX/2
}

last = {
    'ls_x': STICK_MAX/2,
    'ls_y': STICK_MAX/2,
    'rs_x': STICK_MAX/2,
    'rs_y': STICK_MAX/2
}

for event in dev.read_loop():

    # calibrate zero on Y button
    if event.type == ecodes.EV_KEY:
        if categorize(event).keycode[0] == "BTN_WEST":
            center['ls_x'] = last['ls_x']
            center['ls_y'] = last['ls_y']
            center['rs_x'] = last['rs_x']
            center['rs_y'] = last['rs_y']
            print( 'calibrated' )

    #read stick axis movement
    elif event.type == ecodes.EV_ABS:
        if axis[ event.code ] in [ 'ls_x', 'ls_y', 'rs_x', 'rs_y' ]:
            last[ axis[ event.code ] ] = event.value

            value = event.value - center[ axis[ event.code ] ]

            if abs( value ) <= CENTER_TOLERANCE:
                value = 0

            if axis[ event.code ] == 'rs_x':
                if value < 0:
                    print('left')
                else:
                    print('right')
                print( value )

            elif axis[ event.code ] == 'ls_y':
                if value < 0:
                    print('foreward')
                else:
                    print('backward')
                print( value )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多