无人驾驶与机器人领域的中间件与架构设计(一)

时间:2024-01-28 14:59:23

一、中件间系统概述

简述

在无人驾驶与机器人领域,算法,一直都是研究的核心。无论是导航技术、控制技术,还是识别技术都是构成其技术栈的重要组成部分。但是,随着技术的发展,开发者们逐渐认识到一个问题,即程序本身的组织架构与实效性,也对系统的正确性与精度产生了极大的影响。低延时、高负载能力、高易用性等等数据传输的质量与性能指标,也逐渐为工程师们所重视起来。这使得中间件与架构设计的重要性,逐渐凸显出来。目前国内主要分为两类方案:一类是基于既存的开源中间件进行开发;另一类则是自己研发或是基于开源中间件二次研发中间件。

开源中间件

1.ROS

ROS系统是机器人领域最经典的中间件通信框架之一。目前流行的主要开源算法几乎都在ROS上有功能包的实现,如gmapping、teb local planner等等。ROS系统的一大优越性,即是其完备的配套工具。它提供了一个未完成的系统调试时需要的几乎全部的功能,并且完美支持分布式访问。它作为出现较早的机器人领域的主要框架,几乎被应用于各种机器人的研发。而早期的无人驾驶,甚至当前国内部分厂商的低速系统,仍在使用此系统。

由于这个系统最初是为实验性研究所建立的,更注重的是通用性和适应性。所以在性能方面就有所欠缺了。基于xmlrpc的service调用功能速度实在不怎么样,而由于缺少Qos机制,topic的稳定性与质量也难以保证。并且运行时要依赖roscore,一旦roscore出现问题就会造成较大的系统灾难。其安装与运行体积又较大,对很多低资源系统会造成负担。

所以从目前来看,ROS适用对稳定性要求较低的,对实时性要求较低的项目,即一些demo型项目和危险性不大的低速系统项目。

2.ROS2

由于ROS具有如此多的问题,ROS2便逐渐被提起和研发出来。ROS2与ROS不同,它底层主要是基于DDS进行数据传输。DDS是基于RTPS的去中心化的通信框架,这就去除了对roscore的依赖,使得系统的稳定性及对资源的消耗得到了降低。并且,ROS2提供了Qos机制,对通信的实时性、完整性、历史追溯等功能有了支持。大幅加强了框架功能,避免了在ROS上出现的高速系统难以适用等问题。

有优点也不可避免的就会有缺点。首先就是生态,由于ROS已流行多年,其生态具有较高的广度。而ROS2,虽然目标如Navigation Stack等功能包也已向其移植,但整体的生态还是较差。并且ROS2的Qos配置较为复杂,不是十分熟悉的人很容易出错。所以此系统目前主要为国外一些相关专业的大学或实验室所使用,资料稀缺。国内行业内仅有极少数公司在尝试。

所以理论上来说ROS2可以用于任何算力和其他硬件资源能够承载其的平台。但由于生态问题,导致只被少数人所推崇。

3.Apollo

Apollo是百度所开发的一款类ROS无人驾驶系统。在早期版本(v3.1前)中,Apollo其实是基于ROS开发的一个二级系统,底层通信还是ROS,只是包裹成了Apollo App的形式。但是在ROS的弊端逐渐被认识到后,百度开始对核心进行改进,对其进行优化。其所做的主要工具其实与ROS2类似,即去中心化,并且通过如内存映射技术等内核技术进行速度优化。目前百度已将其应用在自家生产的各种系统上。

其相对于其他系统的一大优势是,专为无人架驶设计。这一点与ROS最初主要为机器人设计是不同的,所以Apollo系统从一开始就主攻高精地图技术,并以此为整个导航系统的高质基础保障。在配以深度网络的识别能力、prediction演算的预测能力、gps/lidar/radar等多传感器的综合定位能力、横纵控制器等的众多功能,实现了一个较精细全面和功能强大的导航能力。仅在无人驾驶这一块,Apollo具有天然优势。

而与之相对的,太过强大的能力自然也就带来了麻烦。由于高度依赖高精地图,使得Apollo系统难以简单使用。而各种方面演算对硬件平台的算力要求也极大。故此系统仅适用于较复杂场景下的大中型车使用。如玩具车、扫地车、快递车等较小型低速车并不是十分适合。

 

开源通信框架

