Speedlink Phantom Hawk摇杆Z轴旋转异常:HID描述符修复问询
问题描述
我购买了一台无法退换的二手Speedlink Phantom Hawk摇杆,厂商售后确认这是已知问题但无官方解决方案。该摇杆的**Z-Rotation轴(扭转轴)**存在偏移,读数居中于180,仅能使用实际量程的20-30%。尝试Windows原生驱动、Speedlink官方驱动及第三方替代驱动均无效。
经排查,通过Free Device Monitoring Studio读取的HID报告显示:
- 存在两个Z轴:第一个是具备全量程的真实扭转轴(数值范围35-230),第二个是推力滑块
- Rz轴为存在偏移的异常扭转轴,传感器本身无故障
现有驱动仅支持轴居中设置,询问是否可通过修改HID描述符或让Windows读取真实Z轴来修复问题?
HID数据包读取示例
Report ID:-1 X[0..255]/[0..255]: 128 Y[0..255]/[0..255]: 125 Z[0..255]/[0..255]: 146 <--- 真实扭转轴 Z[0..255]/[0..255]: 127 <---- 推力滑块 Rz[0..255]/[0..255]: 174 <---- 异常扭转轴 Hat Switch[0x0..0x7]/[0x0..0x13b]: 0xf BUTTON1 pressed: 0 BUTTON2 pressed: 0 BUTTON3 pressed: 0 BUTTON4 pressed: 0 BUTTON5 pressed: 0 BUTTON6 pressed: 0 BUTTON7 pressed: 0 BUTTON8 pressed: 0 BUTTON9 pressed: 0 BUTTON10 pressed: 0 BUTTON11 pressed: 0 BUTTON12 pressed: 0 Unknown: 0 Unknown: 0 Unknown: 0 Unknown: 0 Unknown: 0 Unknown: 0 Unknown: 1 Unknown: 0
HID描述符原始数据
05 01 09 04 A1 01 09 00 A1 02 09 30 15 00 25 FF 35 00 45 FF 65 00 55 00 75 08 95 01 81 02 09 31 81 02 09 32 81 02 09 32 81 02 09 35 81 02 09 39 25 07 46 3B 01 65 14 75 04 81 42 05 09 19 01 29 0C 25 01 45 01 65 00 75 01 95 0C 81 02 95 08 81 03 C1 00 06 00 FF 09 00 A1 02 09 02 25 FF 45 FF 75 08 95 07 91 02 C1 00 C1 00
解析后的HID描述符(中文翻译)
0x05, 0x01, // 使用页面(通用桌面控件) 0x09, 0x04, // 使用(摇杆) 0xA1, 0x01, // 集合(应用) 0x09, 0x00, // 使用(未定义) 0xA1, 0x02, // 集合(逻辑) 0x09, 0x30, // 使用(X轴) 0x15, 0x00, // 逻辑最小值(0) 0x25, 0xFF, // 逻辑最大值(255) 0x35, 0x00, // 物理最小值(0) 0x45, 0xFF, // 物理最大值(255) 0x65, 0x00, // 单位(无) 0x55, 0x00, // 单位指数(0) 0x75, 0x08, // 报告大小(8位) 0x95, 0x01, // 报告计数(1) 0x81, 0x02, // 输入(数据、变量、绝对、无环绕、线性、首选状态、无空位置) 0x09, 0x31, // 使用(Y轴) 0x81, 0x02, // 输入(数据、变量、绝对、无环绕、线性、首选状态、无空位置) 0x09, 0x32, // 使用(Z轴) 0x81, 0x02, // 输入(数据、变量、绝对、无环绕、线性、首选状态、无空位置) 0x09, 0x32, // 使用(Z轴) 0x81, 0x02, // 输入(数据、变量、绝对、无环绕、线性、首选状态、无空位置) 0x09, 0x35, // 使用(Rz轴) 0x81, 0x02, // 输入(数据、变量、绝对、无环绕、线性、首选状态、无空位置) 0x09, 0x39, // 使用(方向键) 0x25, 0x07, // 逻辑最大值(7) 0x46, 0x3B, 0x01, // 物理最大值(315) 0x65, 0x14, // 单位(系统:英制旋转,长度:厘米) 0x75, 0x04, // 报告大小(4位) 0x81, 0x42, // 输入(数据、变量、绝对、无环绕、线性、首选状态、空状态) 0x05, 0x09, // 使用页面(按钮) 0x19, 0x01, // 使用最小值(0x01) 0x29, 0x0C, // 使用最大值(0x0C) 0x25, 0x01, // 逻辑最大值(1) 0x45, 0x01, // 物理最大值(1) 0x65, 0x00, // 单位(无) 0x75, 0x01, // 报告大小(1位) 0x95, 0x0C, // 报告计数(12) 0x81, 0x02, // 输入(数据、变量、绝对、无环绕、线性、首选状态、无空位置) 0x95, 0x08, // 报告计数(8) 0x81, 0x03, // 输入(常量、变量、绝对、无环绕、线性、首选状态、无空位置) 0xC1, 0x00, // 结束集合 0x06, 0x00, 0xFF, // 使用页面(厂商自定义0xFF00) 0x09, 0x00, // 使用(0x00) 0xA1, 0x02, // 集合(逻辑) 0x09, 0x02, // 使用(0x02) 0x25, 0xFF, // 逻辑最大值(255) 0x45, 0xFF, // 物理最大值(255) 0x75, 0x08, // 报告大小(8位) 0x95, 0x07, // 报告计数(7) 0x91, 0x02, // 输出(数据、变量、绝对、无环绕、线性、首选状态、无空位置、非易失) 0xC1, 0x00, // 结束集合 0xC1, 0x00 // 结束集合
解决方案
一、修改HID描述符逻辑(硬件层面不可行,仅作原理说明)
从解析后的描述符能看到,硬件确实上报了两个Z轴,系统默认将Rz映射为扭转轴。要让Windows读取真实Z轴,需调整描述符的轴Usage定义:
- 将第一个
0x09, 0x32(对应真实扭转轴)替换为0x09, 0x35(Rz轴标准Usage) - 将原Rz轴的
0x09, 0x35替换为0x09, 0x34(Slider轴,匹配推力滑块功能)
但注意:硬件固件中的HID描述符无法直接修改,此方案仅为逻辑参考,实际操作需通过系统层拦截实现。
二、用户态拦截工具(推荐,无需驱动开发)
利用第三方工具在用户态拦截HID报告,重新映射轴关系:
- VJoy + HIDGuardian + Joystick Mapper:先用HIDGuardian隐藏原始摇杆设备,再用VJoy创建虚拟摇杆,最后通过Joystick Mapper将原始摇杆的真实Z轴(第一个Z)映射到虚拟摇杆的Rz轴,同时忽略异常Rz轴。
- AutoHotkey脚本:编写AHK脚本读取原始摇杆的HID报告,提取真实Z轴数据后转发给虚拟摇杆,需熟悉AHK的HID操作API。
三、自定义过滤驱动(进阶方案)
若具备驱动开发能力,可编写HID过滤驱动:
- 拦截设备的HID描述符请求,返回修改后的描述符
- 拦截输入报告,将真实Z轴的数据替换到Rz轴位置,直接修正轴映射
内容的提问来源于stack exchange,提问作者Kortonox
相关产品推荐
相关产品推荐

