标签: opendbc

  • 两套 Filter 与 PID:同名类为何不能直接替换 import

    结论:openpilot 里同时存在两套控制原语:opendbc 车型侧与 openpilot 主机侧的同名 FirstOrderFilter 与 PIDController。它们在一阶低通更新公式上一致,但在参数顺序、前馈倍率、限幅与积分回退上并不等价,因此同名类不等于可替换 API,也不能仅靠替换 import 完成迁移。

    两套原语并存:车型侧与主机侧

    opendbc 侧的实现位于 opendbc/car/common/filter_simple.py 与 opendbc/car/common/pid.py,服务车型控制器;openpilot 主仓库的同名实现在 common/filter_simple.py 与 common/pid.py,服务 controlsd、风扇控制等主机侧调用方。两者都用源码 diff 与三项原 PID 数值探针核对过,但未运行完整车型控制、CAN 或实车。

    把两套类当成一个接口,最直接的后果是第三位置参数含义错位、前馈被多乘或少乘一个倍率、限幅修改后的内部积分状态分叉。这些差异在静态等式一致时看不出来,只有在动态响应里才暴露。

    函数级对照:滤波与 PID 的差异

    行为 opendbc 实现 openpilot 实现 差异后果
    一阶低通 update() 用 alpha=dt/(rc+dt);update_dt() 可重算系数。 同一更新式,但只有 update_alpha(rc),dt 是公开字段。 当前相同参数下公式一致;插件若依赖 update_dt() 不能直接换成主仓库类。两者都不会自动读取真实采样间隔。
    第二种滤波 HighPassFilter.update() 返回快、慢两个低通输出之差,构造时要求 rc2 > rc1。 BounceFilter.update() 是带速度状态的 UI 动画原语。 高通类严格说是带通;与弹性滤波不是同类用途。
    PID 构造 参数顺序 k_p,k_i,k_f,k_d,...;标量用 numbers.Number 包装。 参数顺序 k_p,k_i,k_d,...;标量用 (int,float) 判断。 第三个位置参数在两套实现中含义不同,必须显式命名与适配。
    PID 前馈 update() 计算 f = feedforward * k_f,另有 override。 update() 直接 f = feedforward,没有 override。 相同 feedforward 值不保证相同输出;更新方法第四位置参数也分别是 override 与 feedforward。
    PID 积分 积分可按 0.3/rate 向零回退,普通更新按 1/rate 积分并按扣除 P/D/前馈后的输出裕度限幅。 对候选总输出越界方向抑制积分增长,同时用输出 neg_limit/pos_limit 直接夹积分项;允许 set_limits() 动态改限。 正下限及运行时收紧限幅会产生不同的内部状态,输出暂时相同不代表后续响应相同。
    PID 附加状态 error_integral 返回 i/k_i,reset() 清空分量。 reset() 清空分量,但无该属性。 当插值 k_i=0 时读取此属性会除零;属性值也随速度相关 k_i 改变。

    真实调用链:谁在用哪一套

    Toyota 控制器为纵向 PID 传 k_f=1、速度相关 k_i 和加速度上下限,每三帧更新加速度滤波器,并使用 HighPassFilter 的坡度动态分量。这里的采样频率是车型控制代码给出的名义频率,不是滤波器自动测得。Nissan 控制器按车速重设转角低通 rc,非横向激活时直接覆写 angle_filter.x,再经过车型角度限制;滤波参数与状态重置策略由车型层负责。

    body 控制器有车速和差速两个 PID,差速积分冻结判断读取 error_integral;当 CC.enabled 为假时输出目标转矩为零,但 PID 内部状态未在该分支调用 reset(),该状态延续的动态影响需要回放或台架核对。主机侧方面,横向 PID 与风扇控制导入的是 openpilot.common.pid,把车型 PID 的经验直接搬到这些调用方会改变前馈和积分语义。

    限幅探针揭示的积分状态差异

    三项原 PID 探针可用固定命令复现。取 k_i=0.004、rate=2、误差 5、前馈 50、输出范围 [30,100],主仓库 PID 把名义积分增量 0.01 夹为 i=30,输出 80;车型 PID 按前馈剩余裕度保留 i=0.01,输出 50.01。改成对称范围 [-100,100] 后两者此步均输出 50.01。这与风扇目标中的 30% 点火下限直接相关,但不等于车辆控制器也使用正下限。

    另一探针先在宽范围积累 i=20,再把输出上限从 100 收到 10 且误差置零:两者当前输出都被夹为 10,但主仓库 PID 保留 i=20,车型 PID 把 i 夹为 10。主仓库的横向与纵向控制器都会变更 PID 限幅,但探针只验证通用原语的构造案例,没有证明实际车型的参数变化会触发同一数值状态。插件迁移必须比较积分状态和后续恢复轨迹,不能只比较饱和帧输出。

    探针设置 主仓库 PID 车型 PID
    范围 [30,100]、误差 5、前馈 50 积分夹为 i=30,输出 80 保留 i=0.01,输出 50.01
    范围 [-100,100]、同参数 输出 50.01 输出 50.01
    先积累 i=20,上限收到 10,误差置零 输出 10,保留 i=20 输出 10,把 i 夹为 10

    面向插件化的约束

    对同一个采样周期,两套实现对「限幅是只夹输出还是也夹积分」的回答并不相同,这正是插件必须显式声明契约、而不能继承默认行为的原因。对滤波/PID 插件应显式记录实现来源、参数单位、采样周期、速度插值表、限幅、前馈倍率、接管与重置策略,不要以类名作为兼容性判断。适配层应使用关键字参数构造和更新,并用离线阶跃、饱和、接管、掉帧、失活重启用例比较输出与内部状态——静态等式一致不能证明车型在新硬件时序下等价。

    最后需要重申边界:这两套 Python 控制原语都只生成候选控制量;车型构帧、card 活动门和 panda MCU safety 仍是独立边界,不能由 PID 插件自行绕过。

    常见问题

    为什么两个同名的 FirstOrderFilter 不能直接互相替换?

    因为在当前相同参数下更新公式虽然一致,但 opendbc 版有 update_dt() 可重算系数、dt 是公开字段;主仓库版只有 update_alpha(rc)。依赖 update_dt() 的插件换成主仓库类会直接失败,两者也都不自动读取真实采样间隔。

    PIDController 的第三个位置参数为什么危险?

    opendbc 侧参数顺序是 k_p,k_i,k_f,k_d,...,主仓库侧是 k_p,k_i,k_d,...。第三个位置参数在两套实现中分别代表 k_f 和 k_d,位置传参迁移会静默改变含义,必须改用关键字参数并显式适配。

    相同错误与前馈下,两套 PID 的输出会一样吗?

    不保证。opendbc 侧计算 f = feedforward * k_f 并有 override,主仓库侧直接 f = feedforward。限幅探针也显示:范围 [30,100] 时两者输出分别为 80 与 50.01,仅当范围对称后才都输出 50.01。

    输出暂时相同是否代表两套 PID 等价?

    不代表。先积累 i=20 再把上限收到 10 时,两者当前输出都被夹为 10,但主仓库 PID 保留 i=20、车型 PID 把 i 夹为 10,后续恢复轨迹不同。迁移必须比较积分状态而非单帧输出。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/OPENDBC_FILTER_PID_CROSS_REPO_CONTRACT_DEEP_DIVE.md(取用了两套滤波/PID 的函数级对照、真实调用链与限幅探针数值)。
    • 项目 02 —— openpilot-research/COMMON_RUNTIME_PRIMITIVES_DEEP_DIVE.md(仅用于确认主仓库运行时算法原语的边界)。

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

    更新记录

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

  • opendbc 车型校验算法族:同名 CRC8 不可替换,RX/TX 共用函数

    结论:opendbc 的车型校验不是「一种 CRC8 走天下」,而是按品牌/平台硬绑定的一族函数:Honda 用半字节补码、Toyota 把帧长本身算进和、Chrysler 用 CRC8 J1850(初值与末异或均为 0xFF)、Hyundai CAN FD 用 CRC16 XMODEM、VW MQB/MEB 用 CRC8 H2F 再追加地址常量。同名「CRC8」只代表多项式查找表相同,地址、帧长、字节顺序与最终 XOR 各不相同,不构成车型间可替换的插件接口。更关键的是,RX 校验与 TX 生成共用同一个函数,任何「只改发送端」的假设都必须重新核对。

    每个校验函数都写死了覆盖字节与校验位位置

    在固定源码快照里,get_checksum_state() 按 DBC 名称与信号名把每帧绑定到一个具体函数。所谓「算法」其实由四件事共同决定:哪些字节进入计算、校验字段在哪个字节或半字节、初始值与末异或是什么、帧长是否参与。源文档明确指出,帧长度和字段位置本身就是协议的一部分,不能当作可省略的装载细节。

    下面的函数目录来自源文档的逐函数静态核对。注意「参与计算的内容」一列——同一种「CRC8」在 Chrysler、VW、body 三处覆盖的字节范围完全不同。

    家族 / 函数 实际参与计算的内容 重要前提
    honda_checksum() 地址各半字节、每个载荷字节的高低半字节;末字节仅取高半字节,结果为 8 - sum,扩展 ID 再加 3,截 4 位。 假定校验位在最后字节低半字节;扩展地址判据是 address > 0x7FF。
    toyota_checksum() len(d)、地址各字节和除最后一字节外的载荷字节,相加截 8 位。 假定校验在末字节,帧长本身参与计算。
    subaru_checksum() 地址各字节与除第一字节外的载荷,相加截 8 位。 Global 版本校验位默认在首字节;和 pre-global 手动辅助函数不是同一算法。
    chrysler_checksum() 对末字节以外数据查 CRC8 J1850 表,初值和末异或均为 0xFF。 不把地址计入此函数;checksum 按末字节处理。
    fca_giorgio_checksum() 同表、初值 0,末异或按地址 0xDE/0x106/0x122/其他 分别为 0x10/0xF6/0xF1/0x0A。 未识别地址落入通用 0x0A 分支;不能把四组样本扩大为所有 FCA 报文。
    hkg_can_fd_checksum() 从第 2 字节到末尾做 CRC16 XMODEM,再加入地址低、高字节;仅 8/16/24/32 字节追加特定末异或常量。 前两字节视作校验字段;其它长度不加表中常量,但函数自身不会拒绝。
    volkswagen_mqb_meb_checksum() 初值 0xFF,对第 1 字节起载荷做 CRC8 H2F;已知地址再按第二字节低半字节选 16 项常量追加一步,最终异或 0xFF。 首字节为校验位;未在常量表中的地址跳过附加常量步骤。
    tesla_checksum() 地址低、高字节加上除 checksum 字节外的所有载荷,截 8 位。 校验位置由 sig.start_bit 决定,不限固定末字节。
    body_checksum() 从倒数第 2 字节向首字节反向迭代做 CRC8 BODY,初值 0xFF。 仅最后一字节不进入计算,函数不检查其字段含义。
    byd_checksum() 前七字节之和按位取反再截 8 位。 固定覆盖前七字节;不是通用「跳过任意校验字段」的算法。
    psa_checksum() 地址选择 4 位初值,先在传入 bytearray 中清除校验半字节,再把全帧高低半字节求和,从初值中减去并截 4 位。 函数就地修改传入缓冲;RX 解析器传副本,TX packer 传当前构帧缓冲。

    CRC8H2F、CRC8J1850、CRC8BODY、CRC16_XMODEM 只是按多项式生成的查找表。查找表可以共享,但函数外层的地址、帧长、字节顺序和最终 XOR 无法共享,这正是「同名不同义」的根源。

    RX 校验与 TX 生成共用同一个函数

    源文档反复强调一个契约:RX 验证和 TX 生成走的是同一份实现,而不是「接收一套、发送另一套」。这带来两个直接后果。第一,校验位的位置往往由信号元数据决定,例如 tesla_checksum() 的校验位置由 sig.start_bit 决定,并非固定在末字节。第二,某些函数带有副作用,例如 psa_checksum() 会就地清除并回写传入缓冲里的校验半字节。

    副作用的差别决定了移植风险:接收解析器传入的是 bytearray(dat) 副本,因此就地修改不影响原始帧;而发送打包器传入的是当前工作缓冲。把这类函数当成无副作用纯函数重用,会直接改变构帧结果。同时,VW MLB 的 XOR 变体以 sig.start_bit // 8 定位整字节,说明「校验在哪个字节」不是全局常量,而是逐信号给定的。

    按「接收帧已有校验字节」选择变体,而不是按算法优劣

    VW MEB 提供了一个容易被误读的变体函数 volkswagen_meb_alt_crc_checksum():它对备用表内六个地址先按指定长度算另一组 CRC,只有候选值等于输入 d[0] 时才返回,否则退回标准 MQB/MEB CRC。这个语义是按接收帧里已经带着的校验字节来「认领」变体,并不代表发送端会主动优先采用备用值。

    源文档用三个隔离探针把边界固定下来,结果如下表。它们都使用原版函数与真实查找表,但只在纯函数层面运行,未加载完整车型 DBC、未发 CAN、未测 ECU。

    探针 输入 观察结果 结论边界
    MEB 双 CRC 选择 地址 0x0DB、64 字节零缓冲 备用长度 42,备用结果 0xEB、标准结果 0xED;d[0]=0 时选 0xED,改成 0xEB 时才选 0xEB CANPacker.pack() 默认从零缓冲开始,故不能凭接收端可识别备用 CRC 就推断发送端会按备用算法生成
    Hyundai 长度分支 长度 8/12/16/24/32 的全零缓冲 各长度均给出结果;12 字节路径不会被拒绝,只是不使用四种已列长度常量 仅验证函数分支,不代表 12 字节是该平台合法帧长
    PSA 就地修改 0x452、start_bit=0、输入 AB CD 返回校验半字节 1,同时把首字节原地改为 A0 移植时不能把该函数当无副作用纯函数

    把这几条合起来看:一个「接收端能认」的校验并不自动意味着「发送端会这么写」。当前实际发送函数是否涉及 MEB 那六个地址,需要按车型另做核对,本篇探针不说明已有车型发生过错误发送。

    「跳过校验字节」不是通用能力

    Subaru 有两个函数常被混为一谈:subaru_checksum() 是 Global 版本,校验位默认在首字节;subaru_preglobal_checksum() 则先用 packer 生成字节,再对除 checksum_byte 指定字节(默认第 7 字节)外的字节求和。后者由 pre-global 构帧函数显式填写 Checksum,不由 DBC.get_checksum_state() 自动绑定。同理,byd_checksum() 固定覆盖前七字节,也是一种特定布局,而不是「跳过任意校验字段」的通用规则。

    这些差异说明:校验算法必须和 DBC 名称、报文地址、DLC、校验字段位位置、覆盖字节范围、counter 位置一起版本化。只声明「用了 CRC8」在车型之间没有任何可迁移性。

    给协议插件的验收底线

    新车型的协议插件应把下列字段作为一个整体来管理和验收,缺一项都可能造成接收能过、发送写错,或反之。

    必须版本化的字段 为什么不能省
    DBC 名称、报文地址、DLC 决定帧长与字段位置,帧长本身参与部分算法(如 Toyota)。
    校验字段位位置、覆盖字节范围 Tesla 由 sig.start_bit 决定、Honda 在低半字节,不能固定假定末字节。
    counter 位置 与 checksum 同级参与健康判定,不能只看数值。
    CRC 多项式 / 初值 / 末异或 Chrysler 与 FCA Giorgio 同表不同初值与末异或。0x10/0xF6/0xF1/0x0A
    长度变体与 RX/TX 选择规则 MEB 备用 CRC 只在匹配接收字节时启用;Hyundai 只在 8/16/24/32 追加常量。

    测试层面,应在参考载荷上直接比对计算值与输出字节,并确认解析器确实接受本帧;还要覆盖坏 checksum、截短/超长帧、counter 回绕与未知地址。需要提醒的是,checksum 只检测某类传输错误,不提供发送身份认证,也不构成执行器安全约束——这些仍由可信的车型逻辑、panda safety 和物理台架验收承担。

    常见问题

    为什么同为「CRC8」,不同车型的校验函数不能互相替换?

    因为查找表相同不代表算法相同。Chrysler 用 CRC8 J1850 且初值与末异或均为 0xFF,VW MQB/MEB 用 CRC8 H2F、初值 0xFF 并追加地址常量,body 则从倒数第二字节反向迭代。地址、帧长、字节顺序和最终 XOR 各不相同,源文档明确指出相同「CRC8」名称不构成车型间可替换的插件接口。

    接收端能校验通过的备用 CRC,发送端也会照此生成吗?

    不会自动如此。MEB 备用函数只有候选值等于输入 d[0] 时才返回,否则退回标准 CRC,这是「按接收帧已有校验字节选择变体」的语义;而 CANPacker.pack() 默认从零缓冲开始,不会凭接收可识别就优先采用备用值。当前发送函数是否涉及那六个地址需按车型另核。

    PSA 校验函数可以直接当纯函数复用吗?

    不可以。源文档探针显示,psa_checksum() 对 0x452、start_bit=0、输入 AB CD 返回校验半字节 1 的同时,把首字节原地改成了 A0。接收解析器传的是副本,发送打包器传的是原始工作缓冲,移植时必须区分。

    checksum 通过是否等于报文安全可信?

    不等于。checksum 只检测某类传输错误,不提供发送身份认证或执行器安全约束。源文档明确这些仍由可信的车型逻辑、panda safety 和物理台架验收承担,并且本专题没有实板证据。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/OPENDBC_CHECKSUM_ALGORITHM_FAMILY_RX_TX_CONTRACT_DEEP_DIVE.md(取用了校验函数目录、RX/TX 共用函数的语义、三个隔离探针结果与插件验收字段清单)。

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

    更新记录

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

  • opendbc 车型档案:DBC 结构、指纹与安全模式

    结论:这份档案记录的是 opendbc——一个「用 Python 读写你的车」的开源库与 DBC 仓库集合,目标是让带 LKAS + ACC 的车(多为 2016 年后)都能被读状态、控油门刹车与转向。它最值得记录的不是某一辆车的信号,而是三件工程约定:DBC 预处理器把品牌级与车型级 DBC 合成 _generated 文件;指纹(fingerprinting)用 ECU 固件版本识别车型;安全模型让 panda 上电默认处于 SAFETY_SILENT(总线静默),必须先选安全模式才能发报文。逐条信号定义在各自的 DBC 里,本文只登记文档明确写出的示例与能力。

    车辆与适用范围

    源文档是 opendbc 项目的总说明与其 DBC 目录说明。它覆盖的车辆范围很宽,但支持清单放在被引用的 docs/CARS.md(本快照未包含)。

    项 内容
    车型 多品牌;指向「支持车型清单」与约 300 个车型的公开 CAN 数据集
    年款 / 市场版本 多为 2016 年后具备电子可执行转向、油门、刹车的车(因 LKAS/ACC 普及)
    ECU / 改装状态 通过 comma four 与车型线束接入两条 CAN 总线,其中一条被拆开用于注入本系统的执行报文
    采集跨度 源文档未给出统一跨度;提供约 300 车型的 CAN 片段数据集
    适用范围 仅限被登记支持并可被指纹识别的车型;自定义安全模式需自行编译烧录

    总线与寻址

    项目结构分为四层:opendbc/dbc/(DBC 仓库)、opendbc/can/(从 DBC 解析与构造报文的库)、opendbc/car/(与车辆交互的高层 Python 库)、opendbc/safety/(功能安全)。这些层共同决定「一辆车能被读到什么、能写什么」。

    项 内容
    物理层 由车型线束决定;线束接两条 CAN 总线并拆开其中一条用于注入
    链路层 / 比特率 源文档未给出(随车型 DBC 与适配器)
    寻址方式 源文档未给出;DBC 内以报文与信号为单位
    CAN FD 源文档未提及
    承载硬件 comma four + 车型线束 + panda;自定义安全模式需自行编译固件

    已解码信号

    源文档是项目总说明,不是逐车信号清单。下表登记文档中明确写出、可核对的示例与能力条目:信号示例来自 DBC 目录说明的书写范例,其余来自项目总说明的术语与结构。具体每辆车的完整信号以各自 DBC 为准。

    条目 位置 解码 / 含义 证据
    车速 DBC 信号示例 7|15@0+ (0.00278,0) [0|70] "m/s" dbc/README 书写范例
    加速踏板位置 DBC 信号示例 6|7@0+ (1,0) [0|100] "%"(留出首比特不分配) dbc/README 书写范例
    纵向加速度 报文 490 / LONG_ACCEL 注释原文:轮速导数,噪声大且会吸附到零 dbc/README 注释范例
    转向角 car 库读取 读出转向角等状态 README 首段
    油门 / 刹车 / 转向控制 执行器写入 控制油门、刹车、转向 README 首段
    EV 充电状态 读写目标 目标之一:读取并写入充电状态 README 首段
    门锁开 / 关 读写目标 目标之一:读写信门锁 README 首段
    雷达解析 radar_interface.py 解析(若车辆配备) README「Structure of a port」
    指纹 fingerprints.py ECU 固件版本数据库,用于识别车型 README「Structure of a port」
    安全模式状态 SAFETY_SILENT / SAFETY_ALLOUTPUT 上电默认静默;部分模式在发布固件中被禁用 README「Safety Model」
    DBC 预处理器产物 *_generated 由品牌 DBC + 车型 DBC 合成 dbc/README「DBC file preprocessor」
    公开 CAN 数据集 commaCarSegments 约 300 个车型的 CAN 数据 README「More resources」

    读取方法与注意事项

    接入第一步是硬件:拿到兼容车型的线束(若没有现成的,就从「开发者线束」起,再压接所需连接器),线束会把你接到两条 CAN 总线并暴露注入点。第二步是反向工程:先录一段包含丰富事件(开启 LKAS 与 ACC、把方向盘打到两端等)的 route,再用 cabana 打开分析。

    一个车型端口的代码结构很固定:carstate.py 解析状态、carcontroller.py 输出控制、<brand>can.py 是围绕 DBC 的构造辅助、fingerprints.py 存 ECU 固件版本、interface.py 是高层接口、radar_interface.py 解析雷达、values.py 枚举该品牌车型。

    DBC 层面有一个实用的约定:同一个品牌下不同车型的 DBC 大量重叠,因此项目提供预处理器,从「品牌 DBC + 车型 DBC」生成输出文件(_generated 后缀)。改动了源文件需重新运行生成脚本。文档还给出两条书写规范:注释直接写进 DBC(便于在 cabana 里查看/编辑),以及信号只用最少的比特——若不能确定某比特归属,就把它留空不分配,以避免误读。

    证据等级与边界

    本档案属于项目登记。可核对的是结构、命名、安全模型与文档示例;不支持据此列出任何一辆车的完整信号表,因为逐车定义在被引用但未包含在本快照内的 DBC 与 docs/CARS.md 里。

    三处不能外推。第一,「支持某品牌」不等于「支持某年款某配置」——支持清单以车型为单位,文档用术语明确区分 port(某车型的集成)与 brand(品牌)。第二,安全模式不是默认可用:panda 上电默认 SAFETY_SILENT,且 SAFETY_ALLOUTPUT 之类在发布固件中被禁用,需要自行编译烧录才能用。第三,DBC 示例里的数值(如 0.00278 的 m/s 系数)只是书写范例,不代表任何真实车型的标定。

    关于「安全访问」类问题:本文只整理公开文档登记的结构与安全模型,未涉及安全访问的绕过;源文档未提供绕过方法,且不建议尝试。

    常见问题

    opendbc 支持哪些车?

    见被引用的支持车型清单:任何具备 LKAS 与 ACC 的车都可能被支持,多为 2016 年后的车型。本快照只含项目总说明与 DBC 目录说明,未包含完整支持清单。

    怎么给一辆新车加支持?

    按「车型端口」的结构来做:先连上硬件并录一段含丰富事件的 route,再用 cabana 反向工程;随后补齐状态解析、控制输出、指纹与车型枚举等文件。相似车型已有支持时,大部分工作可能已经完成。

    panda 上电后能直接发报文吗?

    不能。上电默认处于 SAFETY_SILENT,总线被强制静默;必须先选择一个安全模式才能发送报文。部分模式(如 SAFETY_ALLOUTPUT)在发布固件中被禁用,需要自行编译烧录。

    DBC 里的 _generated 文件是怎么来的?

    由预处理器从「品牌 DBC + 车型 DBC」合成。源文件改动后需重新运行生成脚本,产物放在仓库根目录并带 _generated 后缀。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/commaai-opendbc-master-20261004/README.md(本项目车型档案主来源:项目结构、安全模型、端口结构与反向工程流程)。
    • 项目 01 —— public-can-dbc-datasets/additional/commaai-opendbc-master-20261004/dbc/README.md(DBC 目录说明:书写规范、预处理器与示例)。

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

    更新记录

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