当前位置: 首页 > 编程日记 > 正文

百度Apollo 3.5是如何设计Cyber RT计算框架的?

自百度Apollo自动驾驶平台开源以来,已快速迭代至 3.5 版本,代码行数超过 39 万行,合作伙伴超过 130 家,吸引了来自 97 个国家的超 15000 名开发者。无疑,Apollo 是目前世界范围内最活跃的自动驾驶开放平台之一。


640?wx_fmt=png


最新发布的 Apollo 3.5 总体架构从上到下仍分为四层,最底层为车辆平台,自动驾驶汽车需要对车辆进行线控改造,使得车载大脑可以通过电信号来控制车辆的执行器;往上一层是硬件平台,包括计算单元、传感器以及 V2X 相关接收设备等。再上一层是软件平台,主要包括操作系统、中间件、算法模块等。最顶层的是云端服务,主要包括地图、OTA 服务升级、数据平台、语音交互等方面。


此次发布的Apollo 3.5,解锁了Apollo 在复杂城市道路中的自动驾驶能力,并开源了 Cyber RT 计算框架、V2X 车路协同方案以及硬件平台的一些能力。


随着自动驾驶技术不断发展,Apollo 已经从研发走向量产产品落地。作为 Apollo 开源软件平台的一部分,Apollo Cyber RT 处于底层的实时操作系统(RTOS) 和算法模块之间,那么如何能够在保证高吞吐的情况下,又能低延迟的实时响应上层任务,并保证整个系统确定性的运转,1 月 24 日,在 CSDN 平台上举办的 Apollo 开发者社区公开课上,百度主任架构师王柏生就 Cyber RT 的设计思考,总体架构以及关键模块相关细节同开发者做了分享。


从 ROS 系统说起

640?wx_fmt=png

Apollo 最初用的中间件是 ROS(机器人操作系统),概括来说,ROS 系统主要包含三方面:


第一是通信系统,ROS 是个分布式的松耦合系统,算法模块是以独立的进程形式存在的,也就是我们常说的 Node。ROS 基于 Socket 实现了pub/sub 的通信方式,不同的算法节点(node)之间通过 pub/sub 的发送/接收消息。


第二是 Framework&Tools (框架和工具),开发者可以基于 ROS 提供的 Client Library 和通信层,方便的收发消息。开发者只需要关注消息处理相关的算法,而至于算法何时被调用,全部由框架来处理。


第三是生态系统,从社区内,开发者可以很方便地寻找到很多现成的「传感器驱动」和「算法实现」等进行参考。


640?wx_fmt=png


随着自动驾驶的发展,不少开发者,包括 Apollo 平台,把 ROS 应用于自动驾驶系统,毕竟自动驾驶汽车也相当于一个大的机器人。但是我们在实践中也遇到了很多挑战:


  • 首先,ROS 中的算法模块是以独立的进程形式存在的,那么这些进程之间应该以什么样的顺序去执行?实际上,Linux 本身是一个通用系统,内核中的调度器对上面的算法业务逻辑并不清楚,它只是在尽量满足公平的情况下让大家都得到调度。所以,ROS Node 运行顺序并无任何逻辑。


    但本质上自动驾驶是一个专用系统,任务应该按照一定的业务逻辑执行。那么是在 ROS 层加一个 Node,由其来同步各个算法任务的运行,还是在Linux 内核中实现新的调度策略,使其结合算法业务逻辑进行调度?前者的开销,后者的迁移性,都是需要思考的问题。


  • 其次,ROS 是一个分布式的系统。既然是分布式,就要有通信的开销。即使在同一个物理节点上,依然存在着通信的开销。所以 Apollo 前期曾经使用共享内存去降低 ROS 原生的基于 Socket 通信的开销。ROS 2 也在使用 DDS 解决通信方面的实时性。ROS 也支持 Nodelet 模式,这可以去掉进程间通信的开销,但是调度的挑战依然存在。


  • 第三,除了调度的不确定性,ROS 系统中还存在其他很多不确定的地方,比如内存的动态申请。


