您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



文章 咨询 工具 课程  
会员   
   
软件架构设计方法、案例与实践
9月24日-25日 北京+线上
AI辅助软件测试方法与实践
9月26日-27日 北京+线上
SysML和EA进行系统设计与建模
11月19-20日 北京+线上
   
 
 订阅
自动驾驶 | AutoWare底盘通信全解
 
作者:敢敢不敢写bug
  127  次浏览      5 次
 2025-9-5
 
编辑推荐:
本文从基础开始展开来介绍基础的知识以及详细的Autoware实机使用与扩展。希望对您的学习有所帮助。
本文来自于微信公众号敢敢AUTOHUB,由火龙果软件Alice编辑、推荐。

0. 简介

之前我们从定位内容还有标定内容展开聊了聊,其实剩下的还有规划、感知、底盘控制这些内容,《Autoware 技术代码解读(三)》是整个autoware.universe项目代码比较全的算法整理,而这一块底盘控制这块内容其实虽然不属于算法层面,但是也是比较重要的控制部分,这一块主要涉及到autoware发送的消息传输给底盘,实现对线控底盘的控制。我们会从基础开始展开来介绍基础的知识以及详细的Autoware实机使用与扩展。

1. 串行与并行

1.1 串行通信

串行通信是指数据通过单根线逐位发送的方式。在串行通信中,数据位按照特定的时序依次发送。以字母“C”的二进制表示(01000011)为例,数据位在时钟信号为高电平时接收,1用高电平表示,0用低电平表示。由于串行通信只需一根数据线,通常具有布线简单、成本低的优点,但在数据传输速率较高时可能会受到带宽和延迟的限制。

串行通信示意图

1.2 并行通信

并行通信则是通过多根导线同时传输多个数据位。在并行通信中,数据位可以在同一时刻被发送,从而实现高速数据传输。例如,在传输字母“C”的二进制表示时,8个数据位可以在时钟线为高电平时同时接收。这种方式能够提供更高的数据传输速率,但需要更多的导线连接,布线复杂度和成本也随之增加。

并行通信示意图

在实际应用中,UART、SPI、I2C、CAN等都是串行通信协议,因为它们通过一根数据线进行数据传输。CAN协议使用串行通信,通过一对差分信号线(CAN_H和CAN_L)进行数据传输。这种方式允许多个节点共享同一通信媒介。

2. 全双工与半双工

2.1 全双工

全双工通信允许数据在两个设备之间同时双向传输。就像我们在电话中可以同时说话和听对方一样,全双工通信提高了通信效率。在全双工系统中,数据可以在任意时刻从发送方发送到接收方,同时接收方也可以将数据发送回去。常见的全双工通信协议包括UART和SPI。

2.2 半双工

半双工通信则是指在同一时间内只能进行单向数据传输。尽管两个设备仍然可以互相通信,但在任何时刻只能有一个设备在发送数据。这种方式类似于对讲机,用户必须在说话前按下按钮以防止两个人同时讲话。由于半双工通信不需要额外的信号通道,因此其实现相对简单,但在数据传输效率上相对较低。I2C由于只有一条数据线,因此只能实现半双工通信。CAN协议本质上是半双工的,因为在同一时间内只能有一个节点在发送数据。所以很多时候I2C和CAN一样可以一带多,但是这两者又不太一样。

I2C:I2C是一个串行通信协议,通常由一个主设备和多个从设备组成。主设备通过一个共享的总线(通常包括数据线SDA和时钟线SCL)与所有从设备进行通信。主设备通过发送地址来选择特定的从设备,因此I2C确实可以实现一带多的通信。

CAN:CAN是一种多主机协议,任何节点都可以在总线上发送和接收消息。虽然CAN也可以实现一个节点(如ECU)与多个其他节点(如传感器和执行器)之间的通信,但其实现方式与I2C有所不同。

3. 同步通信与异步通信

同步通信和异步通信是两种不同的信号传输模式,它们的关键区别在于发送方和接收方之间的时序关系。

3.1 同步通信

同步通信是一种阻塞模式,发送方在发送数据后,必须等待接收方的响应才能继续发送下一个数据包。在这种模式下,数据发送的时机是由时钟信号决定的,发送方和接收方之间需要保持时钟同步,以确保数据的正确接收和解析。常见的同步通信协议包括CAN, SPI和I2C,它们都使用时钟线来协调数据传输的时机。

3.2 异步通信

异步通信是一种非阻塞模式,发送方在发送数据后,不需要等待接收方的响应即可继续发送下一个数据包。这意味着发送方和接收方之间不需要保持严格的时钟同步。UART协议是典型的异步通信方式,它只使用两根数据线(发送和接收),发送方在发送完数据后不会确认接收方是否收到数据。这种方式适用于传输延迟不敏感的应用场景。

4. 多种通信方式

4.1 UART通信

在UART通信中,两个UART直接相互通信。 发送UART将控制设备(如CPU)的并行数据转换为串行形式,以串行方式将其发送到接收UART。只需要两条线即可在两个UART之间传输数据,数据从发送UART的Tx引脚流到接收UART的Rx引脚

UART属于异步通讯,这意味着没有时钟信号,取而代之的是在数据包中添加开始和停止位。这些位定义了数据包的开始和结束,因此接收UART知道何时读取这些数据。

当接收UART检测到起始位时,它将以特定波特率的频率读取。波特率是数据传输速度的度量,以每秒比特数(bps)表示。两个UART必须以大约相同的波特率工作,发送和接收UART之间的波特率只能相差约10%。

