How to Create and Run a new Component in Cyber RT¶
Apollo Cyber RT framework is built upon the concept of components. As the building block of Cyber RT, each component is a specific algorithm module which processes a set of inputs and generates its set of outputs.
To successfully create and launch a new component, there are basically 4 steps:
Set up directory layout
Implement the component class
Configuration setup
Launch the component
The example below demonstrates how to create, build and run a simple component
named CommonComponentExample
. To explore more about Cyber RT, you can find a
couple of examples showing different functionalities of Cyber RT under the
cyber/examples
directory.
Note: The examples need to run after successfully built within Apollo Docker container.
Set up directry layout¶
Take the sample component under cyber/examples/common_component_example
for
example:
Header file: common_component_example.h
Source file: common_component_example.cc
BUILD file: BUILD
DAG file: common.dag
Launch file: common.launch
Implement the sample component class¶
Header file¶
In the header file (common_component_example.h
) for the sample component:
Inherit the
Component
base classDefine your own
Init
andProc
functions. Please note that forproc
, input data types need to be specified also.Register the sample component class to be globally visible using the
CYBER_REGISTER_COMPONENT
macro.
#include <memory>
#include "cyber/component/component.h"
#include "cyber/examples/proto/examples.pb.h"
using apollo::cyber::Component;
using apollo::cyber::ComponentBase;
using apollo::cyber::examples::proto::Driver;
class CommonComponentSample : public Component<Driver, Driver> {
public:
bool Init() override;
bool Proc(const std::shared_ptr<Driver>& msg0,
const std::shared_ptr<Driver>& msg1) override;
};
CYBER_REGISTER_COMPONENT(CommonComponentSample)
Source File¶
Implement both the Init
and Proc
functions in common_component_example.cc
:
#include "cyber/examples/common_component_example/common_component_example.h"
bool CommonComponentSample::Init() {
AINFO << "Commontest component init";
return true;
}
bool CommonComponentSample::Proc(const std::shared_ptr<Driver>& msg0,
const std::shared_ptr<Driver>& msg1) {
AINFO << "Start common component Proc [" << msg0->msg_id() << "] ["
<< msg1->msg_id() << "]";
return true;
}
BUILD file¶
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
load("//tools:cpplint.bzl", "cpplint")
package(default_visibility = ["//visibility:public"])
cc_binary(
name = "libcommon_component_example.so",
linkshared = True,
linkstatic = False,
deps = [":common_component_example_lib"],
)
cc_library(
name = "common_component_example_lib",
srcs = ["common_component_example.cc"],
hdrs = ["common_component_example.h"],
visibility = ["//visibility:private"],
deps = [
"//cyber",
"//cyber/examples/proto:examples_cc_proto",
],
)
cpplint()
Configuration setup¶
DAG file¶
To configure the DAG file (common.dag
here), specify the following items:
Channel names: for data input and output
Library path: library built from component class
Class name: the class name of the component
# Define all components in DAG streaming.
module_config {
module_library : "/apollo/bazel-bin/cyber/examples/common_component_example/libcommon_component_example.so"
components {
class_name : "CommonComponentSample"
config {
name : "common"
readers {
channel: "/apollo/prediction"
}
readers {
channel: "/apollo/test"
}
}
}
}
Launch file¶
To configure the launch (common.launch
) file, specify the following items:
The name of the component
The DAG file created in the previous step
The name of the process to run the component
<cyber>
<component>
<name>common</name>
<dag_conf>/apollo/cyber/examples/common_component_example/common.dag</dag_conf>
<process_name>common</process_name>
</component>
</cyber>
Launch the component¶
Build¶
Build the sample component by running the command below:
cd /apollo
bash apollo.sh build
Environment setup¶
Then configure the environment:
source cyber/setup.bash
# To see output from terminal
export GLOG_alsologtostderr=1
Launch the component¶
You can choose either of the two ways to launch the newly built component:
Launch with the launch file (recommended)
cyber_launch start cyber/examples/common_component_example/common.launch
Launch with the DAG file
mainboard -d cyber/examples/common_component_example/common.dag
Feed channel data for the component to process¶
Open another terminal:
source cyber/setup.bash
export GLOG_alsologtostderr=1
/apollo/bazel-bin/cyber/examples/common_component_example/channel_test_writer
Open the 3rd terminal and run:
source cyber/setup.bash
export GLOG_alsologtostderr=1
/apollo/bazel-bin/cyber/examples/common_component_example/channel_prediction_writer
And you should see output from terminal #1 like the following:
I0331 16:49:34.736016 1774773 common_component_example.cc:25] [mainboard]Start common component Proc [1094] [766]
I0331 16:49:35.069005 1774775 common_component_example.cc:25] [mainboard]Start common component Proc [1095] [767]
I0331 16:49:35.402289 1774783 common_component_example.cc:25] [mainboard]Start common component Proc [1096] [768]