结论:SelfdriveD.update_events() 在同一帧内直接引用 53 个 EventName,但它们只是在「生产者」一侧被加入;加入事件之后仍要经过状态门与告警仲裁,才能变成驾驶员听到的告警或执行器退出。两道提前返回(未初始化、CP.passive)会让后续平台健康检查整体跳过,而 cruiseMismatch/noGps 在事件类型映射中为空,不能凭名字推断会触发禁入或退出。以下基于固定源码快照 c8fb906 的静态分析,未运行端到端时序或实车验证。
每帧入口与两道提前返回
update_events() 每帧先执行 clear():它保留静态事件并更新计数,随后处理调试、大模型与一次性启动提示。若 initialized=False,函数添加 selfdriveInitializing 后立即返回,此时不运行后续的驾驶员监测、车况、硬件与通信故障检查。也就是说「初始化中」这一种状态会掩盖其他所有平台健康判定。
初始化本身在 data_sample() 中等待 canValid && sm.all_checks(),或约 6 秒超时;超时只结束等待,不保证订阅数据有效。初始化完成后可以处理书签,但 CP.passive 又会使函数提前返回。carUnrecognized/dashcamMode 是构造时添加的静态事件,startupNoCar/startupNoControl 等则通过 startup_event 变量在首轮间接加入,所以不能从 53 个直接名称的计数推断它们缺席。
53 个直接事件按来源分组
下表按各来源首次直接引用的顺序,列出相应的 EventName 与生产条件的中文摘要。同一帧可能追加多个事件,Events 的有序插入并不等于去重。
| 来源 | 直接 EventName(摘要) | 条件及边界 |
|---|---|---|
| 调试与大模型 | joystickDebug、bigModelLoading、bigModelFailed、lateralManeuver、longitudinalManeuver、selfdriveInitializing |
大模型失败是有条件的软退出(失败/失联/外设消失边沿),非每帧无条件触发;机动实验按接收帧选择,横向优先 |
| 书签与巡航恢复 | userBookmark、userBookmarkNotPaired、resumeBlocked |
非 PCM 巡航、设定速度 vCruise > 250 且加速/恢复按键出现时阻止恢复 |
| 驾驶员监测 | tooDistracted、driverDistracted1~3、driverUnresponsive1~3 |
非 notCar 才检查;lockout 禁止使能;alertLevel 1/2/3 与 activePolicy 是否 vision 决定两套提示 |
| CAN 与踏板 | pcmEnable、pedalPressed |
CS.canValid 后才转发 CarEvents;油门上升沿需开启 DisengageOnAccelerator |
| 设备健康 | overheat、outOfSpace、lowMemory、fanMalfunction |
热状态达 overheated;非仿真空闲空间 <7% 或内存 >90%;风扇见下文数值门 |
| 标定与车道偏离 | calibrationIncomplete、calibrationRecalibrating、calibrationInvalid、ldw |
标定状态非 calibrated 时三选一;IsLdwEnabled 且左右偏离任一成立才产生 ldw |
| panda 安全 | controlsMismatch、relayMalfunction |
与 safetyConfigs 逐项比较;额外 panda 必须 silent/noOutput;mismatch_counter >= 200 可直接触发 |
| 系统/总线/通信 | processNotRunning、cameraMalfunction、canBusMissing、canError、commIssue 等 |
进程故障优先并跳过相机检查;总通信问题仅在 all_checks() 失败且大模型不在缓冲期时产生 |
| 定位/参数/传感器 | posenetInvalid、locationdTemporaryError、paramsdTemporaryError、sensorDataInvalid |
主题曾被收到才看有效位;加速度计或陀螺仪任一主题距最近接收帧超过约 10 秒 |
| 提示与副作用 | fcw、steerSaturated、noGps、modeldLagging、personalityChanged |
FCW 只生产提醒不下发制动;转向饱和看目标/实际横向加速度比值;驾驶风格在按键释放时循环 |
车辆侧的更多事件由 CarEvents.update() 转发,它还会产生车门、安全带、挡位、定速、转向和品牌专属事件,并由 CS.canValid 门控;车辆接口上报的 CarState 信号真假、车型安全钩子和线束电气行为不由这一层证明。
几个容易被名字误导的事件值得单列。excessiveActuation 只在非 notCar 且有校准姿态时调用 ExcessiveActuationCheck.update(),首次触发会写驻车告警并把内存标志置真,之后才持续添加,构造时还会从已有的 Offroad_ExcessiveActuation 恢复该标志。变道提示同理:模型处于预变道且对应方向盲区被占用时阻止提示,进入开始或结束阶段时才发 laneChange——这些是模型状态消费,不代表真实盲区已被验证。
数值门与告警边界
这些条件的触发都绑定具体数值门,且多数在「严格超过某段时间对应的帧数」之后才成立。下表汇总关键阈值。
| 项目 | 阈值 / 时间门 |
|---|---|
| 空闲空间 / 内存 | 非仿真下空闲空间 <7%,或内存使用 >90% |
| 风扇故障 | 已知 panda、风扇目标 >50% 且缓存转速 <500 rpm,严格超过 15 秒对应帧数;注释称「5 秒」,数值实现为 15 秒 |
| 未初始化超时 | 约 6 秒(只结束等待,不保证数据有效) |
| panda 配置不匹配 | 严格超过 10 秒对应帧数;或 safetyRxChecksInvalid / mismatch_counter >= 200 直接触发 |
| 传感器新鲜度 | 加速度计或陀螺仪任一主题距最近接收帧超过约 10 秒 |
| 转向饱和 | 横控活动且最近约 2 秒未检测到驾驶员转向,并满足比值与控制器 saturated |
| 原车巡航一致性 / GPS | cruiseMismatch 约 6 秒;noGps 约 2 秒且累计无 GPS 行驶距离 >1500 m(映射为空) |
| 模型频率 | modelV2.frameDropPerc > 1 即添加 modeldLagging |
需要特别记住两处:风扇反馈故障「注释 5 秒、实现 15 秒」,并且不检查反馈新鲜度;cruiseMismatch 与 noGps 在本快照的 EVENTS 映射中为空,而 Events.contains() 只看类型映射,所以它们不会据此生成禁入或退出类型。
生产条件不等于告警或退出
update_events() 对某些系统故障有意设置了优先级与缓冲:总通信问题仅在 all_checks() 失败、无其他新增系统禁入/退出故障、且大模型不在加载或就绪后 5 秒缓冲期时才产生;进程故障优先,alive 优先于平均频率。这些都是「生产条件」层面的取舍,不是最终告警时刻。
系统与通信故障内部也排了优先级:manager 指出应运行而未运行的进程时先报进程故障并跳过相机检查,recv_frame=0 的首次消息不通过该门,缓存故障可以持续触发事件;车况的 canTimeout 优先于 !canValid,且只有 openpilot 纵控才检查雷达错误,雷达 CAN 错误归入 canError。
因此插件化时,传感器、模型与车型插件必须提供时间戳、数据有效位和失联证据,核心才保留事件归一化、状态机与 panda 安全约束。下一步应逐事件追到上游生产消息及回调告警,配合进程回放、SIL/HIL 和封闭场地验证;本文没有运行测试或控制车辆。
常见问题
未初始化时为什么很多故障检查根本不运行?
因为 clear() 后若 initialized=False,函数会添加 selfdriveInitializing 并立即返回,后续的驾驶员监测、车况、硬件与通信故障检查全部被跳过。
这 53 个直接事件就是全部事件吗?
不是。这只是 update_events() 中直接引用的名称;启动事件通过变量间接加入、车辆事件由 CarEvents 转发,全部 99 个名称与类型组合另见静态事件索引。
风扇故障到底是 5 秒还是 15 秒?
注释称「5 秒」,但数值实现为 15 秒对应帧数;并且该检查不核对反馈新鲜度,只按「从最后一次健康处理帧起严格超过 15 秒」成立。
cruiseMismatch 或 noGps 触发后会退出吗?
不能这样推断。这两个 EventName 在本快照的 EVENTS 映射中为空,而 Events.contains() 只看类型映射,所以不会据此生成告警/退出类型。
延伸阅读
- selfdrive 事件的类型映射与告警仲裁:生产者之后发生了什么 —— 事件从生产到告警/禁入/退出的状态门
- 从使能到车轮:执行链上的八道门,以及它们各自不保证什么 —— 事件、使能与执行之间的分层边界
- 同一个「转向灯」在三家车厂是三种实现:车辆状态归一化的坑 —— 车辆侧信号进入事件前的归一化问题
- 驾驶员监测策略:分级提示与 lockout 的判定链 —— 驾驶员监测事件背后的策略层
参考资料
- 项目 02 ——
openpilot-research/SELFDRIVE_EVENT_PRODUCERS_DEEP_DIVE.md(53 个直接事件的生产条件、两道提前返回与数值门) - 项目 02 ——
openpilot-research/SELFDRIVE_EVENT_CATALOG.md(全部 99 个名称与类型组合的静态事件索引)
说明:本文为对固定源码快照的静态结构分析,未运行完整测试套件、未连接硬件、未验证目标车型的真实参数组合。文中所有阈值、行号索引与配置均出自源文档,标注为未验证的结论保留其原有边界。
更新记录
首次发布 2026-10-11 最近核对:2026-10-11