其工作原理是发送UART从数据总线获取并行数据后,它会添加一个起始位,一个奇偶校验位和一个停止位来组成数据包并从Tx引脚上逐位串行输出,接收UART在其Rx引脚上逐位读取数据包。

此外,UART数据包含有1个起始位,5至9个数据位(取决于UART),一个可选的奇偶校验位以及1个或2个停止位:

起始位

UART数据传输线通常在不传输数据时保持在高电压电平。开始传输时发送UART在一个时钟周期内将传输线从高电平拉低到低电平,当接收UART检测到高电压到低电压转换时,它开始以波特率的频率读取数据帧中的位。

数据帧

数据帧内包含正在传输的实际数据。如果使用奇偶校验位,则可以是5位,最多8位。如果不使用奇偶校验位,则数据帧的长度可以为9位。

校验位

奇偶校验位是接收UART判断传输期间是否有任何数据更改的方式。接收UART读取数据帧后,它将对值为1的位数进行计数,并检查总数是偶数还是奇数,是否与数据相匹配。

停止位

为了向数据包的结尾发出信号,发送UART将数据传输线从低电压驱动到高电压至少持续两位时间。

4.2 SPI总线

SPI是一种常见的设备通用通信协议。它有一个独特优势就是可以无中断传输数据,可以连续地发送或接收任意数量的位。而在I2C和UART中,数据以数据包的形式发送,有着限定位数。

在SPI设备中,设备分为主机与从机系统。主机是控制设备(通常是微控制器),而从机(通常是传感器,显示器或存储芯片)从主机那获取指令。一套SPI通讯共包含四种信号线:

MOSI (Master Output/Slave Input) – 信号线,主机输出,从机输入。

MISO (Master Input/Slave Output) – 信号线,主机输入,从机输出。

SCLK (Clock) – 时钟信号。

SS/CS (Slave Select/Chip Select) – 片选信号。

其工作原理是通过每个时钟周期传输一位数据,因此数据传输的速度取决于时钟信号的频率。 时钟信号由于是主机配置生成的,因此SPI通信始终由主机启动。

设备共享时钟信号的任何通信协议都称为同步。SPI是一种同步通信协议,还有一些异步通信不使用时钟信号。 例如在UART通信中,双方都设置为预先配置的波特率,该波特率决定了数据传输的速度和时序。

4.2.1 片选信号

主机通过拉低从机的CS/SS来使能通信。 在空闲/非传输状态下,片选线保持高电平。在主机上可以存在多个CS/SS引脚,允许主机与多个不同的从机进行通讯。

如果主机只有一个片选引脚可用,则可以通过以下方式连接这些从器件,当然因为SPI通信通过独立的SS线进行从设备的选择,而不是通过地址来实现的,所以如果这么链接则会导致所有的服务端会被触发,需要在软件端来自行判断:

4.2.2 传输步骤

第一步,主机输出时钟信号

第二步,主机拉低SS / CS引脚,激活从机

第三步,主机通过MOSI将数据发送给从机

如果需要响应,则从机通过MISO将数据返回给主机

因为SPI通讯无起始位和停止位,因此数据可以连续流传输而不会中断;没有像I2C这样的复杂的从站寻址系统,数据传输速率比I2C更高(几乎快两倍)。独立的MISO和MOSI线路,可以同时发送和接收数据。上述的这些也导致了SPI使用四根线(I2C和UART使用两根线),但却没有信号接收成功的确认(I2C拥有此功能),也没有任何形式的错误检查(如UART中的奇偶校验位等)。

4.3 I2C总线

I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可传送信息。它结合了 SPI 和 UART 的优点,您可以将多个从机连接到单个主机(如SPI那样),也可以使用多个主机控制一个或多个从机。当您想让多个微控制器将数据记录到单个存储卡或将文本显示到单个LCD时,这将非常有用。

SDA (Serial Data) – 数据线。

SCL (Serial Clock) – 时钟线。

I2C是串行通信协议,因此数据沿着SDA一点一点地传输。与SPI一样,I2C也需要时钟同步信号且时钟始终由主机控制。

I2C的数据传输是以多个msg的形式进行,每个msg都包含从机的二进制地址帧,以及一个或多个数据帧,还包括开始条件和停止条件,读/写位和数据帧之间的ACK / NACK位:

地址帧:每个从属设备唯一的7位或10位序列,用于主从设备之间的地址识别。

读/写位:一位,如果主机是向从机发送数据则为低电平,请求数据则为高电平。

ACK/NACK:消息中的每个帧后均带有一个ACK/NACK位。如果成功接收到地址帧或数据帧,接收设备会返回一个ACK位用于表示确认。

启停条件

4.3.1 寻址

由于I2C没有像SPI那样的片选线,因此它需要使用另一种方式来确认某一个从设备,而这个方式就是 —— 寻址 。

主机将要通信的从机地址发送给每个从机,然后每个从机将其与自己的地址进行比较。如果地址匹配,它将向主机发送一个低电平ACK位。如果不匹配,则不执行任何操作,SDA线保持高电平。

4.3.2 传输步骤

1. 在SCL线为高电平时,主机通过将SDA线从高电平切换到低电平来启动总线通信。

2. 主机向总线发送要与之通信的从机的7位或10位地址,以及读/写位:

3. 每个从机将主机发送的地址与其自己的地址进行比较。如果地址匹配,则从机通过将SDA线拉低一位返回一个ACK位。如果主机的地址与从机的地址不匹配,则从机将SDA线拉高(即代表结束)。

4. 主机发送或接收数据帧:

5. 传输完每个数据帧后,接收设备将另一个ACK位返回给发送方,以确认已成功接收到该帧:

6. 随后主机将SCL切换为高电平,然后再将SDA切换为高电平,从而向从机发送停止条件。

4.4 RS-232通信(补充)

属于串口的一种,因为用的比较多所以展开讲一讲,RS-232是一种广泛使用的串行通信标准,主要用于计算机和外部设备(如调制解调器、打印机等)之间的短距离通信。它定义了电气特性、信号传输和连接器的标准。

主要特点:

• 信号传输:RS-232使用单端信号传输。数据以逻辑电平的方式传输,逻辑“1”通常表示为+3V至+15V,而逻辑“0”表示为-3V至-15V。由于其负电压的使用,RS-232特别适合于噪声环境。

• 连接器:常见的RS-232连接器是DB9和DB25,分别支持9针和25针连接。

• 波特率:RS-232可以支持多种波特率,通常从300 bps到115200 bps不等。

数据格式:

RS-232通信的数据帧通常由起始位、数据位、奇偶校验位和停止位组成。数据位的数量一般为5至8位,奇偶校验位可选,停止位通常为1或2位。

优缺点:

• 优点:

• 硬件实现简单,适合短距离通信(通常在15米以内)。

• 支持全双工通信。

• 缺点:

• 传输距离有限,受到电缆质量和波特率的限制。

• 不适合多点通信,通常只能连接一个主机和一个从机。

4.5 RS-485通信(补充)

属于串口的一种,因为用的比较多所以展开讲一讲,RS-485串行总线广泛用于通信距离必须为几十米到几公里的时候。RS-485使用平衡的发射和差分接收,因此可以抑制共模干扰。除了总线收发器的高灵敏度外,它还可以检测低至200mV的电压,从而将发射的信号恢复到公里以上。RS-485使用半双工工作模式,任何时候只发送一个点。因此,发射电路必须由使能信号控制。

主要特点:

• 差分信号:RS-485使用差分信号传输,通过两条线路传输信号(A和B),减少了电磁干扰的影响和信号衰减。

• 多点通信:RS-485可以连接多达32个设备,适合组网通信。

• 传输距离:可以在最大1200米的距离内实现有效通信,波特率可高达10 Mbps。

数据格式:

RS-485的数据帧结构与RS-232类似,包含起始位、数据位、可选的奇偶校验位和停止位。

优缺点:

• 优点:

• 支持长距离传输和多个设备之间的通信。

• 在噪声环境中表现良好,适合工业应用。

• 缺点:

• 硬件实现相对复杂,需要差分收发器。

• 受限于总线的终端阻抗匹配要求。

4.6 CAN总线

CAN总线是一种异步串行通讯低层网络。对照OSI模型,CAN总线规范仅包含物理层和数据链路层的标准。然而,构建在CAN总线之上的应用层协议(即OSI模型的高层协议)有多种, 譬如针对汽车控制领域和工业控制领域的CANopen协议、针对工业控制领域的DeviceNet协议、针对公交车和卡车控制领域的SAE J1939协议、针对轻型电动汽车领域的EnergyBus协议等。其设计宗旨是提高通信的可靠性和实时性。

CAN的内容比较多,我们放到下一节着重来讲。这个方法非常便捷,只需要将设备挂载到总线上即可,不需要复杂的连线了。

5. CAN总线深入了解

首先我们知道CAN协议使用串行通信,通过一对差分信号线(CAN_H和CAN_L)进行数据传输。这种方式允许多个节点共享同一通信媒介。对于CAN来说主要存在两个CAN的物理层协议。

ISO 11898-3-2006 道路车辆--控制器局域网络(CAN)---低速容错专用媒体接口.ISO 11519-2-1994 道路车辆--低速系列数据通信---低速控制器区域网络.

其中标准ISO 11519-2-1994已经在2006年被ISO 11898-3-2006代替了,就是说符合标准ISO 11898-3的产品也是支持符合ISO 11519-2标准的产品。

ISO11898和 ISO11519-2 标准对于数据链路层的定义相同,物理层不同。ISO11898 是通信速度为 5kbps-1Mbps的 CAN 高速通信标准。高速CAN网络在每个网络端点端接一个120欧姆的电阻。它的总线最大长度为 40m,总线的两端各要求有一个“120 欧”的电阻,且两个线是闭环的。

ISO11519 是通信速度为 125kbps以下的 CAN 低速通信标准,也就是容错CAN(LSFT CAN)。提供从5 Kbit/s到125 Kbits/s的波特率。它的最大传输距离为 1km,该标准允许在CAN总线连线失败时CAN总线通信得以继续进行。由于终端的类型不同,因此高速和低速/容错CAN设备不能在同一个网络中使用。在低速开环总线网络中,两根总线是独立的、不形成闭环,要求每根总线上各串联有一个“2.2千欧”的电阻

与 I2C、SPI 等具有时钟信号的同步通讯方式不同,CAN 通讯并不是以时钟信号来进行同步的,它是一种异步通讯,只具有 CAN_High 和 CAN_Low 两条信号线,共同构成一组差分信号线,以差分信号的形式进行通讯。我们来看一个示意图。左边的是低速的开环总线网络,右边是高速的闭环总线网络,通过两个收发器才能做,不能两个放在一个收发器里面。

5.1 主要特点

