CarSim仿真程序中的MPC自动驾驶轨迹跟踪控制:从原理到实践

1次阅读
没有评论

共计 2304 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

背景痛点

在自动驾驶轨迹跟踪领域,传统 PID 控制存在明显局限性:

  1. 预测能力缺失 :PID 是纯反馈控制,无法预判未来轨迹变化,面对急弯或连续 S 形路段时容易超调
  2. 约束处理困难 :难以直接融入轮胎力饱和、转向角限制等物理约束
  3. 耦合问题 :横向和纵向控制通常需要独立设计,协调性较差

而 MPC(模型预测控制)凭借以下优势成为更优选择:

  • 前馈 + 反馈结合 :基于动力学模型预测未来多步状态
  • 显式处理约束 :将控制量、状态量约束直接写入优化问题
  • 多目标优化 :通过权重矩阵平衡跟踪精度与控制消耗

技术实现

1. MPC 数学模型构建

车辆模型(线性化自行车模型)

\begin{cases}
x_{k+1} = x_k + v_k \cos(\psi_k) \Delta t \\
y_{k+1} = y_k + v_k \sin(\psi_k) \Delta t \\
\psi_{k+1} = \psi_k + \frac{v_k}{L_f} \delta_k \Delta t \\
v_{k+1} = v_k + a_k \Delta t
\end{cases}

其中 $(x,y)$ 为车辆坐标,$\psi$ 为航向角,$\delta$ 为前轮转角,$L_f$ 为轴距

目标函数设计

\min \sum_{i=1}^{N_p} \| y_{ref} - y_i \|_Q^2 + \sum_{i=0}^{N_c-1} \| \Delta u_i \|_R^2

$N_p$ 为预测时域,$N_c$ 为控制时域,$Q/R$ 为权重矩阵

2. CarSim 联合仿真配置

S-Function 接口流程

  1. 在 CarSim 中配置 VS_Comm 模块输出车辆状态(X/Y/Yaw/Vel)
  2. 将 MPC 控制器编译为 S -Function(需 VS2015 以上)
  3. 通过 Simulink Real-Time 模块连接 CarSim RT

关键参数配置

[VS_API]
采样周期 = 0.02s   # 建议与控制器保持一致
输出通道 = 4,5,14,18  # X,Y,Yaw,Vx

3. 代码实现示例

Python 版(CasADi 库)

import casadi as ca

# 构建 QP 问题
opti = ca.Opti()
X = opti.variable(N_p, 4)  # 状态变量
U = opti.variable(N_c, 2)  # 控制量 (加速度, 转向)

# 目标函数
cost = 0
for i in range(N_p):
    cost += (X[i,0]-xref[i])**2 * Q[0]  # X 误差
    cost += (X[i,1]-yref[i])**2 * Q[1]  # Y 误差

# 动力学约束
for k in range(N_p-1):
    x_next = vehicle_model(X[k,:], U[k//step_ratio,:])
    opti.subject_to(X[k+1,:] == x_next )

# 控制量约束
opti.subject_to(opti.bounded(-3, U[:,0], 3) )  # 加速度限制
opti.subject_to(opti.bounded(-0.6, U[:,1], 0.6) )  # 转向角限制

# 求解
opti.solver('ipopt')
sol = opti.solve()

C++ 版(OSQP 求解器)

#include <osqp/osqp.h>

// 构造 QP 矩阵
Eigen::SparseMatrix<double> P(2*N_c, 2*N_c);
Eigen::VectorXd q = Eigen::VectorXd::Zero(2*N_c);

// 填充 P 矩阵(示例)for(int i=0; i<N_c; i++){P.insert(i,i) = R_accel;
    P.insert(N_c+i, N_c+i) = R_steer;
}

// OSQP 求解
OSQPSolver solver;
OSQPSettings settings;
osqp_set_default_settings(&settings);
settings.eps_abs = 1e-5;

OSQPData *data = osqp_data_form(P, q, A, l, u);
osqp_setup(&solver, data, &settings);
osqp_solve(&solver);

避坑指南

1. 采样时间选择

  • CarSim 端 :建议 0.01~0.05s,过大会导致仿真失真
  • MPC 端 :需满足 $N_p \times \Delta t \geq$ 车辆制动距离 / 转向响应时间

2. 权重调参经验

参数 影响 典型初值
Q_x X 跟踪权重 1.0
Q_y Y 跟踪权重 2.0
R_a 加速度惩罚 0.1
R_δ 转向惩罚 0.5

调试技巧
1. 先调大 Q 使跟踪误差收敛
2. 逐渐增加 R 直到控制量无剧烈抖动
3. 高速场景需降低 Q_y 防止横向振荡

3. 数值稳定性问题

  • 现象 :CarSim RT 模式下出现控制量 NaN
  • 解决方案
  • 检查 QP 求解器返回状态
  • 添加控制量滤波(一阶低通滤波)
  • 限制 Hessian 矩阵条件数(OSQP 设置 rho=1e-6

性能验证

圆形轨迹跟踪(半径 50m,车速 60kph)

指标 PID MPC
最大横向误差 1.2m 0.3m
RMS 误差 0.8m 0.15m
转向角波动 ±12° ±5°

8 字形轨迹(车速 30kph)

CarSim 仿真程序中的 MPC 自动驾驶轨迹跟踪控制:从原理到实践

延伸思考

可以尝试以下进阶方向:
1. LSTM-MPC 融合 :用 LSTM 预测未来 3s 的参考轨迹
2. 参数自适应 :根据曲率动态调整 Q 矩阵
3. 多速率控制 :横向(20Hz)+ 纵向(10Hz)独立控制

完整工程代码已开源:github.com/yourname/carsim_mpc_demo

实践感受

在实际调试中发现,MPC 对车辆模型的准确性非常敏感。最初使用简单的运动学模型时,在高速弯道会出现明显的跟踪滞后。后来改用考虑轮胎侧偏刚度的动力学模型后,80kph 下的最大误差从 1.1m 降到了 0.4m。建议新手先从低速场景(<30kph)开始验证,再逐步提高难度。

正文完
 0
评论(没有评论)