0%

(十一)无人驾驶中的CAN消息解析

本文章学习总结自知乎大 V陈光《无人驾驶干货铺》专栏,查阅原文请移步这里

1 正文

实现一个无人驾驶系统,会有几个层级:感知层 → 融合层 → 规划层 → 控制层。更具体一点为:传感器层 → 驱动层 → 信息融合层 → 决策规划层 → 底层控制层。以百度推出的 Apollo 开源的代码为例做 CAN 消息的讲解,我们先看到每一帧的 CAN 消息是如何被定义的:

单帧CAN消息的定义

可以发现,这个名为 CanFrame 的消息结构体中包含 4 个关键信息,分别为:

(1) CAN 消息的 ID 号:uint32_t id
由于 CAN 总线上传播着大量 CAN 消息,因此两个节点进行通信时,会先看 id 号,以确保这是节点想要的 CAN 消息。最初 CAN 消息 id 号的范围是 000-7FF(16 进制数),但随着汽车电控信号的增多,需要传递的消息变多,信息不太够用了,工程师在 CAN 消息基础上,扩展了 id 号的范围,大大增加了 id 号的上限,并将改进后的 CAN 消息称为“扩展帧”,旧版 CAN 消息称为“普通帧”。

(2) CAN 消息的有效长度:uint8_t len
每一帧 CAN 消息最多能够传递 8 个 8 位无符号整形数据,或者说能够传递 8*8 的bool类型的数据,此处的 len 的最大值为 8。

(3) CAN 消息的实际数据:uint8_t data[8]
正如上文所述,每一帧 CAN 消息都至多包含 8*8 个bool类型数据,因此可通过 8*8 的矩阵,可视化 CAN 消息中的 data。如下图所示:

CAN数据示例

(4) CAN 消息的时间戳:timestamp
时间戳表示收到该 CAN 消息的时刻。通过连续多帧的时间戳,可计算出 CAN 消息的发送周期,也可用于判断 CAN 消息是否被持续收到。
如下图所示,为 Mobileye 提供的车道线的 dbc 文件:

Mobileye车道线dbc片段

每个信号的具体描述显示在软件右侧,其中与解析直接相关的三个要素已用
绿色框选中:

  • Value Type(Unsigned 或 Signed)
    某些物理量在描述时是有符号的,例如温度;而有些物理量则是没有符号的,例如曲率。
  • Factor 和 Offset
    Factor 是倍率,Offset 是偏移量,二者需要参与实际的物理量运算。例如 Lane_Type 和 Quality 信号的 Factor 为 1,Offset 为 0,而其他信号的 Factor 均为小数。

双击 LKA_Left_Lane_A,打开 Layout 页,如下图所示:

LKA_Left_Lane_A layout

将上文所述两图进行叠加,将得到如下图所示的 data 图:

CAN数据data图

每个信号物理量的计算公式为:

对于 Factor 为 1 的物理量:
由于 Lane_Type 和 Quality 的 Factor 为 1,Offset 为 0,因此十进制值为多少,实际物理量即为多少。从图中可以看出 Quality 信号占据两个位,二进制数 0011,对应的十进制数为:

Lane_Type 占据四个位,二进制数为 0010,对应的十进制数为:

故此帧信号表示此时的左车道线 Lane_Type 值为 2,Quality 值为 3。对于整数值,通信双方可以约定规则,例如 Mobileye 规定:Quality 为 0 或 1 时表示车道线的置信度较低,不推荐使用此时的值;2 表示置信度中等,3 表示置信度较高,可放心使用。

Factor 为小数的物理量:
对于 Factor 不为 1 的物理量,比如 Position,需要使用移位的方法进行解析,但解析公式保持不变。以百度 Apollo 提供的源码为例:

Apollo CAN解析源码示例

bytes 即为 CAN 消息中的 data,首先将 Position 信号所在的行取出来,将第 1 行的 8 个 bool 值存储在变量 t1 中,将第二行的 8 个 bool 值存储在变量 t0 中。由于在这条 CAN 消息中,Position 同时占据了高 8 位和低 8 位,因此需要将第一行和第二行所有的 bool 位拿来计算,高 8 位存储在 32 位的变量 x 中,低 8 位存储在 32 位的变量 t 中。现在需要将高 8 位和低 8 位拼接,将高 8 位左移 8 位,然后与低 8 位进行求或运算,即可得到 Position 的二进制值。随后进行的左移 16 位,再右移 16 位的操作是为了将 32 位的变量 x 的高 16 位全部初始化为 0(为什么不直接和 0x0000FFFF 进行按位与的操作?)。之后将 x 乘以 Factor 再加上 Offset 即可得到真实的 Position 值,给真实值加上单位 meter,即可获取实际的物理量。VCU、雷达等通过 CAN 总线传递信号,随着 CAN 的负载越来越高,很多传感器使用了其它通信方式,比如激光雷达的点云数据量太过庞大,使用的是局域网通信,而 GPS 和惯导使用的是串口通信。

2 参考

  1. 无人驾驶技术入门(十一)| 无人驾驶中的 CAN 消息解析

Thank you for your donate!