高可靠性:CAN总线采用无主的网络架构,网络传输不依赖于主机的可靠性。CAN总线采用消息ID和消息体的传输机制(无网络节点ID),每个节点可发送或接收多个ID的消息,任何节点失效都不会影响其他节点和网络。

低成本:CAN总线物理层采用低压差分信号,CAN总线物理层接口的收发器成本与RS485收发器相接近,但CAN总线收发器具有网络侦测能力(每个节点都可以检测自己发出的信号)。

高传输效率:CAN总线使用面向位流编码的短数据帧,每个位都采用不归零编码,数据域最大长度位8字节。传输短数据帧时占用的网络周期短,受干扰或导致错误数据位的概率低,而且重传的时间也短。

易组网:CAN总线采用消息ID(11位或29位两种长度的消息ID)的二进制‘0’位的多少分配消息传输优先级,允许多个节点自动竞争和仲裁获取总线的占用权,甚至支持即插即用的节点。

开放协议和生态系统:CAN总线得到广泛应用的关键应归功于Bosch最初采用的开放版权策略,以及由半导体制造商(协议栈的硬件化)、汽车零部件开发商、软件开发商和行业协会等共同参与而打造的CAN总线生态。

下面是一个数据帧的图片,后面我们将围绕这一块来展开介绍:

5.2 通讯节点

从 CAN 通讯网络图可了解到,CAN 总线上可以挂载多个通讯节点,节点之间的信号经过总线传输,实现节点间通讯。由于 CAN 通讯协议不对节点进行地址编码,而是对数据内容进行编码的,所以网络中的节点个数理论上不受限制,只要总线的负载足够即可,可以通过中继器增强负载。

CAN 通讯节点由一个 CAN 控制器及 CAN 收发器组成,控制器与收发器之间通过 CAN_Tx 及CAN_Rx 信号线相连,收发器与 CAN 总线之间使用 CAN_High 及 CAN_Low 信号线相连。其中CAN_Tx 及 CAN_Rx 使用普通的类似 TTL 逻辑信号,而 CAN_High 及 CAN_Low 是一对差分信号线,使用比较特别的差分信号。

当 CAN 节点需要发送数据时,控制器把要发送的二进制编码通过 CAN_Tx 线发送到收发器,然后由收发器把这个普通的逻辑电平信号转化成差分信号,通过差分线CAN_High 和 CAN_Low 线输出到 CAN 总线网络。而通过收发器接收总线上的数据到控制器时,则是相反的过程,收发器把总线上收到的 CAN_High 及 CAN_Low 信号转化成普通的逻辑电平信号,通过 CAN_Rx 输出到控制器中。

目前有以下CAN电平转换芯片

TJA1050原理图如下:

5.3 什么是差分信号

差分信号又称差模信号,与传统使用单根信号线电压表示逻辑的方式有区别,使用差分信号传输时,需要两根信号线,这两个信号线的振幅相等,相位相反,通过两根信号线的电压差值来表示。相对于单信号线传输的方式,使用差分信号有以下优点

1. 传输抗干扰能力强,当外界存在噪声干扰时,几乎会同时耦合到两条信号线上

2. 能够抑制它对外部的电磁干扰,同样的道理,由于两根信号的极性相反,他们对外辐射的电磁场可以相互抵消

3. 时序定位精确,由于差分信号的开关变化是位于两个信号的交点,而不像普通单端信号依靠高低两个阈值电压判断

比如说对于两个CAN 协议中对它使用的 CAN_High 及 CAN_Low 表示的差分信号做了规定。以高速 CAN 协议为例,当表示逻辑 1 时 (隐性电平) ,CAN_High 和 CAN_Low 线上的电压均为 2.5v,即它们的电压差 VH-V:sub:L=0V;而表示逻辑 0 时 (显性电平) ,CAN_High 的电平为 3.5V,CAN_Low 线的电平为 1.5V,即它们的电压差为 VH-V:sub:L=2V

大概的CAN 总线逻辑信号的生成如下,由于 CAN 总线协议的物理层只有 1 对差分线,在一个时刻只能表示一个信号,所以对通讯节点来说,CAN 通讯是半双工的,收发数据需要分时进行。

5.4 CAN 协议层

由于 CAN 属于异步通讯,没有时钟信号线,连接在同一个总线网络中的各个节点会

像串口异步通讯那样,节点间使用约定好的波特率进行通讯

, CAN 会使用“位同步”的方式来抗干扰、吸收误差,实现对总线电平信号进行正确的采样,确保通讯正常。这里面会涉及到硬同步和重新同步这类操作,这里面如果感兴趣可以自行搜索这两个方法,和我们主要讲的内容不太相关。

硬同步

我们主要需要来讲的是CAN 的报文,即怎么来完成通信的。CAN在原始数据段的前面加上传输起始标签、片选 (识别) 标签和控制标签,在数据的尾段加上 CRC校验标签、应答标签和传输结束标签,把这些内容按特定的格式打包好,就可以用一个通道表达各种信号了

上面这个图和我们上文的示意图基本对应。数据帧以一个显性位 (逻辑 0) 开始,以 7 个连续的隐性位 (逻辑 1) 结束,在它们之间,分别有仲裁段、控制段、数据段、CRC 段和 ACK 段。以下是对各个部分的归纳总结:

1. 帧起始 (SOF):

• 唯一的数据位,显性电平。

• 用于通知节点即将开始数据传输,确保各节点进行硬同步。

2. 仲裁段:

• 决定哪个数据包能被传输的部分。

