Files
ASER/Doc/近墙猛修问题.md
2026-04-08 07:38:46 +08:00

134 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 近墙猛修问题记录
## 现象
- 在两侧均为约 `40cm` 墙壁的测试环境中,只要车辆初始摆位明显偏向某一侧,就会出现明显的向另一侧猛打方向现象。
- 具体表现为:
- 车身非常靠近左侧墙时,会明显向右转。
- 车身非常靠近右侧墙时,会明显向左转。
- 当距离墙面非常近时,修正会过猛,看起来像“突然拧过去”。
## 当前判断
- “靠左往右修、靠右往左修”这个方向关系本身是符合居中控制逻辑的,不是转向方向定义反了。
- 真正的问题在于:侧向 VL53 在近墙区域的观测仍然被当作可信几何信息使用,导致横向误差 `e_y` 被一次性拉得过大,控制器再把这个大误差直接转换成较大的转向角速度。
- 因此,当前故障更接近“近墙观测过激 -> 状态估计偏大 -> 控制输出过猛”,而不是“状态机无故乱转”。
## 代码链路
### 1. 侧向 VL53 近墙仍可能被判有效
文件:`App/preproc/corridor_preproc.h`
- 当前侧向最小有效距离为:`PREPROC_MIN_SIDE_RANGE_M = 0.02f`
- 也就是只要大于 `2cm`,观测就可能继续进入后续 EKF。
这对 40cm 通道、20cm 车体来说偏激进,因为车辆一旦贴边,`2cm ~ 3cm` 这个区间很容易出现安装偏差、角度误差、近距非线性等问题。
### 2. EKF 直接把侧向距离变成横向偏差观测
文件:`App/est/corridor_ekf.c`
核心逻辑:
```c
float d_center = (W - Rw) / 2.0f + inset;
if (left_ok) {
z_ey += d_center - ((d_lf + d_lr) / 2.0f) - yoff;
}
if (right_ok) {
z_ey += ((d_rf + d_rr) / 2.0f) - d_center - yoff;
}
```
- 在当前参数下,理论居中时单侧读数大约为 `0.10m`
- 如果左侧因为近墙读到 `0.02m ~ 0.03m`,则 `z_ey` 会立刻表现为“明显偏左”,量级可达数厘米。
- 只要该观测没有被马氏距离检验拒绝,就会被吸收到状态 `e_y` 中。
### 3. 控制器直接用 `e_y` 生成转向命令
文件:`App/nav/corridor_ctrl.c`
```c
float w_cmd = -(s_cfg.kp_theta * state->e_th
+ s_cfg.kd_theta * imu_wz
+ s_cfg.kp_y * state->e_y);
```
-`e_y` 被近墙观测拉得过大时,`w_cmd` 会立刻增大。
- 因此表现出来就是:
- 贴左墙时明显向右修。
- 贴右墙时明显向左修。
- 靠得非常近时会“修得过猛”。
## 为什么这不是“方向反了”
- 如果控制方向反了,现象应该是:靠左还继续往左,靠右还继续往右。
- 实际观测恰好相反,说明控制方向是对的,只是近墙时误差量级过大。
## 与此前“上电就左转/右转”的关系
- 之前怀疑过状态机提前切换、IMU 保直、前向激光异常等路径。
- 结合实车现象后,当前更值得优先处理的是:
- 车辆一旦被放在明显偏向某一侧的位置,系统会把它当成正常走廊纠偏问题来处理。
- 当侧向 VL53 处于近墙区时,这个纠偏会被放大得过于激进。
这意味着当前问题更像“近墙过激纠偏”,而不是“无条件自主转向”。
## 高概率根因
1. 侧向 VL53 的最小可信距离阈值过低,近墙失真数据仍被当作有效观测。
2. EKF 对单拍横向观测 `z_ey` 缺少足够的近墙限幅或退化策略。
3. 控制层对“近墙高风险状态”没有额外保险,导致 `e_y` 一大就直接猛打方向。
## 建议修复方向
### 方案 A预处理层加近墙保护
- 提高侧向最小可信距离阈值,不再把极近距离观测直接当正常数据使用。
- 或新增“近墙退化区”,在该区间内降低观测可信度,而不是简单二值有效/无效。
这是最前面的止血点。
### 方案 BEKF 观测限幅
-`z_ey` 或单拍新息 `y_ey` 增加限幅。
- 防止单次近墙异常读数把 `e_y` 猛拉到过大值。
这是最直接针对“状态一下被拉偏”的修复。
### 方案 C控制层保险
- 在近墙状态下限制 `w_cmd` 的幅度或变化速度。
- 同时降低线速度,避免“边贴墙边急拧”。
这是最后一道保险,不应单独依赖,但建议保留。
## 建议优先级
1. 预处理层近墙保护
2. EKF 横向观测限幅
3. 控制层近墙保险
## 建议调试观测量
后续复现时建议同步观察以下量:
- 四颗侧向 VL53 原始距离
- `obs.valid_mask`
- `obs.d_lf / d_lr / d_rf / d_rr`
- `corridor_state.e_y`
- `corridor_state.e_th`
- `raw_cmd.w`
- `safe_w`
重点确认:
- 近墙时是否有某一侧距离突然跌到极小值。
- `e_y` 是否在同一时刻明显跃迁。
- `raw_cmd.w` 是否跟着立刻增大。
如果这三者时间上连续对应,就可以基本坐实当前分析。