Advertisement

apollo学习笔记十五:apollo ROS(上)

阅读量:

背景介绍

在这里插入图片描述

自动驾驶系统涵盖障碍物检测、行为决策以及路径规划等多个工程模块,并配备激光雷达、相机与GPS等传感器以实现实时数据采集与处理。如何将这些功能模块设计为相互独立却又协同工作的体系,则是构建一个稳定且可靠的自动驾驶系统所面临的巨大挑战,并且这也是自动驾驶计算框架的核心职责。

  • 对框架的支持:
  • 支持高效的开发流程
  • 模块化设计具有高度的灵活性
  • 提供全面的调试解决方案
    ROS的优势如上图所示:
在这里插入图片描述

自动驾驶底层通信框架选择ROS有以下主要原因:
(1)ROS是一个功能丰富且适应性强的机器人编程框架。从软件架构的角度来看,它采用消息传递机制构建了一个多进程分布式系统,在机器人行业已形成较为成熟的使用体系。目前已有诸多基于ROS开发的开源解决方案涵盖了姿态变换计算、三维数据处理、定位算法以及SLAM技术等领域的内容。
(2)基于消息机制的设计使得开发者能够将复杂的系统功能划分为多个独立的功能模块,并通过不断集成这些子模块实现对复杂任务的有效执行能力提升。
(3)ROS因其广泛的学术支持特性,在实验算法开发方面提供了标准化的基础解决方案框架

ROS概述

ROS基本特征

(1)一对一行为:两个Node之间进行消息通讯是一种一对一的行为
(2)被 ROS 提供天然支持:在部署多机间的消息通讯时
(3)跨语言特性下的一次通信过程:你只需按照ROS提供的接口完成订阅与分发即可完成一次通信过程
(4)轻量级程序仅需关注核心模块逻辑:无需深入底层通信机制
(5)开源平台:开放社区致力于完善这一平台

ROS核心概念

(1) loose coupling 的 ROS 体系结构中,各个节点之间的数据交换采用了 loose-coupled architecture 的方式。
(2)功能模块如自动驾驶系统中的感知模块、定位模块、决策模块或控制模块的集合,在 ROS 中被正式称为‘node’。
(3)在 ROS 中定义为 Master node 的 Node Manager(Node Manager 简称 Roscore),它在所有子节点启动完成并建立通信连接之前起到 The intermediary function 的作用。
(4)Topic 定义了两个节点之间的通信主题,并通过 The data format Message 实现。

相互关系:

(1)感知模块Perception,感知车辆周围的一些障碍物信息,用CNN或者RNN算法将障碍物信息提取出来,即Obstacle。再将这些信息输出给下游Planning节点。这两个节点之间的通信连接就需要Roscore,即节点管理器。
(2)Perception、Planning在启动的时候没有先后关系,这是松耦合的一个具体体现。Perception先启动并向Roscore发送一个注册信息,同时会订阅名为Obstacle的Topic;Planning节点启动后也向Roscore发送一个注册信息,同时会订阅名为Obstacle的Topic;在这种情况下,Roscore会发送一个通知信息给Planning,在它发送注册信息之前已经有一个节点启动了。此时Planning会向Perception发送消息请求通信连接,Planning收到消息之后会在Planning和Perception两个节点中间建立一个实时通信链路。当通信链路建立之后,Roscore的功能就暂时完成了。
(3)松耦合在此有两种体现:

  • Perception与Planning之间没有明确的启动顺序。
  • 在通信链路建立起来之后 Roscore的功能也就暂时完成了。
在这里插入图片描述

ROS基本概念

Roscore:启动一个节点管理器。

节点常用命令:

  • Rosnode collection:列出当前系统中所有的节点.*
  • Rosnode node profile:查看特定节点的详细信息.*

Topic常用命令:

  • Rostopic list: 该功能允许展示现有Topic的详细列表。
  • Rostopic info: 此功能可提供发送方和订阅方的信息。
  • Rostopic type: 此模块允许查询Topic内使用的MSG数据结构类型及其配置信息。
  • Rostopic pub: 该功能可用于调试计算节点模块的基本操作流程及性能指标。

ROS实践1:启动Roscore

在这里插入图片描述

(1)ROS运行时
(2)在命令行界面中运行roscore就可以轻松创建一个节点管理器系统组件。该系统组件无需输入任何参数即可运行,并且也无需设置任何配置信息。
(3)当多个系统组件同时运行时,请使用roslaunch来实现统一管理功能。roslaunch是一种将所有组件的行为集中在一个统一定义文件中的方式,在执行过程中系统会根据定义查找并定位各个待启动节点的位置,并进而自动启动这些待定点位的节点。

ROS实践2:启动一个简单的Talker程序

在这里插入图片描述

(1)使用rosrun执行这个特定程序。
(2)这个发送节点通常由一个名为talker的程序实现。
(3)单独运行一个节点时除了通过Roscore这种方式外其他节点在初始化ROS时会自动触发 Rosrun 命令。
(4)在 Rosrun 调用中参数部分由一个包名引导后续则是具体的执行文件。
(5)通过简单的 Ros run命令即可方便地激活并控制一个发送节点。

