鼠标转向标定(MouseRotationCalibration)调查汇总
日期:2026-08-08 涉及任务:
src/tasks/test/MouseRotationCalibration.py结论状态:核心结论已定,待平地复测确认地形假设
一、任务简介
MouseRotationCalibration 是 debug 可见的测试任务,用于标定「鼠标横向位移像素 ↔ 角色视角转动角度」的换算系数:
$$k = \frac{\Delta yaw}{dx} = \frac{after - before}{dx}$$
- 鼠标右移
dx>0→ 视角左转Δyaw<0,故 k 恒为负。 - 系数为「°/px」,标定后可用于把目标转向角度换算为鼠标位移:
dx = round(target_yaw / k)。 - 不持久化,每次运行标定;也支持手动填系数跳过标定直接验证。
配置键(13 个)
| 配置键 | 当前值 | 说明 |
|---|---|---|
标定位移dx |
400 | 单位移标定时用 |
标定位移列表(逗号分隔) |
400,600,1000 |
多位移标定计划 |
重复次数 |
4 | 每位移采样次数 |
W长按时间(秒) |
0.2 | 按 W 刷新朝向的保持时长 |
角度刷新等待(秒) |
1.0 | 按 W 后等箭头刷新 |
转向后等待(秒) |
0.3 | 发鼠标位移后等转向稳定 |
最低置信度 |
0.6 | 箭头 OCR 置信度门槛 |
验证目标角度(度) |
90.0 | 单角度验证用 |
验证角度列表(逗号分隔) |
44,55,77,99 |
多角度验证计划 |
验证次数 |
2 | 每角度验证次数 |
验证误差容差(度) |
5.0 | PASS 容差 |
左右方向成对验证 |
true | 每个角度自动补反方向 |
手动yaw_per_pixel(留空用标定) |
-0.083 |
手动系数(正数自动取负修正) |
二、功能演进史
- 只标定(13:15 起)→ 无 W 长按,读数全 0,无效。
- 加 W 长按刷新朝向(13:26)→ 标定数据首次有效。
- 加单角度验证(16:43)→ +90° 验证闭环。
- 加多角度验证(16:49)→ 4 个角度列表。
- 加多位移标定(16:55)→ 200/400/600/1000 计划。
- 加转向后等待(17:01)→ 解耦转向完成与 W 刷新朝向,用于排除时序假设。
- 加左右成对验证(17:09)→ 每角度自动补反方向,用于排查左右不对称。
- 加手动系数自动取负(17:31 前)→ 防止符号填错。
三、全部运行轮次数据
3.1 调试期(13:15-13:26)——无有效数据
| 时间 | 配置 | 现象 |
|---|---|---|
| 13:15 | dx=100, refresh=0.1 | 角度几乎不动(Δ≈0)→ W 未长按,朝向不刷新 |
| 13:16 | dx=400, refresh=1.0 | 前 2 样本 Δ=0,后 2 样本 Δ=7~9° → 刷新不稳 |
| 13:17 | dx=400 | 全部 Δ=0,完全没反应 |
| 13:26 | w_hold=0.3 | ✅ 首次有效:+400→-39.5°、-400→+34.5° |
关键结论:加
W长按时间=0.3后测量才成立——瞬时按键不足以让角色位移刷新箭头。
3.2 正式标定期(16:34-16:56)
| 时间 | 配置 | mean_k | k_pos | k_neg | 验证 |
|---|---|---|---|---|---|
| 16:34 | dx=400×4 | -0.08063 | -0.08625 | -0.07500 | — |
| 16:43 | dx=400×4 | -0.09937 | -0.12375* | -0.07500 | +90° ✅ 误差 0.5° |
| 16:49 | dx=400×4 | -0.08063 | -0.08625 | -0.07500 | +44/55/77/99 全 PASS |
| 16:55 | 多位移 200..1000 | -0.08493 | -0.09527 | -0.07458 | +44/55/77/99 全 PASS |
* 16:43 的 sample1 因 before=142(起点未复位)产生异常 k=-0.16125。
3.3 时序实验期(17:01-17:05)——排除时序
| 时间 | 配置 | mean_k | k_pos | k_neg |
|---|---|---|---|---|
| 17:01 | turn_settle=1.3 | -0.08522 | -0.09590 | -0.07454 |
| 17:05 | 去 +200,6 样本 | -0.08224 | -0.08842 | -0.07606 |
结论:1.3s 与 0.3s 数据逐位一致 → 排除「转向没转完就被 W 打断」的时序假设。 另:+200 两次 k=-0.115/-0.1175(偏大 40%),删除后 std 从 0.0143 降到 0.0071。
3.4 左右成对验证期(17:09-17:23)——发现地形真相
| 时间 | 起点yaw | mean_k | k_pos | k_neg | 差距 | 验证亮点 |
|---|---|---|---|---|---|---|
| 17:09 | ~112° | -0.08369 | -0.09133 | -0.07606 | 右大 20% | -44° FAIL(-6°) |
| 17:13 | ~4° | -0.08253 | -0.08217 | -0.08289 | 几乎对称 | +44 FAIL(-7°), -99 FAIL(-11°) |
| 17:22 | ~257° | -0.09031 | -0.08258 | -0.09803 | 左大 19% | 大角度 3 项 WARN |
决定性发现:不对称方向随起点约 180° 反转 → 排除游戏左右灵敏度不对称;真凶是测试点地形(按 W 前进时角色被坡度带偏)。
3.5 手动系数期(17:27-17:32)——符号事故 + 验证成功
| 时间 | 手动系数 | 结果 |
|---|---|---|
| 17:27 | +0.083(符号反了) | 8/8 全 FAIL,误差 84~207°(方向全反) |
| 17:30 | +0.083(未改) | 继续全 FAIL |
| 17:31 | -0.083 | 方向恢复,误差收敛到 ±7° 内 |
17:31 轮(手动 -0.083)逐角度明细:
| 角度 | 实际均值 | 误差 | 状态 |
|---|---|---|---|
| +44° | +43.0° | -1.0° | PASS |
| -44° | -50.5° | -6.5° | WARN |
| +55° | +55.5° | +0.5° | PASS |
| -55° | -60.0° | -5.0° | PASS |
| +77° | +80.5° | +3.5° | PASS |
| -77° | -83.5° | -6.5° | WARN |
| +99° | +93.5° | -5.5° | WARN |
| -99° | -103.0° | -4.0° | WARN |
正方向基本正常(≤3.5°),负方向普遍偏 5~6.5°,与此轮起点位置的地形影响一致。
四、跨轮稳定结论
- 左转(dx<0)表现稳定:各轮 -400→+30
32°、-600→+45.550.5°、-1000→+76.587°,大位移 k 稳定在 **-0.076-0.084**。 - 右转(dx>0)受起点/地形影响大:同一位移在不同起点差 8~12°。
- 推荐系数 ≈ -0.082 ~ -0.084 °/px(17:13 轮最对称、std 最小 0.004)。
- 1000px ≈ 84°,600px ≈ 50°,400px ≈ 33°,90° ≈ 1080px。
- +200 是小位移异常区(k 偏大 40%),已从标定列表移除。
- 大角度(99°)误差始终偏大(±4~14°)→ 正式使用建议分段转向。
五、镜头偏心假设分析(用户提出:画面里角色始终偏左)
用户的观察本身成立——很多 3D 游戏镜头偏心(给前方更多视野),角色显得偏左/偏下。但数据上排除固定镜头偏心:
- 固定偏心在 Δyaw 中相消:若镜头固定偏心造成箭头读数带上固定偏差 δ(不随朝向变),则
(after+δ) - (before+δ) = after - before,δ 直接消失,不影响 k。 - 决定性证据——不对称随起点反转:固定偏心是空间固定、方向无关的量,若它让右转偏大,换任何起点都应右转偏大。但 112°→257°(差约 145°)偏大方向整个反转。没有任何固定偏心能解释。
- 唯一自洽解释仍是地形:箭头读的是角色按 W 前进的面朝方向,坡度把角色带偏;不同起点走过坡的方式不同 → 偏大方向随之反转。
- 代码层已排除发送不对称:
send_mouse_delta用user32.mouse_event(MOUSEEVENTF_MOVE, dx, 0, 0, 0)正负直接透传,完全对称。
一锤定音验证方法
找一块完全平坦、开阔的地方(广场/平地)重跑「标定 + 左右成对验证」:
k_pos ≈ k_neg(差 < 2%)、8 角度基本全 PASS → 地形假设确认,镜头偏心排除;- 仍明显不对称 → 才轮到镜头/游戏机制问题。
肉眼辅助:按 W 前进时盯箭头方向,若箭头慢慢漂移(而非纹丝不动),即地形在带偏角色——最直接的证据。
六、符号事故复盘
- 用户曾在
手动yaw_per_pixel填"0.083"(应为负数)。 - 症状:+44° 目标用 dx=+530 右移反而转到 -41°,误差 84°~207°,方向全反。
- 处理:1) 配置文件修正为
"-0.083";2) 代码在手动系数为正时自动取负修正并 notify 日志,杜绝再犯。
七、后续建议
- 换平地重测确认地形假设(当前唯一待办实验)。
- 起点朝向对齐:正式转向任务建议先对齐起点朝向再转向,降低地形影响。
- 正式转向用小角度分段:每步 ≤30°(≈360px),并按方向分系数(k_pos / k_neg)使用。
- 状态判定小修:建议「两次验证都 FAIL 才判 FAIL,单次 FAIL 判 WARN」改为「两次都 FAIL 判 FAIL」更严格,当前实现可能漏报。
附:相关文件
- 任务源码:
src/tasks/test/MouseRotationCalibration.py - 运行配置:
configs/MouseRotationCalibration.json - 单元测试:
tests/TestMouseRotationCalibration.py(12 个用例全过) - 鼠标发送层:
src/interaction/Mouse.py(send_mouse_delta,正负对称) - 核心 API:
src/core/base_mixin/runtime_mixin.py(get_arrow_angle/press_key/active_and_send_mouse_delta)