Apollo详解之canbus模块——代码简要分析1

CanbusComponent主要对象分析

CanClient

can客户端CanClient用于开启can设备、接收与发送can报文,其作为基类接口,可以派生不同种类的can。目前Apollo支持的can类型有EsdCanClientHermesCanClientSocketCanClientRaw以及一个用于调试的FakeCanClient。其最主要的方法有:

  • Start。开启can设备
  • SendSingleFrame发送单个的can报文数据
  • Send发送指定数目的can报文数据
  • Receive接收指定数目的can报文数据

AbstractVehicleFactory

车辆抽象工厂AbstractVehicleFactory用于创建VehicleControllerMessageManager其作为基类接口,可以派生不同种类车型的抽象工厂,从而可以创建车型各种的VehicleControllerMessageManager,目前Apollo支持的车型可以在modules/canbus/vehicle文件夹中查看。

ProtocolData

不同的车型有不同的can协议,ProtocolData是can协议的基类接口,不同的协议继承于该基类接口,每个协议类都在数据成员中定义所需的物理量以及描述协议类型的ID,并定义相关setter和修改和解析规则can报文的方法,不同车型的协议类源文件在相关车型的protocol文件夹下。其主要的方法有:

  • UpdateData,根据该协议的物理量更新can报文数据
  • Parse通过解析规则,将can报文数据解析为消息类型

can协议分为发送接收两种类型,以lincoln的Brake60Brake61协议为例,前者是发送给车辆底层的协议,后者是从车辆底层接收的协议。具体的物理量以及can协议可在每个协议的源文件注释中找到,具体实现不再赘述。

MessageManager

MessageManager是所有车型协议管理类的基类接口,不同的车型继承于该基类接口。
MessageManager用于管理该车型所需要的协议对象,其拥有分别保存发送和接收协议的容器 send_protocol_data_recv_protocol_data_,在不同车型MessageManager的派生类的构造函数当中,需要通过方法AddSendProtocolDataAddRecvProtocolData创建该车型需要所有的发送和接收协议。以lincoln的MessageManager为例:

LincolnMessageManager::LincolnMessageManager() {
  // TODO(Authors): verify which one is recv/sent
  AddSendProtocolData<Brake60, true>();
  AddSendProtocolData<Throttle62, true>();
  AddSendProtocolData<Steering64, true>();
  AddSendProtocolData<Gear66, true>();
  AddSendProtocolData<Turnsignal68, true>();

  AddRecvProtocolData<Brake61, true>();
  AddRecvProtocolData<Throttle63, true>();
  AddRecvProtocolData<Steering65, true>();
  AddRecvProtocolData<Gear67, true>();
  AddRecvProtocolData<Misc69, true>();
  AddRecvProtocolData<Wheelspeed6a, true>();
  AddRecvProtocolData<Accel6b, true>();
  AddRecvProtocolData<Gyro6c, true>();
  AddRecvProtocolData<Gps6d, true>();
  AddRecvProtocolData<Gps6e, true>();
  AddRecvProtocolData<Gps6f, true>();
  AddRecvProtocolData<Tirepressure71, true>();
  AddRecvProtocolData<Fuellevel72, true>();
  AddRecvProtocolData<Surround73, true>();
  AddRecvProtocolData<Brakeinfo74, true>();
  AddRecvProtocolData<Throttleinfo75, true>();
  AddRecvProtocolData<Version7f, true>();
  AddRecvProtocolData<License7e, true>();
}

注意,在canbus模块当中,所有的协议类对象都通过MessageManager在堆上创建,可以通过GetMutableProtocolDataById方法根据协议ID返回对应的协议类堆堆对象的指针。
MessageManager还负责调用相关接收协议对象,通过Parse方法,将从底层接收的can报文的数据解析为消息类型,并保存在其数据成员sensor_data_当中

CanFrame

CanFrame定义了can报文数据,其中最主要的是uint8_t data[8],代表can报文的数据

SenderMessage

发送can报文SenderMessage定义了发送给底层的can报文,其主要包含了:

  • ProtocolData用于描述该can报文的协议类型
  • CanFrame用于描述该can报文的数据
  • period_描述发送的间隔
  • message_id_描述该can报文的协议类型的ID

通过SenderMessage<SensorType>::Update方法,可以根据协议类对象的物理量,根据该更新can报文数据CanFrame

CanReceiver

CanReceiver开启一个线程,其入口函数为RecvThreadFunc,不断接收底盘的can报文,根据其协议ID将can报文的数据解析为消息类型并保存至MessageManager的数据成员sensor_data_中。

CanSender

CanSender有一个包含所有发送协议的can报文容器send_messages_,通过方法AddMessage向其添加发送can报文。
开启一个线程,入口函数为PowerSendThreadFunc,不断循环以对应的协议的间隔将容器当中的can报文发送至can网络。
通过CanSender<SensorType>::Update,可以更新所有发送协议can报文的数据

VehicleController

VehicleController是所有车型控制器的基类接口,可以派生出不同的车型的的控制器。在派生类的初始化函数当中,会获得该车型所有需要的发送协议,并在CanSender的发送协议的can报文容器send_messages_当中创建发送协议can报文,并且会开启一个线程,不断检查错误信息。
VehicleController的主要功能是通过Update方法,接收控制消息control::ControlCommand,更新发送协议can报文的物理量,修改协议相关的方法有:

  • Gear
  • Brake
  • Throttle
  • Acceleration
  • Steer

