You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中读取并解析Logitech Extreme 3D Pro摇杆输入?

读取Logitech Extreme 3D Pro摇杆输入的解析问题

我正在开发一个Python程序读取Logitech Extreme 3D Pro摇杆输入,目前能获取原始数据,但无法正确解析X轴和Y轴数值。怀疑array[1]和array[2]对应X、Y轴,但读数和摇杆移动不匹配。

当前代码

import pywinusb.hid as hid
from time import sleep
from msvcrt import kbhit

def sample_handler(data):
    print("Raw data: {}".format(data))

# Known Logitech vendor_id
vendor_id = 0x046D  # Logitech

# Find Logitech HID devices
devices = hid.HidDeviceFilter(vendor_id=vendor_id).get_devices()

if not devices:
    print("No Logitech device found.")
    exit()

# Select the device
device = devices[0] if len(devices) == 1 else None
if not device:
    print("Multiple Logitech devices found. Please select one:")
    for i, dev in enumerate(devices):
        print(f"{i}: {dev.product_name} (Product ID: {dev.product_id:04X})")
    selection = int(input("\nEnter the number of the device to select (0-{}): ".format(len(devices) - 1)))
    device = devices[selection]
else:
    print(f"Automatically selected device: {device.product_name}")

# Open the device and set the data handler
try:
    device.open()
    device.set_raw_data_handler(sample_handler)
    print("Waiting for data... Press any key to stop.")
    while not kbhit() and device.is_plugged():
        sleep(0.5)
finally:
    device.close()

疑问

  1. 如何正确解析原始数据中的X轴和Y轴数值?
  2. 除inputs库外,还有哪些读取摇杆输入的Python方法?
  3. 如何通过HID描述符理解并自动解析摇杆控制值?

HID描述符

USB Input Device

Connection Status   Device connected
Current Configuration   1
Speed   Full
Device Address  3
Number Of Open Pipes    1
Device Descriptor Extreme 3D pro
Offset  Field   Size    Value   Description
0   bLength 1   12h 
1   bDescriptorType 1   01h Device
2   bcdUSB  2   0200h   USB Spec 2.0
4   bDeviceClass    1   00h Class info in Ifc Descriptors
5   bDeviceSubClass 1   00h 
6   bDeviceProtocol 1   00h 
7   bMaxPacketSize0 1   08h 8 bytes
8   idVendor    2   046Dh   Logitech, Inc.
10  idProduct   2   C215h   
12  bcdDevice   2   5711h   57.11
14  iManufacturer   1   01h "Logitech"
15  iProduct    1   02h "Extreme 3D pro"
16  iSerialNumber   1   03h "00000000002A"
17  bNumConfigurations  1   01h 
Configuration Descriptor 1 Bus Powered, 100 mA
Offset  Field   Size    Value   Description
0   bLength 1   09h 
1   bDescriptorType 1   02h Configuration
2   wTotalLength    2   0022h   
4   bNumInterfaces  1   01h 
5   bConfigurationValue 1   01h 
6   iConfiguration  1   04h "HID Config"
7   bmAttributes    1   80h Bus Powered
4..0: Reserved      ...00000    
5: Remote Wakeup        ..0.....    No
6: Self Powered     .0......    No, Bus Powered
7: Reserved (set to one)
(bus-powered for 1.0)       1.......    
8   bMaxPower   1   32h 100 mA
Interface Descriptor 0/0 HID, 1 Endpoint
Offset  Field   Size    Value   Description
0   bLength 1   09h 
1   bDescriptorType 1   04h Interface
2   bInterfaceNumber    1   00h 
3   bAlternateSetting   1   00h 
4   bNumEndpoints   1   01h 
5   bInterfaceClass 1   03h HID
6   bInterfaceSubClass  1   01h Boot Interface
7   bInterfaceProtocol  1   00h 
8   iInterface  1   00h 
HID Descriptor
Offset  Field   Size    Value   Description
0   bLength 1   09h 
1   bDescriptorType 1   21h HID
2   bcdHID  2   0111h   1.11
4   bCountryCode    1   00h 
5   bNumDescriptors 1   01h 
6   bDescriptorType 1   22h Report
7   wDescriptorLength   2   007Ah   122 bytes
Endpoint Descriptor 81 1 In, Interrupt, 1 ms
Offset  Field   Size    Value   Description
0   bLength 1   07h 
1   bDescriptorType 1   05h Endpoint
2   bEndpointAddress    1   81h 1 In
3   bmAttributes    1   03h Interrupt
1..0: Transfer Type     ......11    Interrupt
7..2: Reserved      000000..    
4   wMaxPacketSize  2   0007h   7 bytes
6   bInterval   1   01h 1 ms
Interface 0 HID Report Descriptor Joystick
Item Tag (Value)    Raw Data
Usage Page (Generic Desktop)    05 01 
Usage (Joystick)    09 04 
Collection (Application)    A1 01 
    Collection (Logical)    A1 02 
        Report Count (2)    95 02 
        Report Size (10)    75 0A 
        Logical Minimum (0) 15 00 
        Logical Maximum (1023)  26 FF 03 
        Physical Minimum (0)    35 00 
        Physical Maximum (1023) 46 FF 03 
        Usage (X)   09 30 
        Usage (Y)   09 31 
        Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 
        Report Size (4) 75 04 
        Report Count (1)    95 01 
        Logical Maximum (7) 25 07 
        Physical Maximum (315)  46 3B 01 
        Unit (Eng Rot: Degree)  66 14 00 
        Usage (Hat Switch)  09 39 
        Input (Data,Var,Abs,NWrp,Lin,Pref,Null,Bit) 81 42 
        Unit (None) 65 00 
        Report Size (8) 75 08 
        Logical Maximum (255)   26 FF 00 
        Physical Maximum (255)  46 FF 00 
        Usage (Rz)  09 35 
        Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 
        Push    A4 
        Report Count (8)    95 08 
        Report Size (1) 75 01 
        Logical Maximum (1) 25 01 
        Physical Maximum (1)    45 01 
        Usage Page (Button) 05 09 
        Usage Minimum (Button 1)    19 01 
        Usage Maximum (Button 8)    29 08 
        Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 
        Pop B4 
        Usage (Slider)  09 36 
        Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 
        Report Count (4)    95 04 
        Report Size (1) 75 01 
        Logical Maximum (1) 25 01 
        Physical Maximum (1)    45 01 
        Usage Page (Button) 05 09 
        Usage Minimum (Button 9)    19 09 
        Usage Maximum (Button 12)   29 0C 
        Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 
        Report Count (4)    95 04 
        Input (Cnst,Ary,Abs)    81 01 
    End Collection  C0 
    Collection (Logical)    A1 02 
        Report Count (4)    95 04 
        Report Size (8) 75 08 
        Logical Maximum (255)   26 FF 00 
        Physical Maximum (255)  46 FF 00 
        Usage Page (Vendor-Defined 1)   06 00 FF 
        Usage (Vendor-Defined 1)    09 01 
        Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit)  B1 02 
    End Collection  C0 
