Apollo之Cyber学习总结

一、Cyber框架

  • Cyber实现的功能主要包括如下几方面:

---消息队列,主要作用是接收和发送各个节点的消息,设计到消息的发布,订阅以及消息的buffer缓存等.

---实时调度,主要作用是调度处理上述消息的算法模块,保证算法模块能够实时调度处理消息.

---用户接口,主要提供灵活的用户接口.

---工具,提供一系列的工具,如bag包,点云可视化,消息监控等.

  • Cyber的入口

---cyber的入口在"cyber/mainboard"目录中:

   |---mainboard.cc     //主函数

   |---module_argument.cc   //模块输入参数,主要是解析加载DAG文件时候带的参数.

   |---module_argument.h

   |---module_controller.cc   //模块加载,卸载

   |---module_controller.h

上述cyber mainboard的整个流程,cyber main 函数中先解析dag参数,然后根据解析的参数,通过类加载器动态的加载对应的模块,然后调用Initalize方法初始化模块.

---类加载器(class_loader):类加载器的作用就是动态的加载动态库,然后实例化对象.

  • Cyber的数据流程

Cyber的数据流程主要分为6个过程:

1、Node节点中的Writer往通道里面写数据.

2、通道中的Transmitter发布消息,通道中的Receiver订阅消息.

3、Receiver接收到消息后,触发回调,触发DataDispather进行消息分发.

4、DataDispather接收到消息后,把消息放入CacheBuffer,并且触发Notifier,通知对应的DataVisitor处理消息.

5、DataVisitor把数据从CacheBuffer中读出,并且进行融合,然后通过notifer_唤醒对应的协程.

6、协程进行对应的注册回调函数,进行数据处理,处理完成之后接着进入睡眠状态.

数据流程各个模块之间的关系:

1、Component和Node之间的关系

Component是Cyber中封装好的数据处理流程,对用户来说,对应自动驾驶中的Planning Component, Perception Component等,目的是帮助我们更方便的订阅和处理消息.实际上Component模块在加载之后会执行"Initialize()"函数,这是个隐藏的初始化过程,对用户不可见.在"Initialize"中,Component会创建一个Node节点,概念上对应ROS的节点,每个Component模块只能有一个Node节点,也就是说每个Component模块有且只能有一个节点,在Node节点中进行消息订阅和发布.

2、Node和Reader\Writer的关系

在Node节点中,可以创建Reader订阅,也可以创建Writer订阅,每个Node节点中可以创建多个Reader和Writer.

3、Reader和Receiver,Writer和Transmitter,Channel的关系

一个Channel对应一个Topic,概念上对应ROS的消息通道,每个Topic都是唯一的,而Channel中包括一个发送器(Transmitter)和接收器(Receiver),通过Reiceiver接收消息,通过Transmitter发送消息.

一个Reader只能订阅一个通道的消息,如果一个Node需要订阅多个通道的消息,需要创建多个Reader。同理一个Writer也只能发布一个通道的消息,如果需要发布多个消息,需要创建多个Writer.

Reader中调用Receiver订阅消息,而Writer通过Transmitter发布消息.

4、Receiver, DataDispather 和 DataVistor的关系

每一个Receiver接收到消息之后,都发触发回调,回调中触发DataDispather(消息分发器)发布消息,DataDispather是一个单例,所有的数据分发都在数据分发器中进行,DataDispather会把数据放到对应的缓存中,然后Notify(通知)对应的协程(实际上这里是调用的DataVisitor中注册的Notify)去处理消息.

DataVistor(消息访问器)是一个辅助的类,一个数据处理过程对应一个DataVistor,通过在DataVistor中注册Notify(唤醒对应的协程,协程执行绑定的回调函数),并且注册对应的Buffer到DataDispather,这样在DataDispather的时候通知对应的DataVistor去唤醒对应的协程.

也就是说DataDispather(消息分发器)发布对应的消息到DataVistor,DataVistor(消息访问器)唤醒对应的协程,协程中执行绑定的数据预处理回调函数.

5、DataVisitor和Croutine的关系

实际上DataVisitor中的Notify是通过唤醒协程(为了方便理解也可以理解为线程,可以理解为你有一个线程池,通过线程池绑定数据处理函数,数据到来之后就唤醒对应的线程去执行任务),每个协程绑定了一个数据处理函数和一个DataVisitor,数据到达之后,通过DataVisitor中的Notify唤醒对应的协程,执行数据处理回调,执行完成之后协程进入休眠状态.

6、Scheduler, Task和Croutine

通过上述分析,数据处理的过程实际上就是通过协程完成的,每一个协程被称为一个Task,所有的Task(任务)都由Scheduler进行调度。从这里我们可以分析得出实际上Cyber的实时调度由协程去保障,并且可以灵活的通过协程去设置对应的调度策略,当然协程依赖于进程,Apollo在linux中设置进程的优先级为实时轮转,先保障进程的优先级最高,然后内部再通过协程实现对应的调度策略.

二、Cyber Component 介绍

Component的流程

1、创建node节点(1个component只能有一个node节点,之后用户可以用node_在init中自己创建reader和writer).

2、调用用户自定义的初始化函数Init()(子类的Init方法)

3、创建reader,订阅几个消息就创建几个reader.

4、创建回调函数,实际上是执行用户定义算法Proc()函数.

5、创建数据访问器,数据访问器的用途为接收数据(融合多个通道的数据),唤醒对应的协程执行任务.

6、创建协程任务绑定回调函数,并且绑定数据访问器到对应的协程任务,用户唤醒对应的任务.

 

 

 

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值