当第一次看到双轮差速机器人的MPC轨迹跟踪时,大多数工程师都会被复杂的数学公式吓退。但真正在工业现场或科研项目中,我们需要的是能快速验证想法的可执行代码,而不是纸上谈兵的推导过程。本文将用Matlab带你完整实现一个可运行的MPC轨迹跟踪仿真系统,从运动学建模到参数调优,全程避开数学陷阱,直击工程实现核心。
双轮差速机器人作为移动机器人中最基础也最经典的模型,其控制方法直接影响着AGV、服务机器人甚至火星车的运动性能。与传统PID控制相比,MPC(模型预测控制)具有三大不可替代的优势:
在Matlab中实现MPC控制时,我们常遇到两个典型问题:一是推导过程复杂导致代码难以验证,二是参数调节缺乏直观反馈。下面的实验数据展示了不同控制方法的跟踪误差对比:
| 控制方法 | 平均误差(m) | 最大误差(m) | 计算耗时(ms) |
|---|---|---|---|
| PID | 0.12 | 0.35 | 1.2 |
| LQR | 0.08 | 0.25 | 2.1 |
| MPC | 0.05 | 0.15 | 5.8 |
表:三种控制算法在S形轨迹下的性能对比
双轮差速机器人的运动学模型是MPC实现的基础。与传统推导不同,我们采用几何关系直接建模的方法,避免繁琐的数学公式。
matlab复制% 双轮差速机器人运动学模型
function [x_dot, y_dot, theta_dot] = diff_kinematics(v, w, theta)
x_dot = v * cos(theta);
y_dot = v * sin(theta);
theta_dot = w;
end
这个模型的核心参数只有两个:
v:机器人前进速度(m/s)w:机器人旋转角速度(rad/s)在实际编码时,需要注意三个常见陷阱:
提示:使用欧拉离散化时,当采样周期超过0.1秒会导致仿真结果严重失真
MPC的核心是预测未来状态,我们需要将连续模型转换为离散预测方程。与传统方法不同,这里采用直接离散化技术:
matlab复制% 构建预测矩阵
function [A, B] = build_prediction_model(Ts, N)
A = eye(3); % 状态矩阵
B = zeros(3,2); % 控制矩阵
% 离散化处理
A(1,3) = -v_ref*sin(theta_ref)*Ts;
A(2,3) = v_ref*cos(theta_ref)*Ts;
B(1,1) = cos(theta_ref)*Ts;
B(2,1) = sin(theta_ref)*Ts;
B(3,2) = Ts;
end
将跟踪问题转化为优化问题时,权重矩阵Q和R的选择直接影响控制效果。经过数十次实验验证,我们总结出如下经验法则:
matlab复制% 代价函数构建示例
Q = diag([10, 10, 3]); % 位置x,y权重10,角度权重3
R = diag([1, 5]); % 线速度权重1,角速度权重5
H = 2*(THETA'*Q*THETA + R); % 二次型矩阵
f = 2*ERR'*Q*THETA; % 线性项矩阵
使用Matlab的quadprog求解器时,关键是要正确处理约束条件。下面是一个带速度限制的求解示例:
matlab复制% 设置约束条件
v_max = 1.0; w_max = pi/2;
A_cons = [1 0; -1 0; 0 1; 0 -1];
b_cons = [v_max; v_max; w_max; w_max];
% 调用求解器
options = optimoptions('quadprog', 'Display', 'off');
[u_opt, ~, exitflag] = quadprog(H, f, A_cons, b_cons, [], [], [], [], [], options);
在MPC调试过程中,我们开发了一套实时可视化工具,包含三个关键视图:
matlab复制% 绘制预测轨迹示例
figure;
plot(ref_path(:,1), ref_path(:,2), 'r--');
hold on;
for i = 1:N
plot(pred_states(:,i,1), pred_states(:,i,2), 'b-', 'LineWidth', 0.5);
end
为快速找到最优参数组合,我们编写了自动参数扫描脚本:
matlab复制% 参数扫描示例
Q_vals = logspace(-1, 1, 5); % 0.1到10对数分布
results = zeros(length(Q_vals), 3);
for i = 1:length(Q_vals)
Q = diag([Q_vals(i), Q_vals(i), Q_vals(i)/3]);
% 运行仿真并记录误差
[~, err] = run_simulation(Q, R);
results(i,:) = [Q_vals(i), mean(err), max(err)];
end
当仿真结果满意后,可通过以下步骤迁移到真实机器人:
我们的MPC实现采用模块化设计,主要包含以下核心文件:
code复制mpc_tracking/
├── main.m # 主仿真脚本
├── models/
│ ├── diff_kinematics.m # 运动学模型
│ └── predictor.m # 预测模型生成
├── solvers/
│ └── qp_solver.m # 优化求解器接口
├── utils/
│ ├── visualizer.m # 可视化工具
│ └── param_scan.m # 参数扫描工具
└── tests/
└── test_cases.m # 测试用例集
在项目实践中,我们发现三个最容易出错的细节:
注意:完整代码包中包含了一个预置的S形轨迹测试用例,可直接运行查看效果