结论:Honda 的 CarState 不直接使用基类的四轮均速 helper:它把四轮 WHEEL_SPEEDS 求均并换算为 m/s,再用 1 到 6 m/s 的插值权重,把低速更依赖的 ENGINE_DATA.XMISSION_SPEED 与轮速混合后送入 KF1D 得到 vEgo/aEgo;standstill 另按变速箱速度小于 1e-5 单独判断。刹车开关信号按源码注释可能含单次噪声,非 BOSCH_ALT_BRAKE 车型要求当前与前值连续两样本同为真。本文为固定源码快照 c8fb906 的静态阅读,未做车型回放、CAN FD 台架或实车验证。
解析器与总线边界
动力和相机解析器的物理总线由 CanBus(CP) 指定,不能把 Bus.pt 恒等为 0。有雷达的 Bosch 平台把动力放在偏移加 1、雷达放在偏移;无雷达或 CAN FD 的 Bosch 与 Nidec 采用另一组映射。HAS_BSM 仅由特定 CR-V 指纹分支动态设置,状态层为此另建 Bus.body 解析器,物理输入使用 CanBus(CP).radar,源码注释说明 B-CAN 要先经 panda 转发——缺少这条物理路径时,软件支持 BSM 字段不等于盲区信息可用。
三个解析器创建时都没有显式报文列表,cp.vl[...] 第一次读取才动态注册报文。由于 CarInterfaceBase.update() 已先调用 parser 更新,新注册报文在第一轮的值与时间戳初始为零,本轮此前到达的帧不会被它解析;此后 vl 保存最近成功值,不保证本轮有新样本。接口对已注册报文做 can_valid 全路聚合、对总线空窗做 bus_timeout 聚合,但若新硬件要以刹车、车速或盲区作为安全条件,仍需逐信号检查来源、时间戳与采样年龄。
| 入口 | 作用 |
|---|---|
CarState.__init__() |
按变速箱/平台选择报文与 DBC 枚举,初始化刹车开关、仪表速度与巡航缓存 |
CarState.update() |
把动力、相机与条件性车身总线信号归一化为 CarState |
CarState.get_can_parsers() |
建动力/相机解析器,BSM 车型额外建 body 解析器 |
CanBus.__init__() |
区分有雷达 Bosch 的动力/雷达交换、纵向模式下的 LKAS 路由与其他平台总线 |
update_speed_kf() |
对 Honda 已混合的 vEgoRaw 做 KF1D 速度/加速度估计 |
create_button_events() |
按本轮/上轮按钮值构造按下与释放事件 |
速度混合与仪表值锁存
Honda 先把四轮 WHEEL_SPEEDS 平均并换成 m/s,再用 1 到 6 m/s 的插值权重把变速箱速度与轮速混合;CP.wheelSpeedFactor 在这段代码里只乘变速箱速度项,高车速主要由轮速项决定。混合值进入 KF1D 形成 vEgo/aEgo,而 standstill 单独按变速箱速度小于 1e-5 判断,不能简单用 vEgo 是否为零替代。轮速与变速箱速度矛盾时的物理可信度尚需目标车型回放验证。
CAR_SPEED.ROUGH_CAR_SPEED_2 首次大于阈值后 dash_speed_seen 永久锁存,之后每轮都把当前解析器缓存经 kph/mph 转换写入 vEgoCluster;在锁存前,基类接口用 vEgo 回退显示速度。台湾 Odyssey 特例不走该字段。状态侧没有单独的仪表速度年龄判据,若报文停发,解析器健康与显示缓存需要分别解读。
车身、转向与刹车
车门可来自四门 DOORS_STATUS、SCM_BUTTONS 驾驶门位或 SCM_FEEDBACK 驾驶门位,安全带用警告灯或未锁扣任一条件。自动/CVT 档位通过 DBC 枚举,手动挡只由倒车灯在倒车与前进之间二选一,无法在这里识别空挡或所有换挡中间态。方向灯调用拨杆型 250 次调用保持器;驾驶员转向直接以 STEER_TORQUE_SENSOR 绝对值对车型阈值比较,不使用基类去抖。STEER_STATUS 的 DBC 数值先转字符串,未知值映射 UNKNOWN,永久与临时故障有独立映射:BOSCH_ALT_RADAR 对预期低速锁定给例外,MDX 4G 的 TJA_LOW_SPEED_LOCKOUT 还单独清除故障位。
有 BOSCH_ALT_BRAKE 时刹车直接读 BRAKE_MODULE.BRAKE_PRESSED;其他车型把 POWERTRAIN_DATA.BRAKE_PRESSED 与刹车开关并联,只有本轮 vl_all 有开关样本时才更新开关状态,单轮有多样本则用倒数第二条作为前值,要求当前和前值都为真。若没有新开关帧,brake_switch_active 保持上次状态;解析器健康是另一层,不应把保留布尔值当成新鲜采样。
巡航、原车 ADAS 与下游
POWERTRAIN_DATA.ACC_STATUS 和选定 SCM 报文主开关决定巡航 enabled/available。Bosch 原车纵向的设定速度读 ACC_HUD.CRUISE_SPEED,遇大于 160 的特殊值就沿用 v_cruise_pcm_prev;源码说明设置时可能脉冲到 254/255,252 又表示 standstill。带动态单位的 Bosch 平台才在英制时使用 mph 转换,其他情况按 kph;Nidec 则读 CRUISE.CRUISE_SPEED_PCM。这些特殊值是软件解码规则,不是一般范围检查。
原车 AEB/FCW 来源也分 Bosch 与 Nidec:Bosch 有雷达且未启用自控纵向时才从动力 ACC_CONTROL 判定原车 AEB;Nidec 从相机 BRAKE_COMMAND 判 AEB/FCW,并保留 ACC_HUD 与刹车字段供控制器构帧;Bosch 无雷达车型另保存相机 LKAS_HUD。这些字段是 parser 的最近缓存引用,CarState 未给每个字段附单独采样年龄,因此不能把有 HUD 字典当作原车 AEB 仍可用的证明。按钮事件来自 SCM_BUTTONS 的巡航/设置字段当前与上次值,下游再由车辆事件层决定取消、启用和故障告警。
| 信号类别 | 来源与处理 | 版本分支 |
|---|---|---|
| 车速 | 四轮均速 + 变速箱速度按 1~6 m/s 插值权重混合,随后 KF1D | 台湾 Odyssey 不锁存仪表速度字段 |
| 刹车 | 直接读 BRAKE_MODULE,或与刹车开关并联并要求连续两样本 |
BOSCH_ALT_BRAKE 走直读分支 |
| 巡航设定速度 | Bosch 读 ACC_HUD.CRUISE_SPEED,Nidec 读 CRUISE.CRUISE_SPEED_PCM |
大于 160 特殊值沿用上轮;252 表示 standstill |
| 原车 AEB | Bosch 读 ACC_CONTROL,Nidec 读相机 BRAKE_COMMAND |
Bosch 无雷达保存 LKAS_HUD |
| 盲区 | BSM 车型经 B-CAN 转发后由 body 解析器读取 | HAS_BSM 由特定 CR-V 指纹动态设置 |
硬件插件验收
车型输入插件应为轮速四路、变速箱速度、刹车开关与压下、EPS 故障、巡航、原车 AEB 与 BSM 分别声明物理总线、DBC、采样时戳、年龄、校验/计数器结果和缺测状态。速度融合参数、仪表速度锁存和刹车连续样本门应按车型版本冻结并在回放中量化。无车测试至少覆盖第一轮动态注册、单轮异常、速度来源矛盾、刹车短脉冲与断流、ACC 特殊速度码、未知 EPS 状态、BSM 路由缺失及 Bosch/Nidec 分支,再与安全钩子的独立 RX 判据对照。
常见问题
Honda 的车速为什么不是简单的四轮平均?
因为低速时四轮均速不够可靠。CarState 先求四轮均速并换算为 m/s,再用 1 到 6 m/s 的插值权重把变速箱速度 XMISSION_SPEED 与轮速混合,混合值才进入 KF1D 形成 vEgo/aEgo;CP.wheelSpeedFactor 只乘变速箱速度项,高车速主要由轮速项决定。
为什么刹车开关需要连续两个样本?
源码注释指出开关信号可能有单次噪声,且驻车挡未必有效。非 BOSCH_ALT_BRAKE 车型把 POWERTRAIN_DATA.BRAKE_PRESSED 与刹车开关并联,只有本轮有开关样本时才更新状态,单轮多样本用倒数第二条作为前值,并要求当前和前值都为真。
巡航设定速度出现 254/255/252 是什么意思?
这是软件解码规则而非一般范围检查。Bosch 原车纵向读 ACC_HUD.CRUISE_SPEED,遇大于 160 的特殊值就沿用 v_cruise_pcm_prev;源码说明设置时可能脉冲到 254/255,而 252 又表示 standstill,因此不能按普通数值范围直接采信。
解析器聚合通过就代表每个信号都新鲜吗?
不代表。接口只对已注册报文做 can_valid 聚合、对总线空窗做 bus_timeout 聚合,而 vl 保存的是最近成功值,不保证本轮有新样本;CarState 也未给原车 HUD 等字段附单独采样年龄,因此仍要逐信号核对来源与年龄。
延伸阅读
- 同一个「转向灯」在三家车厂是三种实现:车辆状态归一化的坑 —— 把 Honda 的混速与信号来源放进跨车厂归一化视角。
- Hyundai 车辆状态输入:经典 CAN 与 CAN FD 双路径 —— 对照另一车厂的输入归一化与总线分支。
- 车辆消息字段契约:从 DBC 到状态量的边界 —— 解释本文
vl缓存与字段语义的通用契约。 - CAN 报文解析的「健康位」在说什么:校验、计数器与总线空窗 —— 展开本文
can_valid与bus_timeout聚合的语义。 - Toyota 车辆状态输入健康契约 —— 同一套输入健康检查在另一车厂的实现对照。
参考资料
- 项目 02 ——
openpilot-research/HONDA_CARSTATE_SPEED_BRAKE_CRUISE_INPUT_DEEP_DIVE.md(取用了 Honda 速度混合、刹车去噪、Bosch/Nidec 巡航分支、BSM 路由与插件验收清单)。 - 项目 02 ——
openpilot-research/CAN_PARSER_HEALTH_DEEP_DIVE.md(仅用于确认解析器健康聚合与总线空窗的语义位置)。
说明:本文为对固定源码快照的静态结构分析,未运行完整测试套件、未连接硬件、未验证目标车型的真实参数组合。文中所有阈值、行号索引与配置均出自源文档,标注为未验证的结论保留其原有边界。
更新记录
首次发布 2026-10-11 最近核对:2026-10-11
发表回复