Files
agv-control-slam/docs/fixes/TRACKING_ERROR_ANALYSIS.md
CaiXiang af65c2425d initial
2025-11-14 16:09:58 +08:00

261 lines
6.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.

# 路径跟踪偏差问题分析报告
## 问题描述
**现象**: AGV实际运行的Trajectory和reference path偏差较大没有很好地追踪
## 根本原因分析
经过深入分析代码,发现以下关键问题:
### 1. 初始状态与路径起点不匹配 ⭐⭐⭐(主要原因)
**问题详情**:
```cpp
// qt_gui_demo.cpp:450
AGVModel::State initial_state(0.0, 0.0, 0.0); // 固定为原点theta=0
tracker_->setInitialState(initial_state);
```
**路径实际起点**以smooth_path.csv为例:
```
x=0, y=0, theta=0.310064 rad (≈17.8度), kappa=0
```
**问题**:
- 初始theta设为0但路径起点theta≈0.31 rad
- **初始朝向偏差17.8度**,导致一开始就偏离路径
- 对于CSV路径起点坐标可能也不是(0,0)
### 2. 控制参数硬编码,无法调整 ⭐⭐⭐
**Pure Pursuit硬编码**path_tracker.cpp:35:
```cpp
control_sequence_ = control_generator_.generatePurePursuit(
reference_path_, initial_state_, dt,
1.5, // lookahead_distance 硬编码!
1.0, // desired_velocity 硬编码!
horizon);
```
**Stanley硬编码**path_tracker.cpp:38:
```cpp
control_sequence_ = control_generator_.generateStanley(
reference_path_, initial_state_, dt,
1.0, // k_gain 硬编码!
1.0, // desired_velocity 硬编码!
horizon);
```
**问题**:
- GUI中有`max_vel_spin_`参数默认2.0 m/s但**从未使用**
- 前视距离1.5米可能不适合所有速度
- Stanley增益1.0可能需要针对不同路径调整
- 用户无法通过GUI调整这些关键参数
### 3. Pure Pursuit前视距离不合理 ⭐⭐
**理论公式**:
```
lookahead_distance = k * velocity
推荐: k = 1.0 到 2.0
```
**当前问题**:
- lookahead固定为1.5米
- 速度硬编码为1.0 m/s → lookahead/v = 1.5
- 如果实际速度是2.0 m/slookahead应该是3.0米但仍用1.5米
- **前视距离太短**导致转弯反应过快,**太长**导致切弯
### 4. Stanley增益可能不适配 ⭐⭐
**Stanley控制律**:
```
delta = heading_error + atan(k * cross_track_error / v)
```
**问题**:
- k_gain=1.0是经验值,不一定适合所有场景
- 对于急弯路径可能需要更大的k比如2.0-3.0
- 对于平缓路径较小的k0.5-1.0)更平滑
### 5. 速度设置不一致 ⭐
**GUI中设置**:
- Max Velocity默认: 2.0 m/s
**实际使用**:
- desired_velocity硬编码: 1.0 m/s
**结果**: 用户以为设置了2.0 m/s实际只用1.0 m/s
## 影响分析
### 偏差来源
| 原因 | 初始偏差 | 累积效应 | 严重度 |
|------|---------|---------|--------|
| 初始theta不匹配 | 大17.8度) | 立即偏离 | ⭐⭐⭐ |
| 前视距离不当 | 中 | 逐渐偏离 | ⭐⭐ |
| 速度参数错误 | 小 | 影响lookahead | ⭐⭐ |
| Stanley增益不当 | 中 | 震荡或滞后 | ⭐⭐ |
### 实际表现
**初始状态不匹配的影响**:
```
时刻0:
AGV朝向: 0度向东
路径朝向: 17.8度(东北)
→ 立即产生17.8度朝向误差
时刻1:
AGV会尝试转向路径但已经偏离
→ 横向误差累积
后续:
持续追赶路径,但始终有偏差
→ 轨迹呈"追赶"模式而非"跟踪"模式
```
**前视距离不当的影响**:
```
lookahead太小(0.5m):
→ 反应过于敏感
→ 轨迹震荡
→ 频繁调整方向
lookahead太大(3.0m):
→ 反应迟钝
→ 切弯
→ 路径跟踪不精确
合适的lookahead(1.5-2.5m @ 1.0m/s):
→ 平滑跟踪
→ 适度预判
```
## 修复方案
### 修复1: 初始状态匹配路径起点 ⭐⭐⭐(必须修复)
**修改位置**: `examples/qt_gui_demo.cpp:450`
**修改前**:
```cpp
AGVModel::State initial_state(0.0, 0.0, 0.0);
tracker_->setInitialState(initial_state);
```
**修改后**:
```cpp
// 从路径起点获取初始状态
const auto& path_points = path.getPathPoints();
if (!path_points.empty()) {
const PathPoint& start = path_points[0];
AGVModel::State initial_state(start.x, start.y, start.theta);
tracker_->setInitialState(initial_state);
} else {
AGVModel::State initial_state(0.0, 0.0, 0.0);
tracker_->setInitialState(initial_state);
}
```
### 修复2: 使用GUI速度参数 ⭐⭐⭐(必须修复)
**修改位置**: `examples/qt_gui_demo.cpp:458-460`
**修改前**:
```cpp
tracker_->generateControlSequence(algo_str, dt, horizon);
```
**修改后**:
```cpp
double desired_velocity = max_vel_spin_->value(); // 使用GUI参数
tracker_->generateControlSequence(algo_str, dt, horizon, desired_velocity);
```
需要修改`path_tracker.h``path_tracker.cpp`添加velocity参数。
### 修复3: 自适应前视距离 ⭐⭐(推荐修复)
**修改位置**: `src/path_tracker.cpp:35`
**修改前**:
```cpp
control_sequence_ = control_generator_.generatePurePursuit(
reference_path_, initial_state_, dt, 1.5, 1.0, horizon);
```
**修改后**:
```cpp
double lookahead = std::max(1.0, desired_velocity * 2.0); // 速度的2倍
control_sequence_ = control_generator_.generatePurePursuit(
reference_path_, initial_state_, dt, lookahead, desired_velocity, horizon);
```
### 修复4: 添加GUI参数控制 ⭐⭐(推荐修复)
在GUI中添加:
- Lookahead参数Pure Pursuit
- K Gain参数Stanley
这样用户可以根据路径特性调整参数。
### 修复5: 改进Stanley增益 ⭐(可选修复)
**修改位置**: `src/path_tracker.cpp:38`
**修改后**:
```cpp
double k_gain = 2.0; // 增加到2.0以提高响应性
control_sequence_ = control_generator_.generateStanley(
reference_path_, initial_state_, dt, k_gain, desired_velocity, horizon);
```
## 优先级
| 修复 | 优先级 | 难度 | 效果 |
|------|--------|------|------|
| 初始状态匹配路径起点 | ⭐⭐⭐ | 简单 | 立即显著改善 |
| 使用GUI速度参数 | ⭐⭐⭐ | 中等 | 提高一致性 |
| 自适应前视距离 | ⭐⭐ | 简单 | 改善跟踪性能 |
| 添加GUI参数 | ⭐⭐ | 复杂 | 提高可调性 |
| 改进Stanley增益 | ⭐ | 简单 | 微小改善 |
## 预期效果
**修复前**:
```
初始状态: (0, 0, 0°)
路径起点: (0, 0, 17.8°)
→ 立即产生17.8度朝向偏差
→ Trajectory始终追赶reference path
→ 横向误差大0.5-2.0米)
```
**修复后**:
```
初始状态: (0, 0, 17.8°) ← 匹配路径起点
路径起点: (0, 0, 17.8°)
→ 完美对齐
→ Trajectory平滑跟踪reference path
→ 横向误差小(<0.2米)
```
## 下一步行动
建议按以下顺序实施修复:
1. **立即修复**: 初始状态匹配路径起点
2. **立即修复**: 使用GUI速度参数
3. **推荐修复**: 自适应前视距离
4. **可选修复**: 添加GUI参数控制
---
**分析日期**: 2025-11-14
**问题类型**: 控制算法参数设置
**严重程度**: 高
**根本原因**: 初始状态不匹配 + 参数硬编码