Cyber RT 的运行流程

640?wx_fmt=png

算法模块通过有向无环图(DAG),配置任务间的逻辑关系。对于每个算法,也有其优先级、运行时间、使用资源等方面的配置。系统启动时,结合DAG、调度配置等,创建相应的 任务,从框架内部来讲,就是协程,调度器把任务放到各个 Processor 的队列中。然后,由 Sensor 输入的数据,驱动整个系统运转。


Cyber RT 架构

 

640?wx_fmt=png

基本上,Cyber RT 包括如下软件模块: 


最下面一层是基础库,为了高效,Cyber RT 实现了自己的基础库。比如我们实现了 Lock-Free 的对象池,实现了 Lock-Free 的队列,随着成熟,会陆续开放更多。除了框架自身外,将来也会逐渐应用于算法模块。除了效率原因为,也希望 Cyber RT 减少依赖。


再往上是通信相关的,包括服务发现,还有 Publish-Subscribe 通信机制。 Cyber RT 也支持跨进程、跨机通信,上层业务逻辑无需关心,通信层会根据算法模块的部署,自动选择相应通信机制。 


通信层之上是 数据缓存/融合层,多路传感器之间数据需要融合,而且算法可能需要缓存一定的数据。比如典型的仿真应用,不同算法模块之间需要有一个数据桥梁,数据层起到了这个模块间通信的桥梁的作用。


再往上是计算模型,计算模型包括刚才前面提到的调度和任务,后面我们会详细讨论。


计算模型之上是为开发者提供的接口。Cyber RT为开发者提供了Component 类,开发者的算法业务模块只需要继承该类,实现其中的 Proc 接口即可。该接口类似于 ROS 中的 Callback,消息通过参数的方式传递,用户只要在Proc中实现算法、消息处理相关的逻辑。Cyber RT 也基于协程,为开发者提供了并行计算相关的接口。


Cyber RT 也为开发者提供了开发调试、录制回放等工具,未来还会开放性能调试工具。


从内核空间到用户空间

 

640?wx_fmt=png

ROS 的主要挑战之一是没有调度,为了解决 ROS 遇到的问题,Cyber RT 的核心设计将调度、任务从内核空间搬到了用户空间。调度可以和算法业务逻辑紧密结合。


从 Cyber RT 角度,OS 的 Native thread 相当于物理 CPU。


在 OS 中,是内核中的调度器负责调度任务(进程、线程…)到物理 CPU 上运行。而在 Cyber RT 中,Cyber RT 中的调度器调度协程(Coroutine)在 Native Thread 上有序运行。


编排调度策略

 

640?wx_fmt=png


任务编排策略是 Cyber RT 开源的主要策略之一。每个 Processor (Native Thread) 一个任务队列,由调度器编排队列中的任务。任务在哪个 CPU 上运行?任务之间是否需要相邻运行?哪些先运行?哪些后运行?都由调度器统一调度,任务基于协程实现。在任务阻塞时,快速让出 CPU。


每个物理 CPU 上除运行1个 normal 级别的 thread 外,运行着另外 1+ 个高优先级的 thread,基于此,实现用户空间的高优先级的任务抢占运行。比如,之前去 GPU 运行的算法,在 GPU 上完成运行返回后,应该尽快的得到运行。


这种调度策略,很好的结合了业务逻辑、数据共享和算力的平衡。并且任务不会在不同 CPU 上随机的调度来调度去,具有非常好的 Cache 友好性。


经典调度策略

 

640?wx_fmt=png


任务编排策略,不仅需要对业务逻辑的深度理解,也需要结合计算机的算力等综合考虑。因此,Cyber RT 也提供了类似经典线程池模式的调度算法,这种模式几乎不存在配置的代价。对此,Cyber RT 也做了一些改进,比如为了减小锁的瓶颈,任务是多队列的。任务队列也支持优先级,后续还会支持分组,通过组控制算法对资源的使用。


算法任务的载体—协程

 

640?wx_fmt=png