有趣的是,Update方法会根据车辆的驾驶模式修改不同的发送协议报文物理量,驾驶模式有以下五种类型:

  • COMPLETE_AUTO_DRIVE
  • COMPLETE_MANUAL
  • AUTO_STEER_ONLY
  • AUTO_SPEED_ONLY
  • EMERGENCY_MODE
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CANBus数据链路层协议采用对等式(Peer to peer)通信方式,即使主机出现故障,系统其余部分仍可运行(当然性能受一定影响)。当一个站点状态改变时,它可广播发送信息到所有站点。 CANBus的信息传输通过报文进行,报文帧有4种类型:数据帧、远程帧、出错帧和超载帧,其中数据帧格式如图8所示。CANBus帧的数据场较短,小于8B,数据长度在控制场中给出。短帧发送一方面降低了报文出错率,同时也有利于减少其他站点的发送延迟时间。帧发送的确认由发送站与接收站共同完成,发送站发出的ACK场包含两个“空闲”位(recessive bit),接收站在收到正确的CRC场后,立即发送一个“占有”位(dominant bit),给发送站一个确认的回答。CANBus还提供很强的错误处理能力,可区分位错误、填充错误、CRC错误、形式错误和应答错误等。 CANBus应用一种面向位型的损伤仲裁方法来解决媒体多路访问带来的冲突问题。其仲裁过程是:当总线空闲时,线路表现为“闲置”电平(recessive level),此时任何站均可发送报文。发送站发出的帧起始字段产生一个“占有”电平(dominant level),标志发送开始。所有站以首先开始发送站的帧起始前沿来同步。若有多个站同时发送,那么在发送的仲裁场进行逐位比较。仲裁场包含标识符ID(标准为llbit),对应其优先级。每个站在发送仲裁场时,将发送位与线路电平比较,若相同则发送;若不同则得知优先级低而退出仲裁, 不再发送。系统响应时间与站点数无关,只取决于安排的优先权。可以看出,这种媒体访问控制方式不像Ethetnet的CSMA/CDCA协议那样会造成数据与信道带宽受损。
### 回答1: Apollo的DBC文件可以通过工具转换成CAN总线的模板代码。这个过程需要使用专门的工具,例如CANdb++或者Vector CANalyzer等。转换完成后,可以得到符合CAN总线通信协议的代码,可以直接用于开发CAN总线通信功能。 ### 回答2: Apollo是由百度开发的一个自动驾驶平台,其中包括了各种功能,例如定位、感知、控制等等。为了实现自动驾驶,需要将车辆的各种数据通过CAN总线进行传输。CAN总线可以把各个部件之间的数据进行高效、可靠、实时的传输。 在Apollo平台中,DBC文件是CAN总线的描述文件。它描述了CAN总线上所有消息和信号的详细信息,包括消息的ID、数据长度、周期、发送者和接收者等等。这些信息都非常重要,因为在开发自动驾驶系统时,需要使用这些信息来编写控制车辆的代码。 为了将DBC文件转换成CAN总线模板代码,需要使用Apollo提供的工具。具体步骤如下: 第一步:打开Apollo Studio,在“CAN总线”界面中点击“新建”,选择“CAN节点”或“CAN设备”作为总线类型。 第二步:在弹出的对话框中,选择DBC文件,并设置节点的参数,例如波特率、发送模式、接收模式、过滤器等等。 第三步:点击“生成”按钮,Apollo会自动生成C++代码,包括消息的发送和接收函数、定时器、过滤器等等。这些代码可以作为开发车辆控制系统的基础,方便开发者进行自定义的编写。 第四步:使用生成的代码,编写车辆控制系统的逻辑,例如调用传感器获取数据、分析数据、计算控制指令等等。通过CAN总线发送命令,实现对车辆的控制。 需要注意的是,转换DBC文件是一个很重要的步骤,因为它直接影响到车辆控制系统的实现效果。开发者需要仔细阅读DBC文件,并检查生成的代码是否符合要求。如果存在任何问题,都需要及时进行调整和修正,以确保车辆控制系统的稳定和安全。 ### 回答3: DBC(Database CAN)文件是一种CAN数据通信协议的描述文件,用于描述不同的CAN消息和信号。而CAN Bus模板代码是一种代码结构,用于实现CAN总线通信协议,将数据从一个设备传输到另一个设备。 将Apollo的DBC文件转换成CAN Bus模板代码,需要经过以下步骤: 1. 导入DBC文件 首先,需要使用DBC编辑器,例如CanKingdom或Vector CANoe,将Apollo的DBC文件导入到编辑器中。这将允许您查看CAN数据通信协议的各个方面,包括CAN消息和信号的定义,以及消息的发送和接收节点。 2. 创建CAN Bus模板代码 接下来,使用CAN代码生成器创建CAN总线模板代码,根据您的需求,生成一个底层CAN的驱动程序,或使用现有的库(如果适用的话)。可以生成与目标平台或硬件一致的CAN代码。 3. 添加CAN消息和信号 使用所选的CAN代码生成器,将定义在DBC文件中的CAN消息和信号添加到CAN总线模板代码。这可以通过手动编写代码或使用GUI工具完成,具体取决于所选的工具和库。在添加CAN消息和信号时,请确保它们与DBC文件中的定义相匹配,以保持数据传输方面的准确性。 4. 测试和调试 完成上述步骤后,使用适当的CAN测试工具来测试CAN总线通信协议,并验证数据的传输。可以使用CAN分析器或测试工具,例如CanKingdom或Vector CANoe,来查看CAN数据通信协议的信息。 总之,将Apollo的DBC文件转换成CAN总线模板代码需要使用DBC编辑器和CAN代码生成器,进行导入DBC文件、创建CAN模板代码、添加CAN消息和信号和测试和调试这几个步骤,这样可以确保CAN通信的稳定性和准确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值