无人驾驶MPC模型预测控制:从建模到代码落地实战

发布时间:2026/10/12 8:37:50
无人驾驶MPC模型预测控制:从建模到代码落地实战
简介这份资料是北京理工大学「无人驾驶车辆模型预测控制」第二版配套程序代码面向智能交通、自动驾驶方向的学习者与研究人员用于理解并实践MPC在无人车路径规划、速度控制与避障中的落地细节。压缩包共349个文件约1.52MB以h头文件、m脚本、mat数据、c源码、obj目标文件、lib库、mak工程配置及mdl/sim仿真模型为主另含bat批处理、mexw64与mol等文件覆盖车辆动力学建模、预测模型、在线优化求解、控制律生成与仿真验证等模块。内容预览可见双积分速度控制、非线性设定距离、MISO与噪声场景等MPC仿真入口便于对照代码梳理算法结构。目前已有780人学习下载适合希望从理论走向工程实现、锻炼建模与优化求解能力的读者研读与复现。1. 从公式到方向盘模型预测控制到底在车里干什么很多人第一次翻开《无人驾驶车辆模型预测控制》这类教材翻到第二版新增的动力学推导部分就卡住了——公式能看懂但不知道这些矩阵到底对应车上哪个零件。我当年也是这么过来的后来在仿真环境里把代码跑通、看着车辆轨迹从画面上歪歪扭扭地收敛到参考线才算真正理解 MPC 在无人驾驶里的位置。它本质上是一个滚动优化的控制器每个控制周期用当前状态往前预测未来 N 步解一个带约束的优化问题只取第一步控制量执行下一周期再重新来一遍。这套逻辑解决的是轨迹跟踪里的核心矛盾——既要跟得紧又要满足前轮转角限制、加速度限制这些物理约束。适合谁看做自动驾驶规控方向的工程师、车辆工程专业做毕设的学生、以及想把 MPC 从 MATLAB 搬到 Python 或 C 的开发者。下面我按建模→离散化→求解→调参→避坑的顺序把这条链路拆开讲。2. 车辆运动学与动力学建模两种模型怎么选、参数怎么定2.1 运动学自行车模型的最小实现做 MPC 的第一步是选模型。运动学自行车模型把车辆简化为前后两个轮子假设轮胎无侧滑状态量取[x, y, θ]控制量取[v, δ]速度与前轮转角。它的连续时间微分方程是ẋ v·cos(θ) ẏ v·sin(θ) θ̇ v·tan(δ)/L其中 L 是轴距。这个模型在低速一般 5 m/s 以下场景足够用泊车、园区低速巡航都能跑。我一般会先用它把 MPC 框架搭起来因为状态量少、雅可比矩阵好推、调试时容易定位问题。下面是一个 Python 里做前向欧拉离散化的最小代码import numpy as np def kinematic_model(state, control, L, dt): 运动学自行车模型离散化 state: [x, y, theta] control: [v, delta] L: 轴距 (m) dt: 采样周期 (s) x, y, theta state v, delta control # 前向欧拉dt 较小时精度够用 x_next x v * np.cos(theta) * dt y_next y v * np.sin(theta) * dt theta_next theta v * np.tan(delta) / L * dt return np.array([x_next, y_next, theta_next])逻辑说明这里用前向欧拉而不是龙格库塔是因为 MPC 内部要反复调用这个函数做预测计算量敏感当 dt 取 0.05~0.1 s 时欧拉法的截断误差在厘米级对轨迹跟踪影响可忽略。参数上L 必须和实际车辆一致差 0.1 m 在高速下就会带来明显跟踪偏差dt 不建议大于 0.1 s否则离散化误差会累积。2.2 动力学模型什么时候必须上当车速超过 10 m/s或者路面附着系数低、需要处理侧偏时运动学模型就不够了。第二版教材里重点补充了动力学模型状态量扩展到[x, y, θ, vx, vy, ω]控制量仍是[前轮转角, 纵向力]。它的核心是把轮胎侧偏力用线性或魔术公式建模再代入车身动力学方程。选型判断标准很简单如果你的仿真场景里出现了明显甩尾、或者参考轨迹曲率对应的侧向加速度超过 0.3g就该换动力学模型。代价是状态维度翻倍QP 求解时间大概增加 2~3 倍实时性要重新评估。2.3 参数标定的三个关键量不管用哪种模型有三个参数必须实测或查车辆手册确认轴距 L、质心到前轴距离 a、质心到后轴距离 b。很多人直接拿默认值凑结果仿真里跟得好好的上车就偏。我一般会做一组定圆测试让车以固定转角跑一圈用轨迹半径反推等效轴距误差能压到 2% 以内。3. 把优化问题写成代码目标函数、约束与求解器落地3.1 目标函数的三项权重怎么配MPC 的目标函数通常由三部分组成跟踪误差项、控制量变化率项、控制量幅值项。写成矩阵形式是J Σ (x_k - x_ref)ᵀ Q (x_k - x_ref) Σ u_kᵀ R u_k Σ Δu_kᵀ S Δu_kQ 管跟踪精度R 管控制量大小S 管控制平滑度。经验配比先设 Q 为单位阵R 取 0.1~1S 取 R 的 5~10 倍。如果轨迹跟踪出现高频抖动优先加大 S如果转弯时明显切内弯加大 Q 里对应横向误差的权重。下面是一个用cvxpy搭 QP 的骨架import cvxpy as cp import numpy as np def build_mpc(N, nx, nu, A, B, Q, R, S, x0, x_ref): N: 预测时域 nx, nu: 状态/控制维度 A, B: 离散化后的状态空间矩阵 Q, R, S: 权重矩阵 x0: 当前状态 x_ref: 参考轨迹序列, shape (N1, nx) x cp.Variable((nx, N 1)) u cp.Variable((nu, N)) cost 0 constraints [x[:, 0] x0] for k in range(N): cost cp.quad_form(x[:, k] - x_ref[k], Q) cost cp.quad_form(u[:, k], R) if k 0: cost cp.quad_form(u[:, k] - u[:, k-1], S) constraints [x[:, k1] A x[:, k] B u[:, k]] # 控制量约束示例 constraints [cp.abs(u[0, :]) 0.5] # 前轮转角限幅 constraints [u[1, :] -3, u[1, :] 2] # 加速度限幅 prob cp.Problem(cp.Minimize(cost), constraints) prob.solve(solvercp.OSQP, warm_startTrue) return u[:, 0].value逻辑说明这里用warm_startTrue是关键MPC 相邻周期的解高度相似热启动能把求解时间压到冷启动的 30%~50%。约束里前轮转角限幅 0.5 rad 对应约 28 度是常见乘用车的物理极限加速度范围按舒适性取的急刹场景可以放宽到 -5。注意x_ref的长度是 N1因为状态从 k0 到 kN 共 N1 个点。3.2 离散化方法的选择连续模型转离散常用零阶保持ZOH或前向欧拉。ZOH 精度高但需要矩阵指数运算前向欧拉简单但要求 dt 小。我一般用scipy.signal.cont2discrete做 ZOH代码如下from scipy.signal import cont2discrete import numpy as np def discretize(Ac, Bc, dt): 零阶保持离散化 C np.eye(Ac.shape[0]) D np.zeros((Ac.shape[0], Bc.shape[1])) Ad, Bd, _, _, _ cont2discrete((Ac, Bc, C, D), dt, methodzoh) return Ad, Bd参数说明methodzoh适合采样周期固定的数字控制器如果 dt 大于系统最小时间常数的 1/10ZOH 也会失真这时要么减小 dt要么改用更精确的模型。3.3 求解器选型与实时性常见 QP 求解器有 OSQP、qpOASES、HPIPM。OSQP 对稀疏问题友好、Python 接口成熟适合原型验证qpOASES 在嵌入式上更常见C 版本实时性稳定。实测在 N20、状态维度 6 的情况下OSQP 单次求解约 2~5 ms满足 100 Hz 控制周期。如果超过 10 ms先查预测时域是不是设太大N 从 20 降到 15 往往能省一半时间跟踪精度损失有限。4. 避坑与排查那些让轨迹画歪的细节4.1 现象车辆在参考线附近高频抖动原因控制量变化率权重 S 太小或者预测时域 N 太短导致控制器短视。解决先把 S 调到 R 的 10 倍再把 N 从 10 加到 20抖动基本消失。如果还抖检查参考轨迹是不是本身有噪声做一次滑动平均滤波。4.2 现象转弯时车辆切内弯稳态误差大原因Q 矩阵里横向误差权重不足或者模型里没考虑曲率前馈。解决把 Q 中对应 y 的权重从 1 提到 5~10同时在参考轨迹里加入曲率前馈项让控制器提前打方向。4.3 现象求解器报 infeasible原因约束太紧比如前轮转角限幅 0.3 rad 但参考轨迹需要 0.5 rad 才能跟上。解决先放宽约束验证可行性再逐步收紧或者把硬约束改成软约束加松弛变量并惩罚松弛量。4.4 现象仿真跟得好实车偏差大原因模型参数和实车不一致最常见的是轴距和质量分布。解决做定圆和直线加减速测试反推等效参数同时检查控制周期是否和仿真一致实车抖动会导致 dt 不稳。4.5 现象低速时正常高速时发散原因用了运动学模型但车速超过适用范围。解决切换到动力学模型或者把运动学模型里的速度项做线性化处理但后者只在 8 m/s 以下有效。5. 从仿真到落地的进阶技巧热启动、变时域与代码移植把 MPC 跑通只是第一步真正上车还要解决实时性和鲁棒性。我常用的两个技巧一是热启动加变时域低速时 N 取 20 保证精度高速时降到 10 保证实时性切换时用上一周期的解做初值求解时间能稳定在 3 ms 以内。二是把 Python 原型移植到 C 时用 Eigen 做矩阵运算、qpOASES 做求解注意 Python 里的numpy切片在 C 里要改成块操作否则性能会掉一个数量级。验证方法上我习惯先做开环测试给定一组控制序列看预测轨迹和实际轨迹是否重合再做闭环测试跑双移线和蛇形工况记录横向误差 RMS一般要求小于 0.1 m。最后提醒一句别在没做参数标定的情况下直接上车我见过太多因为轴距填错导致原地画圈的案例。希望帮到你。本文还有配套的精品资源点击获取