标签: 控制执行

  • 纵向 MPC 候选合成:10 秒 12 段时域与最小加速度选择

    结论:纵向规划器每帧把 MPC 目标加速度、巡航候选和实验模式的 e2e 候选放在一起,取最小加速度作为 aTarget,但 shouldStop 是对全部候选求或——所以两者可能来自不同候选,不能按单一来源重构。最终还要裁到车型接口常量 ACCEL_MIN=-3.5、ACCEL_MAX=2.0,再交给 LongControl。本文为固定源码快照 c8fb906 的静态分析,数学建模说明不等于数值收敛或车辆级认证。

    进程与消息链

    manager 进程表在非纵向机动实验的行车模式运行 plannerd。main() 等待 CarParams,以 modelV2 轮询;只有本轮模型主题更新才调用纵向规划并发布 longitudinalPlan,然后运行车道偏离检测、发布 driverAssistance。两个输出各自写 sm.all_checks() 作为顶层有效位,规划计算本身没有被该检查提前短路。longitudinalPlan 名义频率为 20 Hz,真实时延受输入消息年龄和求解耗时影响。

    输入包括 modelV2 模型动作与油门概率、radarState 两个前车、carState 车速/巡航速度/转角、controlsState 纵向状态与强制减速、vehicleParameters 转向零偏,以及 selfdriveState 模式与驾驶风格。MPC 本体把自车建模为位置、速度、加速度三维状态,以 jerk 为控制量。

    候选是怎么合成的

    LongitudinalPlanner.update() 同步车况、MPC、巡航和可选 e2e 候选,选择目标并推进期望车速滤波。它在 controlsState.forceDecel 时把巡航目标速度置零;纵向控制关闭、巡航速度未初始化或非自控纵向且尚未使能时重置内部目标。carControl.orientationNED 可用时以俯仰估计滑行加速度,否则以 ACCEL_MAX 作缺省值;vehicleParameters.angleOffsetDeg 从转角中扣除,用于非实验巡航候选的横向加速度预算。

    get_cruise_accel() 的巡航候选按车速限制正加速度,并在非实验模式下用 sqrt(max(a_total²-a_y²,0)) 限制弯中纵向余量;若 allow_throttle=False,还把正加速度上限向坡度估得的滑行加速度收紧。allow_throttle 来自模型 gasPressProbs[1] > 0.4 或车速 <= 2.5 m/s;若数组不足两项,代码回退概率 1.0。它的计算顺序是先将速度误差裁到巡航/弯道/滑行候选范围,再按上一帧 a_cruise 和 j_cruise * dt 限变化率。

    四项原函数 NumPy 探针确认了这种「先裁范围、后限变化率」的瞬态:10 m/s、上一帧 2.0 m/s² 时返回 1.94 m/s²,高于该速度的 1.2 m/s² 巡航上限;20 m/s 且弯道预算降为零时仍返回约 0.453 m/s²;禁油门滑行上限为 -0.3 m/s² 时可暂时返回 -0.07 m/s²。这是平滑历史带来的候选瞬态,不等于最终 aTarget 或车辆执行值必然越界。

    最终选择上,MPC 轨迹经 get_accel_from_plan() 按车型纵向延迟插值得到当前目标;再与巡航候选比较,实验模式增加 modelV2.action.desiredAcceleration 候选。代码取最小加速度,再裁到车型接口常量 ACCEL_MIN=-3.5、ACCEL_MAX=2.0;shouldStop 却对全部候选求或。因此 aTarget 与 shouldStop 可来自不同候选。controlsd controlsd 将两者交给 LongControl.update(),后者按 off/stopping/pid 状态与车型 PID 限值给执行器目标;不能把 aTarget 当作直接 CAN 帧。

    字段 来源 相位与边界
    aTarget MPC、巡航与实验模式 e2e 候选取最小加速度后再裁到车型常量。 不是直接 CAN 帧;需经 LongControl。
    shouldStop 对全部候选求或。 可与 aTarget 来自不同候选。
    allowThrottle 模型 gasPressProbs[1] > 0.4 或车速 <= 2.5 m/s。 只提示与巡航候选约束;controlsd 未把它当独立布尔门。
    消息 valid publish() 时写 sm.all_checks()。 与候选计算相分离,计算本身不被它短路。
    函数/组件 作用 关键边界
    get_cruise_accel() 按巡航速度差给目标加速度,非实验模式考虑弯道横向与滑行/油门约束,再做 jerk 限幅。 后置 jerk 限幅可使返回值暂时高于前面算出的候选上限。
    LongitudinalPlanner.update() 同步车况、MPC、巡航与可选 e2e 候选,选择目标并推进期望车速滤波。 允许在输入检查失败时计算;valid 只在发布时反映 sm.all_checks()。
    LongitudinalPlanner.publish() 发布速度/加速度/jerk 轨迹、aTarget、shouldStop、FCW、来源与油门提示。 hasLead 取 leadOne.present,不表达雷达消息有效性。
    get_T_FOLLOW() 选择跟车时距:宽松 1.75 s、标准 1.45 s、激进 1.25 s。 个性化只改变优化参数,不改变独立安全网关策略。

    MPC 时域与跟车时距

    gen_long_model() 在构建期由 CasADi/acados 生成求解器,运行时不是 Python 手工积分器。gen_long_ocp() 建立 12 段、10 秒非均匀预测时域,设置距离/jerk 成本与速度、加速度、危险距离软约束;约束与权重在运行时更新,不能只看静态模型推断车辆一定在物理极限内。get_T_FOLLOW() 按驾驶风格选择 1.75 s、1.45 s 或 1.25 s 的跟车时距。

    process_lead() 处理前车状态、裁剪异常值并外推轨迹;无前车时注入虚拟高速前车。六项原 MPC 前车方法隔离探针确认:无目标时首点为前方 50 m、车速比自车高 10 m/s 的虚拟前车;近目标距离会被可刹距离公式抬高,输入加速度被裁到 [-10,5] m/s²。LongitudinalMpc.update() 把两个前车换算成等效静止障碍,逐节点选择更近约束,运行求解并累计 FCW 近碰撞帧;source 取第零节点最近障碍,后续节点可换前车,FCW 只用 leadOne 且要求 modelProb>0.9。探针确认即使后续节点的逐时刻最小障碍已切换到另一前车,source 只由第零节点决定。set_cur_state() 与上次速度差严格大于 2 m/s 时重设所有 solver 节点状态,等于 2 m/s 不重设。

    求解失败与 FCW 边界

    LongitudinalMpc.run() 在求解状态非零时先读取本次解,再按单调时钟判断是否记录警告并调用 reset();LongitudinalPlanner.update() 随后仍插值当前(已清零的)速度/加速度/jerk 轨迹并参与候选选择,没有专门的「求解失败」消息位。reset() 同时将 solve_time、solution_status、crash_cnt 与 last_cloudlog_t 置零;因此告警时间戳不跨失败保存,当单调时钟已超过 5 秒时,连续失败可每次记录,而非真正跨失败限频。发布的求解耗时为清零后的值,原始失败状态没有发布。

    FCW 侧,LongitudinalMpc.update() 在 5 秒预测窗口内存在距离小于 0.25 m 且首个前车模型概率 >0.9 时累加 crash_cnt;规划器要求计数 >2 且车辆未静止才发布 FCW。selfdrived 还会结合另一条模型硬制动预测生成 FCW 事件,两者不能混为单一碰撞检测器。探针还确认:第一前车模型概率从 0.91 降到严格边界 0.9 时计数清零;dRel=NaN 可继续形成 NaN 位置轨迹,当前纯输入处理层没有有限性校验。

    常见问题

    为什么 aTarget 和 shouldStop 可能来自不同的候选?

    因为最终 aTarget 是「取最小加速度」,而 shouldStop 是对全部候选「求或」。探针确认:MPC 的 -0.5 m/s² 目标获选时,较大的 e2e 候选仍可提供 shouldStop=True。

    跟车距离有哪几档?

    get_T_FOLLOW() 提供宽松 1.75 s、标准 1.45 s、激进 1.25 s 三档;个性化只改变 MPC 的优化参数,不改变独立的安全网关策略。

    MPC 求解失败会怎样?

    run() 遇非零求解状态会调用 reset(),清零轨迹、计数和状态;规划器随后仍插值已清零的轨迹参与候选选择,且没有专门的「求解失败」消息位,发布的求解耗时也是清零后的值。

    allowThrottle=False 是不是就等于禁止加速?

    不完全是。allowThrottle 被发布供 UI 调整显示;本快照 controlsd.state_control() 只显式消费 aTarget/shouldStop,未把 allowThrottle 作为独立布尔门传给 LongControl。它对正常巡航候选的限幅有作用,但不能据此断言所有候选都被禁止正加速度。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/LONGITUDINAL_PLANNER_MPC_DEEP_DIVE.md(plannerd 消息链、候选合成、MPC 时域与求解失败边界)。
    • 项目 02 —— 同目录探针记录:四项巡航数值、四项规划器候选、六项 MPC 前车、四项求解器生命周期隔离探针结论。

    说明:本文为对固定源码快照的静态结构分析,未运行完整测试套件、未连接硬件、未验证目标车型的真实参数组合。文中所有阈值、行号索引与配置均出自源文档,标注为未验证的结论保留其原有边界。

    更新记录

    首次发布 2026-10-11 最近核对:2026-10-11

  • 刹车温度管理:从能用到可控

    结论:决定圈速的不是峰值制动力,而是热衰减。直线末端全力踩刹车是所有人都做得到的事,真正的差距出现在连续几圈之后:刹车盘温度累积升高、摩擦系数下降,而踏板脚感几乎不变,于是你以为踩得和第一圈一样,圈速却慢了零点几秒。因此刹车管理的对象是「热」,不是「力」;硬件升级的顺序也应该按散热能力排,而不是按价格排。

    峰值制动力是个误导

    新手讨论刹车时几乎都在谈制动距离,但这个指标只在单圈、冷刹车的前提下有意义。赛道日的实际工况是连续多圈:连续三圈之后,刹车盘温度可能已经超过 600°C,此时摩擦系数会明显下降,而液压制动在这一阶段还额外承受着热衰减。

    麻烦之处在于它没有体感反馈。第三圈的重刹点踩到底,感觉上和第一圈一样;但圈速显示你晚了 0.4 秒。踏板行程与脚感由液压系统决定,摩擦系数的下降被液压放大补偿掉了,车手感知不到,只有数据看得到。

    三个可以立刻做的动作

    用「刹车占空比」而不是「刹车点」思考

    传统的思路是「在这里踩刹车」,它把刹车当成一次离散事件。更有效的思路是「从出弯到入弯,整个过程的刹车踏板开度应该是多少」——把刹车看成一段连续曲线。这个视角转换会迫使你提前规划,而不是等看到弯才反应,同时也让刹车与油门的重叠区(循迹制动)变得可分析。

    前后分配不是固定值

    多数车手习惯 70% 制动在前。实际比例应该随弯道结构变化:入弯是右弯时,车身重心向左转移,前轴负荷更高,前制动的有效权重也会上升。感知重心的漂移,比记住一个固定数字有用。

    工况 重心转移方向 前制动有效权重 调整方向
    直线重刹 向前 高 基准工况,以此为参照
    入右弯 向左 升高 可适当增加前制动占比
    入左弯 向右 升高(对称) 同上,方向相反
    带转向的制动 复合 取决于转向角 优先降低总制动强度

    让数据告诉你什么时候该收

    刹车温度是可以被记录的。装一套带温度输出的卡钳传感器,或者用记录设备同时采集刹车压力与踏板行程来配合推算,你会发现自己远比自以为的更早进入热衰减区。这是少数几个「装上传感器就能立刻改变驾驶行为」的场景——因为结论与体感冲突,没有数据几乎不可能靠自己意识到。

    硬件升级的顺序

    如果硬件要升级,顺序应当按「对散热与一致性的贡献 / 成本」排列:

    顺序 项目 解决什么 局限
    1 刹车片 提高工作温度上限 最便宜、见效最快,但只适合轻度使用
    2 刹车盘 改善散热 赛道日的关键项,成本显著上升
    3 卡钳 改善刚性、降低踏板行程、提升一致性 对散热贡献有限,主要改善脚感与重复精度
    4 避震与轮胎 改善负荷转移 不解决热衰减本身

    常见的错误是反过来做:先花大钱换避震,结果刹车该热还是热——因为避震改变的是负荷转移节奏,而热衰减是摩擦副的温度问题,两者不在同一条因果链上。

    常见问题

    怎么判断自己已经进入热衰减区?

    体感不可靠,因为液压系统会掩盖摩擦系数下降。可靠的判据是数据:同一刹车点、同等踏板力下,圈速或减速度出现单调下降;或者刹车压力不变而减速度降低。出现这种「输入不变、输出变差」的形态,基本可以判定为热衰减。

    刹车盘温度超过 600°C 就一定要停车降温吗?

    600°C 是原文档中给出的典型量级,不是通用阈值。不同刹车片配方的工作温度窗口差异很大,是否超限应当以刹车片厂商给出的工作区间为准。实际操作中,更可靠的信号是上一问提到的减速度单调下降,而不是某个绝对温度值。

    前后制动比例可以自己调吗?

    取决于车辆是否配备可调比例阀或电子制动力分配。多数原厂车的比例是固定的,车手能调的是「驾驶方式」而非「硬件比例」——即在重心转移的不同阶段分配制动强度。若确实需要调硬件比例,需确认当地法规与赛事规则是否允许。

    赛道日需要刹车导风口吗?

    如果已经出现明确的热衰减信号,导风口是一项低成本的散热改善,优先级介于换刹车片与换刹车盘之间。它的局限是效果依赖管路设计,且会引入额外的进气阻力与部件可靠性风险。

    延伸阅读

    参考资料

    • 本站车型库 —— /data/cars/(用于确认具体车型的制动系统形态与总线通道)
    • 本站文章 —— /blog/trackday-data-review-segment-method/(热衰减的逐段判据)
    • 说明:本文属赛道工程实践经验总结,温度与比例数值为常见赛道日场景的典型量级,非受控实验测量结果。

    说明:本文为赛道刹车管理的经验性方法总结,文中 600°C、0.4 秒、70% 等数值是为说明方法而引用的典型量级,非实测统计结果,不同车型、刹车片配方与环境温度下差异可能很大。涉及制动系统的任何改装与调整,请以厂商规格、当地法规与专业技师意见为准。

    更新记录

    首次发布 2026-10-13(原发布于建站期,本次按本站 GEO 规范重写:补充结论段、前后制动分配表与硬件升级顺序表、常见问题与结构化数据)。最近核对:2026-10-13

  • 圈速之外:一份赛道数据的正确读法

    结论:赛道日结束后最该看的不是「最快圈」这个数字,而是最快圈与第二快圈的逐段差值分布。差值在每个弯均匀出现,说明差距来自当前能力边界,只能靠训练整体提升;差值集中在个别路段,说明是某一次走线或刹车点的判断失误,可以通过复盘直接改善。前者需要时间,后者当天就能修。

    为什么最快圈几乎没有信息量

    跑完一个赛道日回到维修区,大部分人只会记住一个数字:最快圈。但那个数字往往是一组特定条件叠加的产物——轮胎刚好在窗口温度、配重分配最理想、某个弯的走线恰好踩在极限。这些条件里有一部分不可复制,因此最快圈本身不构成可复用的改进目标。

    更有参考价值的指标是最干净圈:所有动作都接近你自己天花板的那一圈。它可能比最快圈慢 0.3 秒,但它能被稳定地重复。一个能被重复 0.3 秒的圈,比一个只能偶然出现一次的最快圈更接近你的真实水平。

    用逐段差值区分两类失分

    把最快圈和第二快圈叠在一起,看差值出现在哪三个路段。判据不是差值的绝对值,而是它的分布形态。

    差值形态 典型表现 归因 可改善性
    均匀分布 第二快圈在每个弯都稳定慢 0.2 秒 当前能力边界 低,需要整体训练
    局部突变 某弯之后突然快 1 秒,下一路段又慢 1.5 秒 单次走线或刹车点判断失误 高,复盘当天可修
    单调递增 越跑越慢,差值集中在后半圈 轮胎或刹车的温度衰减 中,需调整硬件与节奏
    无规律抖动 同一弯每圈差值正负交替 操作一致性不足 中,需固化参照点

    这张表的实际用途是决定当天的时间投向哪里。局部突变优先,因为它是失误而非能力;均匀分布不必当天死磕,因为当天改不动。

    三个值得每天看的图

    数据软件能出几十张图,但真正每天都有决策价值的通常只有三张。

    图 该看什么 常见误读
    刹车点对比 两圈刹车起始位置的差值 把「不敢刹车」当成主因
    油门开度图 本该全油门却只给七成的瞬间 把提前收油归因为推头
    转速与挡位 升挡点的一致性,而非绝对值 只追求更高升挡转速

    刹车点对比:稳定性比早晚更重要

    如果你在某处刹车点偏晚 15 米,而在下一处偏早 10 米,说明你的刹车距离感还不稳定。这通常比「不敢刹车」更值得修——前者可以通过固定参照物解决,后者往往只是前者的表现结果。

    油门开度图:圈速损失藏在这里

    这张图经常让人意外。大量圈速损失藏在「本该全油门却只给了七成」的那些瞬间。车手通常是因为害怕推头而提前收油,但推头的真实原因往往是前胎温度不够,或者走线偏移导致前轴负荷过大——这两个成因对应完全不同的修法,但从油门开度图上看起来是一样的。

    转速与挡位:一致性优先

    升挡点的一致性比升挡点本身的绝对值更重要。每一圈的升挡转速差 300 rpm,会让出弯扭矩输出完全不同,从而影响后面整个弯的节奏。先把升挡转速的圈间波动压下来,再去讨论该在多少转升挡。

    复盘的最小工作流

    不需要每次都做完整分析。一个能在维修区 15 分钟内跑完的最小流程是:

    1. 确定赛道分段与参考圈速(用最快圈作参考,而不是用别人的圈)。
    2. 对比逐段差值,按上表的形态分类,挑出局部突变的那一段。
    3. 对该段叠加刹车点与油门开度图,判断是刹车点、走线还是前胎温度问题。
    4. 只定一条下一次要改的动作,不要一次改三处——否则下次数据无法归因。

    常见问题

    最快圈比第二快圈快很多,是不是说明我状态不稳定?

    不一定。先看差值分布:如果快的那 1 秒集中在单个路段,是那一段的一次性判断成功,属于可复制性低的偶然;如果均匀分布在每个弯,才说明整体状态有明显波动,需要从作息和节奏上找原因。

    没有专业数据软件,能用手机 GPS 做同样的分析吗?

    可以做形态判断,做不了油门开度与挡位分析。GPS 能提供圈速与逐段差值,足以区分均匀分布与局部突变;但油门开度、刹车压力、升挡转速需要接车辆 CAN 或 OBD 通道,手机 GPS 拿不到。

    该拿别人的圈速做参考吗?

    只有在车型、轮胎、赛道条件都接近时才有意义。更稳妥的做法是拿自己的历史最快圈做参考——它自动吸收了车型与轮胎的差异,差值归因更干净。

    每圈都稳定但就是不快,该怎么突破?

    这说明你已经在当前能力边界内跑得很一致,属于上表中的「均匀分布」形态。这种情况下复盘边际收益很低,突破需要外部输入:教练、同车型快手的车载视频,或者先解决轮胎与刹车的硬件瓶颈。

    延伸阅读

    参考资料

    • 本站赛道库 —— /data/tracks/(用于确定赛道分段与参考圈速的赛道几何参数)
    • 本站文章 —— /blog/trackday-data-review-segment-method/(逐段差值法的完整流程)
    • 说明:本文内容属赛道工程实践经验总结,参数区间来自常见赛道日场景而非受控实验测量,未针对特定车型或轮胎做验证。

    说明:本文为赛道数据读法的经验性方法总结,文中涉及的具体数值(0.3 秒、0.2 秒、15 米、300 rpm 等)为便于说明方法而举的典型量级,非实测统计结果,不同车型、赛道与轮胎条件下差异可能很大。任何硬件或驾驶决策请以实际测量与专业指导为准。

    更新记录

    首次发布 2026-10-13(原发布于建站期,本次按本站 GEO 规范重写:补充结论段、逐段差值判据表、常见问题与结构化数据)。最近核对:2026-10-13