结论:StreetDrone 的 CAN 接口不是一份车型协议库,而是一条把 CAN 帧翻译成 ROS 话题的解码链。它的核心定义 databases/candatafile.dbc 有 36 条 BO_ 报文与 184 条 SG_ 信号,把平台/客户控制、诊断、GPS 与惯导报文混在同一份文件里;上游没有确立任何量产车型的年款适配,也没有给出独立的信号精度证据。真正决定它能不能进产品的是另外三件事:VERSION 字符串含异常字符、文件里挂着一条长度为 0 却带大量信号的 Vector 伪报文、以及仓库快照中找不到许可证文件。
ROS 话题里的三层数组:报文名、信号值与单位分开传
这个 ROS 节点订阅 /received_messages,为每条 CAN 报文在 /sd_state_msgs 上发布一个话题。它不做信号侧的强类型封装,而是把解码结果摊平成三层并行数组:报文层给出 message_names 与 message_ids,信号层在每个 message_data 元素里再给出 signal_names、signal_data 与 signal_units。这种结构的好处是新增报文不需要改消息定义,代价是取用方必须自己做索引对齐。
| 层级 | 字段 | 类型 | 取值含义 |
|---|---|---|---|
| 帧头 | std_msgs/Header header |
uint32 seq / time stamp / string frame_id |
标准 ROS 头,用于对齐时间戳 |
| 报文层 | string[] message_names |
字符串数组 | 与 DBC 报文名一一对应 |
| 报文层 | uint16[] message_ids |
无符号 16 位数组 | CAN 报文 ID,索引查找的入口 |
| 报文层 | sd_state_msgs/Message_Data[] message_data |
结构体数组 | 与 message_ids 同下标对齐 |
| 信号层 | string[] signal_names |
字符串数组 | 单条报文内的信号名 |
| 信号层 | float64[] signal_data |
双精度数组 | 已按 DBC 缩放解出的物理值 |
| 信号层 | string[] signal_units |
字符串数组 | 信号单位,与信号值同下标 |
看清楚这张表才能理解后面所有取数操作:没有 message_data.wheel_speed 这种字段,只有「先按 ID 找到下标,再用下标取三个数组」这一条路。单位随值一起下发,说明物理量换算已经在节点内完成,下游只负责消费。
36 条报文与 184 条信号:控制、诊断与定位混编
36 条报文除以 184 条信号,平均每条约 5 条信号,说明这份 DBC 里既有少量高位复用的控制/状态帧,也有信号数很少的稀疏帧。上游 README 明确写到,每个报文的细节都在 candatafile.dbc 里,并给出了大小端帧布局的外部说明链接,但并未逐条给出标定方法。因此把它当作「平台内部的解码契约」是合适的,当作「某款量产车的信号定义」则超出证据范围。
| 内容类别 | 是否在文件内 | 证据边界 |
|---|---|---|
| StreetDrone / 客户控制报文 | 包含 | 未给出执行机构分辨率与时延证据 |
| 诊断类报文 | 包含 | 未给出会话类型与服务号清单 |
| GPS 报文 | 包含 | 未给出坐标系、更新率与精度 |
| 惯性传感器报文 | 包含 | 未给出零偏、量程与标定方法 |
| 量产车型 / 年款适配 | 不包含 | README 未确立任何 make / model / year |
| 信号精度的独立证据 | 不包含 | README 中没有独立精度验证记录 |
| 常用报文速查表 | 另有文件 | 指向 message_index.pdf,不在 DBC 内 |
从报文 ID 到信号值:索引查找模型
上游给出的示例是取轮速报文:在 message_ids 里线性查找等于 280 的下标,命中后用同一个下标去取 message_names 与 message_data,再遍历该元素的三个数组打印信号名、值与单位。这里的 280 是 README 中的十进制写法,换算成十六进制为 0x118。整个模式没有任何 ID 到结构体的映射表,ID 就是唯一的键。
复现解码链:从 rosbag 回放到话题抽样
上游给出的运行方式是双终端:一端回放 can-interface/bags 下的 2020-02-28-12-19-00.bag(加 -l 循环播放),另一端构建并启动解码节点。这样无需实车即可验证 DBC 与节点的对齐情况。
| 步骤 | 操作 | 产物 / 判据 |
|---|---|---|
| 1 构建 | cd can-interface/catkin_ws 后 catkin_make |
工作空间编译通过 |
| 2 加载环境 | source devel/setup.bash |
自定义消息可被 rosmsg 找到 |
| 3 核对结构 | rosmsg show sd_state_msgs/SD_State_Msgs |
打印出三层数组定义 |
| 4 回放数据 | cd can-interface/bags 后 rosbag play -l 2020-02-28-12-19-00.bag |
模拟 /received_messages 输入 |
| 5 启动节点 | roslaunch sd_state_msgs sd_state_msgs.launch |
开始发布 /sd_state_msgs |
| 6 抽样验证 | rostopic echo -n1 /sd_state_msgs |
单帧三层数组,检查单位串是否为空 |
| 7 取指定报文 | 遍历 message_ids 命中 280,取 message_data[i] |
轮速信号名、值与单位 |
接入自写节点时还要补两处依赖声明:CMakeLists.txt 的 find_package(catkin REQUIRED COMPONENTS ...) 里加入 sd_state_msgs,package.xml 里同时写 build_depend 与 exec_depend。上游对 kinetic 版本的说明还给了排错路径:删掉 devel 与 build,rosdep install --from-paths src --ignore-src 后重新 catkin_make。
入库前必须核对的三处风险
这份 DBC 的问题不在信号数量,而在文件本身的规范性。它同时触发了「严格解析器可能直接拒绝」与「分发权利不可判定」两类风险,且两者都不能靠读信号定义发现。
| 风险点 | 具体表现 | 处理动作 |
|---|---|---|
VERSION 异常字符 |
版本串含非常规字符,部分解析器在文件头即报错 | 先用宽松解析器预检,必要时手工规整版本行 |
| 零长度伪报文 | 存在一条长度为 0 的 Vector 独立信号伪报文,却挂载大量信号 | 单独剥离该条定义,再校验其余报文的长度一致性 |
| 无许可证文件 | 检查的仓库快照里没有许可证文件,再分发权利不可判定 | 仅作离线研究副本,对外分发前先确认权利 |
| 车型适配缺位 | 未确立量产车型与原厂 CAN 装配关系 | 只作平台内解码参照,不写进车型协议档案 |
常见问题
这份 DBC 能直接解析量产车型的 CAN 吗?
不能。上游明确没有确立任何量产 make / model / year,也没有原厂 CAN 装配关系。36 条报文混合了 StreetDrone 与客户的控制报文、诊断报文、GPS 与惯导报文,属于平台自有的解码契约,只能作为同类平台的参照。
为什么 36 条报文里会混进 GPS 和惯导报文?
因为这份 DBC 描述的是整套平台状态话题,而不是某个 ECU 的收发矩阵。自动驾驶平台把定位与惯量传感器也挂到同一条解码链上,是常见的工程做法;代价是这份文件不能按「车型总线」口径去切分或复用。
严格解析器报错时第一步该查什么?
先查 VERSION 行与零长度伪报文这两处。文件里有一个含非常规字符的版本串,部分解析器在读文件头阶段就会失败;另有一条长度为 0 却挂载大量信号的 Vector 独立信号伪报文,会让长度校验失败。建议先剥离该条定义,再校验其余报文。
在 ROS 里取轮速报文 280 的信号值要几步?
核心是两步:先在 message_ids 里线性查找等于 280 的下标(280 是十进制写法,换算为 0x118),再用同一下标取 message_data 元素的 signal_names、signal_data 与 signal_units。前提是已完成 catkin_make、source devel/setup.bash,并在 CMakeLists.txt 与 package.xml 中声明 sd_state_msgs 依赖。
这份素材可以随产品分发吗?
不建议在未确认权利前分发。检查的仓库快照里没有找到任何许可证文件,再分发权利不可判定。当前定位是私有离线研究副本,若确需分发,应先向上游确认授权,并保留原始文件用于离线分析。
延伸阅读
- MARV 无人车的 CAN 集成层:35 报文与 115 信号 —— 同为无人车平台的 ROS 侧 CAN 集成口径
- ADS-DV 2021 的 CAN 架构:7 个 API、8 ms 节流与两套 DBC —— 自动驾驶平台的双 DBC 分工
- Kia Soul OSCC 档案:归一化命令与 200 ms 保活接口 —— 线控命令报文的接口约定
- 公共 CAN/DBC 数据集怎么选:四类来源与三道筛查 —— 把规范性与权利核对前置
参考资料
- 项目 01 ——
public-can-dbc-datasets/additional/hngu97-streetdrone-can/SOURCE.md(36 条 BO_ 与 184 条 SG_、VERSION 异常、零长度伪报文与许可证状态) - 项目 01 ——
public-can-dbc-datasets/additional/hngu97-streetdrone-can/UPSTREAM_README.md(ROS 消息结构、轮速报文 280 示例、kinetic 运行与排错步骤)
免责声明
本文所述 DBC 与解码链均来自公开仓库的说明文件,未经过独立实车验证,不代表车辆制造商或平台方的官方数据。不同车型年款、市场与固件版本可能存在差异。涉及安全相关用途时请仅作参考,并以实际测量与官方资料为准。
更新记录
- 2026-10-14 初稿
发表回复