• 包含报文的 ID 信息(标识符),分为标准格式(11 位)和扩展格式(29 位)。ID信息每一个MCU都是独立且唯一的

• ID 决定了数据帧的优先级,重要信息会有较高优先级的 ID。

• 通过显性电平和隐性电平的竞争实现仲裁,隐性电平优先级低,发送隐性电平的节点将失去总线控制权。即逻辑0更加优先,所以ID越大优先级越低

此外上面还有RTR、IDE 和 SRR 位

1. RTR 位 (Remote Transmission Request Bit),译作远程传输请求位,它是用于区分数据帧和遥控帧的,当它为显性电平0时表示数据帧,隐性电平1时表示遥控帧(远程请求帧)。

2. IDE 位 (Identifier ExtensionBit),译作标识符扩展位,它是用于区分标准格式与扩展格式,当它为显性电平0时表示标准格式,隐性电平1时表示扩展格式。

下面是标准帧和拓展帧在识别位上的区别

3. SRR 位 (Substitute Remote Request Bit),只存在于扩展格式,它用于替代标准格式中的 RTR位。由于扩展帧中的 SRR 位为隐性位,RTR 在数据帧为显性位,所以在两个 ID相同的标准格式报文与扩展格式报文中,标准格式的优先级较高。

1. 控制段:

对应的数据长度为:

• 包含保留位(r1 和 r0,默认为显性位)和数据长度码(DLC),后者表示数据段的字节数(0~8 字节)。

2. 数据段:

• 数据帧的核心,包含要发送的原始信息,长度为 0~8 字节,采用 MSB 先行的格式(即0-64位)。

3. CRC 段:

• 包含 15 位的 CRC 校验码,用于验证报文的正确传输。

• 如果接收到的 CRC 与计算出的 CRC 不同,接收节点会请求重新发送。

• CRC 后有一个隐性位的 CRC 界定符,用于分隔 CRC 和 ACK 段。

4. ACK 段:

• 包括 ACK 槽位和 ACK 界定符。

• ACK 槽发送节点发送隐性位1,接收节点发送显性位0以表示应答。

5. 帧结束 (EOF):

• 由发送节点发送的 7 个隐性位表示帧的结束。

下面是一些CAN的报文结构:

5.5 CAN系列协议扩展与以太网协议

上面我们介绍了CAN协议的优势包括低成本、抗干扰能力强、支持多节点和实时响应。然而,传统的CAN协议在数据传输速率上存在限制,无法满足现代复杂系统对高带宽的需求。这就导致了有一些扩展。

5.5.1 CAN FD协议

为了克服传统CAN协议的带宽限制,CAN FD协议应运而生。CAN FD允许更高的数据传输速率和更大的数据帧,提供了更灵活的数据传输选项。它保留了传统CAN的实时性和可靠性优势,同时能够处理更多的数据量,适应了现代汽车系统日益增长的数据需求。

5.5.2 CAN XL协议

CAN XL是CAN FD的进一步扩展,旨在进一步增加数据传输速率和灵活性。它支持更大的数据帧和更高的传输速率,为未来的汽车应用提供了更多的扩展性和性能潜力。CAN XL协议在处理复杂的汽车控制和传感器数据时能够提供更高的效率和响应速度。

5.5.3 以太网协议

随着汽车电子系统变得更加复杂和互联,以太网协议开始在汽车领域中崭露头角。以太网具有更高的数据传输速率和更大的带宽,能够支持大规模数据的传输和实时处理需求。它使得车载网络能够与云服务、高清视频流、远程诊断等现代汽车应用无缝集成。

下面是常见的车辆控制系统中的系统通信协议:

6. AutoWare车辆接口设计

在Autoware中,车辆接口是将Autoware计算出的控制消息转换为车辆能够理解的格式,并将其传输到车辆(如CAN、串行消息等),然后也可以接受来自车辆的数据,并通过ROS 2主题发布。这里我们将Autoware控制命令转换为特定于车辆的格式,比如说

• 速度控制

• 转向控制

• 车辆灯光命令 .....

然后,车辆接口将这些命令转换为执行动作,例如:

• 电机和刹车激

• 转向盘操作

• 灯光控制 .......

在这里我们需要将整个车辆接口视为一个模块然后由Autoware下发的车辆控制指令完成控制。这里所有的工作都是由

vehicle_interface_IO

这个来完成输入和控制的。这里有两种类型的接口用于控制您的车辆:

目标转向和目标速度/加速度接口

(在本文档中称为类型A),

一般化目标命令接口

(即加速/刹车踏板、转向扭矩)(在本文档中称为类型B)。

对于类型A,控制接口包括目标转向和目标速度/加速度。在这种类型中,速度控制是通过期望的速度或加速度实现的。转向控制是通过期望的转向角度和/或转向角速度实现的。

另一方面,类型B以一般化目标命令接口(例如,加速/刹车踏板、转向扭矩)为特征,介绍了一种

更动态和适应性强的控制方案。在这种配置中,车辆根据来自Autoware的执行命令

(即原始车辆命令转换器的输出)进行控制,从而实现更直观和人性化的驾驶体验。如果您以这种方式使用自己的车辆(即控制油门和刹车踏板),则需要使用

raw_vehicle_cmd_converter

包将Autoware输出的

控制命令转换为刹车、油门和转向映射

。为此,您需要进行刹车、油门和转向的标定。您可以使用

accel_brake_map_calibrator

包进行标定。请按照步骤对您的车辆执行器进行标定。

