标签: DBC

  • 2025 Ford F-150 Gen14 的 HS-CAN3 车身信号接入

    结论:这份档案记录的是一台 2025 款福特 F-150(第 14 代)上的车身 CAN 接入实践:车主没有从 OBD 诊断口取数,而是接到 HS-CAN3(500 kbit/s) 上的 C3154A(音响功放)连接器,用 ESP32 板读取床灯、门锁、变速箱 P 挡与电池状态,并反过来驱动床灯与工具箱继电器。它的价值不在「有多少条解码」,而在于一条不改原厂线束的取数路径:具体车身报文的逐字节定义并不在这份文档里,而是引用自公开的 ford_lincoln_base_pt.dbc。下述结论仅限源文档记录的这一台车,不能外推到其他年款、配置或市场版本。

    车辆与适用范围

    源文档是一位车主对自己车辆的改造记录,属于单台车、单人实验,不是车厂或第三方机构的批量采集。文档明确声明「不提供任何支持」,并反复警告接线错误可能危及生命。

    项 内容
    车型 Ford F-150(Generation 14,2025 款),Lariat V8
    年款 / 市场版本 2025 款;源文档未给出市场版本,仅说明为 501A Mid 配置包(无车内氛围灯、无 Bed Utility Package)
    ECU / 改装状态 原厂未改动线束;作者以尾插(pigtail)转接件接到 C3154A,追求「可完全还原」
    采集跨度 源文档未给出日志数或帧数;固件附带 49 个原生单元测试
    适用范围 仅限这一台 2025 Gen14 F150;不同配置的车身电路差异很大(例:尾门独立锁电路只存在于低配车型)

    总线与寻址

    源文档从原厂维修手册得到各条总线的走向,最终选定 HS-CAN3 作为取数总线。物理接入走 C3154A:HS-CAN3 High 在 1 脚(22ga 绿-蓝线),HS-CAN3 Low 在 11 脚(22ga 白-绿线),连接器为 Molex 34728-0200;相邻的 C3154B 提供常电(SBA40,40 号保险)与接地。

    项 内容
    物理层 双绞线 CAN,HS-CAN3 高/低线;需 120Ω 终端
    链路层 / 比特率 500 kbit/s(源文档明示 HS-CAN3 at 500kbps)
    寻址方式 源文档未给出 11 位 / 29 位说明;报文的逐字节定义引用自外部 DBC
    CAN FD 源文档提到曾用某款双通道 CAN FD HAT 抓包,但未说明车辆是否运行 CAN FD;实际按 500 kbit/s 经典 CAN 处理
    接入硬件 AutoSport Labs ESP32-CAN-X2(ESP32-S3 + 双收发器 + 车规电源),Arduino 框架 + PlatformIO

    已解码信号

    这份主素材没有给出任何逐字节报文 ID,它记录的是「这台车被读取/被控制的功能清单」以及对应的硬件引脚。为守住「只抄源文档里有证据的条目」这条线,下表登记源文档明确写出的功能与位置,涉及具体 ID、字节与缩放的条目一律指向被引用但未包含在本快照内的 DBC。

    信号 / 功能 总线或位置 方向 证据
    床灯(CHMSL bed lights)状态 HS-CAN3 只读 README「Features」
    迎宾灯 / 水坑灯(puddle lamp)状态 HS-CAN3 只读 README「Features」
    车门锁状态 HS-CAN3 只读 README「Features」
    变速箱 P 挡状态 HS-CAN3 只读 README「Features」
    蓄电池状态 HS-CAN3 只读 README「Features」
    床灯继电器输出 GPIO5(BEDLIGHT_PIN) 写 README「Configuration」
    工具箱开启继电器 GPIO4(TOOLBOX_OPENER_PIN) 写 README「Configuration」
    工具箱解锁按钮 GPIO17(TOOLBOX_BUTTON_PIN) 读 README「Configuration」
    系统就绪指示 GPIO18(SYSTEM_READY_PIN) 写 README「Configuration」
    CAN 缓冲溢出计数 MCP2515 / TWAI 诊断 诊断 README「Buffer Overflow Detection」
    TWAI 驱动状态 运行时诊断 诊断 README「can_status」
    RX / TX 错误计数(<128 为健康) 运行时诊断 诊断 README「can_status」

    读取方法与注意事项

    接入顺序在源文档里有明确交代:先在手套箱后方的在线连接器上反探测做初步实验,因为车尾拖车连接器处在车辆未运行时「似乎不广播有用报文」。确定 HS-CAN3 承载所需信号后,才改到 C3154A 做正式取数。取数用尾插转接件,不切断原厂线束;文档强调压接与焊点都要做拉拔测试。

    软件侧,固件通过串口(115200)提供诊断命令:can_status 看驱动状态与错误计数,can_debug 连续 10 秒打印全部报文,can_buffers 看缓冲溢出,can_reset 做恢复。若完全收不到报文,文档建议先把 ENABLE_HARDWARE_CAN_FILTERING 置 0 再编译烧录,以排除过滤配置问题。

    一个明确的工程约束是缓冲深度:源文档指出 MCP2515 的硬件缓冲只有 2 条报文,会丢帧。文档给出的缓解方向包括把主循环延时(当前 10ms)调小、把 MAX_MESSAGES_PER_LOOP(当前 10)调大,或改用 ESP32 的 TWAI 控制器。溢出会表现为「繁忙期报文突然停止」「日志出现 Suspected buffer overflow」「静默后出现突发」等。

    证据等级与边界

    本档案的信号清单属于单车主记录:只有一台 2025 Gen14 F150 Lariat V8(501A Mid)作为样本。总线走向、连接器针脚、GPIO 分配这些属于实车观测与手册交叉,可核对;而「车身报文里门锁、床灯具体是哪个 ID、哪些字节」在本文档里没有答案,它来自作者引用的公开 DBC,属于外部旁证,本项目并未逐条复现。

    三处不能外推。第一,配置差异会改变电路:源文档明确说只有低配车型才为尾门保留独立锁电路,而带电动尾门的高配由尾门内模块控制——同型号不同配置不得套用。第二,接入点与线序是针对这台车枚举出来的,其他年款/市场的 HS-CAN3 连接器编号与针位可能不同。第三,作者本人声明不提供任何支持,并警告可能失去保修、损坏车辆甚至造成人身伤害,因此任何照搬都超出源文档的证据范围。

    关于「安全访问」类问题:源文档未提供任何绕过方法,且不建议尝试;本文只整理公开文档登记的可读/可控功能,不涉及对车辆安全机制的规避。

    常见问题

    2025 F-150 的 OBD 口能直接抓到这些车身信号吗?

    源文档没有走 OBD 诊断口,而是接到 HS-CAN3 的 C3154A(音响功放)连接器。OBD 口在本车是否可读这些车身报文,源文档未给出结论,因此不能据此推断。

    为什么接上后收不到报文?

    文档给出的排查顺序是:先确认 CAN 高低线序与 120Ω 终端,再把 ENABLE_HARDWARE_CAN_FILTERING 置 0 用 can_debug 看总线上是否有任何流量,然后用 can_status 看错误计数,用 can_buffers 看是否溢出。若在车尾拖车连接器处取数,车辆未运行时可能本就没有有用报文。

    床灯和门锁的 CAN 报文 ID 是什么?

    源文档未给出具体 ID。它说明所需报文定义来自公开的 ford_lincoln_base_pt.dbc,本档案不代填字节与 ID。

    这套接入会不会影响保修?

    作者明确警告可能失去保修、烧毁车辆甚至危及生命,并声明不提供任何支持。本档案只是对公开文档的整理,不构成任何实车操作建议。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/jantman-ford-f150-gen14/README.md(本项目车型档案主来源:车辆信息、硬件、接线、固件与诊断说明;本快照仅含此文件)。

    说明:本文整理自第三方开源项目的公开文档,仅代表该文档所记录的单个车辆样本,不代表同型号全系车型。CAN 与诊断操作存在风险,任何实车操作前请自行复核并遵守当地法规。

    更新记录

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

  • Vtrux 与 Coda EV:网关型改装车的 CAN 信号档案

    结论:Vtrux(2014 款 Silverado 1500 的 EREV 改装车)最典型的数据特征是「一车三总线 + 主动网关」:OBD-II 口后面不是一条总线,而是三条独立 CAN,由 VCM 做跨总线网关,并且 VCM 会主动改写 ECM 的发动机数据——真实转速只在 OBD 总线上,Vehicle 总线上是约 800 RPM 的合成值。同仓库记录的 Coda EV 则是「一车四总线 + 网关转发」。以下结论仅限源文档记录的这两辆车及其固件与校准。

    车辆与适用范围

    本文数据来自第三方开源项目对两台实车的逆向记录:一台是 2014 款 Silverado 1500 的 EREV 改装车 Vtrux,另一台是 Coda EV 纯电轿车,两者出自同一仓库。

    项 内容
    车型 Vtrux —— 2014 款 Silverado 1500 的 EREV 改装车;同仓库另记录一台 Coda EV 轿车
    年款 / 市场版本 Vtrux 底车为 2014 款;Coda 年款与市场版本源文档未确认
    动力与改装状态 A123 LFP 电池包 116 节串联,标称约 383 V(约 360 V@10% SoC 至约 422 V 充满);原 GM 变速箱换成双 Remy 电机配 Dana TM4 CO150 逆变器;Woodward Motohawk 整车控制器(Via Motors VCM)兼作 GM CAN 网关
    采集跨度 源文档为多条实车日志(充电、公路巡航、隔离与互锁故障、过热等场景)加台架回放,未给出统一时长与帧数
    适用范围 仅限源文档记录的这两辆车与所列日志;不适用于量产 Silverado,也不保证适用于同型号其他改装车

    总线与寻址

    两台车都以经典 CAN 与 11 位标准帧为主,源文档未给出这两辆车的总线波特率。Vtrux 的核心特征是「三总线 + 主动网关」,Coda 是「四总线 + 网关转发」。日志通道编号都会随采集器插拔顺序变化,因此必须按报文内容识别总线。

    项 内容
    帧格式 车控主用 11 位标准帧;Bel 充电机/逆变器与 DCDC 使用 29 位 J1939 扩展帧
    Vtrux 三条总线 Powertrain(DLC 引脚 CAN-H 1 / CAN-L 9)、Vehicle(引脚 6 / 14)、OBD(引脚 10 / 2)
    Vtrux 总线识别 含 0x051 即 Powertrain;含 0x1E5 与 0x500 即 Vehicle;含 0x040–0x044 即 OBD。不要用 0x441–0x464 判 OBD,该区间含被网关桥接的 GMLAN 报文
    Coda 四条总线 B CAN(引脚 2 / 3)、D CAN(引脚 10 / 11)、C CAN(引脚 7 / 15,直读单体电压)、Diag CAN(引脚 6 / 14,标准 OBD 引脚);另有不可经 OBD 访问的私有 Motor CAN(DLCM↔MCM)
    Coda 总线识别 C CAN 恒含 0x000–0x019(104 节单体电压);B CAN 含 0x1D5、0x48A、0x275、0x381、0x383;D CAN 含 0x308、0x312、0x325、0x330、0x580
    网关 Vtrux 用 VCM 跨三总线选择性桥接并改写 ECM 数据;Coda 用 GWM 把 Diag CAN 路由到 J1962 并选择性转发

    已解码信号

    下表从源文档已标注置信度的条目中抽取。Vtrux 的置信度分级为 CONFIRMED(编码与用途均已独立验证)、CONFIRMED-SYMM(由对称结构推出)、CONFIRMED-DECOMPILE(编码由反编译确认,用途仍为标签)、PARTIAL(编码确认但角色或刻度存疑)与 REMOVED(已按策略移除)。Coda 部分沿用源文档的 CONFIRMED 标注。

    信号 位置(ID / DID / 字节) 解码 证据
    bcm_soc(电池 SoC) 0x0410 B3 raw × 0.5 % CONFIRMED(与 0x411 高分辨率 SoC 相关 r=0.9999)
    bcm_ibat(电池电流) 0x0410 B4:B5(大端 uint16) raw × 0.025 − 1000 A CONFIRMED(raw=40000 对应 0 A,发电机启停处穿越零点)
    bcm_vbat(电池包电压) 0x0410 B6[3:0]:B7(12 位) raw × 0.25 V CONFIRMED(接触器闭合后与 GENE_HighPwr_Volt 差不超过 1.25 V;启动哨兵值 1023.5 V 表示无效)
    bcm_cell_vmax / vmin 0x0430 B0[4:0]:B1 / B2[4:0]:B3(13 位) raw × 0.001 V CONFIRMED(稳定窗口内 r 大于 0.99)
    bcm_cell_tmax / tmin 0x0430 B4 / B5 raw × 0.5 − 40 ℃ CONFIRMED
    bcm_lvbat(12 V 电压) 0x0430 B7 raw × 0.1 V CONFIRMED(140=14.0 V DCDC 工作,127=12.7 V 静置)
    bcm_mainc_stat(主接触器状态) 0x0440 B0[5:2](4 位,16 态) 状态机枚举 CONFIRMED(充电日志观测到 ALL_OPEN→CLOSE_MAINR→WAIT_PRECHARGE→… 的状态转移)
    bcm_vbus_pos / vbus_neg 0x0440 B4:B5[7:4] / B5[3:0]:B6(12 位) raw × 0.25 V / raw × 0.25 − 500 V CONFIRMED(正、负直流母线对地电压)
    GENE_Mot_Trq(发电机扭矩回馈) 0x0471 B0:B1(小端 uint16) raw × 0.125 − 4096 Nm CONFIRMED(与 0x051 扭矩指令相关 r=0.9984)
    GENE_HighPwr_Volt 0x0482 B1:B2[2:0](11 位小端) raw × 1 V CONFIRMED(高速巡航稳定在 383–384 V)
    GENE_HighPwr_Curr 0x0482 B3:B4[5:0](14 位小端) raw × 0.25 − 2048 A CONFIRMED(巡航约 −40 A)
    parkLockState(驻车锁状态) 0x055C B0[2:0](3 位,7 项) 枚举 CONFIRMED(两车原始日志交叉验证)
    ess_power(电池包功率) 0x0598 B0:B1 (raw − 32768)× 0.01 kW CONFIRMED(线上格式不变;源文档另记录某类商业诊断工具自身解码有偏置,该信号已迁出原 DBC 归入实验 DBC)
    VehicleOdometer(整车里程) 0x0625 B0:B1:B2(24 位大端) raw × 1 km CONFIRMED(日志 raw=95,517 km 与仪表读数一致)
    DLCM_TorqueRequest(Coda 扭矩请求) 0x212 B4[3:0]:B5(12 位 nibble 拆分) raw × 0.244 Nm,零点 raw=2000 CONFIRMED(与 0x1C0 扭矩相关 r=0.999,峰值 293 Nm)

    读取方法与注意事项

    最关键的工程约束是总线识别。两台车的日志通道号都不可信——采集器插拔顺序一变,同一通道对应的总线就变了。做法是用 anchor ID 判定:先用一条稳定广播的专属 ID 认出总线,再做解析。Vtrux 还提醒,0x441–0x464 区间混入了被 VCM 桥接到 Vehicle 总线的 GMLAN 报文,用它判 OBD 会误判。

    第二条是网关的影响。Vtrux 的 VCM 会对转发内容做改写:ECM 的真实转速只出现在 OBD 总线(0x0C9,熄火时为 0,运转时为真实值),而 Vehicle 总线上是约 800 RPM 的合成值。轮速被掩零后,ECM 自行算出零车速并广播 0x3E9,形成级联——这不是 VCM 直接改写车速,而是屏蔽输入后的自然结果。因此同一物理量在不同总线上可能有不同含义。

    第三条是周期与新鲜度。同一 ID 在不同固件上周期可能不同(例如某电池电流报文在一种 BMS 变体上是 1 Hz,另一种上是 10 Hz),源文档做相关分析时对不同周期分别用了零阶保持与线性插值,并指出周期差异会影响标定。解析前应先统计每个 ID 的实测频率。

    证据等级与边界

    源文档对每条信号都给了证据分级。CONFIRMED 表示编码与用途都被独立验证(物理试验、日志相关或与参考交叉匹配);CONFIRMED-DECOMPILE 只说明编码来自反编译,用途仍是原厂标签;CONFIRMED-SYMM 由已确认信号的对称结构推出,没有独立测试;PARTIAL 表示编码确认但角色或刻度仍有未决问题——例如油压信号 GeneOilPress 的零点偏移未确认,其换算在怠速下会得到物理上不合理的数值。

    还有一类被明确记录为「异常」的条目。0x0451 曾被某类商业诊断工具误标为牵引逆变器扭矩,日志显示它其实是 GMLAN 报文,源文档已把对应条目移除;牵引逆变器热信号的真实 ID 是 0x044A,而非工具里列的 0x0459(后者在所有日志中为零帧)。

    边界上必须强调:以上结论仅来自源文档记录的这一台 Vtrux 与这一台 Coda 及其固件与校准。不同年款、不同 BMS 变体,甚至同一车型换了电池包,位置与刻度都可能变化,实车读取前应先在目标车上复核。

    常见问题

    Vtrux 的 OBD 口能直接抓到全部三条总线吗?

    三条总线在 J1962 口上都有引脚可达(Powertrain 1/9、Vehicle 6/14、OBD 10/2),但日志里的通道号是任意的,必须用 anchor ID 判断当前通道对应哪条总线。另外 VCM 会对桥接内容做过滤与改写,因此「在车上抓到」不等于「拿到原始数据」。

    为什么同一辆车上车速会有两个来源?

    因为 VCM 掩零了发给 ECM 的轮速输入,ECM 于是算出零车速并广播 0x3E9,OBD 总线上的该广播因此恒为零。真实车速在 Vehicle 总线上,由 VCM 用真实轮速生成;标准 OBD PID 0x0D 也返回真实车速,但它由 VCM 自己应答,而不是把请求桥接给 ECM。

    标注 CONFIRMED 的信号可以直接拿来用吗?

    可以用,但要区分级别。CONFIRMED 表示编码与用途都被独立验证;CONFIRMED-DECOMPILE 与 CONFIRMED-SYMM 只解决了「编码是什么」,用途仍是推断或标签,源文档已明确保留这一不确定性。PARTIAL 条目在使用前应先补验证。

    这些解码能套用到别的 Vtrux 或 Coda 上吗?

    不能。源文档的全部结论都限定在被记录的这两辆车及其固件与校准上,并明确指出不同 BMS 变体、不同固件之间字节偏移与周期存在差异。换车使用前必须重新复核。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/nickyivyca-vtrux-coda/projects/vtrux/README.md(Vtrux 总线、网关与模块拓扑主来源)
    • 项目 01 —— public-can-dbc-datasets/additional/nickyivyca-vtrux-coda/projects/vtrux/notes/epri-verification.md(已解码信号的置信度分级与证据)
    • 项目 01 —— public-can-dbc-datasets/additional/nickyivyca-vtrux-coda/projects/coda/README.md(Coda 四总线、anchor ID 与解码条目)

    说明:本文整理自第三方开源项目的公开文档,仅代表该文档所记录的单个车辆样本,不代表同型号全系车型。CAN 与诊断操作存在风险,任何实车操作前请自行复核并遵守当地法规。

    更新记录

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

  • openpilot legacy 支持矩阵:可读车型与低速边界登记表

    结论:这份「车型 CAN 数据档案」记录的不是某一辆车的逐条报文,而是一套多车型支持矩阵:源文档以「原车纵向 / 自控纵向、出厂 ACC 是否被替换、低于多少速度不可用」为列,逐平台登记可读能力,并说明车辆数据由 opendbc 目录下的文件解释。换言之,它回答的是「这台车能否被读取、由谁供给纵向控制、低速边界在哪」,而不是「0x1XX 的第几个字节是什么」。下述结论仅限源文档登记的那份 legacy 支持清单,不能外推到清单之外的车型、年款或市场版本;源文档本身也未提供任何逐信号 DBC 定义。

    车辆与适用范围

    源文档是一份开源驾驶辅助系统的总览说明,覆盖其官方支持与社区维护两级车辆名单。数据来自该项目的公开文档快照,不是对某台实车的采集记录,因此这里不存在「采样了几小时、几万帧」的采集跨度,只有一份能力登记表。

    项 内容
    车型 多品牌多车型的平台集合(Acura、Honda、Hyundai、Lexus、Toyota、Subaru、Volkswagen 等)
    年款 / 市场版本 以「美国市场参照(US Market Reference)」列登记,年款随平台不同;源文档未确认其他市场版本的对应关系
    ECU / 改装状态 分「官方支持」与「社区维护」两级;部分平台需断开驾驶员支持单元(DSU)或加装 ASCM 线束才能由本系统接管纵向
    采集跨度 源文档未提供日志数或事务数,仅提供能力矩阵与目录结构
    适用范围 仅覆盖源文档列出的平台与年款区间;社区维护平台未被上游安全模型验证

    总线与寻址

    源文档不描述物理层细节,只在目录结构中说明 opendbc「展示如何解释来自车辆的数据」,并由 selfdrive/car 承载各车型的状态读取与执行器控制。也就是说,寻址方式、比特率与帧格式都在被引用的 DBC 与车型代码里,本快照未包含这些定义本身。

    项 内容
    物理层 源文档未给出(由各车型 DBC / 适配器决定)
    链路层 / 比特率 源文档未给出
    寻址方式 源文档未给出;仅提及 opendbc 存放「如何解释数据」的文件
    CAN FD 源文档未提供该版本是否包含 CAN FD 车型
    承载硬件 EON DevKit 或 comma two,配合车型线束;实验场景可用带外置摄像头的 Ubuntu 电脑

    已解码信号

    本项目的源文档是一张能力矩阵,而非逐信号解码表。为保持「只抄源文档里有证据的条目」这一原则,下表登记的是源文档逐平台明确给出的可读字段(支持包、ACC 供给方、低速边界),并逐条注明证据页。任何涉及具体字节、DID 或缩放系数的内容,源文档均未提供。

    平台(美国市场参照) 支持包 可读字段(ACC 供给 / 低速边界) 证据
    Acura ILX 2016-19 AcuraWatch Plus ACC 由本系统供给;低于 25mph 不可加速;低于 25mph 无 ALC Supported Cars 表
    Acura RDX 2019-21 All ACC 保留出厂;低于 0mph 不可加速;低于 3mph 无 ALC Supported Cars 表
    Honda Accord 2018-20 All ACC 保留出厂;低于 0mph 不可加速;低于 3mph 无 ALC Supported Cars 表
    Honda Civic Sedan/Coupe 2016-18 Honda Sensing ACC 由本系统供给;低于 0mph 不可加速;低于 12mph 无 ALC Supported Cars 表
    Honda CR-V 2017-20 Honda Sensing ACC 保留出厂;低于 0mph 不可加速;低于 12mph 无 ALC Supported Cars 表
    Hyundai Palisade 2020-21 All ACC 保留出厂;低于 0mph 不可加速;低于 0mph 无 ALC Supported Cars 表
    Lexus ES 2019-21 All ACC 由本系统供给;低于 0mph 不可加速;低于 0mph 无 ALC Supported Cars 表
    Toyota Camry 2018-20 All ACC 保留出厂;低于 0mph 不可加速;低于 0mph 无 ALC Supported Cars 表
    Toyota Corolla 2020-21 All ACC 由本系统供给;低于 0mph 不可加速;低于 0mph 无 ALC Supported Cars 表
    Toyota Rav4 2019-21 All ACC 由本系统供给;低于 0mph 不可加速;低于 0mph 无 ALC Supported Cars 表
    Toyota Prius 2016-20 TSS-P ACC 保留出厂;低于 0mph 不可加速;低于 0mph 无 ALC Supported Cars 表
    Subaru Forester 2019-21 EyeSight ACC 保留出厂;低于 0mph 不可加速;低于 0mph 无 ALC Supported Cars 表
    Volkswagen Golf 2015-19 Driver Assistance ACC 保留出厂;低于 0mph 不可加速;低于 0mph 无 ALC Community Maintained 表

    读取方法与注意事项

    源文档给出的操作条件集中在安装与接入层面:安装时在设备安装向导中输入指定的安装地址,随后按视频说明把设备固定到风挡;设备自带位姿自动标定,轻微的俯仰、偏航安装误差不影响性能。上车前需先确认当地法规是否禁止在风挡上放置物品。

    数据层面,源文档说明系统会记录面向道路的摄像头、CAN、GPS、IMU、磁力计、温度传感器、碰撞与系统日志;面向驾驶员的摄像头仅在设置中显式开启时记录,麦克风不记录。因此从 CAN 侧能拿到什么,取决于各车型的 opendbc 定义与本机车型代码,源文档并未展开。

    能力边界方面,官方支持的车型将被纳入上游安全模型验证;社区维护车型未被验证,需要先在 Settings->Developer->Enable Community Features 中打开开关才能使用,且使用时须格外谨慎。若要把社区平台提升为官方支持,需满足:brand 下至少拥有一辆车、对应线束在售、panda 与本系统均具备完整 ISO 26262 支持、存在纵向控制的推进路径、AEB 仍保持启用、且支持 fingerprinting 2.0。

    证据等级与边界

    本文全部内容属于「文档登记」,既不是实车观测,也不是外部旁证。能力矩阵中的每一行都来自源文档的表格,可核对;但表格只回答「该平台被登记为支持/社区支持」,不保证具体年款、市场版本、配置包与软件版本都能匹配。源文档用「美国市场参照」列明确提示了这一点。

    三处不能外推。第一,低速边界(No ACC accel below、No ALC below)是按平台登记的名义值,不是对某一台实车测得的曲线,同型号不同配置可能不同——例如源文档用脚注说明 2019 Honda Civic 1.6L Diesel Sedan 在 12mph 以下无 ALC,Camry 的 4CYL 部分配置边界为 28mph。第二,断开 DSU 或加装 ASCM 线束会让本系统接管 ACC,但同时关闭 AEB,这是功能取舍而非免费升级。第三,车速相关字段(如 ALC 边界)来自源文档表格,源文档未提供任何原始报文或 DBC 条目作为间接支持。

    关于「安全访问」类问题,源文档未提供任何绕过方法,且不建议尝试;本项目讨论的是公开文档登记的可读能力,不涉及对车辆安全机制的规避。

    常见问题

    这份档案为什么没有逐条 CAN 信号?

    因为主素材是一份多车型支持矩阵与安装说明,只登记「平台 / 支持包 / ACC 供给方 / 低速边界」四类字段,逐信号定义放在被引用但未包含在本快照内的 opendbc 文件中。这是素材本身的边界,不是解析遗漏。

    「ACC 由本系统供给」与「ACC 保留出厂」有什么区别?

    前者的纵向控制由本系统承担,后者仍由原车 ACC 执行、本系统只做横向。源文档同时提示:在部分平台上,需断开驾驶员支持单元(DSU)或加装社区 ASCM 线束才能切换,而这两种做法都会关闭原车 AEB。

    社区维护车型能当官方支持用吗?

    不能。源文档明确社区维护车型未经上游安全模型验证,须在开发者设置中手动开启社区功能,并提示使用时格外谨慎;升级为官方支持还需同时满足拥有车辆、线束在售、完整 ISO 26262、纵向路径、AEB 保持启用、支持 fingerprinting 2.0 等条件。

    低速边界能不能套用到同型号其他车?

    不建议。源文档的边界是按平台以「美国市场参照」登记的名义值,并以脚注给出个别配置的例外(如某柴油版 Civic 与部分 Camry 配置)。把它直接外推到其他年款、市场版本或配置,超出了源文档的证据范围。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/openpilotusers-opkr084-legacy-subset/README.md(本项目车型档案主来源:支持车型与社区维护车型矩阵、安装说明、目录结构)。

    说明:本文整理自第三方开源项目的公开文档,仅代表该文档所记录的单个车辆样本,不代表同型号全系车型。CAN 与诊断操作存在风险,任何实车操作前请自行复核并遵守当地法规。

    更新记录

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

  • 离线与实时两条数据管线:rlog/qlog 选择、时间归零与视窗边界

    结论:JotPluggler 把「离线看路段」和「实时看数据流」做成两条互斥管线:启动时路段与 --stream 互斥。离线路段的两次 Auto 选择可能读到不同文件——selected_log_path() 的 Auto 优先 rlog,而 detect_route_metadata() 的 Auto 优先 qlog,所以固定实验必须同时记录二者与 DBC。实时侧,Buffer (seconds) 在这条调用链上更像视窗宽度而非内存淘汰上限,长时流的内存上界尚无证据。

    启动:一条命令里的路段与实时流互斥

    main() 解析路段或 --stream(两者互斥)、窗口尺寸、布局和 PNG 输出。无输出路径且未显式 --show 时默认开窗口;路线模式可同步或异步加载。两个容易被误读的点:--output 是截图路径而非日志导出,且 save_framebuffer_png() 先写 PPM,再调用外部 convert,因此截图依赖额外程序并会产生文件。

    异步加载由 AsyncRouteLoader::Impl::start() 启动工作线程调用 load_route_data(),用原子计数发布下载/解析进度,consume() 在线程结束后交付结果或错误。它会先 join() 旧工作线程,因此切换路线可能等待旧加载完成;源文档指出这里未见取消令牌。进度数字是加载阶段信息,不是数据完整性证明。

    离线链:从选择到并行抽取

    离线链的每一步都有明确的失败模式:

    函数/组件 源码行为 需要注意
    load_route_data() 解析路线/片段选择,查询服务端或扫描本地目录,按 /r、/q、/a 选择日志;探测 carFingerprint 和 DBC,再并行抽取,构建 RouteData 与四类相机索引 两次 Auto 选择可能不同(见下节)
    load_route_series_parallel() 按路段并行加载 C++ LogReader,每段抽取曲线/CAN/日志/时间轴/缩略图;大段可再分块;最后按段序合并 任一路段缺失或加载失败会记录首个错误并整体抛出
    LogReader 对非空损坏前缀仍可能返回成功 图表「加载完成」不等于完整日志
    build_route_data() / apply_route_data() 对四类数据计算公共时间原点并归零,整理路径、时间轴、GPS;重建浏览索引、自定义曲线和相机索引 时间归零基准不等于路线首帧

    线程预算来自 load_worker_budget(),可用环境变量 JOTP_LOAD_WORKERS 调整。时间归零的细节值得单独记:build_route_data() 以可用数据算出的 x_min 为基准,不一定等于路线首帧或首段开始;跨工具比较时必须保存原始单调时间与该偏移,否则同一段路在两份数据里会「对不上」。

    rlog/qlog 的两次 Auto 选择可能不一致

    这是最容易导致复盘出错的一处:selected_log_path() 的 Auto 优先 rlog、缺失时用 qlog;但 detect_route_metadata() 的 Auto 优先 qlog 读取车型。也就是说,实际抽取的日志与读取车型的日志可能不是同一个文件。对于要复现的实验,必须同时记录这两个输入以及所用的 DBC,否则「车型识别结果」和「曲线数据」可能来自不同来源而不自知。

    实时流:四个阶段的批次交接

    实时侧从 start_stream_session() 切换模式开始,默认重置旧路线数据并启动 StreamPoller;暂停保留数据时只暂停消费,stop_stream_session() 区分保留与清空。之后是四段式的批次交接:

    阶段 组件 职责
    订阅 run_cereal_source() 本地地址固定 127.0.0.1;订阅 services,跳过编码数据、缩略图和原始音频;检查 Cap’n Proto word 对齐
    累加 StreamAccumulator 以首个事件单调时间为 offset;carParams 更新指纹/DBC;生成数值曲线与日志/告警时间轴
    交接 merge_batch() / consume() 按曲线路径和 CAN 标识合并后台待取批次;UI 线程移走批次和错误
    应用 apply_stream_batch() 追加到 AppSession::route_data,更新浏览、时间轴、CAN、GPS 与时间范围

    这里要分清职责:这是数据订阅,不是 CAN 发送网关。另外 StreamAccumulator::appendEvent() 会通过 with_parseable_event() 静默跳过本地 schema 无法解析的事件,因此 received_messages 只代表收到的消息数,不代表成功解析、提取或绘图——需要单独计数丢弃原因。

    时间与资源边界

    ensure_shared_range() 与 update_follow_range() 把 stream_buffer_seconds 用作显示窗口跨度;advance_playback() 操作的是 UI tracker,并非重新发布历史消息——不能把画面播放位置当作控制回放进度。

    当前追踪到的 apply_stream_batch() 对曲线、日志和 CAN 样本做追加,未见按 stream_buffer_seconds 裁剪旧样本;StreamPoller 保存该值用于快照而非消费端内存淘汰。所以「Buffer (seconds)」在这条调用链上更像视窗宽度,长时流的内存上界尚无证据——源文档把这列为需要长跑内存测试进一步验证的静态观察。

    还有一处进程级副作用:run_cereal_source() 在工作线程调用 setenv/unsetenv("ZMQ"),会影响同进程其他环境读取。源文档的建议是:若插件框架允许并发源,应改为显式传输配置,不能靠全局环境切换。

    插件化与验证

    可以把 RouteCatalog/LogLoader、EventExtractor、DbcResolver、StreamSource 和 ViewModel 作为只读插件分层,但必须统一 schema + 时间基准 + DBC 版本 + 来源 manifest。实时插件需独立声明网络地址、消息白名单、队列上限、后台背压和保留时长;不能因其能读 CAN/sendcan 主题就获得物理 CAN TX 权限。日志中包含位置、告警和车况,远端流应附授权与隐私策略。

    测试现状要如实标注:test_help() 只检查可执行文件帮助输出;源文档未见对路段缺口、损坏日志、实时断连、长时内存、同时间戳/乱序、DBC 热切换的同目录专门测试,也未运行编译或 GUI 验证。JotPluggler 其余 UI/图表/地图/自定义曲线组件仍待逐专题分析,不能把本篇视作整个目录已完成。

    常见问题

    为什么同一路段的车型识别和曲线数据可能对不上?

    因为 selected_log_path() 的 Auto 优先 rlog、缺失时 qlog,而 detect_route_metadata() 的 Auto 优先 qlog 读取车型,两次选择的输入文件可能不同。固定实验需要同时记录二者及 DBC。

    Buffer (seconds) 会限制内存增长吗?

    就当前追踪到的调用链而言不能这样理解。stream_buffer_seconds 被用作显示窗口跨度,apply_stream_batch() 未见按该值裁剪旧样本,StreamPoller 仅用它做快照。因此长时流的内存上界尚无证据,需要长跑内存测试验证。

    图表显示「加载完成」就代表日志完整吗?

    不代表。LogReader 对非空损坏前缀仍可能返回成功,而图表加载完成只反映流程结束;源文档明确「加载完成」不等于完整日志。此外任一路段缺失会记录首个错误并整体抛出。

    实时流的播放位置就是控制回放进度吗?

    不是。advance_playback() 操作的是 UI tracker,并非重新发布历史消息。把画面播放位置当作控制回放进度会产生误判。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/JOTPLUGGLER_DATA_PIPELINES_DEEP_DIVE.md(取用了离线链、rlog/qlog 双 Auto 选择、实时流批次交接与时间/资源边界)。
    • 项目 02 —— openpilot-research/CAR_PROTOCOL_IMPLEMENTATIONS.md(仅用于确认 DBC 与车型指纹在离线链中的探测位置)。

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

    更新记录

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

  • 大众四平台加斯巴鲁两代:一套安全模式为什么不能按品牌复用

    结论:品牌名不是能力边界。同一家车厂的不同平台在安全模式、报文地址、校验方式和控制类型上差异很大:大众至少要分成 MQB、MEB、MLB、PQ 四套,斯巴鲁至少要分成 Global Gen1/Gen2 与 Preglobal;插件能力必须按平台 + 固件 + 接线位置 + 总线拓扑 + 控制类型声明,不能按品牌名继承。而且该快照把大众 MLB/PQ 与斯巴鲁 Preglobal 放在 ALLOW_DEBUG 条件下,不能因源码实现存在就认定发布固件支持执行。以下基于源码快照 c8fb906 与固定版本 opendbc_repo 的静态阅读,未接目标 ECU、未验证具体年款。

    大众:四套平台不能合并

    参数层 CarInterface._get_params() 会按 PQ、MLB、MEB、默认 MQB 选择安全模式;变速箱、网关/前相机接入、盲区监测等由指纹决定。MEB 使用曲率控制且配置自控纵向;非 MEB 的 alphaLongitudinalAvailable 与 alpha_long 路径须结合实际发布配置判断,不能只看能力字段放行。另外,若 PT bus 编号不在首组,还会前置 noOutput 安全配置。

    层 关键组件 源码行为
    输入 CarState.update() 分发到 update_mqb/pq/meb/mlb();update_hca_state() 与 update_acc_fault() 是故障状态收敛点。
    控制 CarController.update() MEB 将目标曲率与测量曲率差补偿后限幅,控制转向功率逐步升降;其余平台按驾驶员扭矩限制目标扭矩。
    MEB 停车 MebLongStateMachine.update() 协调 ACC 状态、保持/起步/释放坡道与退出斜坡,避免停车保持直接切到无请求;它不是通用纵向 PID。
    雷达 RadarInterface.update() MEB 网关接法读取相机发布的过滤后轨迹,不是原始雷达点;校验消息、状态与重复 ID,维护目标生命周期。

    大众固件模式差异

    把四套平台的固件行为并排看,差异集中在校验、TX 白名单与纵向编译门上:

    模式 初始化、RX、TX 必须保留的区别
    MQB init()、rx()、tx() 原车 ACC 与自控纵向用不同 TX 白名单;纵向固件标志仅在 ALLOW_DEBUG 分支读取。RX 从 ESP、EPS、TSK、油门、刹车和按钮更新状态。
    MEB init()、rx()、tx() Gen2 的替代 CRC 与消息长度单独选择;TX 校验曲率、转向功率、ACC 加速度,并限制停车保持与起步请求。
    MLB init()、rx()、tx() TX 表只含转向、HUD 与原车 ACC 按钮,没有纵向加速/制动帧;六组 RX 全部显式忽略 checksum,但检查计数器。
    PQ init()、rx()、tx() 使用不同地址、XOR 校验和与计数器位置;纵向标志同样有 ALLOW_DEBUG 编译门。

    MLB 与 PQ 的细节很典型:MLB 的 TX 表根本不发纵向帧,且源码保留着校验 TODO,不能据「通用大众模式」推断它的校验能力;PQ 用 XOR 校验和与不同计数器位置,原车 ACC 与自控纵向的使能事件也不同。MEB 的停车保持即使 ACC 未激活仍可能影响车辆,因此必须维持独立固件门。

    斯巴鲁:Global 与 Preglobal

    参数层 CarInterface._get_params() 对 Preglobal 选 subaruPreglobal,其余选 subaru;Global Gen2 会写入安全参数。Preglobal、角度 LKAS、Hybrid 被标为 dashcamOnly,而此快照显式将 alphaLongitudinalAvailable=False,所以普通参数路径不会启用自控纵向——相关代码仍存在,不代表当前可用。

    层 关键组件 源码行为
    输入 CarState.update() 按 Gen2、Hybrid、Preglobal、角度 LKAS 改变刹车、轮速、巡航、转角来源;保留原车 EyeSight 报文副本供控制器改写。
    输出 CarController.update() 软件侧按驾驶员扭矩限幅;STEER_RATE_LIMITED 时在高转向速率下周期性切断请求以避免 EPS 故障。
    构帧 subarucan.py Global 与 Preglobal 的转向、EyeSight Distance、HUD 及校验和函数分开;不能把同名逻辑当作相同总线或相同编码。
    Global 固件 subaru_init()、subaru_rx_hook()、subaru_tx_hook() Gen2 的车速/制动/巡航来自 alt bus,Gen1 来自主总线;ES_Distance 仅准许取消且油门值必须为 inactive。
    Preglobal 固件 subaru_preglobal_init()、rx()、tx() 另一套报文地址与驾驶员扭矩符号,特定车型可反转扭矩方向;RX 对计数器/校验和的忽略有源码 TODO。

    Global 的纵向限值常量虽然存在,但当前 TX 路径没有放行纵向控制;Preglobal 的 TX 白名单也含 ES_Distance,按钮行为需按平台测试核对。ECU 生命周期上,只有 DISABLE_EYESIGHT 标志才会执行 EyeSight 通信控制,这条分支不能当作默认运行路径。

    对硬件与插件化的约束

    1. 插件能力必须按平台、固件、接线位置、总线拓扑与控制类型声明,不按品牌名继承。MEB 曲率控制、MQB/PQ/MLB 扭矩控制以及斯巴鲁 Global/Preglobal 不能共用一套执行器协议配置。
    2. 固件安全模式仍是独立硬件信任边界:插件可选择经审计的模式与参数,但不得改写 TX 白名单、CRC、转向/加速度限值,也不能以主机软件状态替代固件 RX 检查。
    3. 大众 MEB 的停车保持/起步是动作语义,不只是加速度数字;应在插件契约中显式建模,并用故障注入验证失联、错误 CRC、错误 bus、状态迁移及退出斜坡。
    4. 斯巴鲁 Hybrid、角度 LKAS、Preglobal 与大众 PQ/MLB 在源码中有待验证或发布限制,应保持被动,直到目标车的 DBC、帧重放、台架与封闭场地证据齐全。

    常见问题

    能不能写一套代码同时适配大众所有车型?

    不能。大众至少分 MQB、MEB、MLB、PQ 四套平台,安全模式、TX 白名单、校验方式与控制类型都不同。参数层必须按平台选择,MEB 用曲率控制,其余用扭矩控制,不能合并。

    源码里实现了某平台的纵向控制,就代表能用吗?

    不代表。此快照把大众 MLB/PQ 与斯巴鲁 Preglobal 放在 ALLOW_DEBUG 条件下,斯巴鲁还显式将 alphaLongitudinalAvailable=False。源码实现存在不等于发布固件支持执行。

    为什么 MLB 模式不能按「大众通用」假设校验能力?

    因为 MLB 的六组 RX 全部显式忽略 checksum、只检查计数器,源码还保留着校验 TODO。不能据通用大众模式推断它具备同样的完整性校验。

    斯巴鲁 Global 和 Preglobal 的报文可以复用吗?

    不可以。两者的转向、EyeSight Distance、HUD 以及校验和函数分开实现,Preglobal 还使用另一套报文地址与驾驶员扭矩符号、特定车型可反转扭矩方向。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/VW_SUBARU_DEEP_DIVE.md(大众与斯巴鲁车型实现专题,含源码行号索引)
    • 项目 02 —— openpilot-research/VOLKSWAGEN_MEB_PANDA_SAFETY_DEEP_DIVE.md(源文档指向的 MEB 安全钩子逐函数专题)
    • 项目 02 —— openpilot-research/SUBARU_GLOBAL_PANDA_SAFETY_DEEP_DIVE.md(源文档指向的斯巴鲁 Global 安全专题)

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

    更新记录

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

  • Mazda 52/45 迟滞与 Nissan 12 帧平均:三品牌横控差异

    结论:Chrysler、Nissan、Mazda 三家都保留了原车的纵向巡航控制,但横向控制、取消策略与安全模式差异显著,不能抽象成同一套报文插件。Nissan 用后轮速度做安全侧转角限制、驾驶员扭矩按 12 帧平均;Mazda 的最低价速度门用 52/45 km/h 上/下行迟滞并等待 LKAS_BLOCK 清除;Chrysler 的 Ram HD 与 CUSW 被标为 dashcamOnly,CUSW 还使用独立的 chryslerCusw 模式且固件注册仅在 ALLOW_DEBUG。本文为对本地 source/ 与固定版本 opendbc_repo 的静态阅读,未运行测试、未连接实板、未验证任何年款。

    Chrysler:多平台 EPS 电机扭矩

    CarInterface._get_params() 根据 Pacifica/Jeep、Ram DT、Ram HD、CUSW 选择安全模式与参数;Ram HD、CUSW 标为 dashcamOnly,CUSW 使用独立的 chryslerCusw 模式,其固件注册仅存在于 ALLOW_DEBUG 编译块。此快照中雷达解析接口虽存在,但始终 radarUnavailable=True。EPS 固件/车型还会影响最低转向速度。

    CarState.update() 与 update_cusw() 使用不同的状态映射,Ram 的 ACC 状态来自相机总线。CarController.update() 在软件侧按 EPS 测得扭矩限幅,按平台采用最低转向速度迟滞,并在 LKAS 控制位下降后等待一段帧数再重新使能,以避免 EPS 故障。chryslercan.py 里的构帧函数各自编码仪表、转向与巡航按钮,车型报文与 checksum 不能仅靠品牌名复用。

    层 关键入口 已核对行为
    参数 CarInterface._get_params() 按 Pacifica/Jeep、Ram DT、Ram HD、CUSW 选安全模式;Ram HD、CUSW 标 dashcamOnly;CUSW 注册仅 ALLOW_DEBUG
    输入 CarState.update() / update_cusw() 主流平台与 CUSW 用不同状态映射;Ram 的 ACC 状态来自相机总线
    输出 CarController.update() 按 EPS 测得扭矩限幅,采用最低转向速度迟滞,LKAS 位下降后等一段帧数再重新使能
    构帧 chryslercan.py create_lkas_hud()、create_lkas_command()、create_cruise_buttons() 分别编码
    固件 RX/TX chrysler_rx_hook() / chrysler_tx_hook() / chrysler_init() Pacifica/Jeep 与 Ram DT/HD 分别设扭矩、变化率与电机扭矩误差限值;按钮只允许取消或恢复
    CUSW 固件 chrysler_cusw_init() / rx() / tx() 另套地址、RX 表、扭矩限值与按钮位定义;注释仍记载转向故障待解决

    验证入口是 Chrysler 与 CUSW 的安全测试以及通用车型接口测试;这三品牌各自目录下尚无独立车型测试套件,本次也未运行。CUSW 即使源码可编译,其安全模式注册也仅存在于调试固件,注释仍记载转向故障待解决,不可视为量产可用。

    Nissan:转角控制与车型专属取消

    Nissan 侧选择 nissan 安全模式,采用转角控制与原车纵向;Altima 通过安全参数切换 EPS 及相关状态报文总线。此快照中雷达不可用,但不能据此认定原车 ADAS 的内部感知已被软件接管。

    CarState.update() 里,Altima 与其他车型的 PT/相机 bus 对调;后轮速度用于安全侧转角限制的原始速度,四轮均值用于平滑估计,驾驶员扭矩按 12 帧平均以避免误报。CarController.update() 先用一阶滤波平滑低速大转角指令,再按速度/实际角度限制目标,驾驶员施力时降低 EPS 可用扭矩上限。

    取消策略是 Nissan 最不能包装成通用插件的部分:Rogue/X-Trail/Altima 发送 CRUISE_THROTTLE 取消,Leaf 则用 create_cancel_msg() 把 CANCEL_SEATBELT 置位,让 ProPILOT 将其解释为安全带未系而退出,源码说明会伴随蜂鸣和警告——这是明确的 HMI/安全语义。

    层 关键入口 已核对行为
    参数 CarInterface._get_params() 选 nissan 安全模式、转角控制、原车纵向;Altima 切换 EPS 相关报文总线
    输入 CarState.update() / get_can_parsers() Altima 与其余车型 PT/相机 bus 对调;后轮速度用于安全侧转角限制;驾驶员扭矩按 12 帧平均
    输出 CarController.update() 低速大转角先一阶滤波,再按速度/实际角度限幅;驾驶员施力时降低 EPS 可用扭矩上限
    Leaf 取消 create_cancel_msg() 置 CANCEL_SEATBELT 使 ProPILOT 解释为安全带未系退出,源码说明伴随蜂鸣与警告
    固件 RX/TX nissan_rx_hook() / nissan_tx_hook() / nissan_init() 转角幅度与速度相关变化率由固件检查;0x20b 按钮帧只允许取消位;Leaf 0x280 在白名单但无逐位附加约束

    Nissan 的 RX 表显式忽略 checksum/counter,因此不能声称该路径有独立的报文完整性检验。此外,MCU 的 RX 变体锁定、Altima 总线、0x20B 按钮掩码与 Leaf 0x280 载荷边界都需按具体 DBC 与测试核对,不能只凭品牌推断。

    Mazda:扭矩控制与速度迟滞

    Mazda 选择 mazda 安全模式与扭矩调校;此快照仅 CX-5 2022、CX-9 2021 不标 dashcamOnly,部分车型有最低转向车速门。CarState.update() 解析四轮速度、原车巡航、踏板、驾驶员/EPS 扭矩及相机 LKAS 状态。

    最低速度门使用 52/45 km/h 上/下行迟滞,并等待 LKAS_BLOCK 清除;低速告警与临时转向故障由状态逻辑产生。CarController.update() 按驾驶员扭矩限幅 LKAS,踩刹车后延迟发取消以规避与原车巡航主开关的竞态,停车恢复按间隔发 Resume。mazdacan.py 的构帧函数使用不同来源与计数器,需要保持相机/主总线消息时序。

    层 关键入口 已核对行为
    参数 CarInterface._get_params() 选 mazda 安全模式与扭矩调校;仅 CX-5 2022、CX-9 2021 不标 dashcamOnly
    输入 CarState.update() 最低速度门用 52/45 km/h 上/下行迟滞,并等待 LKAS_BLOCK 清除
    输出 CarController.update() 按驾驶员扭矩限幅 LKAS;踩刹车后延迟发取消;停车恢复按间隔发 Resume
    构帧 mazdacan.py create_steering_control()、create_alert_command()、create_button_cmd() 来源与计数器各异
    固件 RX/TX mazda_rx_hook() / mazda_tx_hook() / mazda_init() LKAS 扭矩受最大值、速率、驾驶员反向扭矩约束;未使能时按钮帧只能是取消

    Mazda 的 RX 表忽略 checksum/counter/质量位,同样不能声称有独立报文完整性检验。

    三者共用同一套通用边界:指纹 DBC、CarState、CarController 与 panda 的 RX/TX 钩子,但具体报文与状态各自实现。验证入口包括 Chrysler、CUSW、Nissan、Mazda 各自的 panda 安全测试以及通用车型接口测试;这些测试覆盖按钮、平台扭矩与部分总线变体,本次均未运行。

    对硬件与插件化的含义

    1. 车型契约必须区分 Pacifica/Ram/CUSW、Altima/Leaf、CX-5/CX-9 的报文地址、总线、控制类型、计数器与发布状态,不能只给出 brand 和 canfd 两个字段。
    2. 调试固件的 Chrysler CUSW 与 Ram HD 路径、Nissan Leaf 的安全带模拟取消、Mazda 的刹车后取消延迟,都应列为需要人机交互与实车故障分析的高风险策略,不开放为通用插件选项。
    3. 软件限幅、倒车/低速/停用状态和原车辅助系统冲突,必须与 panda 的 TX 白名单和 RX 状态独立核对;缺少 checksum/counter 的 RX 路径还需额外评估错误帧、重放与总线时序失效。
    4. 目标车型应先做只读采集、DBC/总线回放、错误帧注入、台架与封闭场地验证;本篇不是上车许可。

    常见问题

    三个品牌能共用一套转向控制插件吗?

    不能。三者的报文地址、总线、控制类型(Chrysler 为 EPS 电机扭矩、Nissan 为转角、Mazda 为扭矩)与计数器都不同,且取消策略各异,因此不能抽象成同一套报文插件。

    Nissan Leaf 是怎么取消巡航的?

    它不用普通取消按钮,而是用 create_cancel_msg() 把 CANCEL_SEATBELT 置位,让 ProPILOT 将其解释为安全带未系而退出,源码说明会伴随蜂鸣和警告,具有明确 HMI/安全语义。

    Mazda 的最低转向速度门是多少?

    源文档给出的最低速度门使用 52/45 km/h 上/下行迟滞,并等待 LKAS_BLOCK 清除后才允许。该阈值出自源文档,本文未在实车验证。

    为什么说这些品牌的 RX 路径没有独立完整性校验?

    Nissan 与 Mazda 的 RX 表都显式忽略 checksum/counter(Mazda 还忽略质量位),Chrysler 的 CUSW 也是另套定义。缺少这些字段意味着错误帧、重放与总线时序失效需要额外评估。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/CHRYSLER_NISSAN_MAZDA_DEEP_DIVE.md(三品牌参数、输入/输出、构帧与固件 RX/TX 对照)
    • 项目 02 —— openpilot-research/CHRYSLER_PANDA_SAFETY_MODE_DEEP_DIVE.md(源文档指向的 Chrysler panda 安全函数级专题)
    • 项目 02 —— openpilot-research/PANDA_BOARD_DEEP_DIVE.md(源文档指向的板级执行专题)

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

    更新记录

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

  • Toyota 固件指纹:子版本不同也能命中同一车型的三级匹配

    结论:Toyota 的固件指纹识别是三级顺序匹配:先精确固件匹配,再通用「至少两个唯一 ECU」模糊匹配,最后才调用品牌自定义的平台码回退。平台码只比较「零件号-平台-主版本」键,不比较子版本,所以小版本更新仍可能命中旧车型数据库;而「模糊」只是容忍子版本差异,并不容忍任意 ECU 集合。候选不唯一时必须保持被动或人工核验,不能在控制插件里猜。

    平台配置不是运行时健康

    CAR 的每个枚举成员包含 CarSpecs、车型文档、动力/雷达 DBC 映射和静态 flags。构造平台时执行配置 init(),创建 CAR 枚举时写入平台名并冻结配置对象——这是一份冻结的静态表,不是运行时健康状态。

    几个容易混淆的映射:TSS2 配置默认指向 toyota_nodsu_pt_generated 和 toyota_tss2_adas;SecOC 配置改用 toyota_secoc_pt_generated。若配置含 RADAR_ACC,两个配置类都只留下动力 DBC,表示本快照不按对应雷达 DBC 解析该路径——不能推论车辆没有物理雷达。

    同理,ToyotaCarDocs 默认标注 Toyota A 线束,SecOC 车型文档另用 CUSTOM 支持类型。源文档强调:文档展示字段、DBC 可用性、CarParams.radarUnavailable 和实车传感器健康是四个不同维度。EPS_SCALE 对大多数车型默认 73,少数车型显式覆盖;它进入 Toyota safety 参数低字节与状态侧 EPS 扭矩缩放,不能作为插件自报的可信运行标定。

    固件查询的实际覆盖

    FW_QUERY_CONFIG 声明三组总线 0 诊断请求,各组有独立 ECU 白名单:

    组别 请求流程 边界
    KWP tester-present 后查询 0x1a8801 与其他组共享 ECU 白名单机制
    OBD 版本 短 tester-present 后查询 OBD 版本 独立白名单
    UDS 版本 tester-present / 默认会话 / 扩展会话后查询 UDS 版本 独立白名单

    其中 extra_ecus 只列出额外可查地址,并不表示都参与模糊匹配;部分车型的 ABS 或发动机 ECU 被列为 non_essential_ecus,用来处理缺报或多地址。源文档特别提醒:不能把「可缺席」理解成「该 ECU 的所有错误版本都允许通过」,具体精确匹配语义由通用的 match_fw_to_car_exact() 实施。

    匹配顺序:精确、通用模糊、品牌回退

    通用识别顺序是固定的三级,越靠后越宽松,但每一级都不做「最像的一款」打分:

    阶段 条件 结果处理
    精确固件匹配 固件版本与数据库精确命中 返回是否精确及候选集
    通用唯一 ECU 模糊匹配 「至少两个唯一 ECU」 可返回多个候选
    Toyota 平台码回退 仅当前品牌在模糊阶段尚无候选时调用 返回所有通过的候选

    关键规则在 get_car():只有固件候选恰好一个时,才用它覆盖 CAN 指纹结果;零个或多个候选则保留 CAN 识别结果,显式固定车型设置又可覆盖两者。源文档明确这里没有把唯一固件候选与 CAN 指纹做一致性合取。此外,match_fw_to_car_fuzzy() 虽然接收 vin 参数,但 Toyota 此实现没有读取该参数——VIN 字符串不能消解平台码歧义。

    平台码算法逐步拆解

    get_platform_codes() 从固件字节提取零件号/平台/主版本键,并保留子版本集合。它的步骤可以逐条核对:

    1. 检查首字节是否为 0x01 至 0x03 的块数;未命中则按单块处理。
    2. 总字节长度必须等于块数乘 16,否则跳过该固件。
    3. 每块去掉头尾零和空格,但仅解析第一块;第一块长度 8、10、12 时分别尝试 short、medium、long 正则,且正则使用 search(),不是额外的全字节锚定校验。
    4. 返回字典键为 platform-major(短格式)或 part-platform-major(中/长格式),值是子版本集合。
    5. 第二块和子版本可被保留或解析出来,却不参与最终车型键比较——因此小版本更新可以命中旧车型数据库。

    在模糊匹配阶段,match_fw_to_car_fuzzy() 对每个候选车型遍历数据库里类型属于 fwdCamera、fwdRadar、eps 的 ECU,以地址/子地址从实车固件表取版本;每个预期 ECU 至少要找到一个平台键,否则该候选失败;通过的部分必须覆盖候选的这些预期地址。最后减去 FUZZY_EXCLUDED_PLATFORMS——该集合在本快照为空。

    歧义与插件契约

    跨地址、漏回包、固件格式异常会导致匹配缺席;共享平台/主版本键则可能导致多个候选。源文档对此的定性很直白:这里的「模糊」是容忍子版本差异,不是容忍任意 ECU 集合,更不是把单条相机固件当作充分身份凭证。

    对于硬件自制或插件化平台,错误识别会连带选择错误的 DBC、转向模式和 safety 参数。因此源文档提出一条比现状更严格的拟议契约:车型识别服务应返回 CAN 候选、固件候选及其交叉一致性、证据 ECU/地址/原始回包、精确或模糊等级、冲突原因和数据集版本;安全核心在候选唯一、且 DBC/固件/safety 组合得到验证前,保持 noOutput。这是重构建议,不是当前行为。

    测试层面,test_toyota.py 检查角度/RADAR_ACC 标志属于 TSS2、当前 LTA 车型集合、TSS2 动力 DBC、必要 ECU 项和固件格式,并遍历数据库版本检查专属回退的唯一性与排除集合。但这只证明「现有固件数据库样本」受到约束,不能证明未知地区、替换 ECU 或故意构造的相似固件不会误识别;且本轮未运行这些测试。

    常见问题

    为什么小版本固件更新后还能识别成同一车型?

    因为 get_platform_codes() 返回的键只到「零件号-平台-主版本」,值是子版本集合,而子版本不参与最终车型键比较。第二块和子版本可被保留或解析出来,却不会被用来区分车型,所以小版本更新可以命中旧车型数据库。

    固件匹配失败一定会退回到品牌专用逻辑吗?

    不一定。顺序是精确固件匹配、通用模糊匹配,最后一层才调用 Toyota 自定义平台码回退,而且仅当当前品牌在模糊阶段尚无候选时才调用。若前面的阶段已经返回候选,就不会进入品牌回退。

    VIN 能帮助消除固件候选歧义吗?

    在这份实现里不能。match_fw_to_car_fuzzy() 虽然接收 vin 参数,但 Toyota 该实现没有读取该参数,因此 VIN 字符串不能消解平台码歧义。

    多个固件候选时,最终选哪个车型?

    get_car() 只有在固件候选恰好一个时才用它覆盖 CAN 指纹结果;零个或多个候选则保留 CAN 识别结果,显式固定车型设置又可覆盖两者。源文档说明这里没有把唯一固件候选与 CAN 指纹做一致性合取,因此歧义不会被自动「合取」消解。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/TOYOTA_PLATFORM_FIRMWARE_MATCHING_DEEP_DIVE.md(取用了 FW_QUERY_CONFIG 三组请求、三级匹配顺序、平台码算法步骤与拟议插件契约)。
    • 项目 02 —— openpilot-research/CAR_PROTOCOL_IMPLEMENTATIONS.md(仅用于确认 match_fw_to_car() 与 get_car() 在整条识别链中的位置)。

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

    更新记录

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

  • 2330 份 DBC、294 个来源:公开 CAN 数据集的收录与分级

    结论:公开 CAN/DBC 数据集的核心不是「收了多少文件」,而是「每个文件能不能溯源、能不能分级、能不能再分发」。本次整理收录 2,330 个 DBC 文件副本,来自 294 个 DBC 来源集合,收录日期为 2026-10-03 并扩至 2026-10-05;其中相当一部分条目只有「研究用途」而没有明确许可证,只能离线留存,不能当成可直接商用的车型字典。.dbc 只描述 CAN 标识符、位域、缩放、单位与枚举,它不是适配保证书。

    一次整理到底收了多少东西

    这次收录的主体是 DBC 文件:.dbc 与 .DBC 合计 2,330 个副本,分布在 294 个 DBC 来源集合里。之所以把「文件副本数」和「来源集合数」分开记,是因为同一份定义会在不同快照里反复出现;只看文件总数会高估真实覆盖度。

    DBC 之外还附带了一批原始数据,用来在信号定义之外做交叉验证:Renault Mascott 的 6 份 CAN 日志、Mitsubishi Outlander PHEV 的 11 份 CSV 抓包与 8 份 CMU 记录、Fiat Ducato X250 的 5 份 SLCAN 抓包、BMW PHEV BMS 的 7 份 CSV 日志、Volvo V50 的 3 份 CSV 抓包、RAM ProMaster 的 2 份 CAN-B 抓包,以及 Jeep/Dodge 的 3 份 ODS CAN 映射。

    另一部分是 opendbc/ 的本地副本,共 119 个 .dbc,包含 model/platform 定义与品牌级 generator 源文件,随附的许可证是 MIT。来源快照之间存在文件重叠,因此目录被刻意分开保存,而不是合并成一个扁平库——分开保存是为了保住每个文件的来源路径。

    类别 数量 说明
    DBC 文件副本 2,330 .dbc 与 .DBC,来自 294 个来源集合
    opendbc 本地副本 119 相邻工作区快照,含模型/平台与品牌 generator,MIT 许可
    原始 CAN 日志 / 抓包 数十份 Mascott 6、Outlander PHEV 11+8、Ducato X250 5、BMW PHEV BMS 7、Volvo V50 3、ProMaster 2、Jeep/Dodge ODS 3
    分析 / 转换工具 若干 抓包查看、格式转换与信号反推类工具

    为什么同一款车会出现多个 DBC 版本

    整理时最容易被误解的一点是「同车型为什么有好几份 DBC」。原因大多不是数据变多,而是来源重叠:一批 fork 里 77 个上游 DBC 与已归档文件字节完全相同,被直接省略;另一归档省略了 68 个上游重复文件与 1 个 parser 测试夹具;还有若干「仅行尾不同」的副本被判定为重复而不重复收录。

    因此整理用的计数口径是字节不同(byte-distinct),而不是「文件名不同」。真正的版本差异还包括:更新的信号定义、字段增删,甚至只是一处注释错别字。每个来源条目都记录了本地文件、车型覆盖、来源 Git 修订号和许可证,这样后续才能回答「这份 DBC 到底来自哪一次提交」。

    许可证决定「能不能再分发」

    收录不等于可用。公开来源里许可证状态差异很大:有的是 MIT、Apache-2.0、GPL-3.0、CC BY 4.0、CC BY-SA 4.0、CC0,也有大量条目写着「未找到许可证,仅作离线研究副本」。后者可以离线分析,但不代表可以再分发给第三方,更不代表可用于商业产品。

    许可证状态 可否再分发 整理时的处理
    MIT / Apache-2.0 可以 保留版权与署名声明
    GPL-3.0 可以(具传染性) 衍生作品需沿用同协议
    CC BY 4.0 / CC BY-SA 4.0 可以(需署名 / 同协议) 保留原作者署名
    CC0 1.0 可以 无附加限制
    未找到许可证 不可以 仅离线研究,不重分发;部分来源仅保留发现链接

    还有一层坑:上游仓库带 MIT,不代表其中每一份车辆定义都干净。「上游 MIT 但个别车辆定义可能另有来源或第三方权利」是明确写在质量说明里的,需要单独核查。个别来源的 LICENSE 甚至明确禁止复制,整理时只保留发现链接、不归档文件本体。

    DBC 只描述信号,不保证适配

    质量说明里有几条必须原样保留的边界:DBC 解码的是 CAN 标识符、位域、缩放、单位与枚举,它不构成通用适配保证,必须针对目标车辆的年款、市场、动力总成、ECU 与总线拓扑逐一核实;社区推导出的信号名与缩放往往不完整,在拿到只读抓包与独立测量之前,只能当作假设。

    此外,opendbc/ 副本是一份工作区快照,其原始 Git 提交号未被记录,其他下载来源则钉住了具体修订号。整理说明也明确划出红线:本目录不包含绕过防盗器、安全访问或操纵安全关键车辆控制的说明。安全研究类数据集(如带标签注入流量的车联网数据集)虽然也是公开来源,但性质是安全研究数据集而非信号 DBC,必须在隔离、离线的轨迹上实验。

    整理时留下的四条纪律

    1. 目录按来源分开,不按车型合并。来源路径是溯源链,合并即丢失。
    2. 用字节不同计数,不用文件名计数。行尾差异与上游重复要被识别并剔除。
    3. 许可证随文件一起记。没有许可证的只做离线研究,不进入可分发集合。
    4. 信号当假设,不当事实。DBC 与原始抓包并存,等待只读验证。

    常见问题

    有了公开 DBC 就能直接上车解码吗?

    不能直接等同。DBC 只给出标识符、位域、缩放、单位与枚举的解释方式,是否匹配还要按目标车辆的年款、市场、动力总成、ECU 和总线拓扑逐一核对;社区信号在通过只读抓包与独立测量验证前只能视为假设。

    为什么同一车型会出现多个 DBC 版本,哪个才对?

    多数是来源重叠造成的:同一份定义在不同快照里重复出现,或仅行尾不同。整理按「字节不同」计数,并保留每个来源的 Git 修订号;真正的版本差异要看字段增删与信号定义变化,不能只看文件名。

    没有许可证的 DBC 可以商用吗?

    不可以。收录里明确标注「未找到许可证,仅作离线研究副本」的条目,只能离线分析,不能重分发;个别来源的 LICENSE 甚至直接禁止复制,整理时只保留发现链接、不归档文件。

    DBC 数量能当作覆盖度指标吗?

    不能。2,330 个文件副本里存在大量上游重复与行尾差异副本,数量会被重复计数放大;更有意义的指标是「字节不同的定义数」加上「已验证车型 / 总目标车型」的比例。

    延伸阅读

    参考资料

    • 项目 01 —— car-scanner-research/public-can-dbc-datasets/README.md(收录规模、来源清单、许可证与质量说明、其他公开来源)
    • 项目 01 —— car-scanner-research/public-can-dbc-datasets/opendbc/dbc/README.md(opendbc 本地副本的项目说明与生成器结构)

    说明:本文为对固定素材快照的静态整理分析,未逐份打开并验证全部 DBC、未连接车辆、未验证目标车型的真实信号组合。文中所有数量、许可证与来源信息均出自源文档,标注为未验证的结论保留其原有边界。

    更新记录

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

  • 17 个品牌参数怎么构建:CarParams 冻结只到顶层,嵌套字典仍可变

    结论:车型参数不是一张静态表,而是「17 个品牌枚举 → PLATFORMS 候选字典 → CarSpecs 尺寸 + PlatformConfig 文档与 DBC → 品牌 _get_params() 覆写」的多段构建结果。冻结(freeze)只作用于配置对象这一层:flags 被锁定后不可改,但嵌套的 dbc_dict 与 car_docs 仍可原地修改,override() 返回的还是未冻结副本。因此「能生成 CarParams」只说明字典装载成功,既不等于该车型被识别,也不等于控制器获准发送。以下为固定源码快照 c8fb906 的静态结构分析。

    参数构建的顺序与产物

    values.py 汇集 17 个品牌的 CAR 枚举,并生成候选名到平台对象的 PLATFORMS 字典。每个平台带着三样东西:描述整车尺寸的 CarSpecs、记录文档与 DBC 映射的 PlatformConfig,以及一组 flags。枚举构造时给配置填 platform_str 并冻结配置对象;CarSpecs 本身是 frozen dataclass。

    真正把参数拼起来的是两段函数。get_std_params() 先写入车型名、横向最大加速度文档值、控制类型、轮速系数、PCM 巡航与纵向缺省;随后 get_params() 复制平台规格并调用品牌 _get_params()。这个钩子可以依据 CAN 指纹、固件、开发/发布模式设置总线、雷达、纵向与控制调参,是品牌策略的主要落点。

    品牌覆写之后,普通汽车会加 STD_CARGO_KG=136 kg,再按以 Civic 为基准的比例公式估计 rotationalInertia 与 tireStiffnessFront/Rear;notCar 跳过载荷。这里要强调:刚度与惯量是启发式缩放,不是本次车辆的在线辨识结果,自制硬件接入车型时这些动力学参数不保证准确。

    阶段 入口 产出或作用
    平台注册 values.py / PLATFORMS 17 个品牌候选名映射到平台对象与 PlatformConfig。
    共同缺省 get_std_params() 写入车型名、控制类型、轮速系数、巡航与纵向缺省。
    品牌覆写 品牌 _get_params() 按指纹/固件/模式设置总线、雷达、纵向、panda 安全配置。
    载荷与动力学 STD_CARGO_KG 与缩放公式 非 notCar 加 136 kg,估计转动惯量与轮胎刚度。

    冻结边界:顶层不可变,嵌套仍可变

    隔离探针确认了一个容易被误读的边界:创建 Platforms 子枚举时,PlatformsType.__new__() 给配置写入平台名并冻结,随后直接改 flags 会抛异常;但 dbc_dict 的条目与 car_docs 列表仍可原地修改。

    更关键的是 override() 的语义。对已冻结配置调用 override(flags=...) 会通过 dataclasses.replace() 产生一个未冻结的新对象,且新旧配置共用同一 dbc_dict 引用;相对地,CarSpecs.override() 返回的新规格仍是 frozen dataclass。也就是说,「冻结的是配置对象属性」不能被误解为整个嵌套对象图都经过不可变性与签名校验。自制插件若用 manifest 描述车型,需把嵌套映射与列表做不可变快照或深拷贝并纳入签名与哈希,不能只依赖顶层 freeze()。

    扭矩数据与横向回调

    横向能力由三份 TOML 与一组回调共同决定。get_torque_params() 读取 substitute.toml、params.toml、override.toml,以 legend 解释三列数值,结果缓存在进程内;同一候选若直接出现在多个 TOML 会抛异常,替代目标则按 override 优先、params 次之取值。configure_torque_tune() 设置 FRICTION、LAT_ACCEL_FACTOR、零 offset 与角度死区。

    缺省前馈 get_steer_feedforward_default() 约为目标转角乘车速平方,GM 等品牌可重写。缺省的 torque_from_lateral_accel_linear() 与 lateral_accel_from_torque_linear() 按 latAccelFactor 正反映射,品牌同样可替换。要注意 MAX_LAT_ACCEL_MEASURED 用于 CarParams.maxLateralAccel,而摩擦与侧向加速度因子进入扭矩调参,三者不能互换。

    源或函数 实际作用 关注点
    get_torque_params() 读取三份 TOML 并缓存结果 同候选出现在多个 TOML 会抛异常;替代目标按 override 优先。
    configure_torque_tune() 设置摩擦、侧向加速度因子、零 offset 与角度死区 数据表与平台覆写共同决定控制器输入,不能假设热改立即生效。
    get_steer_feedforward_default() 缺省前馈约为目标转角乘车速平方 GM 等品牌可重写,不是跨车型通用标定。
    torque_from_lateral_accel_linear() 按 latAccelFactor 正反映射扭矩与侧向加速度 需验证符号、单位、摩擦与零点。

    实例运行契约与基类扩展点

    CarInterfaceBase.__init__() 创建品牌 CarState、其 CANParser 集合与 CarController,并把解析器的 DBC 名传给控制器。update() 更新所有解析器、调用品牌状态函数、汇总 canValid/canTimeout 并处理仪表速度与按键;apply() 委派品牌控制器生成回报与待发 CAN 帧,但它不负责硬件限幅。

    仓储里还有几个常被忽略的基类语义:RadarInterfaceBase.update() 缺省每五次调用返回空雷达数据、其余返回 None;init()/deinit() 供品牌实施 ECU 初始化或恢复,基类为空,且 deinit() 在 card 退出时不保证被调用;get_interface_attr() 动态导入品牌 values/fingerprints 属性,ImportError/OSError 会被静默跳过,因此它并不是可靠的插件装载审计。

    基类接口 职责与边界
    __init__() 创建品牌 CarState、CANParser 与 CarController;DBC 名传给控制器。
    update() 更新解析器、汇总 canValid/canTimeout、处理仪表速度与按键。
    apply() 委派品牌控制器生成回报与待发帧,不负责硬件限幅。
    RadarInterfaceBase.update() 缺省每五次返回空雷达数据,其余返回 None,有雷达平台须覆写。
    init()/deinit() 品牌可实施 ECU 初始化或恢复;deinit() 不保证在 card 退出时被调用。
    get_interface_attr() 动态导入品牌属性,异常静默跳过,非可靠装载审计。

    插件化边界与验证缺口

    面向自制硬件,源文档给出的是一组建议设计而非已实现能力:平台插件以版本化 manifest 声明车型、硬件拓扑、DBC 哈希、固件证据、单位、参数范围与所需安全模式;参数构建拆成纯函数与受限生命周期钩子,_get_params()、init() 不应由普通诊断或 UI 插件获得原始 CAN 发送权;行车期间冻结参数与插件版本,重启后再重新识别与验证。

    同时应区分四个层级的门:「可生成 CarParams」「CANParser 正常」「控制器允许发送」「MCU 允许执行」;任一失败都应退回只读或 noOutput。需要提醒的是,现有测试只覆盖参数基本范围与空 CAN 下的不崩溃行为,不覆盖真实车型识别、DBC 真实性、全部 _get_params() 分支与实车动力学。自研硬件仍需要离线日志、台架与实车的分级验证。

    常见问题

    冻结后的 PlatformConfig 真的完全不能改吗?

    不是。冻结只锁住配置对象属性:flags 不可改会抛异常,但嵌套的 dbc_dict 条目与 car_docs 列表仍可原地修改。override() 还会通过 dataclasses.replace() 生成未冻结新对象,并且新旧配置共用同一 dbc_dict 引用。插件若依赖不可变性,需自行做深拷贝并纳入签名。

    STD_CARGO_KG 是 136 kg 吗,为什么有的车型不加?

    源文档给出 STD_CARGO_KG=136 kg,普通汽车在品牌覆写后加上,notCar 跳过载荷。转动惯量与轮胎刚度也是按以 Civic 为基准的比例公式估计的启发式缩放,不是本次车辆的在线辨识结果。

    get_non_essential_params() 能当作上车参数吗?

    不能。它用空 CAN 指纹、空固件及关闭的特性开关构建参数,自身文档明确警告缺少真实 FW/指纹时控制必需参数可能不完整或错误,适合文档、测试与离线展示,不是上车控制参数的证明。

    同一个候选车型出现在多个扭矩 TOML 会怎样?

    会抛异常。源文档说明:同一候选若直接出现在多个 TOML 会抛异常;被替换的目标则按 override 优先、params 次之取值。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/CAR_PLATFORM_PARAMS_CONTRACT_DEEP_DIVE.md(参数构建顺序、冻结边界、扭矩 TOML 与基类实例契约)。
    • 项目 02 —— openpilot-research/ 同目录探针记录:四项平台配置冻结契约与假平台枚举隔离探针结论。

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

    更新记录

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

  • 17 个车型目录与 DBC 编解码:车型指纹为什么不能只看一条报文

    结论:车型识别不是「看到某条报文就认出车」,而是一条固定链路:panda 收帧 → CAN 指纹 → ECU 固件匹配 → 生成 CarParams / safetyConfigs → DBC 编解码 → 车型 CarState/CarController。在固定源码快照里,17 个车型目录只证明「实现入口存在」,不构成对任何年款、平台的适用性声明;未识别或模糊匹配的候选会被降为被动(noOutput),而不是「先跑起来再说」。

    车型实现的共同骨架:五个模块各管一段

    车型能力的加载入口是 load_interfaces(),它由 BRANDS 加载车型 CarInterface,不是运行时扫描任意插件目录。也就是说,能不能被识别,先取决于是否在注册表里,而不是目录里有没有文件。

    每个品牌常规包含四个模块:values.py 负责车型枚举与物理配置;interface.py 负责车型参数与安全模式;carstate.py 把接收帧变成 CarState;carcontroller.py 把 CarControl 变成候选发送帧。部分品牌另有 radar_interface.py。四者职责不能互相替代——这是接口契约,不是风格问题。

    把整条链路摊开看:panda 接收 CAN,交给 card;card 做指纹与 ECU 固件匹配,得到 CarParams 与 safetyConfigs;同一路用 DBC 加 CANParser 解出车型 CarState.update;controlsd 产出 carControl,交回车型 CarController.update;再经 DBC 加 CANPacker 编码为 sendcan,由 pandad 经 USB 发出,最终落在 panda 固件的 safety_tx_hook。主机侧解码和编码只是前段,是否真正上总线由固件独立许可。

    17 个车型目录索引:是入口索引,不是适用性声明

    下表仅证明固定快照中的实现入口存在——每个目录的 interface.py、carstate.py、carcontroller.py、values.py 均已在目录中核对。它不代表已完成 17 个品牌、所有平台和年款的报文与安全审计。

    品牌目录 额外雷达接口 当前深度
    body 无 非汽车双轮平台链路已追踪
    byd 无 Atto 3 转角链路已追踪,仅调试安全模式
    chrysler 有 Pacifica/Ram/CUSW 主要链路已追踪
    ford 有 经典 CAN/CAN FD 主要链路已追踪
    gm 有 ASCM/相机 ACC 主要链路已追踪
    honda 有 Nidec/Bosch 主要链路已追踪
    hyundai 有 经典 CAN/CAN FD 主要链路已追踪
    mazda 无 扭矩/速度迟滞主要链路已追踪
    mg 无 扭矩链路已追踪,仅调试安全模式
    mock 无 非实车空发送回退已追踪
    nissan 无 转角/车型取消主要链路已追踪
    psa 无 三总线转角链路已追踪,仅调试安全模式
    rivian 有 Gen1/Gen2 主要链路已追踪
    subaru 无 Global/Preglobal 主要链路已追踪
    tesla 有 转角/原车转发主要链路已追踪
    toyota 有 本篇样本已逐层追踪
    volkswagen 有 MQB/MEB/MLB/PQ 主要链路已追踪

    这张表不能用同一品牌的安全文件代替平台差异验证。例如 Hyundai 有 CAN FD 分支,Volkswagen 有多种平台安全模式,Subaru 有 preglobal 分支。尤其 set_safety_hooks() 注册表把 MG、PSA、BYD、Subaru Preglobal、Volkswagen MLB/PQ 等模式置于 ALLOW_DEBUG 条件下——实现目录和测试存在,并不表示发布固件可启用执行。

    从 CAN 指纹到 safetyConfigs:启动阶段的门

    识别发生在启动阶段,顺序由若干入口固定。下面每一行的边界都需要单独记住:

    入口 行为与边界
    can_fingerprint() 在总线 0/1 以 CAN 地址及数据长度逐步排除候选;超过限定帧数后停止,不保证未知车型能识别。
    fingerprint() 优先查询 VIN、ECU 存在性及固件版本,再收集 CAN 指纹;单一固件候选可覆盖 CAN 结果;环境变量可强制指纹,仅用于受控开发。
    match_fw_to_car() 先尝试精确固件匹配,失败再尝试模糊或品牌自定义匹配;返回是否精确及候选集。
    get_car() 无候选时回退 MOCK;用候选接口生成 CarParams,并保留 VIN、固件、指纹来源及模糊匹配标记。
    Car.__init__() 发布 CarParams;无控制器、开关关闭或仅仪表记录时设为 passive,安全配置改为 noOutput。
    Car.controls_update() 仅在进程初始化、非被动、carControl 存活的路径调用车型 apply() 形成 sendcan;首次进入时设置 ControlsReady。

    MOCK、passive、dashcamOnly 是不可等同的三种状态,但都不能作为「未知车型可以开始执行」的理由。用户配置或环境变量强制指纹,也不构成车辆协议兼容性验证。

    DBC 编解码的函数级语义

    DBC 层决定「字节怎么变成数、数怎么变成字节」,但它既不负责安全,也不负责身份。以下入口的语义是这张表的核心:

    入口 关键实现与含义
    DBC.__init__() / get_checksum_state() 从生成 DBC 或文件加载消息、信号、枚举;按 DBC 系列选择校验算法。
    get_raw_value() 按大小端与 bit 位提取原始整数;符号、倍率和偏移由 MessageState.parse() 处理。
    MessageState.parse() 解码信号、计算校验和与计数器;失败时返回 False,不把该帧的部分值提交到 vl。
    MessageState.update_counter() 递增错误计数,达到阈值拒绝;有效后逐步恢复。
    CANParser.update() 仅接收指定 bus 和已注册地址,更新 vl、本次所有值和时间戳,返回成功解析的地址集合。
    CANParser.can_valid / bus_timeout 前者检查已注册报文的最近成功时间、计数器及累计缺失次数;后者单独观察整条总线空窗,两者语义不同。
    CANPacker.pack() 反向应用倍率/偏移,编码信号,自动补计数器与校验和;未知信号仅记录错误并跳过,不负责安全许可。

    两个容易踩的边界:CANParser 的 vl 只保存最近一次成功解析值,不能只看数值而忽略 can_valid、时间戳与 bus 健康;can_valid 在读取时也会更新缺失计数,所以调用频率会影响去抖过程,它不是纯无副作用的 getter。另外,CANPacker 是协议编码器,不是转向扭矩或加速度安全门。

    面向插件化的最低契约

    把上面几层抽象成可替换的插件时,有五条底线必须写进契约:

    1. 车型插件声明平台、ECU 固件范围、DBC 版本、总线拓扑、能力位、CarParams 与安全模式;未识别或模糊匹配默认被动。
    2. 解码插件输出值、时间戳、来源与校验/计数器/超时状态;不能把上次成功值伪装成当前有效观测。
    3. 控制插件只产生结构化 CarControl 或候选 CAN 帧;不能自行改固件白名单、安全模式、ControlsReady,或绕过 card/pandad。
    4. 硬件安全控制器独立于应用 CPU,实现 RX/TX/转发限制、心跳失效回退与板级故障处理;新硬件须用故障注入、SIL/HIL 与封闭场地验证。
    5. 每个目标车型逐一建立解析、编码、固件安全和回放基线;17 个品牌目录不是「一套通用线束或固件配置」规格。

    换句话说,能不能读到一条报文,与"这套配置能否在目标车上安全执行"是两个不同层级的问题。把前者当成后者,正是识别与安全最常被混淆的地方。

    常见问题

    为什么不能靠一条 CAN 报文就确定车型?

    因为 can_fingerprint() 是在总线 0/1 上以地址和数据长度逐步排除候选,超过限定帧数后会停止,源文档明确它不保证未知车型能识别;而 fingerprint() 还要结合 VIN、ECU 存在性与固件版本,单一固件候选才可能覆盖 CAN 结果。单条报文只是排除过程的一个输入。

    车型目录里有文件,是否代表这辆车就能用?

    不代表。17 个目录只证明实现入口存在,源文档特别说明它不代表已完成 17 个品牌、所有平台和年款的报文/安全审计;而且 MG、PSA、BYD 等模式被放在 ALLOW_DEBUG 条件下,实现目录和测试存在并不表示发布固件可启用执行。

    DBC 解析成功,是否意味着数据可信?

    不等于。CANParser 的 vl 只保存最近一次成功解析值,必须同时看 can_valid、时间戳与 bus 健康;can_valid 读取时会更新缺失计数,调用频率会影响去抖。数值正确但报文陈旧或总线超时,仍属于不可信输入。

    未识别或模糊匹配时,系统会怎样处理?

    get_car() 在无候选时回退 MOCK;当车型被设为 passive(无控制器、开关关闭或仅仪表记录)时,安全配置改为 noOutput。源文档强调 MOCK、passive、dashcamOnly 不可等同,且都不能作为未知车型开始执行的理由。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/CAR_PROTOCOL_IMPLEMENTATIONS.md(取用了 17 个车型目录索引、启动识别门、DBC 编解码函数语义与插件化最低契约)。
    • 项目 02 —— openpilot-research/CAN_PARSER_HEALTH_DEEP_DIVE.md(仅用于确认 can_valid/bus_timeout 的健康位语义边界,未取用其未公开内容)。

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

    更新记录

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