在自动驾驶和车辆动力学研究领域,轨迹跟踪控制一直是核心技术难题之一。想象一下,当你在高速公路上驾驶时,眼睛会自然地看向前方一定距离的路面,根据看到的道路走向提前调整方向盘角度——这正是预瞄控制的基本原理在人类驾驶行为中的体现。
预瞄控制(Preview Control)的核心思想是让控制系统"看到"前方一定距离(称为预瞄距离)处的轨迹信息,通过计算当前车辆状态与预瞄点之间的偏差,提前做出控制决策。这种方法相比传统的反馈控制具有显著优势:
在实际工程实现中,CarSim和Simulink的组合为我们提供了完美的工具链。CarSim提供高精度的车辆动力学模型,能够准确模拟车辆在各种工况下的动态响应;而Simulink则提供了灵活的控制算法开发环境,两者结合可以快速验证各种控制策略的有效性。
要实现CarSim和Simulink的联合仿真,需要建立如图所示的系统架构:
code复制[Simulink控制算法] ↔ [CarSim-Simulink接口] ↔ [CarSim车辆模型]
数据流向是双向的:
重要提示:在开始仿真前,必须确保CarSim和MATLAB/Simulink的版本兼容,并正确安装CarSim的Simulink接口模块。我曾在项目初期因为版本不匹配浪费了两天时间排查连接问题。
CarSim的车辆模型配置主要通过参数文件(.par文件)实现。对于轨迹跟踪控制研究,以下几个参数组需要特别关注:
车辆质量参数:
悬架系统参数:
轮胎模型参数:
转向系统参数:
一个典型的CarSim参数修改示例如下:
code复制Vehicle Mass and Dimensions:
Total vehicle mass = 1500 kg
Sprung mass C.G. location = [1.2, 0, 0.5] m
预瞄点计算是控制算法的第一步,其核心是根据车辆当前位置和预瞄距离,在参考轨迹上找到合适的预瞄点。以下是改进后的MATLAB实现代码:
matlab复制function preview_point = calculatePreviewPoint(current_pose, trajectory, look_ahead_distance)
% current_pose: [x, y, heading] 车辆当前位姿
% trajectory: N×3矩阵,每行是轨迹点的[x, y, curvature]
% look_ahead_distance: 预瞄距离
% 转换到车辆坐标系
rel_pos = trajectory(:,1:2) - current_pose(1:2);
rot_matrix = [cos(current_pose(3)) sin(current_pose(3));
-sin(current_pose(3)) cos(current_pose(3))];
vehicle_coord = (rot_matrix * rel_pos')';
% 计算前方点的纵向距离
forward_dist = vehicle_coord(:,1);
% 找到第一个超过预瞄距离的点
preview_idx = find(forward_dist > look_ahead_distance, 1);
if isempty(preview_idx)
preview_point = trajectory(end,:);
else
% 线性插值得到精确的预瞄点
alpha = (look_ahead_distance - forward_dist(preview_idx-1)) / ...
(forward_dist(preview_idx) - forward_dist(preview_idx-1));
preview_point = (1-alpha)*trajectory(preview_idx-1,:) + ...
alpha*trajectory(preview_idx,:);
end
end
这个改进版本考虑了车辆航向角,将轨迹点转换到车辆坐标系下计算,并使用插值法提高预瞄点精度。
基于预瞄点的横向控制通常采用Stanley方法或纯追踪算法。这里我们介绍一种改进的Stanley方法:
航向误差修正:
ψ_error = preview_point.heading - current_heading
横向位置误差修正:
计算车辆前轴中心到预瞄点轨迹的法向距离e
转向角计算:
δ = ψ_error + arctan(k*e/v)
其中k为增益系数,v为车速
在Simulink中实现时,需要注意:
完整的Simulink模型应包含以下子系统:
轨迹生成模块:
车辆状态处理模块:
预瞄控制模块:
接口模块:
采样时间设置:
信号处理技巧:
matlab复制% 在MATLAB Function模块中处理信号时,添加以下代码防止代数环
persistent init_flag
if isempty(init_flag)
init_flag = true;
% 初始化代码
end
调试技巧:
预瞄距离不是固定值,应与车速动态相关。经验公式为:
code复制look_ahead_distance = base_distance + k * vehicle_speed
其中:
调试方法:
横向控制参数调试步骤:
初始参数设置:
调试流程:
不同车速下的参数调度:
matlab复制function Kp = scheduleKp(velocity)
if velocity < 5
Kp = 0.15;
elseif velocity < 15
Kp = 0.1;
else
Kp = 0.07;
end
end
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 仿真无法启动 | 接口未正确配置 | 检查CarSim Solver设置中的MATLAB路径 |
| 数据不同步 | 采样时间不匹配 | 统一设置Simulink和CarSim的采样时间 |
| 车辆无响应 | 信号接口错误 | 验证控制信号单位与CarSim预期是否一致 |
轨迹跟踪振荡:
过弯切内线:
高速不稳定:
模型简化:
代码优化:
matlab复制% 避免在循环中使用动态内存分配
% 不好的写法
for i = 1:100
data(i) = i^2; % 每次迭代都会改变data大小
end
% 好的写法
data = zeros(1,100);
for i = 1:100
data(i) = i^2;
end
执行效率工具: