【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::Driver
    public:
    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

相关推荐

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

    2024-07-23 03:14:03       16 阅读
  2. 02-k8s学习笔记相关组件

    2024-07-23 03:14:03       41 阅读
  3. Vue学习笔记应用创建和基础知识

    2024-07-23 03:14:03       59 阅读
  4. vue学习笔记组合式API

    2024-07-23 03:14:03       45 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-23 03:14:03       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-23 03:14:03       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-23 03:14:03       45 阅读
  4. Python语言-面向对象

    2024-07-23 03:14:03       55 阅读

热门阅读

  1. Linux Shell 022-按日期清理文件

    2024-07-23 03:14:03       16 阅读
  2. Red Playing Cards (牛客多校2 I)

    2024-07-23 03:14:03       17 阅读
  3. Husky 入门

    2024-07-23 03:14:03       16 阅读
  4. ResNeSt

    ResNeSt

    2024-07-23 03:14:03      18 阅读
  5. 如何引入全局样式文件?

    2024-07-23 03:14:03       16 阅读
  6. 长短期记忆网络(LSTM)及其Python和MATLAB实现

    2024-07-23 03:14:03       19 阅读
  7. python的open()函数

    2024-07-23 03:14:03       12 阅读
  8. 【过题记录】 7.22

    2024-07-23 03:14:03       14 阅读
  9. linux kernel 内核缓存回收的相关配置项

    2024-07-23 03:14:03       17 阅读
  10. Asp Net Web API 请求报错

    2024-07-23 03:14:03       12 阅读
  11. 欧鹏 数据库第二次作业

    2024-07-23 03:14:03       13 阅读
  12. FTP传输的两种模式的技术原理和应用

    2024-07-23 03:14:03       15 阅读