查看原文
其他

技术文档 | 如何使用Cyber RT创建新组件

阿波君 Apollo开发者社区 2022-07-29

Apollo Cyber 运行时。

其框架 ( Apollo Cyber RT Framework ) 是基于组件概念来构建的。

组件化开发的成果是基础库和公共组件,其原则是高重用,低耦合

如果让我们来看组件化开发的定义,它的着重点就是代码重用。代码重构这一步最后的结果就是提炼出一个个组件给不同的功能使用。 


这里我们可以看一下其中的依赖关系:具体功能依赖提炼出来的组件,组件本身之间可能也有依赖关系,但一般不多。

每个组件都是Cyber框架的一个构建块, 它包括一个特定的算法模块,此算法模块处理一组输入数椐并产生一组输出数椐。

要创建并启动一个算法组件, 需要通过以下4个步骤:


  • 初如化组件的文件结构

  • 实现组件类

  • 设置配置文件

  • 启动组件


下面的例子中,阿波君将为大家展示如何创建、编译和运行一个组件,并观察组件在屏幕上的输出。


如果想更深入的探索Apollo Cyber RT框架。


可以在这个目录/apollo/cyber/examples/找到很多例子,这些例子详细展示如何使用Cyber框架的各种功能。


Note: 这些例子必须运行在Apollo docker环境, 且需要通过Bazel来编译。




例如组件的根目录为

/apollo/cyber/examples/common_component_example/

需要创建以下文件:


  • Header file: common_component_example.h

  • Source file: common_component_example.cc

  • Build file: BUILD

  • DAG dependency file: common.dag

  • Launch file: common.launch


1#include 
2#include "cyber/class_loader/class_loader.h"
3#include "cyber/component/component.h"
4#include "cyber/examples/proto/examples.pb.h"
5
6using apollo::cyber::examples::proto::Driver;
7using apollo::cyber::Component;
8using apollo::cyber::ComponentBase;
9
10class CommonComponentSample : public Component
 {
11 public:
12  bool Init() override;
13  bool Proc(const std::shared_ptr& msg0,
14            const std::shared_ptr& msg1)
 override;
15};
16
17CYBER_REGISTER_COMPONENT(CommonComponentSample)

,>



如何实现common_component_example.h:


  • 继承 Component 类;

  • 定义自己的 Init 和 Proc 函数. Proc 需要指定输入数椐类型;

  • 使用CYBER_REGISTER_COMPONENT宏定义把组件类注册成全局可用。

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


1#include "cyber/examples/common_component_example/common_component_example.h"
2#include "cyber/class_loader/class_loader.h"
3#include "cyber/component/component.h"
4
5bool CommonComponentSample::Init() {
6  AINFO << "Commontest component init";
7  return true;
8}
9
10bool CommonComponentSample::Proc(const std::shared_ptr
& msg0,
11                               const std::shared_ptr
& msg1) {
12  AINFO << "Start common component Proc [" << msg0->msg_id() << "] ["
13        << msg1->msg_id() << "]";
14  return true;
15}

创建 Bazel BUILD 文件.


1load("//tools:cpplint.bzl", "cpplint")
2
3package(default_visibility = ["//visibility:public"])
4
5cc_binary(
6    name = "libcommon_component_example.so",
7    deps = [":common_component_example_lib"],
8    linkopts = ["-shared"],
9    linkstatic = False,
10)
11
12cc_library(
13    name = "common_component_example_lib",
14    srcs = [
15        "common_component_example.cc",
16    ],
17    hdrs = [
18        "common_component_example.h",
19    ],
20    deps = [
21        "//cyber",
22        "//cyber/examples/proto:examples_cc_proto",
23    ],
24)
25
26cpplint()



在DAG依赖配置文件 (例如common.dag)中配置下面的项:


  • Channel names: 输入输出数椐的Channel名字

  • Library path: 此组件最终编译出的库的名字

  • Class name: 此组件的入口类的名字


1# Define all coms in DAG streaming.
2    component_config {
3    component_library : "/apollo/bazel-bin/cyber/examples/common_component_example/libcommon_component_example.so"
4    components {
5        class_name : "CommonComponentSample"
6        config {
7            name : "common"
8            readers {
9                channel: "/apollo/prediction"
10            }
11            readers {
12                channel: "/apollo/test"
13            }
14        }
15      }
16    }

在Launch启动文件中(common.launch), 配置下面的项:


  • 组件的名字。

  • 上一步创建的dag配置的名字。

  • 组件运行时所在的进程目录。


1<cyber>
2    <component>
3        <name>commonname>
4        <dag_conf>/apollo/cyber/examples/common_component_example/common.dagdag_conf>
5        <process_name>commonprocess_name>
6    component>
7cyber>




通过下面的命令来编译组件:


1bash /apollo/apollo.sh build


Note:确定组件正常编译成功


然后配置环境:


1cd /apollo/cyber
2source setup.bash


有两种方法来启动组件:


  • 使用Launch文件来启动 (推荐这种方式)


1cyber_launch start /apollo/cyber/examples/common_component_example/common.launch

   

  • 使用Dag文件来启动:


1mainboard -d /apollo/cyber/examples/common_component_example/common.dag


在完成以上步骤后,您就使用Cyber RT成功创建一个新的组件


﹏﹏﹏﹏﹏﹏﹏   END  ﹏﹏﹏﹏﹏﹏




点击阅读原文,了解更多

  ◤


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存