变道意图与 LDW:20 mph 与 31 mph 两道阈值各管什么

作者:

在

结论:变道意图和车道偏离预警是两条不同的辅助链路。变道意图靠转向灯新沿、驾驶员同向扭矩与盲区位,在车速不低于 20 mph 时从 off 进入准备态;车道偏离预警则要求车速严格大于 31 mph、近 5 秒无转向灯且横向未激活。两者都只产生提示或候选,不直接授权转向或制动执行器。本文为固定源码快照 c8fb906 的静态分析。

消息与时序:本帧状态、下一帧脉冲

modeld.main() 在本帧推理前读取上一次 DH.desire,编码到 desire_pulse;ModelState.run() 只将 desire 从低到高的变化送入模型。推理后才从本帧 desireState 左右变道项之和计算 lane_change_prob,调用 DH.update(),并把更新后的状态/方向写入本帧 modelV2.meta。因此状态提示可在本帧出现,新意图要到下一帧才进入模型;不能把它们当同一时刻的闭环输出。

plannerd.main() 以 modelV2 轮询,只有该主题更新时计算 LDW 并发布 driverAssistance;消息顶层 valid=sm.all_checks(),所以计算出的左右布尔值与可供消费的有效性是两回事。服务表配置 driverAssistance 为 20 Hz,这不是端到端时延保证。desirePrediction 是 LDW 使用的另一组模型值,不能与 desireState 混写。

组件/入口 主要逻辑 下游或边界
DesireHelper.get_lane_change_direction() 从左转向灯决定左,否则决定右;调用者先要求仅单侧灯亮。 准备态方向可随灯变化。
DesireHelper.update() 转向灯新沿、速度、横向活动、驾驶员同向扭矩、盲区和模型完成概率推进状态。 只设置意图/状态,不直接写转向执行器。
ModelState.run() 在推理输入中把非零 desire 的上升沿转为脉冲。 持续保持同一意图不会每帧重发脉冲。
LaneDepartureWarning.update() 根据车速、灯冷却、横向活动、线可见度/距离及预测概率设置左右偏离。 仅产生布尔结果,不制动或转向。
Controls.state_control() laneChangeState!=off 时设置 carControl 转向灯请求,按有效位设置 HUD 偏离方向。 车型是否实现灯控需逐车型检查。

变道意图的状态门

DesireHelper.update() 只有横向激活、单侧转向灯出现新沿、速度不低于 20 mph,才从 off 进入 preLaneChange。准备态要求 steeringPressed 且扭矩方向与转向灯一致,并且该侧无盲区报警,才进入 laneChangeStarting。熄灯或降到门槛以下会关闭准备态;已启动后源码不再以盲区位直接撤销,而是依赖模型概率和超时等分支,因此不能把盲区位当成持续的安全许可。

完成门要求启动至少 0.5 s 且左右变道 desireState 概率和严格小于 0.02,之后若灯仍亮回准备态,否则关闭。横向失活或累计计时超过 10 s 关闭。laneChangeFinishing 虽在 log.capnp 中定义、selfdrived 也接受,本版本 helper 没有赋值该状态。五项原 DesireHelper 类假消息枚举探针确认:20 mph 恰好允许新沿进入准备态;横向失活会把上一灯沿记忆清零,再激活时即使灯一直亮也可视为新沿;同向扭矩在盲区亮时不能启动,但进入 laneChangeStarting 后熄灯/盲区亮且模型完成概率仍高时,意图继续输出。十秒上限在每次调用开头检查,首次越过十秒的该帧仍处于启动态,下一次调用才复位。

车道偏离预警的判定条件

LaneDepartureWarning.update() 要求车速严格大于 31 mph、按模型帧估算的近 5 s 内没有转向灯、carControl.latActive=False,且 desirePrediction 非空。左/右车道线各自概率大于 0.5;以相机横向偏移 0.04 m 修正后的近线条件分别是左侧 y[0]>-1.12 m、右侧 y[0]<1.04 m;对应方向的模型变道预测概率还须大于 0.1。last_blinker_frame 初值为零,冷却按 SubMaster.frame * DT_MDL 估算,不是单独的墙钟计时。四项原 LDW 类假模型字段探针确认:初始帧号 99 仍在五秒冷却内,帧号 100 恰好结束;31 mph 等值不允许 LDW,模型概率/线可见度/近线距离的等值也不触发;空 desirePrediction 会清左右状态,但非空且短于所需索引的向量直接抛 IndexError。

维度 变道意图 车道偏离预警
车速门槛 不低于 20 mph 才能进入准备态。 严格大于 31 mph。
转向灯 需要单侧灯的新沿。 近 5 s 内没有转向灯。
横向活动 要求横向激活。 要求 latActive=False。
驾驶员输入 要求 steeringPressed 且扭矩同向。 不依赖驾驶员扭矩,依赖线可见度与模型预测。
输出 变道状态/方向、转向灯请求与提示。 左右偏离布尔值、HUD 方向与声音提示。

提示与执行边界

selfdrived 仅在 IsLdwEnabled 和 driverAssistance 有效时生成 ldw;开关由参数轮询更新。该事件是 PERMANENT 小型提示及声音,不是 disengage 或执行器指令。准备变道、盲区阻挡和变道中分别是 WARNING 提示;其中盲区阻挡带提示音。controlsd 也会在 driverAssistance 有效时把左右偏离送入 HUD。

两项原消费者条件组合探针确认了旧值消费的边界:先收 driverAssistance.valid=True,随后假时钟推进到超出 20 Hz 服务的十倍存活窗口且无新消息时,updated=False、alive=False,但 valid=True 与旧左右字段保留,隔离执行 SelfdriveD.update_events() 的 LDW 分支仍会添加 ldw;若收到新消息且外层 valid=False,两个分支都跳过。转向灯、驾驶员扭矩/按压、盲区都来自车型解码,不是模型自己「看见了」即可替代,新硬件接口必须逐车型证明同向扭矩和盲区位的确切含义。

常见问题

变道是车辆自己判断安全后完成的吗?

不是。这里的变道是驾驶员参与的 L2 辅助行为,DesireHelper 只设置意图/状态,不直接写转向执行器;车型是否实现灯控还需逐车型检查。它不自动判断周围交通安全后自行变道。

为什么变道用 20 mph、LDW 用 31 mph?

两条链路的门槛是独立定义的:DesireHelper.update() 要求速度不低于 20 mph 才进入准备态;LaneDepartureWarning.update() 要求车速严格大于 31 mph。源码没有把两者合并为同一策略函数。

盲区位会一直阻止变道吗?

不会。准备态要求该侧无盲区报警,但一旦进入 laneChangeStarting,源码不再以盲区位直接撤销,而依赖模型概率和超时等分支,因此不能把盲区位当成持续的安全许可。

LDW 的 5 秒冷却按墙钟算吗?

不是。冷却按 SubMaster.frame * DT_MDL 估算,last_blinker_frame 初值为零;探针确认灯亮后的第 99 帧仍冷却、第 100 帧可再次触发。

延伸阅读

参考资料

  • 项目 02 —— openpilot-research/LANE_CHANGE_LDW_DEEP_DIVE.md(DesireHelper 状态机、LDW 阈值、消息发布与提示边界)。
  • 项目 02 —— 同目录探针记录:五项 DesireHelper 状态、四项 LDW 阈值、两项 plannerd 发布、两项消费者分支隔离探针结论。

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

更新记录

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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注