当前位置: 首页 > news >正文

【Apollo学习笔记】—— Cyber RT之创建组件, test ok

0. 前置知识

这部分内容详见第三章:Component组件认知与实践https://apollo.baidu.com/community/article/1103

0.1 什么是 Component

Apollo 的 Cyber RT 框架是基于组件(component)概念来构建的。每个组件都是 Cyber RT 框架的一个特定的算法模块, 处理一组输入并产生其输出数椐,配合Component对应的DAG文件,Cyber RT可实现对该模块的动态加载。

0.2 Component 的类型

Component分为2类:一类是消息驱动的Component(即消息到来时,才会调用proc()),第二类是定时调用的TimerComponent。定时调度模块没有绑定消息收发,需要用户自己创建reader来读取消息,如果需要读取多个消息,可以创建多个reader。

Component提供消息融合机制,最多可以支持 4 路消息融合,当 从多个 Channel 读取数据的时候,以第一个 Channel 为主 Channel。当主 Channel 有消息到达,Cyber RT会调用 Component的Proc()进行一次数据处理。
TimerComponent不提供消息融合,与Component不同的是TimeComponent的 Proc()函数不是基于主channel触发执行,而是由系统定时调用,开发者可以在配置文件中确定调用的时间间隔。

0.3 Component 的创建及工作流程

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动态加载时报错。

见2.1头文件部分具体实现

0.4 Component 如何被加载


在 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文件。

0.5 Component 的优点


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

初始化组件的目录结构
实现组件类
设置配置文件
启动组件


1. 初始化组件的目录结构


以example-component 为例.(以下案例请先暂时忽略timer部分)

├── BUILD
├── cyberfile.xml
├── example-components.BUILD
├── example.dag
├── example.launch
├── proto
│   ├── BUILD
│   └── examples.proto
└── src├── BUILD├── common_component_example.cc├── common_component_example.h├── timer_common_component_example.cc└── timer_common_component_example.h


C++头文件: common_component_example.h
C++源文件: common_component_example.cc
Bazel 构建文件: BUILD
DAG 文件: examples.dag
Launch 文件: examples.launch


2. 实现组件类

2.1 头文件

实现common_component_example.h有以下步骤:包含头文件
基于模板类 Component 派生出组件类CommonComponentSample
在派生类中定义自己的 InitProc 函数。Proc 需要指定输入数椐类型。
使用CYBER_REGISTER_COMPONENT宏定义把组件类注册成全局可用。

#pragma once
#include <memory>#include "cyber/component/component.h"
#include "example_components/proto/examples.pb.h"//  CommonComponentSample类不能被继承
class CommonComponentSample : public apollo::cyber::Component<example::proto::Driver, example::proto::Driver> {//有几个数据就有几个example::proto::Driverpublic:bool Init() override;bool Proc(const std::shared_ptr<example::proto::Driver>& msg0,const std::shared_ptr<example::proto::Driver>& msg1) override;
};
CYBER_REGISTER_COMPONENT(CommonComponentSample)


模板类Component的定义在cyber/component/component.h中.

template <typename M0 = NullType, typename M1 = NullType,typename M2 = NullType, typename M3 = NullType>
class Component : public ComponentBase {public:Component() {}~Component() override {}/*** @brief init the component by protobuf object.** @param config which is defined in 'cyber/proto/component_conf.proto'** @return returns true if successful, otherwise returns false*/bool Initialize(const ComponentConfig& config) override;bool Process(const std::shared_ptr<M0>& msg0, const std::shared_ptr<M1>& msg1,const std::shared_ptr<M2>& msg2,const std::shared_ptr<M3>& msg3);private:/*** @brief The process logical of yours.** @param msg0 the first channel message.* @param msg1 the second channel message.* @param msg2 the third channel message.* @param msg3 the fourth channel message.** @return returns true if successful, otherwise returns false*/virtual bool Proc(const std::shared_ptr<M0>& msg0,const std::shared_ptr<M1>& msg1,const std::shared_ptr<M2>& msg2,const std::shared_ptr<M3>& msg3) = 0;
};


由代码可见,Component类最多接受4个模板参数,每个模板参数均表示一种输入的消息类型,这些消息在Proc函数中被周期性地接收并处理.

2.2 源文件

对于源文件 common_component_example.cc, Init 和 Proc 这两个函数需要实现。

#include "example_components/src/common_component_example.h"bool CommonComponentSample::Init() {AINFO << "Commontest component init";return true;
}bool CommonComponentSample::Proc(const std::shared_ptr<example::proto::Driver>& msg0,const std::shared_ptr<example::proto::Driver>& msg1) {AINFO << "Start common component Proc [" << msg0->msg_id() << "] ["<< msg1->msg_id() << "]";return true;
}


2.3 创建 BUILD 文件


可见基于common_component_example_lib库最终生成了一个共享库文件libcommon_component_example.so,而该共享库通过Cyber RT调度程序mainboard动态加载运行

load("//tools:cpplint.bzl", "cpplint")
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")package(default_visibility = ["//visibility:public"])cc_binary(name = "libcomponent_examples.so",linkshar

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • python Requests库7种主要方法及13个控制参数(实例实验)
  • Linux云计算 |【第一阶段】ENGINEER-DAY5
  • MyBatis-Plus的几种常见用法
  • HTML5大作业三农有机,农产品,农庄,农旅网站源码
  • C语言 | Leetcode C语言题解之第239题滑动窗口最大值
  • 线程安全性问题(一)
  • SQL Server性能监控秘籍:数据库性能计数器阈值设置指南
  • 紫光展锐5G安卓核心板T760__国产手机芯片方案
  • 【分布式存储系统HDFS】架构和使用
  • Spring Boot集成starrocks快速入门Demo
  • laravel为Model设置全局作用域
  • Unity Apple Vision Pro 开发(四):体积相机 Volume Camera
  • golang性能调试工具net/http/pprof
  • 时序数据库如何选型?详细指标总结!
  • ubuntu如何彻底卸载android studio?
  • [译] React v16.8: 含有Hooks的版本
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • ComponentOne 2017 V2版本正式发布
  • css的样式优先级
  • CSS实用技巧干货
  • Github访问慢解决办法
  • HTML5新特性总结
  • IOS评论框不贴底(ios12新bug)
  • JAVA之继承和多态
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • Mac转Windows的拯救指南
  • Mysql5.6主从复制
  • PV统计优化设计
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 你不可错过的前端面试题(一)
  • 驱动程序原理
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 移动端解决方案学习记录
  • - 转 Ext2.0 form使用实例
  • ​configparser --- 配置文件解析器​
  • ​学习一下,什么是预包装食品?​
  • # include “ “ 和 # include < >两者的区别
  • #微信小程序(布局、渲染层基础知识)
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (20050108)又读《平凡的世界》
  • (Note)C++中的继承方式
  • (面试必看!)锁策略
  • (十六)Flask之蓝图
  • (四)js前端开发中设计模式之工厂方法模式
  • (一) springboot详细介绍
  • (一)SpringBoot3---尚硅谷总结
  • (一)基于IDEA的JAVA基础10
  • (转)h264中avc和flv数据的解析
  • (转)甲方乙方——赵民谈找工作
  • (转)项目管理杂谈-我所期望的新人
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .form文件_SSM框架文件上传篇
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记