1. 项目概述:当四驱电动车遇上MPC控制
在自动驾驶技术快速发展的今天,轨迹跟踪控制一直是核心难题之一。特别是对于分布式驱动电动汽车(即每个车轮都有独立电机驱动),如何协调四个车轮的扭矩输出,让车辆精准跟随预定轨迹,这背后隐藏着一场精妙的数学游戏。我最近用Carsim2020和Matlab2020b搭建了一套基于模型预测控制(MPC)的变道轨迹跟踪系统,实测在80km/h速度下能实现厘米级跟踪精度。
这个项目的独特之处在于,它不仅要解决传统MPC控制问题,还要处理四轮扭矩的动态分配。想象一下,你同时控制四个性格各异的"兄弟"(四个车轮),让他们在高速行驶中完美配合完成变道动作——前轮需要更多转向响应,后轮则要保证稳定性;内侧轮要适当减小扭矩防止打滑,外侧轮则要增加扭矩维持车速。这就像指挥一支弦乐四重奏,每个乐手(电机)都要在正确的时间发出恰到好处的音量(扭矩)。
2. 系统架构与核心原理
2.1 整体控制框架
系统采用分层控制架构:
- 上层MPC控制器:基于车辆动力学模型,计算所需的广义控制量(总驱动力矩和前轮转向角)
- 下层扭矩分配层:将总驱动力矩动态分配给四个电机
- Carsim车辆模型:提供高保真的六自由度车辆动力学仿真
code复制[期望轨迹] → [MPC控制器] → [扭矩分配算法] → [四轮独立电机] → [车辆状态]
↑ |
|________________________________________________|
2.2 关键数学模型
2.2.1 车辆动力学模型
采用经典的自行车模型(简化版):
code复制ẋ = v*cos(ψ+β)
ẏ = v*sin(ψ+β)
ψ̇ = r
ṙ = (aF_yf - bF_yr)/I_z
其中β为车辆侧偏角,F_yf和F_yr分别为前、后轴侧向力。
2.2.2 MPC预测模型
将上述非线性模型在工作点线性化后得到状态空间表达式:
code复制x(k+1) = A x(k) + B u(k)
y(k) = C x(k)
状态变量x=[y, ψ, ṙ, v_y]^T,分别表示横向位置、横摆角、横摆角速度和横向速度。
注意:实际实现时需要考虑纵向速度v_x的变化,这会导致A矩阵中的部分元素时变。常见的处理方法是假设v_x在一个控制周期内恒定,但需要设计速度观测器进行补偿。
3. 核心实现细节
3.1 MPC控制器实现
3.1.1 权重矩阵设计
代价函数采用标准二次型:
code复制J = Σ [x'(k)Qx(k) + u'(k)Ru(k)] + x'(N)Px(N)
经过多次调试,最终采用的权重矩阵为:
matlab复制Q = diag([10, 1, 0.5, 0.1]); % 更重视横向位置误差
R = 0.01*eye(2); % 控制量权重
P = Q; % 终端代价
3.1.2 约束处理
实际车辆存在物理限制:
matlab复制% 转向角约束
u_min = [-deg2rad(15); -2000];
u_max = [ deg2rad(15); 2000];
% 转向角速度约束
delta_u_min = [-deg2rad(5)/Ts; -1000];
delta_u_max = [ deg2rad(5)/Ts; 1000];
使用MATLAB的quadprog求解带约束的QP问题。
3.2 扭矩分配算法
3.2.1 基本分配策略
matlab复制function [torque_FL, torque_FR, torque_RL, torque_RR] = ...
torque_distribute(total_torque, mu, alpha, vx)
% 前轴分配系数随侧偏角变化
k_front = 0.6 * (1 - 0.2*abs(alpha));
% 考虑载荷转移
load_transfer = 0.1*vx^2/9.8; % 简化的载荷转移模型
k_front = k_front * (1 - 0.05*load_transfer);
torque_front = total_torque * k_front;
torque_rear = total_torque * (1 - k_front);
% 左右轮按摩擦系数动态调整
torque_FL = torque_front * (0.55 + 0.1*mu);
torque_FR = torque_front * (0.45 - 0.05*mu);
% 后轴分配考虑防滑
[torque_RL, torque_RR] = rear_torque_distribute(torque_rear, mu, alpha);
end
3.2.2 后轴防滑分配
matlab复制function [torque_RL, torque_RR] = rear_torque_distribute(torque_rear, mu, alpha)
% 轮胎力饱和特性
Fz_RL = 2000 - 50*alpha; % 简化载荷计算
Fz_RR = 2000 + 50*alpha;
% 最大可用扭矩
max_RL = mu * Fz_RL * R_wheel;
max_RR = mu * Fz_RR * R_wheel;
% 二次规划分配
H = diag([1/Fz_RL, 1/Fz_RR]);
f = zeros(2,1);
Aeq = [1, 1];
beq = torque_rear;
lb = [0; 0];
ub = [max_RL; max_RR];
options = optimoptions('quadprog', 'Display', 'off');
torque = quadprog(H, f, [], [], Aeq, beq, lb, ub, [], options);
torque_RL = torque(1);
torque_RR = torque(2);
end
3.3 Carsim-Matlab联合仿真
3.3.1 接口配置
-
在Carsim中设置输入变量:
- 前轮转向角
- 四个电机的驱动扭矩
-
输出变量配置:
- 车辆位置(x,y)
- 横摆角、横摆角速度
- 纵向/横向速度
- 四个车轮的滑移率
3.3.2 同步问题解决
matlab复制function sys = carsimInterface(u, t, ~)
persistent vp_handle last_time
if isempty(vp_handle)
vp_handle = vsb('open','xiLINK');
last_time = 0;
end
% 确保同步
while (t - last_time) < Ts - 1e-6
pause(0.001);
end
vsb('send', vp_handle, u);
state = vsb('get', vp_handle);
last_time = t;
sys = [state.y; state.psi; state.r; state.vy];
end
4. 调试经验与问题解决
4.1 典型问题记录
| 问题现象 | 原因分析 | 解决方案 |
|---|---|---|
| 高速时车辆振荡 | 预测模型中的v_x假设不成立 | 增加速度观测器,每5ms更新一次v_x |
| 急变道时内侧轮打滑 | 扭矩分配未考虑载荷转移 | 在分配算法中加入载荷转移补偿 |
| 联合仿真数据不同步 | Carsim和Simulink步长不一致 | 添加同步等待循环,如代码所示 |
| 低附着路面控制失效 | 轮胎力进入强非线性区 | 触发降级策略,切换为PID控制 |
4.2 参数调试技巧
-
MPC预测时域选择:
- 初始值:Np=20,Nc=5(对应1s预测时域)
- 调试方法:从短时域开始逐步增加,直到性能不再明显提升
- 最终值:Np=15,Nc=3(平衡实时性与性能)
-
权重矩阵调整:
matlab复制% 调试脚本示例 for q_y = logspace(0,2,5) Q(1,1) = q_y; sim('mpc_controller'); plot_results(); pause(1); end -
实时性优化:
- 将QP求解改为热启动
- 使用显式MPC(离线计算查找表)
- 对A矩阵进行提前计算和缓存
5. 进阶优化方向
-
路面坡度估计:
matlab复制function slope = estimate_slope(ax_meas, torque_total) persistent m g R_w if isempty(m) m = 1800; g = 9.8; R_w = 0.3; end ax_pred = sum(torque_total)/(m*R_w); slope = asin((ax_meas - ax_pred)/g); end -
轮胎参数在线辨识:
- 基于递归最小二乘法估计轮胎侧偏刚度
- 更新MPC模型中的Caf和Car参数
-
执行器故障容错:
- 当检测到某个电机故障时
- 重新构建B矩阵,将控制量分配到正常电机
这个项目最让我着迷的是控制理论与实际物理系统的互动过程。当你看到那些抽象的矩阵运算最终转化为车辆在仿真中的精准运动时,那种成就感无与伦比。特别是调试扭矩分配算法时,通过观察四个轮子的扭矩曲线如何协同变化来应对不同工况,就像在解一个动态的四人舞蹈编排问题。