6.1 车辆接口与车辆控制设备之间的通信

如果您计划使用Autoware驾驶您的车辆,则您的车辆必须满足一些要求:

类型A 类型B
您的车辆可以通过目标速度或加速度在纵向上进行控制。 您的车辆可以通过特定目标命令在纵向上进行控制(即刹车和油门踏板)。
您的车辆可以通过目标转向角在横向上进行控制(可选,您也可以使用转向速率)。 您的车辆可以通过特定目标命令在横向上进行控制(即转向扭矩)。
您的车辆必须提供速度或加速度信息和转向信息,这些信息在上述车辆状态主题中描述。 您的车辆必须提供速度或加速度信息和转向信息,这些信息在上述车辆状态主题中描述。

您还可以混合使用类型A和类型B,例如,您希望使用转向角进行横向控制,并使用特定目标进行纵向控制。为此,您必须订阅/control/command/control_cmd以获取转向信息,并且必须订阅/control/command/actuation_cmd以获取油门和刹车踏板的执行命令。然后,您必须在自己的车辆接口设计中处理这些消息。

6.2 ROS通信包

如果在车辆上使用CAN通信ros2_socketcan包。

如果在车辆上使用串行通信,可以查看serial-port。

7. 车辆接口实现

我们上面大致了解了整个车辆接口大概的输入和输出的流程,我们怎么样接收各种planning控制信号以及类似手柄这类的控制信号

7.1 创建车辆接口目录

建议在 <your-autoware-dir>/src/vehicle/external 下创建您的车辆接口。

cd <your-autoware-dir>/src/vehicle/external

7.2 安装或实现您自己的车辆接口

如果已经有一个完整的车辆接口包(如 pacmod_interface),您可以将其安装到您的环境中。如果没有,您需要自己实现车辆接口。让我们通过 ros2 pkg create 创建一个新的包。以下示例将展示如何创建一个名为 my_vehicle_interface 的车辆接口包。

ros2 pkg create --build-type ament_cmake my_vehicle_interface

然后,您应该在 my_vehicle_interface/src 中编写车辆接口的实现。你怎么样控制你自己的车辆这个其实是不固定的,但是下面是一些必要的控制命令主题订阅,方便 Autoware 控制设定的车辆:

主题名称 主题类型 描述
/control/command/ control_cmd autoware_auto_control _msgs/msg /Ackermann ControlCommand 此主题包含控制车辆的主要主题,如转向轮角度、速度、加速度等。
/control/command/ gear_cmd autoware_auto _vehicle_msgs / msg/GearCommand 此主题包含自动驾驶的档位命令,请检查消息值以理解档位值。请查看此类型的消息定义。
/control/ current_gate_mode tier4_control_msgs / msg/GateMode 此主题描述 Autoware 的控制状态。
请查看 GateMode 消息类型以获取详细信息。
/control/command/ emergency_cmd tier4_vehicle_msgs / msg /VehicleEmer gencyStamped 当 Autoware 处于紧急状态时,此主题发送紧急信号。
请查看 VehicleEmergency Stamped 消息类型以获取详细信息。
/control/command/ turn_indicators_cmd
autoware_auto _vehicle_msgs /msg / TurnIndicatorsCommand 此主题指示您车辆的转向信号。
请查看 TurnIndicators Command 消息类型以获取详细信息。
/control/command/ hazard_lights_cmd autoware_auto _vehicle_msgs/msg / HazardLightsCommand 此主题发送危险灯的命令。
请查看 HazardLights Command 消息类型以获取详细信息。
/control/command/ actuation_cmd tier4_vehicle_ msgs/msg /Actuation CommandStamped 当您使用 raw _ vehicle _ command_converter 控制您的车辆时,此主题启用,适用于我们在车辆接口部分提到的 TYPE B
。总之,如果您在车辆上使用 Type B,此主题将出现,并包含油门、刹车、转向轮的执行命令。
请查看 ActuationCommand Stamped 消息类型以获取详细信息。
etc. etc. etc.

 

一些必要的车辆状态主题发布,来自车辆接口到 Autoware:

主题名称 主题类型 描述
/vehicle/status/ battery_charge tier4_vehicle_msgs / msg/BatteryStatus 此主题包含电池信息。请查看 BatteryStatus 消息类型以获取详细信息。您可以使用此值来描述燃料水平等。
/vehicle/status/ control_mode autoware_auto_ vehicle_msgs /msg/ ControlModeReport 此主题描述车辆的当前控制模式。
请查看 Control ModeReport 消息类型以获取详细信息。
/vehicle/status/ gear_status autoware_auto_ vehicle_msgs /msg/
GearReport
此主题包含车辆的当前档位状态。
请查看 GearReport 消息类型以获取详细信息。
/vehicle/status/
hazard_lights_status
autoware_auto_ vehicle_msgs /msg/ HazardLightsReport 此主题描述车辆的危险灯状态。 请查看 Hazard LightsReport 消息类型以获取详细信息。
/vehicle/status/ turn_indicators_status autoware_auto_
vehicle_msgs /msg/
TurnIndicatorsReport
此主题报告车辆的转向状态。请查看 SteeringReport 消息类型以获取详细信息。
/vehicle/status/ steering_status autoware_auto_vehicle _msgs /msg/
SteeringReport

此主题报告车辆的转向状态。
请查看 SteeringReport 消息类型以获取详细信息。
/vehicle/status/ velocity_Status autoware_auto _vehicle_msgs /msg/ VelocityReport 此主题提供车辆的速度状态。
请查看 VelocityReport 消息类型以获取详细信息。
etc. etc. etc.

