apollo cyber RT初学

一 初识

ROS无法调度协调,且通信开销大,耗资源。百度自动驾驶团队开发了Cyber RT。

CyberRT从下到上依次为:

基础库:高性能,无锁队列;

通信层:Publish/Subscribe机制,Service/Client机制,服务自发现,自适应的通信机制(共享内存、Socket、进程内);

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

计算层:计算模型,任务以及任务调度;

此外,相比Ros,CyberRT增加了Component组件,组件之间通过 Cyber channel 通信。Cyber RT 中用Message实现模块间通信,其实现基于 protobuf。同时,CyberRT也支持异步计算任务,优化线程使用与系统资源分配,同时支持定义模块拓扑结构的配置文件。

但是CyberRT也存在用户经验少的短板,同时资源也没有Ros全面。

二 组件

早期,没有组件,使用一个公共基类。所有模块都继承此基类。

Component 是 Cyber RT提供的用来构建功能模块的基础类,可以理解为Cyber RT对算法功能模块的封装,配合Component对应的DAG文件,Cyber RT可实现对该功能模块的动态加载。以Apollo为例, Apollo 中所有的模块都由 Component 构建的。

被 Cyber RT加载的 Component 构成了一张去中心化的网络。每一个Component是一个算法功能模块,其依赖关系由对应的配置文件定义,而一个系统是由多个component组成,各个component由其相互间的依赖关系连接在一起,构成一张计算图。

下图是具有3个component,2个channel的简单网络:

2.1 Component 的优点

相较于在 main() 函数中写通信逻辑并编译为单独的可执行文件的方法,Component 有以下优点:

  • 可以通过配置 launch 文件加载到不同进程中,可以弹性部署。
  • 可以通过配置 DAG 文件来修改其中的参数配置,调度策略,Channel 名称。
  • 可以接收多个种类的消息,并有多种消息融合策略。
  • 接口简单,并且可以被 Cyber 框架动态地加载,更加灵活易用。

2.2 组件启动

在 Cyber RT中,所有的 Comopnent 都会被编译成独立的.so文件,Cyber RT 会根据开发者提供的配置文件,按需加载对应的 Component。所以,开发者需要为.so文件编写好配置文.dag文件和.launch文件,以供 Cyber RT正确的加载执行Component。

Cyber RT提供两种加载启动Component的方式,分别是使用cyber_launch工具启动component对应的launch文件,和使用mainboard启动component对应的dag文件。

cyber_launch工具可以启动dag文件和二进制文件,而mainboard执行启动dag文件。

一个dag文件对应一个进程,接着根据dag文件中有几个components,生成几个协程,每个components对应一个协程。每个components对应一个dag文件,而一个dag文件则对应一个或者多个components。

对于配置文件中已经编排好的任务,其拓扑结构就依据优先级确定了。我们根据上面的 conf 文档,可以简单画出任务的优先级拓扑情况,如下图,A、B、C、D 任务在第一个 group 中执行,E在第二个 group 中执行,对于没有出现在配置中的任务,比如F默认会放到第一个 group 中执行。 而且配置中我们对于任务进行了优先级设置,A、B、C、D 的任务优先级依次增大,正好对应下图的拓扑依赖关系,在链路中越靠后的任务优先级越高。其实,数据也是这样在任务拓扑图中传递,数据走到最后,执行的任务优先级越高,这是为保证整个流程可以快速走完,不被其他流程的任务打断。

分组的原理及意义?

2.3 创建及如何工作

- 组件类:通用的组件处理消息触发

- 定时组件类:带了定时触发的属性

  • Init():初始化函数可以用来加载配置文件,实例化对象等。
  • Proc():处理数据的逻辑

1、包含头文件;

2、定义一个类,并继承Component或者time Component;根据Component功能需要,选择继承Component或者继承TimeComponent。

3、重写Init()和Proc()函数;Init()函数在 Component 被加载的时候执行,用来对Component进行初始化,如Node创建,Node Reader创建,Node Writer创建等等;Proc()函数是实现该Component功能的核心函数,其中实现了该Component的核心逻辑功能。

4、在Cyber RT中注册该Component,只有在Cyber RT中注册了该Component,Cyber RT才能对其进行动态的加载,否则,cyber RT动态加载时报错。

‍Component 的通信是基于 Channel 通信实现的,使用 reader 和 writer 对 channel 读写实现数据读取与写出。

组件使用的详细教程,可参考如下博客。

Apollo Cyber RT学习日记 (一)_// 这里只是例子,实际上用的是`artracker`的`autosync`属性。 // 但也是一个-CSDN博客

三 调度

3.1 实现原理

  • M,Machine,表示系统级线程,goroutine 是跑在 M 上的。线程想运行任务就得获取 P,从 P 的本地队列获取 G,P 队列为空时,M 也会尝试从全局队列拿一批G放到P的本地队列,或从其他P的本地队列偷一半放到自己P的本地队列。M运行G,G执行之后,M会从P获取下一个G,不断重复下去。
  • P,processor,是 goroutine 执行所必须的上下文环境,可以理解为协程处理器,是用来执行 goroutine 的。processor 维护着可运行的 goroutine 队列,里面存储着所有需要它来执行的 goroutine。
  • G,goroutine,协程。

支持优先级抢占。

M是进程。

3.2 调度策略

