1. 项目背景与核心价值
轨迹跟踪是自动驾驶和智能车辆控制领域的经典问题。传统PID控制方法在复杂路况下往往表现不佳,而模型预测控制(MPC)凭借其滚动优化和反馈校正的特性,成为解决这一难题的利器。我在参与某园区无人配送车项目时,就曾用Matlab实现了这套MPC轨迹跟踪算法,实测横向跟踪误差能控制在0.1米以内。
MPC的核心思想可以类比老司机开车:他们不会死盯着当前的方向偏差,而是根据车辆动态预判未来几秒的行驶轨迹,不断微调方向盘。这种"走一步看三步"的控制策略,正是MPC相比传统方法的优势所在。
2. 模型预测控制原理拆解
2.1 车辆动力学建模
采用经典的自行车模型(如图1),其状态方程可表示为:
matlab复制function dx = vehicleModel(t,x,u)
% 参数定义
lf = 1.2; % 前轴到质心距离(m)
lr = 1.6; % 后轴到质心距离(m)
C_f = 80000; % 前轮侧偏刚度(N/rad)
C_r = 80000; % 后轮侧偏刚度(N/rad)
m = 1500; % 质量(kg)
Iz = 2500; % 转动惯量(kg·m^2)
% 状态变量提取
psi = x(3); % 横摆角(rad)
vx = x(4); % 纵向速度(m/s)
vy = x(5); % 横向速度(m/s)
r = x(6); % 横摆角速度(rad/s)
% 控制输入
delta = u(1); % 前轮转角(rad)
a = u(2); % 纵向加速度(m/s^2)
% 动力学方程
dx(1) = vx*cos(psi) - vy*sin(psi); % X方向位移
dx(2) = vx*sin(psi) + vy*cos(psi); % Y方向位移
dx(3) = r; % 横摆角
dx(4) = a; % 纵向加速度
dx(5) = (2*(C_f*(delta - (vy + lf*r)/vx) + C_r*(-(vy - lr*r)/vx))/m) - r*vx;
dx(6) = (2*(lf*C_f*(delta - (vy + lf*r)/vx) - lr*C_r*(-(vy - lr*r)/vx))/Iz);
end
注意:当车速低于1m/s时,上述模型会出现奇点。实际工程中需做低速处理,比如采用阿克曼转向几何简化模型。
2.2 预测时域与优化问题
MPC的核心是求解如下优化问题:
code复制min J = Σ(跟踪误差) + Σ(控制量变化) + Σ(约束违反惩罚)
s.t. 车辆动力学约束
控制量上下限
状态量安全边界
在Matlab中通常转化为二次规划(QP)问题求解。关键参数选择经验:
- 预测时域T=3s(过短则预见性不足,过长则计算负担大)
- 控制时域Δt=0.1s(需小于系统响应时间常数)
- 权重矩阵Q=diag([10,10,1,0.1])(横向误差权重大于纵向)
3. Matlab实现全流程
3.1 环境配置
matlab复制% 必需工具箱检查
assert(~isempty(ver('optim')), '需要安装Optimization Toolbox');
assert(~isempty(ver('mpc')), '建议安装Model Predictive Control Toolbox');
% 参考轨迹生成(以8字轨迹为例)
theta = linspace(0,2*pi,100);
refTraj = [50*sin(theta); 30*sin(2*theta)]';
3.2 MPC控制器构建
matlab复制% 创建MPC对象
mpcObj = mpc(vehicleModel, Ts, p, m);
% 设置约束
mpcObj.MV(1).Min = -0.5; % 前轮转角下限(rad)
mpcObj.MV(1).Max = 0.5; % 前轮转角上限
mpcObj.MV(2).Min = -3; % 加速度下限(m/s^2)
mpcObj.MV(2).Max = 2; % 加速度上限
% 权重调整
mpcObj.Weights.OV = [10 10 1 0.1]; % 输出变量权重
mpcObj.Weights.MV = [0.1 0.1]; % 控制变量权重
3.3 闭环仿真实现
matlab复制% 初始化
x0 = [0; 0; 0; 5; 0; 0]; % 初始状态
simTime = 60; % 仿真时长(s)
% 主循环
for k = 1:simTime/Ts
% 获取当前参考轨迹段
refWindow = getRefWindow(refTraj, x0, T);
% 求解最优控制量
[u, info] = nlmpcMove(mpcObj, x0, refWindow);
% 更新车辆状态
[~,x] = ode45(@(t,x)vehicleModel(t,x,u),[0 Ts],x0);
x0 = x(end,:)';
% 记录数据
logData(k) = packLog(x0, u, refWindow);
end
4. 工程实践中的关键技巧
4.1 实时性优化方案
当采样周期要求<50ms时,可采用以下加速策略:
- 热启动:用上一周期的解作为本次优化初值
- 提前终止:设置最大迭代次数(如20次)
- 代码生成:用Matlab Coder将算法转为C代码
matlab复制% 设置优化选项
options = optimoptions('fmincon','MaxIterations',20,...
'Algorithm','sqp','Display','none');
4.2 典型问题排查指南
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 控制量剧烈抖动 | 权重矩阵Q/R设置不当 | 增大控制量变化权重 |
| 跟踪滞后明显 | 预测时域过短 | 延长T或提高车速 |
| 优化求解失败 | 初始猜测偏离可行域 | 添加松弛变量或调整约束 |
| 低速时控制不稳定 | 动力学模型奇点 | 切换为低速简化模型 |
5. 进阶改进方向
在实际项目中,我们进一步优化了基础方案:
- 考虑路面摩擦系数估计
- 加入障碍物避碰约束
- 融合视觉的轨迹预测
- 多车协同控制
matlab复制% 障碍物避碰约束示例
function [c,ceq] = obstacleAvoid(x,u)
% 获取预测轨迹
predTraj = predictTrajectory(x,u);
% 计算与障碍物的最小距离
minDist = min(vecnorm(predTraj - obstaclePos,2,2));
% 非线性约束
c = 1 - minDist; % 要求距离>1m
ceq = [];
end
这个Matlab实现框架已经成功应用于我们的园区物流车项目。建议初次尝试时先用MATLAB 2021b以上版本运行,遇到求解器问题可以尝试切换为'interior-point'算法。对于更复杂的场景,可能需要考虑C++重写核心算法模块以提升实时性。