以下示例图展示了车辆接口与 Autoware 之间的通信,描述了示例主题和消息类型。

下面是车辆与 Autoware 通信的示例演示。图中包含了一些主题和类型,您可以根据需要更改控制命令或 Autoware 更新。

您必须在车辆接口中创建这些主题的订阅者和发布者。让我们通过简单的示例来解释如何订阅 /control/command/control_cmd 并发布 /vehicle/status/gear_status 主题。

因此,您的 YOUR-OWN-VEHICLE-INTERFACE.hpp 头文件应如下所示:

...
#include <autoware_auto_control_msgs/msg/ackermann_control_command.hpp>
#include <autoware_auto_vehicle_msgs/msg/gear_report.hpp>
...

class <YOUR-OWN-INTERFACE> : public rclcpp::Node
{
public:
    ...
private:
    ...
    // 来自 Autoware
    rclcpp::Subscription<autoware_auto_control_msgs::msg::AckermannControlCommand>::SharedPtr
    control_cmd_sub_;
    ...
    // 来自车辆
    rclcpp::Publisher<autoware_auto_vehicle_msgs::msg::GearReport>::SharedPtr gear_status_pub_;
    ...
    // Autoware 命令消息
    ...
    autoware_auto_control_msgs::msg::AckermannControlCommand::ConstSharedPtr control_cmd_ptr_;
    ...
    // 回调函数
    ...
    void callback_control_cmd(
    const autoware_auto_control_msgs::msg::AckermannControlCommand::ConstSharedPtr msg)
;
    ...
    void to_vehicle();
    void from_vehicle();
}

您的 YOUR-OWN-VEHICLE-INTERFACE.cpp 文件应如下所示:

#include <YOUR-OWN-VEHICLE-INTERFACE>/<YOUR-OWN-VEHICLE-INTERFACE>.hpp>
...

<YOUR-OWN-VEHICLE-INTERFACE>::<YOUR-OWN-VEHICLE-INTERFACE>()
Node("<YOUR-OWN-VEHICLE-INTERFACE>")
{
  ...
  /* 订阅者 */
  using std::placeholders::_1;
  // 来自 Autoware
  control_cmd_sub_ = create_subscription<autoware_auto_control_msgs::msg::AckermannControlCommand>(
    "/control/command/control_cmd"1, std::bind(&<YOUR-OWN-VEHICLE-INTERFACE>::callback_control_cmd, this, _1));
  ...
  // 向 Autoware 发布
  gear_status_pub_ = create_publisher<autoware_auto_vehicle_msgs::msg::GearReport>(
    "/vehicle/status/gear_status", rclcpp::QoS{1});
  ...
}

void <YOUR-OWN-VEHICLE-INTERFACE>::callback_control_cmd(
  const autoware_auto_control_msgs::msg::AckermannControlCommand::ConstSharedPtr msg)
{
  control_cmd_ptr_ = msg;
}

void <YOUR-OWN-VEHICLE-INTERFACE>::to_vehicle()
{
  ...
  // 您应根据自己的车辆设计实现此结构
  control_command_to_vehicle(control_cmd_ptr_);
  ...
}

void <YOUR-OWN-VEHICLE-INTERFACE>::to_autoware()
{
  ...
  // 您应根据自己的车辆设计实现此结构
  autoware_auto_vehicle_msgs::msg::GearReport gear_report_msg;
  convert_gear_status_to_autoware_msg(gear_report_msg);
  gear_status_pub_->publish(gear_report_msg);
  ...
}

7.3 准备启动文件

在实现车辆接口后,或者您想通过启动它进行调试,请创建车辆接口的启动文件,并将其包含到我们在创建车辆和传感器模型页面中复制并创建的<VEHICLE_ID>_vehicle_launch包中的vehicle_interface.launch.xml中。这在我们传感器章节中讲到过,下面我们来梳理一下这四个文件对应的意思:

在Autoware中,这些文件通常用于配置和启动与传感器和车辆相关的功能。以下是每个文件的简要说明:

1. sample_sensor_kit_launch:这个文件通常用于启动与传感器相关的配置和节点。它包含传感器的初始化、数据发布以及与其他节点的连接设置。当中包含所有的tf链接

下面是对应文件里面包含的意思,通过修改sample_sensor_kit_launch中的配置完成传感器的更换

2. sample_vehicle_launch:这个文件用于启动与特定车辆相关的功能和节点。它包括车辆模型的加载、传感器的配置与启动、车辆控制节点的启动等工作。(这里我们没有下载external的内容,一般拉repo会有这个交互模块的)

下面是对应文件里面包含的意思

3. autoware_individual_params:这个文件通常包含与特定车辆或传感器相关的参数设置。为不同的车辆定义自定义传感器校准参数。它允许用户在使用相同的启动文件和传感器模型的情况下,为不同的车辆配置不同的传感器校准,这样可以实现更灵活的传感器管理和配置。individual_params 包使用户能够为每辆车提供特定的传感器校准参数,这些参数会覆盖默认的传感器校准设置。

4. autoware_launch:这个文件是Autoware的主要启动文件,通常用于启动整个系统的各个组件。包含了autoware所有的启动项目,包括感知模块,控制模块,评估模块,地图模块,定位模块等,我们发现在universe/autoware.universe/launch/
tier4_vehicle_launch/launch/vehicle.launch.xml 下面管理了所有的tf发送操作。