ROS实践3:通过命令查看Talker node

在这里插入图片描述

(1)当启动这个节点之后,用Rosnode list,见上图Talker的Node文件,还有一个Rosout的程序节点。Roscore默认启动的时候启动了一个隐藏节点,它是一个记录日志相关的节点,所有节点发生的Log都会被Roscore启动的Rosout所订阅,订阅完之后会根据一些特定的规则把这些Log分级,然后分模块、分文件打印到对应的模块日志里。
(2)Rosnode info查看Talker相关的一些节点,Talker发送的Topic以及它发送的Service。它有两个Service:Setlogger、Getlogger。这两个是每一个节点都会默认启动的两个Service,这两个Service的作用是设置这一个节点里面的日志层级,如果日志层级是INFO,那么它打印的Debug信息就不会记录在Roscore的Rosout节点里面。
(3)Rostopic info,通过这个命令我们能看到Topic的发送方和接收方。

在这里插入图片描述

(4)Rostopic type用于查看Topic的一个Message的消息类型。
(5)Rostopic echo类似于设置了一个Listener节点以显示或反映Talker发送的Topic包含的具体信息。
(6)Rostopic还提供了HZ和BW功能分别用于统计发送Obstacle topic消息的数量频率以及判断系统是否按照预期方向正常运行等。例如,在自动驾驶系统中各个传感器都有特定的工作频率:激光雷达的工作频率为10赫兹即每秒10圈并产生10帧点云数据;通过配置Rostopic HZ功能即可检测当前系统的运行状态:如果发现该系统的HZ值低于理论值则可能表明受端设备如激光雷达发生故障或者其上层Driver节点在处理相关数据时出现了问题此时就需要进一步排查具体问题发生的位置。

ROS实践4:启动一个Listener节点

在这里插入图片描述

(1)创建一个Listener节点,在其启动后会导致整个系统架构发生明显的转变。该监听器不仅会发布注册请求至Roscore系统,并且还会开始关注特定主题或话题; Roscore随后会向该监听器发送确认通知:在它发布注册请求前就已经存在另一个监听器被激活。
(2)当此之时,在线听众将尝试与说话者之间建立直接通信连接请求。
(3)该通信通道建立在TCP协议基础之上; 当TCP通道建立后,在线听众将接收到来自说话者的持续不断地传输数据,并根据接收到的信息进行相应的回调处理以完成实际决策和执行过程。

ROS实践5:再次通过命令查看Node

在这里插入图片描述

在激活Talker节点后, 利用 ROSnode list查看发现新增了一个新的节点即为Listener 节点. 该拓扑完整地包含了发送端和接收端的节点.

ROS的Catkin编译系统

在这里插入图片描述

ROS是基于Cmake编写的Catkin编译系统。

搭建一个工程包,在ROS框架中编写一个节点程序时,推荐采用Catkin create工具来快速构建项目结构。这些目录结构会预先配置好必要的开发环境。通过使用Catkin build命令进行构建过程就可以生成完整的软件包部署文件。

Catkin build完成后会在项目根目录下新增两个子目录:‘DEVEL’和‘BUILD’。其中‘BUILD’目录是用于存储该编译阶段产生的构建信息的。

一旦编译完成后,在源devel目录下的setup_bash配置下,
就可以将自己编写好的节点程序导入进入ros环境,
并开始执行我们所设计的一些基础功能。

三个比较重要的文件夹

在这里插入图片描述
复制代码
* src用来放源文件的一些目录
* 第二个是build
* 第三个是devel

build 和 dev 是在 catkin building 的过程中生成的临时目录项。如果希望重新构建项目,则可以直接执行 catkin build 命令;如果遇到一些冲突问题,则可以通过 catkin clean 命令简便地清除掉当前构建过程中生成的所有临时文件以及之前的产物。

Catkin config决定了命令行编译的多种方法,在CMKELISTS中能够进行配置设置。

在这里插入图片描述

CmakeLists配置了这个文件编译所需的库、生成了可执行文件,并将这些文件与相关的库连接起来。

在CmakeLists中详细说明了如何依赖所需库以及构建生成的可执行程序。

该列表明确地指定了编译所需的资源和构建过程中的依赖关系。

CmakeLists详细说明了编译所需的资源及其相互关系。

该列表明确了编译所需的资源及其构建过程中的依赖关系。

当启动节点时采用了Roslaunch。 Roslaunch属于一种基于Shell的脚本文件。 根据语言定义的一些Xml格式去找一系列节点的位置并执行。 其运行方式是在前缀上附加Package Name,在后缀上指定具体的Launch文件。

在这里插入图片描述

ROS的仿真工具Gazebo

在这里插入图片描述

在实际开发过程中(不论是机器人领域还是自动驾驶相关的具体功能),我们无法仅仅将单个功能部署到实体设备上进行测试

Apollo ROS原理-1

