自动驾驶技术之——无人驾驶中的CAN总线
该技术贯穿整个无人驾驶系统,在提升可靠性方面发挥了关键作用。除了VCU接收器发送信号之外,在无人车上的某些特定传感器(如雷达、Mobileye摄像头)的信息传输也依赖于CAN总线。
前言
本文主要内容是——无人驾驶中的CAN(Controller Area Network )总线。
在整个无人驾驶系统中扮演着至关重要的角色
我在无人驾驶,个人如何研究?中提到过
实现一个无人驾驶系统时会经历多个层级:感知层面包括感应器等设备;随后是动力驱动系统;接着是数据整合与战略决策单元;最后是基础调控机制。
"传感器层级在本次分享中已做全面讲解,请问您对'驱动层'相关内容有了解吗?"
正文
高性能且具有高度可靠性的通信机制是一种叫做CAN的技术,在现代汽车电子系统中得到了广泛的应用。虽然关于CAN总线的工作原理及其特性并不是我们今天讨论的重点。本文的核心在于阐述无人驾驶系统如何接收并解析CAN消息后如何利用协议提取所需信息。从分析 CAN 总线中获得传感器信息是一项对于自动驾驶和汽车电子工程师来说都是基础且必要的技能
认识CAN消息
基于Apollo开源框架对CAN通信协议进行详细解析,在分析每一帧数据的基础上深入探讨其数据结构及其构成要素。

可以看到这个名为CanFrame的消息结构中包含4个关键信息,分别是:
1. uint32_t id
CAN消息的ID号。
因为使用的是基于总线的技术,在工业自动化系统中应用广泛;通过这种技术架构,在各个设备之间建立统一的数据传输通道。每个设备通过接收特定的数据包来处理 incoming messages,并根据这些数据包中的唯一标识符字段来识别不同的事件类型。这些数据包通常包含一个唯一的标识符字段,并且这个字段用于区分不同的事件类型。最初的设计能够支持从0到16383(十进制)即十六位二进制数这一范围内的数值编码。然而随着现代工业的发展需求不断增加这一传统设计已经无法满足实时性和数据传输速率的需求。为此开发了一种新的数据包格式这种新格式增加了最大值字段的数量并命名为'扩展数据包'而原来的格式则被称为'标准数据包'。
如果拿写信做比较,这个id就有点类似写在信件封面上的名字。
2. uint8_t len
CAN消息的有效长度。
每帧CAN消息能够传递至多8个无符号整形数据;同时也能传递包含有长度信息的布尔型数据块(大小为8\times1)。其中len的最大值设定为N=16;如果在该帧中的某些位未被使用,则对应的长度信息通常会小于或等于当前最大允许值(即不超过当前配置下的最大长度)。
3. uint8_t data[8]
CAN消息的实际数据。
如前所述,在每一帧CAN消息中最多包含64个布尔类型的数据信息,并可通过这些数据被表示为网格结构。
如上文所述,
如上图所示:

当我们缺乏通过CAN协议进行数据解析的能力时,在这种情况下所获取的数据就像是不可解的编码状态,并且几乎无法提取出任何有价值的信息。这也正是为何CAN消息具有高度复杂性的原因之一。
4. timestamp
CAN消息的时间戳。
时间戳代表的是接收该CAN消息的时间点。通过连续多帧的时间戳进行推导分析,可以得出该CAN消息的发送周期以及接收到的信息。
总体而言,在每帧CAN消息中最重要的信息其实是数据部分——即为一个8×8的布尔值矩阵。所谓的解析CAN消息的过程,则等同于对这些布尔类型信息进行解码或解析。
认识CAN协议
业界普遍采用以后缀名为dbc的文件来存储数据。德国Vector公司推出了一个名为CANdb++ Editor的应用程序,主要用于查看DBC文件。
如上图所示,则是一份 lane line dbc file for Mobileye. 文末将附带 CANdb++ Editor 安装包及相关获取途径以供参考.