Apollo 提供了两种调度策略,一种是 classic 策略,在代码中,用 SchedulerClassic 类实现;另一种是 Choreography 策略,代码中用 SchedulerChoreography 类实现。

  • classic 策略
    • 较为通用的调度策略
    • 如果对当前自动驾驶车辆上的 DAG 结构不清楚,建议使用此策略
    • 相关协程任务以组为单位与线程作绑定
    • SchedulerClassic 采用了协程池的概念,协程不会绑定到具体的 Processor,而是放在全局的优先级队列中。Processor 运行时,每次从最高优先级的任务开始调度执行。
  • choreography 策略
    • 需要对车上的任务、结构足够熟悉
    • 根据任务的执行依赖关系、任务的执行时长、任务 CPU 消耗情况、消息频率等,对某些任务进行编排
    • SchedulerChoreography 类采用了本地队列和全局队列相结合的方式。他将主链路(choreography开头的配置)进行编排;而对非主链路的任务放到线程池中使用 classic 策略执行。

当使用 choreography 策略时,具体该怎么办?Well,根据任务优先级、执行时长、频率与调度之间的关系,任务编排有如下几个依据(经验):

  • 在同一个路径上的任务尽量编排在同一个 Processor 中,如果 Processor 负载过高,可考虑将部分任务拆分到其他 Processor
  • 为防止优先级倒挂,同一个路径上的任务从开始到结束,优先级应逐级升高
  • 不同路径上的任务尽量不混排
  • 高频且短耗时任务尽量编排在同一个 Processor 上

调度系统的详细分析,请参考如下博客。

Apollo Cyber RT 调度系统 - 峰子的乐园 (dingfen.github.io)

四 通信

​​​​​​​4.1 Node

节点,CyberRT的另一个基础构件;每个模块都包含节点,它能够基于信道,服务等功能,与其他节点进行通信。各个节点之间进行通信即可形成拓扑关系。并完成指定任务。

​​​​​​​4.2 Channel

信道,在 Cyber RT 中,若需要完成节点之间的通信,则需要建立一条信息传输通道,这被称为信道。节点可以将信息发送进入某一指定的信道之中,若有其他节点定义接口接收此信道消息,则可完成消息收发过程。若没有,则消息也依然存在于信道之中。

​​​​​​​4.3 Reader/Writer

若需要完成基于信道的通信,首先需要定义消息的发送方(Writer)和接收方(Reader),以保证消息可以通过 Writer 和 Reader 共同指定的 Channel ,从一个节点传输到另一个节点。这类通信方式称之为基于信道的通信(也成发布—订阅通信),有如下特点: - 同一个节点可以同时发送多条消息,也可以同时接收多条消息,即可以同时定义多个 Writer 和 Reader - 基于信道的通信是一种单向通信,消息只能由 Writer 传输到 Reader,而不能够反向传输 - 信道中的消息不需要实时应答,也就是说,当某一条消息通过 Writer 送入 Channel 后,可以没有 Reader 来读取消息。当某一个 Reader 想要读取 Channel 中的信息时,Channel 中也许并没有消息输入。

​​​​​​​4.4 Service/client

节点间双向通信,对服务发出请求时,客户端节点将收到响应。

​​​​​​​​​​​​​​4.5 传输原理

- INTRA:如果是同进程的,因为在同一地址空间,直接传指针就完了。
- SHM(Shared memory):如果是同一机器上,但跨进程的,为了高效可以使用共享内存。
- RTPS:如果是跨设备的,那就老老实实通过网络传吧。 - HYBRID: 框架需要根据节点间关系选择合适的传输后端。

五 插件

六 总结

模块化的component,分布式部署(动态化加载),标准化的通信,灵活的调度,且component还支持插件。

易于部署,灵活,好维护。

Apollo Cyber RT是基于Apollo自动驾驶开放平台的一种实时仿真工具。它能够对自动驾驶算法进行快速的模拟测试和验证。 Apollo Cyber RT可以在没有物理车辆的情况下,使用虚拟仿真环境对自动驾驶系统进行全面的测试。它提供了高度逼真的虚拟场景,包括各种路况、天气条件、道路标志和交通规则。用户可以在这个仿真环境中,验证自动驾驶算法在各种复杂情况下的性能和稳定性。 Apollo Cyber RT还提供了丰富的仿真工具和API接口,可以进行车辆动力学仿真、传感器数据仿真、车辆控制仿真等。用户可以根据实际需求,快速搭建自己的仿真场景,并通过API接口与自己的自动驾驶算法进行集成。这样,用户就可以在不同场景下进行大规模的仿真测试,测试自动驾驶系统对各种情况的应对能力。 与传统的实地测试相比,Apollo Cyber RT的优势在于它可以大大缩短测试周期和降低测试成本。传统的实地测试需要耗费大量的时间和资源,并且受到地理和气候等限制。而Apollo Cyber RT可以在任何时间和地点进行仿真测试,同时还可以通过调整仿真参数、重复测试等方式,快速地验证和迭代自动驾驶算法。 总之,Apollo Cyber RT是一种基于Apollo开放平台的实时仿真工具,它能够帮助用户快速测试和验证自动驾驶算法。它提供了丰富的虚拟场景和仿真工具,可以满足用户在不同场景下的测试需求,同时还能显著缩短测试周期和降低测试成本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值