除过使用完整的开源中间件系统,其实一些开源通信框架也可以用来进行无人驾驶与机器人的开发。这些通信框架通常都是面向数据的,即基于topic的架构。

1. Fast-RTPS/OpenDDS

之所以将这两种框架放在一起,是因为它们具有一定的相似性。它们都是基于RTPS实现的面向数据通信框架,遵循的是同一的标准。这类框架的特别是去中心化,支持Qos机制,支持实时通信。通常会绑定如protobuf等序列化工具。功能强大,但使用麻烦,比较适合对实时性要求较高的项目和大型项目。这两种框架都可以在github上找到它们的源码。

Fast-RTPS: https://github.com/eProsima/Fast-DDS

OpenDDS: https://github.com/objectcomputing/OpenDDS

 

2. MQTT

MQTT通常用于物联网技术。但实际上它对于低速车领域也同样适用。它体积极小,并提供了简单的Qos保证,非常适合玩具车,扫地车等功能简单、硬件资源有限的项目。但由于对延时控制等方面功能较差,不适用于高速项目和大型项目。

MQTT的一个实现mosquitto: https://github.com/eclipse/mosquitto

 

自研系统

由于开源系统较复杂且对系统要求较高,很多厂商选择自行研发中间件系统。因为这样在提供系统掌控性的同时,也可以作为产品的一个亮点进行宣传。自研系统的话,通常分为几个层级:

1. 仅支持多线程

对于很多小型车或机器人项目,其实整个系统只有一块核心板,系统所分的模块也并不是很多,那么就完全没必要去支持进程间通信。所以只完成一个小型的线程间通信框架即可。而面向数据的通信模式目前已经成为无人驾驶与机器人领域的主流,故对于这种情况,通常是实现一个支持publish/subscribe和service/call的线程通信框架。实现时,可考虑几种方式,分别是针对不同的开发人员架构:

1)集成组-算法组架构

此种架构下,算法组人员只负责实现某一算法,封装为lib库,提供为集成组人员使用。算法组人员非必要情况下不直接参与系统的整体调试,所以实机调试工作都由集成组人员负责。故算法组人员对中间件系统并不敏感,只有集成组人员才与中间件接触。此时集成组人员是整个系统应用的核心研发人员,如果开发线程通信的中间件系统,应当对各模块回调线程等进行管理与维护,故需要开发本身支持消息队列与线程回调的框架,以便掌握整个系统的运行。

2)集成组-模块组架构

此种架构下,模块组成员是主要角色,他们不仅要负责某一功能模块算法的实现,还要深入的参与到本组模块与其他组模块的对接调试工作。而集成组人员则主要负责提供统一的数据对接途径,保证整体应用系统与操作系统的协调等。在功能调试上,集成组人员更多的是协助工作,而非主导。此时由于集成组人员并不负责系统的应用功能部分,而是由各模块组协调负责,故集成组不应对功能性线程等进程维护。那么,仅提供面向数据的无队列消息通信框架即可。不应由中间通信造成过多的额外性能开销,力求最简。更多的系统状态功能交由各模块组自己负责。

 

2. 支持多进程/多线程

当由于系统需要,不得不将应用切分为多个进程时,则需要开发同时支持多线程与多进程通信的框架。通常此种框架应具有的功能为:提供publish/subscribe和service/call,并且,能够根据订阅对象对通信进行优化:当订阅对象在同一进程内时,采用线程间传输模式;当订阅对象在不同进程时,采用进程间通信模式。这种框架较仅支持线程的框架就要复杂了很多,因为要考虑性能开锁、实时性、稳定性等诸多问题。由于具有跨进程特性,所以系统必须带有消息队列功能。这种框架通常要一个组来单独负责,即中间件组专注负责其开发,而不再是由集成组兼职提供。而采用的架构一般是中间件组-算法组-集成组或中间件组-模块组-集成组。

 

3. 支持分布式

极特殊情况下,我们可能要支持多板系统,这时就要支持分布式了。分布式系统对系统实现方式就有了一定的限制,跨板情况下无法采用共享内存等较高效的方式实现。但整体状态与普通多进程相似,只是更加复杂而已。

 

总结

总之,无论采用开源系统还是自研系统,都应根据项目的实际情况进程中间件的规模选择与配置。能采用线程通信的,就不要采用进程通信,能单板完成的,就不要采用分布式系统。尽量减少系统的不必要开销才是保障实时性和稳定性的根本。