Cyber RT 使用了协程作为算法任务的载体。协程之于线程,就类似于线程之于物理 CPU,由 Cyber RT 中的调度器负责在各个线程之上周而复始,切换调度协程。为了算法模块在其他协处理器执行计算时,可以让出Processor(Native Thread),并在完成之后,回来时可以再次运行,Cyber RT采用了有状态的协程。


那么 Cyber RT 为什么采用协程呢?除了协程的切换非常快之外,调度的确定性是另外一个重要的原因。举个典型的例子,假设用 native thread 去执行一个任务,当任务因为去 GPU 等加速器运算时,或者因为资源原因被Block 时,在 thread 就绪时,什么时候调度上来其实是一个非确定的过程,完全依赖于操作系统以及其上任务的情况。


Cyber RT也支持跨进程、跨机通信


640?wx_fmt=png


实际部署中,也存在着比如某个工具需要运行在独立的进程,安全系统部署在另外的节点。因此,Cyber RT 也支持跨进程、跨机通信。上层业务逻辑无需关心,通信层会根据算法模块的部署,自动选择相应通信机制。 

 

以上就是本次直播分享的内容。非常感谢大家的参加!也欢迎大家提出问题,进行交流。更多 Apollo 相关的技术干货也可以继续关注 Apollo 开发者社区每月的课程分享,也可以在 Apollo GitHub(https://github.com/ApolloAuto/apollo)上提出技术问题与我们互动,期待大家的沟通交流!

相关文章:

Spark Streaming实践和优化

2019独角兽企业重金招聘Python工程师标准>>> Spark Streaming实践和优化 博客分类: spark 在流式计算领域,Spark Streaming和Storm时下应用最广泛的两个计算引擎。其中,Spark Streaming是Spark生态系统中的重要组成部分&#xff0…

Python | 一万多条拼车数据,看春运的迁徙图

作者 | 白苏,医疗健康领域产品经理一枚,Python&R爱好者来源 | InThirty编辑 | Jane今天是腊月二十八,你们都到家了吗?这篇文章,作者对北京、上海、广州、深圳、杭州等地 1万多条出行数据进行分析,得出了…

[转载] sql server 2000系统表解释

sql server 2000系统表解释汇总了几个比较有用的系统表,内容摘自联机帮助sysobjects---------------在数据库内创建的每个对象(约束、默认值、日志、规则、存储过程等)在表中占一行。只有在 tempdb 内,每个临时对象才在该表中占一…

【驱动】uboot环境变量分析

0、bootcmd 0.1 飞凌原设置 bootcmdif mmc rescan; then if run loadbootscript; then run bootscript; else if test ${bootdev} sd1; then echo update firmware.........;run update_from_sd;else echo mmc boot..........;if run loadimage; then run mmcboot; else run n…

python--属性魔法方法

转载于:https://www.cnblogs.com/Purp1e/p/8149773.html

利用三层交换机实现VLAN的通信实验报告

利用三层交换机实现VLAN的通信实验报告<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />背景&#xff1a;要想实现VLAN之间的通讯,我们可以采用通过路由器实现VLAN间的通信 使用路由器实现VLAN间通信时&#xff0c;路由器与交换机…

【Qt】Qt Creator中文输入设置

#【Qt】Qt Creator中文输入设置 一、ubuntu中文输入法的设置 1、在终端中输入&#xff1a; $ ibus-setup 弹出界面如图&#xff1a; 2、选择中文输入法 3、点击右上角设置–》选择系统设置–》选择语言支持 4、语言支持选择&#xff1a; 汉语&#xff08;中国&#xff09…

为何Google将几十亿行源代码放在一个仓库?

作者 | Rachel Potvin&#xff0c;Josh Levenberg 译者 | 张建军 编辑 | apddd 【AI科技大本营导读】与大多数开发者的想象不同&#xff0c;Google只有一个代码仓库——全公司使用不同语言编写的超过10亿文件&#xff0c;近百TB源代码都存放在自行开发的版本管理系统Piper中&…

Java反射得到属性的值和设置属性的值

package com.whbs.bean; public class UserBean { private Integer id; private int age; private String name; private String address; public UserBean(){ System.out.println("实例化"); } public Integer getId() { return id; } public void setI…

ASP.NET 中的正则表达式

引言 Microsoft.NET Framework 对正则表达式的支持是一流的&#xff0c;甚至在 Microsoft ASP.NET 中也有依赖正则表达式语言的控件。本文介绍了深入学习正则表达式的基础知识和推荐内容。 本文主要面向对正则表达式知之甚少或没有使用经验&#xff0c;但却熟悉 ASP.NET、可借助…

如何用最强模型BERT做NLP迁移学习?

作者 | 台湾大学网红教授李宏毅的三名爱徒来源 | 井森堡&#xff0c;不定期更新机器学习技术文并附上质量佳且可读性高的代码。编辑 | Jane谷歌此前发布的NLP模型BERT&#xff0c;在知乎、Reddit上都引起了轰动。其模型效果极好&#xff0c;BERT论文的作者在论文里做的几个实验…

【驱动】GPIO寄存器配置总结

#【驱动】GPIO寄存器配置总结 0、设置复用功能为GPIO 1、设置引脚特性&#xff0c;与硬件匹配 2、配置寄存器举例 字段解释&#xff1a; 2.0、SRE 数据位&#xff1a;0 SRE(Slew Rate Field)&#xff1a;转换速度字段&#xff1f;&#xff1f;&#xff1f;这是一个可以调…

android Tabhost部件

本文结合源代码和实例来说明TabHost的用法。 使用TabHost 可以在一个屏幕间进行不同版面的切换&#xff0c;例如android自带的拨号应用&#xff0c;截图&#xff1a; 查看tabhost的源代码&#xff0c;主要实例变量有&#xff1a; private TabWidget mTabWidget; private Fr…

网易开源支持图像识别的自动化UI测试工具,零基础亲测好评!

编辑 | Jane出品 | AI科技大本营AI科技大本营给大家推荐了很多有意思、适合开发者们的工具&#xff0c;比如代码修复神器、帮小白快速分析 Error、PDF 翻译工具、变量命名神器等等。今天&#xff0c;营长要专门给测试人员&#xff0c;或者想做测试的小伙伴们推荐一款工具&#…

【驱动】GPIO 作为按键时的 设备树 配置

#【驱动】GPIO作为按键时的 设备树 配置 0、设备树 0.0 别名 imx6ul.dtsi 什么作用&#xff1f;&#xff1f;&#xff1f; /*************开始/ / { aliases {… gpio0 &gpio1; gpio1 &gpio2; gpio2 &gpio3; gpio3 &gpio4; gpio4 &gpio5; /**********…

最小树形图及其生产方法

诸位看官&#xff0c;这是我第一次在整篇文章的所有图片里面加水印。小弟写博客的时间不长&#xff0c;就有两篇博客被盗用并未注明原文网址。这一方面使我痛心不已&#xff0c;另一方面迫使我不得不重新考虑一下版权保护问题。小弟不是吝啬鬼&#xff0c;如果影响阅读或者是确…

【数据库】MySQL的C语言接口学习

0、【初始化】 MYSQL* mysql_init(MYSQL *mysql); 1、【设置连接选项】 int mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg); 2、【连接】 MYSQL* mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, cons…

程序员单身比例有多高?【2019开发者图鉴】告诉你

编辑 | Jane 出品 | AI科技大本营 本次调查共 8 个问题&#xff0c;根据这些数字我们整理了《2019开发者图鉴》&#xff0c;下面营长将发现的一些有意思的数字分享给大家&#xff1a; 性别与年龄 本次参与调查的男女比例约为 8&#xff1a;2&#xff08;男8女2&#xff09;。 …

26.2. Web UI

http://localhost:3000/ 原文出处&#xff1a;Netkiller 系列 手札 本文作者&#xff1a;陈景峯 转载请与作者联系&#xff0c;同时请务必标明文章原始出处和作者信息及本声明。

VC++ 6.0的小花招

Visual Studio系列中产品中&#xff0c;Visual Studio 6.0是最经典的一个版本&#xff0c;虽然后来有Visual Studio .NET 2003&#xff0c;以及2005&#xff0c;也确实添加了很多让我觉得激动的特性&#xff0c;但是从使用细节的细腻程度上来看&#xff0c;VS 6.0无疑是最棒的。…

【linux】嵌入式中 crontab的使用

0、编辑 执行&#xff1a;crontab -e 执行命令后&#xff0c;将出现一个编辑界面&#xff0c;内容格式如下 Minute Hour Day Month Dayofweek command 分钟 小时 天 月 天每星期 命令 每个字段代表的含义如下&#xff1a; Minute 每个小时的第几分钟执行该任务 Hour 每天的第几…

程序员该怎么做,才能成为coding王者?

每当做编程题目时&#xff0c;大多数人都会靠基本的直觉&#xff0c;遵循一些固定的步骤来有效地解题。不管是有意还是无意&#xff0c;在做编程题目的时你会下意识地遵循一些步骤&#xff0c;在阅读完这篇文章后你就可以将这些步骤和这篇文章联系起来&#xff0c;从而就可以更…

27.3. source code

tar zxvf bandwidthd-2.0.1.tgz cd bandwidthd-2.0.1 ./configure --prefix/srv/bandwidthd-2.0.1 make make install 原文出处&#xff1a;Netkiller 系列 手札 本文作者&#xff1a;陈景峯 转载请与作者联系&#xff0c;同时请务必标明文章原始出处和作者信息及本声明。

WF4.0实战(一):文件审批流程

http://www.cnblogs.com/zhuqil/archive/2010/04/13/DocumentApprovalProcess.html转载于:https://www.cnblogs.com/Little-Li/archive/2010/06/01/1749392.html

AI科技大本营在线公开课大放送(附演讲PPT)

新年新思&#xff01;新一年&#xff0c;每个人的梦想都闪耀着多彩光芒&#xff0c;对于AI领域的每一位学习者和从业者&#xff0c;我们充满渴望&#xff0c;怀揣梦想&#xff0c;心系对技术的不懈追求。AI科技大本营同样也有自己的新年梦想和脚踏实地的规划&#xff0c;比如今…

《微信跳一跳》安卓手机刷分软件搭建及攻略

2019独角兽企业重金招聘Python工程师标准>>> 元旦期间被微信小程序的游戏刷屏幕了。手笨脚笨的我也尝试了下这新出的小玩意&#xff0c;实在话手脚不协调最高仅仅90分&#xff0c;处于做技术的角度&#xff0c;直觉上可以技术上模拟解决&#xff0c;凑好朋友在微信群…

【libevent】libevent库学习总结(一)——基础

libevent库学习总结&#xff08;一&#xff09;——基础 一、基础 1.1、 介绍 Libevent是一个用于开发可伸缩网络服务器的事件通知库。Libevent API提供了一种机制来执行回调函数&#xff0c;当某个特定事件发生在文件描述符上或超时到达之后。此外&#xff0c;Libevent还支…

AS1.0(2.0)中的XML示例

虽然Flash早就升级为AS3.0&#xff0c;但是FMS的服务端编程依然仅支持AS1.0(2.0)&#xff0c;服务端与.net通讯的最简单方式莫过于请求一个RESTful的webService或wcf&#xff0c;通过它们返回的xml来获取数据。 var _xml:XML new XML("<ArrayOfstring xmlns\"htt…

【Qt】Qt发布可执行程序(打包依赖库)

Qt发布可执行程序&#xff08;打包依赖库&#xff09; 0、编译出可执行文件 如&#xff1a;xxx.exe 1、将xxx.exe拷贝到一个目录下面 2、启动Qt终端交互界面程序 如&#xff1a;Qt 5.6 for Desktop&#xff08;MinGW&#xff09; 3、进入xxx.exe所在的目录 4、执行命令…