1. 项目背景与核心目标
最近在做一个无人驾驶路径跟踪控制的仿真项目,主要验证斯坦利(Stanley)控制器在自动驾驶车辆横向控制中的表现。这个项目需要用到Matlab和CarSim的联合仿真环境,正好把整个搭建过程和测试结果记录下来,给同样做自动驾驶控制研究的朋友们参考。
路径跟踪是自动驾驶核心技术之一,简单说就是让车辆按照规划好的路径行驶。斯坦利控制器作为经典的横向控制算法,最早由斯坦福大学在DARPA挑战赛中提出并验证,特别适合处理中低速场景下的路径跟踪问题。它的核心思想是通过航向角偏差和横向位置偏差的综合修正来实现精准跟踪。
2. 仿真环境搭建
2.1 软件准备与配置
做联合仿真需要准备好几个关键软件:
- CarSim 2019.1(建议版本)
- Matlab R2020b及以上
- CarSim Matlab Interface插件
安装时有个细节要注意:CarSim和Matlab的安装顺序很重要。建议先装CarSim,再装Matlab,最后安装接口插件。我试过反过来装,结果接口死活连不上,浪费了半天时间排查。
配置环境变量时,需要把CarSim的bin目录添加到系统PATH。在Matlab中还要设置搜索路径,把CarSim的Solver目录加进去。这里有个小技巧:可以在Matlab命令窗口运行"csim_configure"命令来检查配置是否正确。
2.2 车辆模型参数设置
在CarSim中建立测试车辆模型时,有几个关键参数需要特别注意:
- 质量参数:整车质量、前后轴质量分配
- 轮胎参数:侧偏刚度对控制效果影响很大
- 转向系统:转向传动比、最大转向角
- 发动机特性:直接影响纵向控制响应
建议先用CarSim自带的Demo车辆模型作为基础,再根据实际需求调整。我用的是一辆中型轿车模型,主要参数如下:
| 参数名称 | 数值 | 单位 |
|---|---|---|
| 整车质量 | 1500 | kg |
| 轴距 | 2.7 | m |
| 前轮侧偏刚度 | 60000 | N/rad |
| 最大转向角 | 30 | deg |
3. 斯坦利控制器实现
3.1 算法原理详解
斯坦利控制器的核心公式其实很简洁:
δ = θ_e + arctan(k * e / v)其中:
- δ:前轮转向角
- θ_e:航向角偏差(车辆航向与路径切线方向的夹角)
- e:横向位置偏差
- v:车辆速度
- k:调节增益
这个公式的物理意义很明确:第一项修正航向偏差,第二项根据横向偏差和车速动态调整转向角度。车速越高,对同样的横向偏差,转向修正越柔和,这符合实际驾驶经验。
在Matlab中实现时,需要特别注意几个细节:
- 角度单位统一(全部用弧度制)
- 加入转向角速率限制(模拟真实转向系统)
- 处理路径曲率不连续点
3.2 Matlab实现代码
下面是我的核心控制代码(简化版):
function delta = stanley_controller(veh_state, path, k_gain) % 获取当前车辆状态 x = veh_state.x; y = veh_state.y; yaw = veh_state.yaw; v = veh_state.v; % 寻找最近路径点 [~, idx] = min(sum(([path.x, path.y] - [x, y]).^2, 2)); % 计算航向角偏差 path_yaw = atan2(path.y(idx+1)-path.y(idx), path.x(idx+1)-path.x(idx)); theta_e = wrapToPi(path_yaw - yaw); % 计算横向偏差 e = -(x - path.x(idx)) * sin(path_yaw) + (y - path.y(idx)) * cos(path_yaw); % 斯坦利控制律 delta = theta_e + atan(k_gain * e / (v + 0.1)); % 加0.1避免除零 % 转向角限制 delta = min(max(delta, -deg2rad(30)), deg2rad(30)); end重要提示:wrapToPi函数用于将角度规整到[-π,π]区间,避免角度跳变问题。如果没有这个函数,可以用mod(angle+pi, 2*pi)-pi实现相同功能。
4. 联合仿真实现
4.1 Simulink模型搭建
联合仿真的核心是在Simulink中建立与CarSim的接口模型。主要包含以下几个部分:
- CarSim S-Function块:负责与CarSim求解器通信
- 控制器模块:实现斯坦利算法
- 路径输入模块:提供参考路径
- 可视化模块:实时显示车辆轨迹
模型搭建时最容易出错的是信号接口的匹配。CarSim输出的车辆状态信号和控制器需要的输入信号必须严格对应。建议先用一个简单的PID控制器测试接口是否正常工作,再替换成斯坦利控制器。
4.2 参数调试技巧
调试斯坦利控制器时,主要调整两个参数:
- 增益系数k:影响横向偏差修正的强度
- 前视距离:影响控制的前瞻性
我的调试经验是:
- 先从k=0.5开始,逐步增大直到出现振荡,然后回退20%
- 前视距离一般设为车速的0.8-1.2倍时间对应的距离
- 低速时(k=1.0)效果最好,高速时需要适当减小k值
下面是我测试过的参数组合效果对比:
| 速度(km/h) | k值 | 最大横向误差(m) | RMS误差(m) |
|---|---|---|---|
| 30 | 1.0 | 0.12 | 0.05 |
| 50 | 0.8 | 0.18 | 0.08 |
| 70 | 0.6 | 0.25 | 0.12 |
5. 典型问题与解决方案
5.1 路径曲率不连续问题
在实际测试中,当参考路径存在曲率不连续点(如直线接急弯)时,车辆容易出现明显的转向抖动。这是因为斯坦利控制器的航向角偏差计算对路径曲率变化敏感。
解决方案:
- 对参考路径进行平滑处理(如样条插值)
- 在控制器中加入转向角速率限制
- 适当增大前视距离
我采用三次样条插值对原始路径进行平滑,效果显著改善。Matlab代码片段:
% 原始路径点 x = [0 10 20 30 40]; y = [0 5 0 5 0]; % 样条插值 t = 1:length(x); ts = linspace(1,length(x),100); xs = spline(t,x,ts); ys = spline(t,y,ts);5.2 高速工况下的稳定性问题
当车速超过80km/h时,发现车辆容易出现横向振荡。这是因为斯坦利控制器本质上是一个纯比例控制器,缺乏阻尼项。
改进方案:
- 加入微分项,形成PD控制结构
- 根据车速动态调整增益参数
- 增加横向加速度反馈
改进后的控制律:
δ = θ_e + arctan(k * e / (v + v0)) + kd * de/dt其中v0是防止除零的小常数,kd是微分增益。
6. 仿真结果分析
6.1 典型场景测试
我设计了三种典型场景进行测试:
- 双移线测试:评估瞬态响应
- 圆形路径:评估稳态性能
- 复杂曲线:评估综合性能
双移线测试的结果最直观。下图展示了车速50km/h时的跟踪效果: [此处应有轨迹对比图,实际使用时请插入图片]
从结果看,最大横向误差小于0.2m,满足一般自动驾驶的精度要求。在曲率较大的弯道处,误差会稍大,但仍在可控范围内。
6.2 性能指标对比
为了量化评估,我定义了三个性能指标:
- 最大横向误差
- RMS误差
- 转向角变化率
与传统PID控制器对比,斯坦利控制器在中等车速下表现更优:
| 控制器类型 | 最大误差(m) | RMS误差(m) | 转向角变化率(deg/s) |
|---|---|---|---|
| PID | 0.25 | 0.12 | 35 |
| Stanley | 0.18 | 0.08 | 28 |
7. 扩展与优化方向
在实际项目中,我还尝试了几种优化方案:
- 动态增益调整:根据车速和路径曲率实时调整k值
k = k0 / (1 + 0.5*abs(curvature)*v^2);- 结合预瞄控制:在前方路径点中选取最优预瞄点
lookahead_dist = min(5, max(1, 0.8*v));- 加入道路摩擦估计:根据横向加速度动态调整控制强度
这些优化进一步提升了控制性能,特别是在复杂场景下的鲁棒性。不过也要注意,增加太多补偿项会影响控制器的简洁性和可解释性,需要根据实际需求权衡。
在CarSim中测试时,记得打开数据记录功能,保存关键的信号变量。我通常记录以下信号:
- 车辆位置(x,y)
- 航向角
- 转向角
- 横向偏差
- 参考路径
这样后期分析时可以用Matlab脚本批量处理数据,生成专业的性能分析图表。