ROS的不足

  • 大规模数据传输性能障碍

    • 实验项目中使用的主题为Message,在其中处理的数据规模较小可能仅限于几KB或至多1到2MHz,在实际应用如自动驾驶中所处理的数据规模远超预期。
    • ROS系统存在较高的延迟问题
    • 现有ROS系统难以满足自动驾驶工程的实际需求
  • 集中式网络架构容易受到单一节点故障的影响。

  • 集中化的架构往往伴随着较高的系统可靠性风险。整个ROS作为一个松耦合架构包含了一个负责协调节点间通信的节点管理器,在其介入之前仅进行简单的拓扑映射以减少各子系统间的耦合性。然而尽管这种方式显著降低了系统的耦合度但仍带来了较大的安全隐患。

  • 当Roscore出现异常退出情况时(例如服务失效或参数配置错误),基于定时或其他非定时机制的数据交互会增加潜在的安全漏洞。

  • 在分布式计算环境中 Roscore通常部署于单一服务器上 因此当Roscore发生故障会导致所有参与计算的机器间通信陷入不可信状态。

  • 数据格式在向后兼容方面存在不足。

  • ROS的消息系统基于分发与订阅机制工作:使用Message时需明确其包含的数据类型。将其模块整合至更复杂的系统中时需特别注意Message间的数据兼容性。

  • 我们根据实际场景需求在Obstacle信息中增加了相关说明:这会导致所有依赖该Obstacle的消息处理节点都需要做相应的功能适配工作。基于原有实验数据在新框架下应用则需要完成一批数据转换工作。

  • Apollo ROS系统解决了现有数据格式在向后兼容方面的不足问题。

apollo ROS对ROS的改进

在这里插入图片描述

(1)通信性能的优化:

通信性能优化原因

复制代码
* 自动驾驶大量使用传感器引发很大的传输带宽需求。自动驾驶使用大量的传感器,这些传感器的数据量非常庞大。大量数据在目前ROS的通讯架构里面会带来比较高的延迟或是丢帧。节点之间通信是一帧一帧进行的,如果上一帧消息高延迟时,下一帧消息的发送就需要等待。ROS提供了这种消息丢弃的机制,如果等待时间长会丢弃一些数据,数据丢弃在实际自动驾驶系统中会造成比较大的风险。
* 单路传感器消息有多个消费者时负载成倍增长。自动驾驶系统发送传感器数据是一对一进行的。例如Lidar向自动驾驶系统发送数据时,如果只有一个订阅节点,传输的数据量是7M乘以10HZ,也就是70MB/S。自动驾驶系统是一个比较复杂的拓扑结构,一个传感器数据可能会有很多的下游订阅节点。例如感知的障碍物检测、通过视觉定位的模块、用红绿灯识别等都会订阅Camera信息。在单点的情况下是一对一,如果是一对多,传输的数据会被复制多次,造成网络负载成倍增加。  
在这里插入图片描述

共享内存

在这里插入图片描述
  • 左侧为基于ROS生态系统的原始通信架构,在消息从发布者传递至订阅者的过程中经历了四个关键的数据复制环节:首先是由节点将消息发送至用户内存空间并完成一次数据复制;随后由发布方完成将消息传递至内核系统的第二次数据复制;接着通过TCP连接实现了内核与订阅者之间的第三次跨态空间的数据传播;最后由订阅节点完成接收并解码第四次信息转换的操作。
  • 右侧采用了Apollo ROS优化方案后的新架构,在消息传递流程中去除了两个冗余的数据拷贝环节:首先是发布节点将消息序列化为流式数据后直接发送至共享内存区域;其次是订阅节点通过直接读取共享内存中的指针定位并解码相应消息块完成信息获取。

当存在多个订阅节点时(假设 Camera 后台有多个订阅节点),如果有三个这样的节点,则会产生三条通信链路。每次通信链路都会涉及四次内存拷贝操作(即总共进行 12 次数据拷贝)。然而,在采用共享内存机制的情况下(每条链路只需两次内存拷贝),完成三条链路所需的总数据交换次数仅为 6 次)。

在这里插入图片描述

消息通信延迟:当消息规模增大时,基于共享内存通信的延迟较基于原声ROS Socket通信的延迟显著下降(约减半)。在5M数据的情况下,在5M数据的情况下(即当处理大小为5MB的数据时),传输一帧大小为5MB的数据大约需要4ms的时间(即大约4ms),而基于共享内存通信则仅需约2ms的时间(即只需约2ms)。

吞吐量:整个自动驾驶系统的网络架构具有高度复杂性,在其数据流动路径同样具有较高的复杂度。在某些极端条件下整机存储容量可能会有所增长而在车流量较大的场景中感知层与规划层与其他模块的数据交互流量也会显著提升特别是在评估极端条件下的系统性能时系统吞吐量的考量同样不可或缺

CPU资源占用率:在共享内存通信场景中,CPU资源占用率减少了约30%,主要原因是因为降低了频繁的内存复制次数。

全部评论 (0)

还没有任何评论哟~