End Collection

解答

1. 正确解析X轴和Y轴数值

根据你提供的HID报告描述符,X、Y轴是10位的绝对数值(范围0-1023),这两个值被打包在原始数据的前3个字节中,需要按位合并计算:

def sample_handler(data):
    # 解析X轴:取data[1]全8位 + data[2]的低2位
    x_axis = ((data[2] & 0x03) << 8) | data[1]
    # 解析Y轴:取data[3]的低4位左移6位 + data[2]的高6位
    y_axis = ((data[3] & 0x0F) << 6) | ((data[2] >> 2) & 0x3F)
    print(f"Raw data: {data} | X: {x_axis}, Y: {y_axis}")

验证逻辑:X/Y轴各占10位,合计20位,后续紧跟4位的帽子开关数据,因此前3字节(24位)包含这三个输入项。

2. 其他读取摇杆输入的Python方法

  • pygame:游戏开发常用库,封装了摇杆输入逻辑,跨平台支持:
import pygame
pygame.init()
joystick = pygame.joystick.Joystick(0)
joystick.init()

while True:
    for event in pygame.event.get():
        if event.type == pygame.JOYAXISMOTION:
            x = joystick.get_axis(0)  # 范围-1.0到1.0
            y = joystick.get_axis(1)
            print(f"X: {x:.2f}, Y: {y:.2f}")
  • pysdl2:SDL2的Python绑定,底层支持多种输入设备,适合需要更灵活控制的场景。
  • directinput(Windows专属):通过pywin32调用Windows DirectInput API,直接与硬件交互,适合底层开发。

3. 利用HID描述符自动解析

HID报告描述符定义了设备输入数据的格式,可通过以下步骤自动解析:

  1. 提取报告描述符结构:使用pywinusb的内置方法获取输入报告的项信息:
from pywinusb import hid

# 获取设备的输入报告描述符
input_report = device.find_input_reports()[0]
# 遍历所有输入项
for item in input_report:
    if item.item_type == "input":
        print(f"Usage: {item.usage}, 位长: {item.report_size}, 数量: {item.report_count}")
  1. 计算位偏移:按顺序累加每个输入项的总位数(report_size * report_count),确定每个轴/按键在原始数据中的起始位和长度。
  2. 动态生成解析逻辑:根据位偏移信息,编写通用解析函数,自动提取对应位置的数值,无需硬编码字节位置。

内容的提问来源于stack exchange,提问作者sakthivel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:54:49