1.0
This commit is contained in:
133
Doc/近墙猛修问题.md
Normal file
133
Doc/近墙猛修问题.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# 近墙猛修问题记录
|
||||
|
||||
## 现象
|
||||
|
||||
- 在两侧均为约 `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:预处理层加近墙保护
|
||||
|
||||
- 提高侧向最小可信距离阈值,不再把极近距离观测直接当正常数据使用。
|
||||
- 或新增“近墙退化区”,在该区间内降低观测可信度,而不是简单二值有效/无效。
|
||||
|
||||
这是最前面的止血点。
|
||||
|
||||
### 方案 B:EKF 观测限幅
|
||||
|
||||
- 对 `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` 是否跟着立刻增大。
|
||||
|
||||
如果这三者时间上连续对应,就可以基本坐实当前分析。
|
||||
Reference in New Issue
Block a user