ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于MPC的自适应巡航控制:从仿真到实车的完整实践

基于MPC的自适应巡航控制:从仿真到实车的完整实践 很多人一听到“自适应巡航控制”这六个字下意识觉得就是定速巡航加了个跟车功能前面慢了我也慢前面快了我也快听起来没什么技术含量。真把这个问题丢给控制工程师去做第一轮道路测试就会被按在地上反复摩擦——前车急刹你怎么跟加塞车辆切入你如何让走走停停堵车工况下乘客会不会晕车这些都是ACC项目里绕不开的硬骨头。我做整车纵向控制做了快十年在MPC模型预测控制上踩过不少坑也用它做过量产的自适应巡航控制项目。这篇博客就把我从仿真到实车、从理论到标定过程中积累的经验完整梳理一遍。内容主要面向做ADAS、自动驾驶规划控制算法的工程师或者正在从PID往MPC转型的研究生。文章里会给出可以直接抄作业的状态空间模型、QP目标函数、约束配置和一份实测过的基础参数表也整理了我在调参和实车测试中遇到的典型问题。看完之后你可以直接照着搭一个最小可用的MPC-ACC控制器再放到仿真环境里跑通完整跟车工况。1. 自适应巡航控制到底在解决什么问题1.1 从定速巡航到ACC控制目标发生了本质变化定速巡航的控制目标非常单一把车速稳定在驾驶员设定的值。这本质上是一个一维的跟踪问题PID就能解决得很好。但ACC一旦介入控制目标就从“跟踪车速”变成了“跟踪场景”——既要保证与目标车辆的安全间距又要保证不超过驾驶员设定的巡航速度还要在两者冲突时做出合理决策。这里就引出了ACC的核心模型——安全时距策略。最常见的公式是d_des d0 tau_h * v_ego其中d_des是期望跟车距离d0是停车时保持的最小间距一般取2到5米tau_h是车间时距常数量产车通常在0.8秒到2秒之间调整v_ego是自车车速。这个公式的含义很容易理解车速越高跟车距离要成比例拉大。以30m/s108km/h巡航、tau_h取1.2s、d0取5m为例期望跟车距离就是5 1.2*30 41米。这个距离在高速工况下是合理的但放到市区拥堵场景里就显得太保守容易被加塞。所以在量产标定中tau_h往往不是固定值而是按车速分段的查表函数——低速时收小一点高速时放大一点。这意味着ACC控制器的参考轨迹是动态变化的d_des跟随v_ego实时变化控制系统的状态方程里天然带有时变参考项给控制器提出了比定速巡航高得多的跟踪精度要求。1.2 为什么传统PID在ACC场景下不够用我在学校刚接触控制的时候也觉得PID是万能的直到做ACC项目吃过亏才彻底改变看法。PID在ACC上有几个结构性短板第一个短板是约束无法显式处理。ACC系统里充斥着硬约束加速度不能超过轮胎附着力极限一般舒适性要求是-3到2m/s^2紧急制动可以到-6、jerk加速度变化率不能太大否则乘客晕车、跟车距离不能小于安全下限。PID输出油门刹车的时候完全不考虑这些约束只能在外面套一堆if-else逻辑来限幅和防抖限幅之后控制品质会明显劣化。第二个短板是预测能力缺失。PID只有误差反馈没有前馈和预测能力。当前车突然以-6m/s^2减速时PID要等误差累积到一定程度才开始响应而这个响应延迟在高速工况下可能就是几米的距离损失。实车测试中你很容易遇到这种情况前车急刹ACC车辆反应慢半拍最终不得不触发AEB自动紧急制动体验非常糟糕。第三个短板是参数整定的噩梦。ACC工作在很宽的速度区间0到150km/h以上轮胎与地面的附着条件、风阻、坡道都在变化一套PID参数很难覆盖所有工况。于是要做增益调度按车速分段标定多组PID参数然后在切换点做平滑过渡标定工作量极大而且各段交界处容易出现控制量跳变。1.3 MPC凭什么能撑起ACC这种安全关键场景MPC的核心竞争力在于“看得远、算得清、管得住”。它会在每个控制周期内基于车辆模型预测未来一段时域内系统的状态轨迹然后求解一个带约束的优化问题把加速度、jerk、跟车距离等指标全部放进目标函数和约束里最后只取最优控制序列的第一步作用于系统下一个周期重新滚动优化。这个机制和人类驾驶员的决策方式高度相似。老司机开车不是只看当前车距而是会预判未来两三秒的交通态势前车刹车灯亮了提前松油门旁边车道车辆有并入趋势主动收速留出空间。MPC本质上就是在做这件事——用模型替代经验用优化替代判断。把MPC用在ACC上最直接的好处有三点。第一安全距离约束可以直接写进优化问题里从原理上保证任何时候都不会越界第二预测时域让控制器能提前响应前车的加速度变化急刹场景下的反应速度远快于PID第三所有性能指标跟车精度、舒适性、油耗以权重形式统一在一个代价函数里调参的过程就是调权重物理意义非常清晰。2. MPC核心思想拆解预测、滚动、反馈三板斧2.1 预测模型你拿什么去预测未来MPC的“预测”不是凭空猜测而是基于被控对象数学模型的外推。在ACC场景里被控对象是自车的纵向运动以及自车与前车的相对运动关系。建立一个足够描述动态、又足够简单的模型是MPC落地中最关键的环节。我常用的是一个四状态纵向动力学模型状态量定义为x [d, v_ego, v_rel, a_ego]。其中d是自车与前车的实际相对距离v_ego是自车车速v_rel是相对车速等于前车车速减去自车车速a_ego是自车加速度。控制输入u我取的是jerk也就是加速度的变化率。为什么要用jerk做输入而不是直接用期望加速度因为直接以加速度为控制量时目标函数里对jerk的约束需要额外做差分处理而以jerk为输入舒适性约束天然就落在控制量边界上问题更干净。在这个定义下连续时间状态方程可以写成d_dot v_rel v_ego_dot a_ego v_rel_dot a_lead - a_ego a_ego_dot u其中a_lead是前车加速度它在系统里是外部扰动。在MPC预测时域内我们通常假设前车加速度保持当前采样时刻的值不变——这个假设不完美但目前工程上最实用。更激进的做法是把前车加速度建模为一阶惯性衰减过程但会增加状态维度和调参复杂程度对性能提升并不显著。离散化这一步用最简单的欧拉法就行采样周期Ts取100ms对于ACC这种带宽只有零点几赫兹的纵向控制场景精度完全够。离散后的模型长这样d(k1) d(k) Ts * v_rel(k) v_ego(k1) v_ego(k) Ts * a_ego(k) v_rel(k1) v_rel(k) Ts * (a_lead(k) - a_ego(k)) a_ego(k1) a_ego(k) Ts * u(k)在实际量产项目中这里还会加一个一阶惯性环节来描述执行器延迟。因为从控制器发出加速度请求到底盘真正响应中间隔着发动机/电机的响应时间、制动的建压时间通常有0.2到0.5秒的滞后。把滞后建模进去能显著降低实车调参的试错成本但教学和仿真的第一步上面这个模型就足够了。2.2 滚动优化为什么每次都只走一小步MPC在每一个控制周期做的事可以归纳为一句话在满足所有约束的前提下求解一组最优的未来控制序列使得未来一段时域内系统的状态轨迹尽可能接近期望目标。这段“未来一段时域”叫预测时域Np“最优控制序列”的长度叫控制时域Nc。需要强调的是MPC并不是把这一步解出来的整个控制序列一股脑全执行完。它只执行序列中的第一步然后下一个采样周期重新测量状态、重新求解优化问题。这个过程叫滚动优化Receding Horizon。滚动带来的好处是抗干扰和抗模型失配。因为每一次优化都会基于最新的测量状态重新出发模型预测误差不会不断累积而是被周期性修正。用一个生活化的例子帮助理解你开车去一个陌生的目的地导航的路线规划相当于一次全局优化但实际行驶中你不会完全迷信预规划路线而是每到一个路口结合实时路况重新计算接下来怎么走。MPC就是这样预测时域相当于导航看得到的前方道路而每次重规划就是滚动的过程。预测时域Np越长控制器“看得越远”越容易提前决策但计算量更大、对模型精度的要求也更高。在ACC中Np通常取10到30步对应1到3秒。配合100ms的采样周期10步刚好是1秒20步是2秒。体验上2秒的预测能力在100km/h巡航时意味着你可以提前约55米开始感知前车动态这个提前量已经非常可观了。2.3 反馈校正预测错了怎么办模型永远是模型的简化MPC从来不敢百分百相信模型预测的结果。所以在每个控制周期开始的时候MPC要把真实的测量状态作为优化问题的初始条件。不管你上一周期预测得准不准这一周期的优化一定是从当前实测状态出发这就形成了一种隐式的闭环校正。这种反馈机制的价值在实车上体现得非常明显。轮胎打滑导致加速度响应异常、传感器噪声导致相对距离测量波动、坡道导数模型偏差这些不可预测的因素都会让预测模型失效。如果控制器没有闭环的刷新机制模型误差会在多个控制周期内不断累积最终导致系统发散。而MPC的滚动优化天然自带校正能力因为每一步都把实际状态拉回到优化起点。这也是MPC比开环最优控制Robust的根本原因。在实际工程实现中还有一层更显式的校正手段值得做。预测模型通常会对状态做一步预测而这一步预测值往往在下一周期初被测量值覆盖。这时候可以对预测输出与实际测量之间的偏差做一个低通滤波然后再用于后续时域的预测能进一步抑制传感器周期性的噪声。我在实车项目中试过这个操作对低速走走停停工况的稳定性提升非常明显。3. 基于MPC的ACC控制器完整设计3.1 状态空间模型与离散化搭建我们直接进入实操。首先把上面的四状态连续模型整理成标准状态空间形式。定义状态向量x(k) [d(k), v_ego(k), v_rel(k), a_ego(k)]^T控制输入u(k)为jerk外部扰动w(k) a_lead(k)。状态方程矩阵形式如下x(k1) A * x(k) B * u(k) G * w(k)其中离散后的矩阵为A [[1, 0, Ts, 0], [0, 1, 0, Ts], [0, 0, 1, -Ts], [0, 0, 0, 1]]B [[0], [0], [0], [Ts]]G [[0], [0], [Ts], [0]]这个模型在MATLAB、Simulink里很好搭在Python里用NumPy定义也不复杂。关键是每一列的含义要对得上尤其是第三行相对速度v_rel的更新里同时出现了前车加速度扰动项和自车加速度状态项这一项决定了MPC对未来相对位置演化的预测精度。在预测时域内MPC需要用这个递推形式从初态x(k)出发逐步算出未来Np步的状态序列。这个迭代过程可以用矩阵形式一次性算出来也就是构造预测矩阵Phi和Gamma也可以像我在下面代码示例里那样逐循环递推。两种方式得到的结果一样构造预测矩阵的形式计算更快适合C代码部署循环递推的形式可读性更好适合快速原型验证。3.2 目标函数、约束条件与权重设计MPC-ACC的优化问题可以写成min Σ_{i0}^{Np-1} [ q1 * (d(ki|k) - d_des(ki|k))^2 q2 * v_rel(ki|k)^2 q3 * a_ego(ki|k)^2 ] Σ_{i0}^{Nc-1} r * u(ki|k)^2subject to: u_min u(ki|k) u_max, i 0, ..., Nc-1 a_min a_ego(ki|k) a_max, i 1, ..., Np d(ki|k) d_min 0 v_ego(ki|k) v_set我来逐项解释这个目标函数的物理含义。第一项是跟车距离误差惩罚q1越大控制器越积极地把实际车距拉向期望车距第二项是相对车速惩罚q2越大越希望尽快消除相对速度让跟车平稳第三项是自车加速度惩罚q3越大加速度越克制乘坐越舒适最后一项是控制输入jerk的惩罚r越大油门和刹车的切换越平缓。这四项之间是互相矛盾的。q1调大则跟车紧但车速跟随剧烈q3调大则加速度平淡但车距误差收敛慢。所以权重设计的本质是不同性能指标之间的取舍没有绝对正确的组合只有针对场景最合适的组合。以我做过的高速ACC项目为例初始权重我一般从q10.8、q20.5、q30.1、r0.3开始然后按工况微调。约束方面也需要详细说。加速度的上下限要区分舒适性与极限性能。一般舒适性加速度约束是-3到2m/s^2但为了应对前车急刹我倾向于把约束放宽到-5到3m/s^2用jerk约束来保证舒适性——即使加速度上限大只要jerk小乘客也不会感到突兀。jerk约束来自人体工学实验表明超过2.5m/s^3的jerk会让乘客明显不适所以我把jerk限制在-2到2m/s^3。距离下限d_min建议取1到2米给传感器噪声和模型误差留一点余量。3.3 模型预测控制关键参数初选参考表为了让新手少走弯路我把一套经过仿真和实车初步验证过的参数列成表格可以直接作为起点再根据具体场景微调。参数符号初选值调整方向采样周期Ts100ms实车响应慢可放宽到200ms追求激进响应可收窄到50ms预测时域Np20步2秒高速工况取25-30步市区低速工况取10-15步控制时域Nc5步控制时域越大越激进一般不超过Np的一半车间时距tau_h1.2s高速1.5-2.0s市区防加塞0.8-1.0s停车间距d05m根据传感器盲区和执行器延迟调整跟车误差权重q10.8想要跟车更紧就加大相对速度权重q20.5出现频繁加速减速时适当加大加速度惩罚q30.1乘员反馈不适时加大jerk惩罚r0.3希望油门刹车更平顺时加大加速度下限a_min-5 m/s^2舒适性优先时收窄至-3加速度上限a_max3 m/s^2动力性优先时可到4jerk限值u_min/u_max±2 m/s^3激烈驾驶场景可放宽至±3关于这个表格我想特别强调一点这套初始参数不是拍脑袋给的。Np20配合Ts100ms对应2秒预测时域在高速工况100km/h巡航下意味着约55米的预瞄距离正好覆盖驾驶员典型反应距离与制动距离之和。jerk限值±2 m/s^3来自ISO标准和大量乘客主观评价实验的数据不是经验主义。ACC的调参很多时候不是找最优解而是在安全性、舒适性和交通效率之间找那个你最能接受的妥协点。4. 从仿真到实车关键实现环节与实验之旅4.1 用Python写一个最小可用的MPC-ACC控制器理论讲再多不如跑一段代码来得直观。我用Python和cvxpy库写了一个最小可用的MPC-ACC核心函数。cvxpy的优势是可以直接把目标函数和约束按数学形式表达不用手动做QPsolver的矩阵拼装非常适合原型验证。部署到实车时再用手写的QP求解器替换掉cvxpy但算法逻辑完全一样。import numpy as np import cvxpy as cp Ts 0.1 # 采样周期 100ms Np 20 # 预测时域 Nc 5 # 控制时域 # 控制器配置参数 tau_h 1.2 # 车间时距 d0 5.0 # 停车安全距离 a_min, a_max -5.0, 3.0 u_min, u_max -2.0, 2.0 d_min 1.0 # 最小跟车距离 # 目标函数权重 q1 0.8 q2 0.5 q3 0.1 r 0.3 def mpc_acc(d_meas, v_ego_meas, v_rel_meas, a_ego_meas, a_lead_meas, v_set): 基于MPC的自适应巡航控制核心函数 输入: 当前测量状态 (d, v_ego, v_rel, a_ego)前车加速度设定车速 输出: 最优控制输入 u (jerk)以及期望加速度 a_des # 定义优化变量控制输入序列 u cp.Variable(Nc) # 定义预测状态矩阵 x cp.Variable((Np1, 4)) x0 np.array([d_meas, v_ego_meas, v_rel_meas, a_ego_meas]) constraints [x[0, :] x0] for i in range(Np): if i Nc: u_act u[i] else: u_act u[Nc-1] # 预测时域后半段保持最后一个控制量 constraints [ x[i1, 0] x[i, 0] Ts * x[i, 2], # 距离更新 x[i1, 1] x[i, 1] Ts * x[i, 3], # 自车速度更新 x[i1, 2] x[i, 2] Ts * (a_lead_meas - x[i, 3]), # 相对速度更新 x[i1, 3] x[i, 3] Ts * u_act, # 加速度更新 ] # 距离约束 constraints [x[1:, 0] d_min] # 加速度约束 constraints [x[1:, 3] a_min, x[1:, 3] a_max] # 自车速度约束 constraints [x[1:, 1] 0, x[1:, 1] v_set] # 控制量约束 constraints [u u_min, u u_max] # 期望车距动态计算d_des d0 tau_h * v_ego d_des d0 tau_h * x[:, 1] # 目标函数 cost 0.0 for i in range(Np): cost q1 * cp.square(x[i, 0] - d_des[i]) # 跟车距离误差 cost q2 * cp.square(x[i, 2]) # 相对速度 cost q3 * cp.square(x[i, 3]) # 加速度 for i in range(Nc): cost r * cp.square(u[i]) # jerk problem cp.Problem(cp.Minimize(cost), constraints) problem.solve(solvercp.OSQP) if problem.status in (optimal, optimal_inaccurate): u_opt u.value[0] a_des a_ego_meas Ts * u_opt return u_opt, a_des else: # 求解失败时回退到安全策略 return 0.0, a_ego_meas这段代码里有几个细节要说明。预计状态矩阵x规模是21×4也就是每个预测步都有四个状态变量。约束递推时当索引i大于等于Nc后我用了Nc-1的控制量——这个操作很关键否则预测时域里的后半段控制量没有定义。目标函数里的d_des是随v_ego动态变化的由于v_ego是优化变量所以整个问题依然是一个凸二次规划可以由OSQP高效求解。实车部署时这个函数会被一个固定频率10Hz的定时器循环调用。每次调用时把当前传感器测得的状态塞进去得到u_opt和a_des然后a_des会传给底层的执行器控制器。我实际测试过这个代码在工业级Linux控制器上单次求解耗时约1毫秒左右远小于100ms的控制周期时间预算非常充裕。4.2 典型工况仿真前车急减速、跟停与重新起步我搭了一个简单的仿真环境来验证这个控制器的行为。场景设置如下自车以30m/s108km/h巡航前车初始速度也是30m/s。第5秒前车开始以-4m/s^2的减速度制动减速到5m/s后保持匀速第20秒开始再以2m/s^2加速度重新起步。仿真结果中最值得关注的是前车开始制动的瞬间。由于MPC内部预测了未来2秒的状态轨迹它会在车距误差还很小的时候就感知到前车减速带来的相对速度趋势提前进入制动工况。实测下来MPC控制器的制动介入时间比纯PID反馈控制器提前了大约0.3到0.4秒别小看这零点几秒在高速工况下对应的距离差接近10米这往往是能否避免触发AEB的关键。跟停工况同样表现稳定。前车完全停下来之后MPC会把自车平滑地停在距前车约5米的位置满足d0的设定。因为停车后相对速度为零、相对距离等于期望距离目标函数达到最小值控制器会输出零控制量系统进入稳态。重新起步阶段由于d_des随着v_ego增大而增大MPC会平滑施加正向jerk让自车逐步提速整个过程中加速度的峰值不超过2m/s^2乘客不会有被一脚油门踹出去的感觉。我在仿真中还特意加了一种极限场景前车以-8m/s^2的接近极限减速度制动。这时候MPC会在约束允许的范围内a_min-5m/s^2全力制动同时因为jerk限制制动力是渐进建立的而不是瞬间到位。这个渐进过程在物理上非常重要突然踩死刹车不仅让乘客极度不适还会导致轮胎抱死。实际测试中这种场景往往需要AEB系统作为最后兜底但MPC的存在显著降低了AEB被触发的频率。4.3 从仿真到实车要补哪些课仿真跑通了只是万里长征走完第一步从仿真到实车之间的鸿沟我栽过的跟头比写过的代码还多。第一个要解决的是求解器的实时性问题。cvxpy在PC上跑得很好但到了实车ECU上你必须换成C语言实现的手写QP求解器。比较成熟的选择有qpOASES和OSQP的嵌入式版本两者都支持代码生成和固定迭代次数可以精确控制每个控制周期的计算耗时。第二个问题更隐蔽执行器延迟。仿真里你发出jerk命令加速度立刻变实车里从指令到底盘响应有几百毫秒的延迟。解决方式我在前面提过就是在模型里加一阶惯性环节。我个人习惯是把执行器延迟模型写成a_ego_dot (u - a_ego) / tau_exec其中tau_exec是等效执行器时滞刹车工况取0.3秒左右。这个改进对仿真结果的影响不大但对实车稳定性的影响是决定性的。第三个问题是传感器噪声和测量滞后。毫米波雷达测得的相对距离和相对速度噪声都不小尤其在小距离时测量值跳动明显。实车项目中我加了一个卡尔曼滤波器来做状态估计把雷达和IMU的数据融合成干净的状态输入再送给MPC。如果你只是做仿真这一步可以跳过但做实车必须处理否则高频噪声会让控制器做出非常神经质的加速减速决策。最后一个比技术更重要的点是安全兜底逻辑。MPC再聪明也会有模型失配、极端工况超出约束假设的可能。实车开发一定要保留一套独立于MPC的安全监控模块检测到MPC求解失败、输出异常或者与模型预测偏差过大时立即切换到保守策略或请求驾驶员接管。这套安全逻辑不难得但它决定了你的系统能不能上路。5. 常见问题与调参避坑实录5.1 控制器振荡、反复加油刹车怎么排查运行MPC-ACC时最常见的问题就是控制器输出上下跳动车辆表现为反复加油、松油、刹车乘客体验极差。这个问题我在仿真阶段几乎逢调必遇原因无外乎以下几类按排查顺序排列第一检查权重比例。q1跟车距离误差权重和q2相对速度权重之间如果失衡最常见的错误是q1太大、q2太小导致控制器对车距误差过度敏感。车距稍微偏离期望值就猛加油或猛刹车加速-超调-减速-再超调形成振荡。我的经验是最先查q2相对速度的惩罚必须足够压住跟车误差调节过程中产生的动力冲击。第二检查jerk惩罚r。r太小意味着控制器不心疼jerk它会选择极快的加速度变化来消除误差。这种方案在数值仿真里看很完美误差收敛得又快又准但实车表现就是一顿一顿的。当q1和q2都正常但车辆仍然不平顺时优先把r调大。第三检查预测时域Np。Np太短的时候MPC实际上变成了一个近视眼它看不到远期后果于是每个控制周期都只顾眼前最优导致决策前后不一致宏观上呈现为振荡。这个问题最容易判断把Np从20加到30如果振荡明显缓解那基本可以确诊。还有一类特殊问题跟求解器有关。OSQP求解半正定问题时偶尔会返回一个次优解而且这个解与控制周期之间有跳变。我遇到过明明所有参数都正常但控制器仍偶发抖动的情况最后发现是求解器收敛精度设置太松。把OSQP的eps_abs和eps_rel从默认的1e-3收紧到1e-5问题就消失了。这个细节很偏门但排查成本极低值得一试。5.2 约束过紧导致优化无解怎么办MPC-AAC在极限工况下有一个非常头疼的数学问题优化问题无解。典型场景是前车以极限减速度紧急制动自车已经以最大减速度制动但车距仍然在缩小——此时距离下限d_min与加速度下限a_min产生了冲突没有任何控制序列能满足所有约束。处理这个问题的标准做法是引入松弛变量Slack Variable。把强约束变成软约束允许在极端情况下暂时突破距离下限但要为这个突破付出极大的代价。在目标函数末尾加上一个大权重M乘以松弛变量的平方项M通常取正常目标函数量级的100到1000倍。这样优化问题永远可解而求解结果会优先保住所有硬约束只在无路可走时才允许突破软约束。操作上我会把安全距离约束和加速度约束区分开处理。最终车速上限v_set是政策硬约束不可以突破加速度上下限可以稍微放宽距离下限是柔性约束用松弛变量处理。这种分级处理方案既保证了行车安全底线又保证了算法的数值稳定性。实车标定时这套策略帮了大忙我用它扛过了很多传感器异常和极端场景测试。5.3 乘坐舒适性与通行效率的平衡艺术ACC的调参本质上是在舒适性、跟车效率和安全性三者之间找平衡。乘客要的是丝般顺滑的加速减速交通效率要的是车距够近、跟车够紧安全底线要求的是距离余量充足。三者天然冲突MPC的权重参数就是你表达取舍倾向的语言。我在实车标定时总结的经验是分工况处理。高速巡航场景时速80km/h以上安全是第一优先级tau_h取1.5秒以上jerk限制控制到±1.5m/s^3倾向让乘坐体验尽量柔和。市区低速跟车场景车速低于40km/h通行效率的重要性上升tau_h可以收紧到0.8到1.0秒但jerk限制反而不能放松因为市区走走停停的加减速频率高jerk稍大就晕车。高速公路拥堵蠕行场景是最难调的车速很低但油门刹车切换极频繁我倾向于在这里用更大的q2和更小的q1让控制器优先缓和相对速度的波动而不是死磕距离误差。还有一个很有用的小技巧让期望车间时距tau_h跟随驾驶风格和场景实时调整。我在量产项目中通过方向盘按键或中控界面提供了三档设置运动模式tau_h0.8s、标准模式tau_h1.2s、舒适模式tau_h1.8s用同一个MPC控制器只改变tau_h参数就能映射出截然不同的驾驶性格。这套方法让ACC在同一个算法框架下满足了不同用户群体的偏好标定工程师也不用为每个模式单独维护一套权重了。最后再分享一个我在项目后期才领悟到的经验。MPC-ACC的参数永远不要追求理论上的最优而要追求在极端情况下依然“体面”的那组值。什么叫体面就是当前车突然切入时系统不像受过惊吓一样猛踩刹车而是在安全前提下尽量平滑地让出空间当前车离开车道时系统不激动地猛加速追赶设定车速而是渐进地恢复巡航。这些微妙的行为差异权重配比只起一半作用另一半来自约束太紧时怎么松弛、预测太远时怎么取舍的经验。多跑几种极端场景多记录控制器在“犹豫”时刻的表现你的调参手感会很快建立起来。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进