在这里我们可以在 my_vehicle_interface 目录中添加一个启动目录,并在其中创建您自己的车辆接口的启动文件。在launch文件中,我们需要将为车辆接口创建的启动文件包含到 <YOUR-VEHICLE-NAME>_launch/<YOUR-
VEHICLE-NAME>_launch/launch/vehicle_interface.launch.xml 中,打开它并添加如下包含项。

vehicle_interface.launch.xml

<?xml version="1.0" encoding="UTF-8"?>
<launch>
    <arg name="vehicle_id" default="$(env VEHICLE_ID default)"/>
    <!-- 请添加您创建的车辆接口启动文件 -->
    <include file="$(find-pkg-share my_vehicle_interface)/launch/my_vehicle_interface.launch.xml">
    </include>
</launch>

 

整个对应的内容为

<your-autoware-dir>/
└─ src/
    └─ vehicle/
        ├─ external/
        │   └─ <YOUR-VEHICLE-NAME>_interface/
        │       ├─ src/
        │       │   └─ <YOUR-OWN-VEHICLE-INTERFACE>_interface.cpp  # 实现车辆接口的源代码
        │       └─ launch/
        │           └─ my_vehicle_interface.launch.xml      # 启动文件,用于启动车辆接口节点
        └─ <YOUR-VEHICLE-NAME>_launch/                       # 车辆启动配置目录
            ├─ <YOUR-VEHICLE-NAME>_launch/
            │  ├─ launch/
            │  │  └─ vehicle_interface.launch.xml           # 启动文件,配置车辆接口节点及其他相关节点
            │  ├─ CMakeLists.txt                             # CMake 构建文件,用于定义如何编译该包
            │  └─ package.xml                                # 包描述文件,包含包的元数据,如依赖关系、版本等
            ├─ <YOUR-VEHICLE-NAME>_description/             # 车辆描述配置目录
            │  ├─ config/                                    # 配置文件目录,存放车辆相关的配置文件
            │  ├─ mesh/                                      # 网格文件目录,存放车辆的3D模型文件
            │  ├─ urdf/                                      # URDF 模型目录,存放车辆的 URDF 文件,用于描述车辆的物理结构
            │  │  └─ vehicle.xacro                          # XACRO 文件,便于生成 URDF 文件的宏文件
            │  ├─ CMakeLists.txt                             # CMake 构建文件,用于定义如何编译该描述包
            │  └─ package.xml                                # 包描述文件,包含该描述包的元数据,如依赖关系、版本等
            └─ README.md                                      # 该目录的说明文件,提供该包的使用说明和其他相关信息

我们下载的时候就有vehicle/sample_vehicle_launch这个文件夹,对应里面的内容可以在上面第二点看到,如果需要自己创建上游和底盘的交互可以external下面创建一个上下游的interface模块

7.4 构建车辆接口包和启动包

通过 colcon build 构建三个包 my_vehicle_interface、<YOUR-VEHICLE-NAME
>_launch 和 <YOUR-VEHICLE-NAME>_description(这里就是上面三个内容)。

colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release --packages-select my_vehicle_interface <YOUR-VEHICLE-NAME>_launch <YOUR-VEHICLE-NAME>_description

7.5 启动 Autoware

最后,您完成了车辆接口模块的实现!请注意,您需要使用正确的 vehicle_model 选项启动 Autoware,如下例所示。此示例启动规划模拟器。

ros2 launch autoware_launch planning.launch.xml map_path:=$HOME/autoware_map/sample-map-planning vehicle_model:=<YOUR-VEHICLE-NAME> sensor_model:=<YOUR-VEHICLE-NAME>_sensor_kit
   
127 次浏览       5
相关文章

中央计算的软件定义汽车架构设计
汽车电子控制系统中的软件开发过程
一文读懂汽车芯片-有线通信芯片
OTA在汽车上有哪些难点痛点?
相关文档

汽车设计-汽车的整体结构及动力系统
自动驾驶汽车软件计算框架
SysML在汽车领域的应用实践
电子电气架构-大陆汽车系统架构平台
相关课程

AutoSAR原理与实践
功能安全管理体系(基于ISO26262)
MBSE(基于模型的系统工程)
基于SOA的汽车电子架构设计与开发

最新活动计划
基于 UML 和EA进行分析设计 9-9[北京]
软件架构设计方法、案例实践 9-24[北京]
AI辅助软件测试方法与实践 9-26[北京]
代码质量标准与评审方法 11-6[北京]
OCSMP认证:OCSMP-MBF 11-18[北京]
Web应用安全、入侵检测 12-11[北京]
 
 
最新文章
ASPICE中配置管理是个什么东西?
了解软件安全分析与组件鉴定
掌握Autosar ComStack的精髓!
基于整车功能的正向诊断需求开发
搞定Autosar SWC开发秘籍,码住!
汽车OTA更新的系统性威胁评估
最新课程
基于SOA的汽车电子架构设计与开发
Auto SAR原理与实践
AUTOSAR架构与实践(从CP到 AP )
AUTOSAR架构建模方法与工具(EA)
ASPICE4.0核心开发过程指南
MBSE(基于模型的系统工程)
更多...   
成功案例
某知名车企 AUTOSAR应用设计与开发
吉利汽车 MBSE工程体系汽车建模及评估
某整车企业 《功能需求分析与设计》
富奥汽车零部件 建模工具EA
零跑汽车 建模工具EA及服务
北汽福田 建模工具EA
小鹏汽车 建模工具EA
更多...