Apollo 软件系统概述
百度 Apollo 5.5 自动驾驶软件系统概述
由于课题组研究需要,博主这段时间一直在研究百度的 Apollo 自动驾驶系统,其中有一些成果和感悟,放在这里与大家分享,也算作一个研究笔记吧。
什么是 Apollo?
Apollo 是百度开发的自动驾驶开源框架,其特点是高性能和灵活的架构,可以加速对自动驾驶的开发、测试、部署流程。博主这次主要介绍一下 Apollo 5.5 的软件架构。下面是整个 Apollo 代码的目录结构,主要是按照功能模块划分:
-
cyber 消息中间件,替换 ROS 作为消息层
-
docker 容器相关
-
docs 文档相关
-
modules 自动驾驶模块,主要的定位,预测,感知,规划都在这里
- calibration 校准模块,主要用于传感器坐标的校准,用于感知模块做传感器融合
- canbus 通讯总线,接受并执行控制模块的指令,以及收集汽车的底盘状态进行反馈
- common 集合了一些常用到的基本功能
- contrib
- control 控制模块,顺着规划生成的路径,对车辆轨迹进行控制,它发送机械控制命令到 Can 总线,实现车辆的控制
- data 地图等生成好的数据放在这里(其他数据待补充)
- dreamview 仿真,能够对自动驾驶过程中的数据进行回放,其他厂家也有推出一些仿真平台,后面有机会再介绍下
- drivers 雷达,lidar,GPS, canbus,camera等驱动
- guardian 监护模块,万一出现软硬件故障,可以采取相应处理的措施保证安全
- localization 定位模块,融合 GPS、IMU、LiDAR等设备,获取汽车的定位信息
- map 地图模块
- monitor 监控模块,接受来自各个模块的数据和状态,传送到人机交互接口,可以及时地将自动驾驶车辆的各个软硬件设备情况告知驾驶员
- perception 感知模块,获取汽车当前的环境,行人,车辆,红绿灯等,给planning模块规划线路
- planning 规划模块,针对感知到的情况,对自动驾驶车辆规划时空轨迹,与路由模块不同,这指的是短期规划
- prediction 预测模块,对障碍物的轨迹做预测
- routing 路由模块,对目的地进行导航,查询走过的路线图
- third_party_perception 第三方感知模块
- tools 工具,这里面的工具有很多,有机会可详细介绍
- transform 转换
- v2x(vehicle-to-everything)其希望实现车辆与一切可能影响车辆的实体实现信息交互,能减少事故发生,减缓交通拥堵,降低环境污染以及提供其他信息服务
-
scripts 脚本
-
third_party 第三方库
-
tools 工具目录
安装与构建
在开始前,你需要一个 Ubuntu 操作系统和 Apollo 源码。官方的准备内容非常详细,这里不再罗列。
Apollo 的 构建与运行文档也非常详细。值得注意的是,考虑到github下载速度过慢,国内用户推荐使用gitee。
软件架构概览
下图是 Apollo 5.5 的软件架构图,软件平台包括各个模块以及 Cyber RT 框架和 ROS 系统。在本篇博文中,这次我重点关注的是建立在 Cyber RT 上的软件模块部分。为了充分了解工作原理,可能还会涉及到一些自动驾驶的硬件方面的知识。
博主从 Apollo 官方文档中找到了软件系统模块之间的关系图。每个模块都作为独立的 CarOS-based 的 ROS 节点运行。 每个模块节点都发送和接受某些消息。 接下来,我会对各个模块作专门的介绍,并了解他们之间的交互作用。不同于官方文档,我尽量避开技术细节,用更加通俗的语言去阐述各个模块的功能。
Perception
感知模块。相当于自动驾驶车辆的眼睛和耳朵,这是自动驾驶系统获取外界信息的主要模块,是不可或缺的部分。该模块主要感知(或者说把注意力集中在)行车时遇到的障碍物、交通信号灯、车道线、交通标志等。这很容易理解,因为人在驾驶时也需要注意这些事物,机器也一样。
感知模块需要调用的硬件设备主要是摄像机、激光雷达和雷达。这其中就涉及到深度学习识别图像技术,以及激光雷达测距技术和雷达点云阵列建模技术等。在一开始,我认为不需要深入理解这些技术在干嘛,需要了解的是,感知模块在得到硬件设备的输入后,会输出交通信号灯的指示和感知范围内障碍物的距离、速度、位置等信息。
Prediction
正如那张关系图绘制的那样,在接受到感知模块传来的信息时,预测模块会首先开始工作,自动驾驶系统必须和人类一样,能对场景中未来一段时间可能发生的情况进行正确而又适当的判断。预测模块就必须做到这一点,为此,它将于规划模块、定位模块等一起合作,给汽车下达一些合适的指令。
预测模块中内置了一个复杂的预测数学模型,该数学模型通过对接收到的信息进行分析,再结合目前的场景,给出各个物体的可能速度和路径的概率,进而预测物体的时空轨迹。
### Planning规划模块。它负责为自动驾驶车辆规划一条可行的时空轨迹。为了完成这一艰巨的任务,规划模块需要
- 自动驾驶车辆的自身状态,例如速度、位置、朝向、加速度等
- 地图相关信息,例如道路基础设施、交通灯、交通标志和导航信息
- 周围的障碍物情况,例如周围车辆、行人、非机动车等未来可能的状态
参考规划模块的相关文档,在5.5版本前,规划模块在不同的场景下,使用了相同的配置和参数进行规划。在5.5版本中,Apollo 聚焦于城市街道上的 curb-to-curb 自动驾驶,引入了两个新的规划场景。而在6.0版本中,Apollo 引入了两种新的规划模式:E2E 模式和混合模式。这两个模式都采用了基于学习的方法,对未来的行车轨迹进行规划。
从文档中可进一步了解到,Apollo 团队目前正聚焦于五种重要场景的解决,分别是沿车道线行驶、十字路口会车、找到停车位停车、从停车位离开和避让紧急车辆。
Control
根据规划轨迹和汽车的当前状态,控制模块使用不同的控制算法,尽可能地给乘客带来舒适的驾驶体验。控制模块可以在常规和导航模式下工作。它要求的输入有:
- 规划好的时空轨迹
- 自动驾驶车辆的状态
- 定位信息
控制模块在接收到完整的信息后,会使用控制算法产生一系列诸如油门、刹车、转向等控制命令。
CANBus
总线部分,用于传递控制指令到汽车的底盘上,这可能是汽车工业的总线。除了传达控制指令之外,它还会收集汽车底盘的状态信息,并反馈给控制模块等,用于矫正可能出现的偏差。
### Localization定位模块有两种方式提供定位服务:
- RTK(Real Time Kinematic),整合了 GPS 和 IMU(惯性测量单元)信息
- 多感知器融合的方案,在 RTK 的基础上加入了 LiDAR 信息
输出的当然就是车辆的精确位置了。
Miscellaneous
- HMI 人机交互接口,包括驾驶时的显示器和 DreamView(用于回看自动驾驶过程),主要功能是可视化地查看车辆驾驶的状态、测试模块、提供调试工具,以及方便司机实时地控制车辆的行驶等。
- Monitor 接收来自不同模块的数据,传给 HMI 给司机查看;监管各个软硬件系统
- Guardian 会根据 Monitor 传来的信息,决定采取何种行动来保证安全
- HD-Map 用于查询,提供关于道路情况的特制结构化信息
- StoryTelling 用于隔离和管理复杂的场景,考虑到某些场景在真实情况下实验可能会发生危险,该模块就虚拟地创建可以触发多个模块动作的场景情况。
什么是 Cyber RT
Apollo Cyber RT 是一个专门为自动驾驶场景设计的开源、高性能运行时框架。基于集中式计算模型,大大提升了自主驾驶的高并发性、低延迟性和高吞吐量。
简单来说,Cyber 是百度 Apollo 推出的替代 ROS 的消息中间件,自动驾驶中的各个模块通过 Cyber 进行消息传输,同时 Cyber 还提供了任务调度、录制Bag包等功能。
那么为什么百度 Apollo 团队要花大力气开发 Cyber RT呢?官方文档上是这么说的:
During the last few years of the development of autonomous driving technologies, we have learned a lot from our previous experience with Apollo. The industry is evolving and so is Apollo. Going forward, Apollo has already moved from development to productization, with volume deployments in the real world, we see the demands for the highest level of robustness and performance. That’s why we spent years building and perfecting Apollo Cyber RT, which addresses that requirements of autonomous driving solutions.
总结一下,就是多年的开发经验以及现实世界中的自动驾驶系统的批量部署,Apollo 团队认识到了自动驾驶对健壮性和性能的最高水平的需求,所以开发了 Cyber RT。
简单地说说它的优点:
- 加快开发。有一系列的开发工具,大量的感知器驱动和便利的数据任务接口
- 易于部署。有高效和自适应的消息通信,可配置的用户级调度器以及相比之下更少的依赖项
- 可个性化扩展。开源的运行时架构和为自动驾驶设计的模块化编程方式,可以方便用户个性化的自动驾驶系统
相关术语介绍
在这一小节,我参考百度 Apollo 文档,先给大家讲解一下 Cyber RT 中经常出现的术语。
Component
组件,简单的来说就是一个算法模块。在自动驾驶系统中,感知、定位、控制系统等模块以组件 (Component) 的形式存在于 Cyber RT 下,每个组件通过网络通道 (Channel) 与其他组件进行通信。组件的概念不仅对模块进行了解耦,还提供了将模块划分为组件的设计灵活性。
Cyber RT 为开发者提供了 Component 类簇,开发者的算法业务模块只需要继承相关的Component 类,并实现其中的接口即可,主要是关于实现算法、消息处理相关的逻辑。除此之外,Cyber RT 基于协程(后面我们会提到),为开发者提供了并行计算相关的接口。
Node
节点是 Cyber RT 的基础构件;每个模块都包含节点,它能够基于信道、服务等功能与其他节点进行通信。各个节点之间进行通信即可形成拓扑关系,并完成指定任务。通过使用节点,可将代码和功能解耦,提高了系统的容错能力和可维护性,使系统简化。同时,节点允许了 Cyber RT 能够布置在任意多个机器上并同时运行。
Channel
信道。在 Cyber RT 中,若需要完成节点之间的通信,则需要建立一条信息传输通道,这被称为信道。节点可以将消息发送进入某一指定的信道之中,若有其他节点定义接口接收此信道消息,则可完成消息收发过程。若没有,则消息也依然存在于信道之中。
Reader/Writer
若需要完成基于信道的通信,首先需要定义消息的发送方(Writer)和接收方(Reader),以保证消息可以通过 Writer 和 Reader 共同指定的 Channel ,从一个节点传输到另一个节点。这类通信方式称之为基于信道的通信(也成发布—订阅通信),有如下特点:
- 同一个节点可以同时发送多条消息,也可以同时接收多条消息,即可以同时定义多个 Writer 和 Reader
- 基于信道的通信是一种单向通信,消息只能由 Writer 传输到 Reader,而不能够反向传输
- 信道中的消息不需要实时应答,也就是说,当某一条消息通过 Writer 送入 Channel 后,可以没有 Reader 来读取消息。当某一个 Reader 想要读取 Channel 中的信息时,Channel 中也许并没有消息输入
Task 与 CRoutine
任务 (Task) 是对 Cyber RT 中异步计算任务的抽象描述。
CRoutine 就是指的协程 (Coroutine) ,Cyber RT 实现了 CRoutine 来优化线程的使用和系统资源的分配。
Service/Client
基于服务(Service)的通信是 Cyber RT 中的另一种通信方式,与信道通信相同,基于服务的通信也需要有消息的收发节点。但与信道不同的是,服务需要两个节点之间完成请求或应答才可完成通信。
在自动驾驶系统中,除了各节点的消息发送和接收之外,很多场景还需要在节点之间进行双向通信,并能够获得应答。这就需要利用服务来通信。不同于 Channel 的通信方式,Service 的一个节点如果想要获取信息,需要给另一个节点发送请求,以此来获取响应,这就完成了节点之间的双向通信。在 Service 中,发送请求的一方为客户端(Client),接收请求的一端为服务端(Server)。
结语
这篇博客粗略介绍了一下 Apollo 系统的各个软件模块以及 Cyber RT 的相关术语。接下来,根据课题组的具体要求,我会深入到 Cyber RT,继续研究 Apollo 自动驾驶系统。
参考文献
[1] Dig into Apollo
[2] Apollo 官方文档