以id号为0x766的LKA_Left_Lane_A为例,在Mobileye的无人车左侧车道线检测系统中包含着重要的信息数据:其中包含左侧车道线的偏移量与曲率等关键参数信息。在当前帧的数据包中(Message),通过五个关键信号(Signal)来表征这一区域的状态:分别为Lane_Type标识类型(类型)、Quality表示质量评估结果(质量)、Curvature表示曲线程度(弯曲度)、Curvature_Derivative表示曲率的变化速率(变化率)、Width_left_marking表示左侧标记条纹宽度(左右标记条宽)以及Position的位置坐标数据(位置坐标)。
每个信号的具体描述呈现于软件右侧区域,在其关键的三个参数已被以绿色背景突出显示的情况下。
1. Value Type(Unsigned或Signed)
存在某些物理量,在其描述过程中带有正负号。例如温度即是其中之一。相比之下,在描述另一些量时则不带符号,默认采用正值表示。例如曲率即是此类情况的一种典型表现形式。
2. Factor 和 Offset
这两个参数必须参与到实际的物理量运算中去,其中Factor代表倍率因子,Offset代表偏移量值。举例来说,Lane_Type和Quality信号其倍率因子设为1,偏移量值设为0,而其他类型的信号则采用小数值作为倍率因子进行处理。具体计算方法将在后续部分详细说明。
双击LKA_Left_Lane_A,打开Layout页,会发现很熟悉的方块阵列,如下图所示。

工程师关注的就是这块彩色图。由于该图上的每个小方块与data中的每一个bool量一一对应的关系,这也是CAN协议的本质。
解析CAN信号
因为彩色方块图与data之间存在一一对应关系,在叠加这两个图形后,请查看下图所示的数据图表。

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

1.Factor为1的物理量
基于Lane_Type和Quality的Factor设置为1且Offset设为0的情况下,其十进制数值是多少?对应的物理量即等于多少?
通过图形直观地可以看出, Quality这个信号占用两位二定位于, 其对应的二值编码为5, 换算后得到十值编码5; 而Lane_Type则占用了四位码定位, 其对应的四值编码表示为6, 计算得到最终的八值编码6.
此帧信号表明当前左车道线Lane_Type值为2且Quality值为3的状态。当处理整数值时通信双方应遵循既定规则例如Mobileye公司规定将Quality值为0或1视为车道线信心水平较低的情况建议避免采用此类参数;当Quality值为2时则表示信心水平中等建议继续使用;而Quality值为3则意味着信心水平较高建议放心使用该参数值。
2.Factor为小数的物理量
当Factor值不等于1时涉及的物理量中存在Position这类变量时,则需要通过移位运算来进行解析过程中的计算,并且该过程对应的公式结构维持不变。参考百度Apollo开源项目的实现思路。

这里的bytes即代表该CAN消息中的data。随后提取出包含Position信号的那一行,并将其分为两部分:第一部分是第1行的全部布尔值;第二部分是第2行的所有布尔值。因为在这条特定的CAN消息中,Position占用了高位和低位各8位。因此需要整合这两部分的数据进行计算,并分别赋值到32位整数x(高位)与32位整数t(低位)。
为了获得Position的二进制表示, 我们需要对高8 bit与低8 bit进行组合, 然后对高8 bit执行左移操作. 接着, 通过与低8 bit执行按bitwise OR运算, 就能获得Position变量中存储的真实位置信息. 为了实现这一目标, 我们首先会对整个数值执行左移16次操作. 接着再右移16次以便清除高位超出范围的部分. 最后, 我们会用这个变量乘以缩放因子并加上偏置量后就得到了真实的Position值. 将其真实值赋予单位meter后就可得到实际测量结果.
与CAN类似的通信协议
VCU及其相关雷达设备均采用CAN总线进行信号传输。随着CAN总线负载的增加,许多传感器转而采用了其他通信方式以应对更高的数据传输需求。例如,激光雷达由于其产生的点云数据体积较大,选择了局域网传输模式;而GPS和惯导系统则采用了串口通信模式以满足其特定的工作需求。
虽然通信方式和通信协议千差万别,但解析的方法都是一样的。
结语
好的(o)/~ ,这篇分享内容已经明确了CAN总线消息的解析流程。这部分知识涉及到了无人驾驶系统传感器驱动层的基本理论。
因为不同标识符(ID)所对应的CAN消息结构存在显著差异,在编写解析代码时必须高度谨慎。如果不如此操作,则可能导致后续处理中难以预料的问题出现。
如果你对CAN总线的解析还有什么疑问,可以在评论区与我互动。
▎本文转载自自动驾驶干货铺,作者:陈光,智车科技整编,转载请注明来源。
