Apollo学习(1)-- Cyber模块解析

一、Talker-Listener

1、参考文件

参考教程:docs/cyber/CyberRT_API_for_Developers.md github
代码示例:cyber/examples/
其中,文件均为apollo根目录的相对路径

2、发布-订阅机制

Apollo的Cyber话题发布-订阅机制及代码架构与ROS类似,可以参考ROS教程对Cyber机制有更好地理解

ROS教程–编写简单的发布者和订阅者(C++)

3、代码示例

(1)Talker (cyber/examples/talker.cc)
#include "cyber/cyber.h"
#include "cyber/proto/chatter.pb.h"
#include "cyber/time/rate.h"
#include "cyber/time/time.h"
using apollo::cyber::Rate;
using apollo::cyber::Time;
using apollo::cyber::proto::Chatter;
int main(int argc, char *argv[]) {
  // init cyber framework
  apollo::cyber::Init(argv[0]);
  // create talker node
  std::shared_ptr<apollo::cyber::Node> talker_node(
      apollo::cyber::CreateNode("talker"));
  // create talker
  auto talker = talker_node->CreateWriter<Chatter>("channel/chatter");
  Rate rate(1.0);
  while (apollo::cyber::OK()) {
    static uint64_t seq = 0;
    auto msg = std::make_shared<apollo::cyber::proto::Chatter>();
    msg->set_timestamp(Time::Now().ToNanosecond());
    msg->set_lidar_timestamp(Time::Now().ToNanosecond());
    msg->set_seq(seq++);
    msg->set_content("Hello, apollo!");
    talker->Write(msg);
    AINFO << "talker sent a message!";
    rate.Sleep();
  }
  return 0;
}
(2)Listener (cyber/examples/listener.cc)
#include "cyber/cyber.h"
#include "cyber/proto/chatter.pb.h"
void MessageCallback(
    const std::shared_ptr<apollo::cyber::proto::Chatter>& msg) {
  AINFO << "Received message seq-> " << msg->seq();
  AINFO << "msgcontent->" << msg->content();
}
int main(int argc, char *argv[]) {
  // init cyber framework
  apollo::cyber::Init(argv[0]);
  // create listener node
  auto listener_node = apollo::cyber::CreateNode("listener");
  // create listener
  auto listener =
      listener_node->CreateReader<apollo::cyber::proto::Chatter>(
          "channel/chatter", MessageCallback);
  apollo::cyber::WaitForShutdown();
  return 0;
}
(3)Bazel BUILD file(cyber/samples/BUILD) 编译文件,类似ROS中的CMakeLists文件
cc_binary(
    name = "talker",
    srcs = [ "talker.cc", ],
    deps = [
        "//cyber",
        "//cyber/examples/proto:examples_cc_proto",
    ],
)

cc_binary(
    name = "listener",
    srcs = [ "listener.cc", ],
    deps = [
        "//cyber",
        "//cyber/examples/proto:examples_cc_proto",
    ],
)

4、运行示例程序

  1. 进入容器
sudo bash docker/scripts/dev_start.sh
sudo bash docker/scripts/dev_into.sh
  1. 编译示例文件bazel build cyber/examples/…
  2. 分别在不同的终端启动talker和listener,命令如下:
./bazel-bin/cyber/examples/talker
./bazel-bin/cyber/examples/listener

注释:docker启动新终端方式

(base) lv@lv-Legion:~/apollo$ sudo docker ps
CONTAINER ID   IMAGE                                              COMMAND       CREATED          STATUS          PORTS     NAMES
5cf01a6ace92   apolloauto/apollo:dev-x86_64-18.04-20210914_1336   "/bin/bash"   38 minutes ago   Up 38 minutes             apollo_dev_root

执行下面两条命令中任一命令均可,其中5cf01a6ace92为容器ID,apollo_dev_root为容器名字

sudo docker exec -ti apollo_dev_root bash
sudo docker exec -ti 5cf01a6ace92 bash
  1. 打开两个终端执行命令后,终端未显示输出,原因是程序中用的输出语句为AINFO << "talker sent a message!";AINFO为apollo的log信息,若想在输出方法如下:
  • Change GLOG_alsologtostderr from 0 to 1 in cyber/setup.bash
  • Run source cyber/setup.bash in current console.

或者终端输入命令export GLOG_alsologtostderr=1

另外可通过cyber_channel查看话题信息

cyber_channel echo channel/chatter

若提示未找到命令,bash: cyber_channel: command not found

source ./cyber/setup.bash
  1. 运行成功,可看到如下输出:
root@in-dev-docker:/apollo# cyber_channel echo channel/chatter
timestamp: 1676884418184410648
lidar_timestamp: 1676884418184411113
seq: 413
content: "Hello, apollo!"

timestamp: 1676884419184403591
lidar_timestamp: 1676884419184403985
seq: 414
content: "Hello, apollo!"

timestamp: 1676884420184459860
lidar_timestamp: 1676884420184460322
seq: 415
content: "Hello, apollo!"

二、Component

1、参考文件

参考文档:docs/cyber/CyberRT_API_for_Developers.md和cyber/examples/common_component_example/README.md
代码位置:cyber/examples/common_component_example

2、概念及优点

  • 概念
    Component是Cyber RT提供的基类,通过继承InitProc函数将应用载入Cyber RT框架
    Component中Init()函数等价于主函数
    Component中Proc() 函数等价于接受端回调函数

  • 优点
    Component可以通过launch文件在不同的进程中被载入,应用灵活
    Component通过改变dag文件改变接受话题名而不需要重新编译
    Component支持接受多种类型数据
    Component支持提供多种融合策略

3、代码解析

文件架构
文件名功能
BUILD编译文件,将component文件编译成动态链接库
channel_test_writer.cc发布话题/apollo/test
channel_prediction_writer.cc发布话题/apollo/prediction
common_component_example.cccomponent源文件
common_component_example.hcomponent头文件
common.dagdag文件
common.launchlaunch文件
(1)common_component_example.h(重载Component函数,类名CommonComponentSample)
#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)
(2)common_component_example.cc

init()为初始化函数 ,Proc()为回调函数

#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;
}
(3)BUILD

common_component_example.cccommon_component_example.h文件编译成libcommon_component_example.so动态链接库,dag文件使用动态链接库进行操作。

(4)common.dag
# Define all coms 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"
            }
        }
      }
    }
  • module_library:动态链接库(.so)文件
  • components & timer_component: 选择基类的类别,一共两种基类:componentstimer_component,此示例为components
  • class_name: 需要被载入的类名
  • name: 新建节点的名字
  • readers: 接收1~3个话题名
(5)代码运行

1、编译文件:

bazel build //cyber/examples/common_component_example/...

2、log语句显示为终端输出

export GLOG_alsologtostderr=1

3、启动程序

cyber_launch start cyber/examples/common_component_example/common.launch

或者

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

4、分别打开docker两个终端,运行两个发布话题程序

bazel run  //cyber/examples/common_component_example:channel_test_writer
bazel run //cyber/examples/common_component_example:channel_prediction_writer

5、查看commen.launch程序终端

I0220 22:23:12.235702 11926 common_component_example.cc:19] [mainboard]Commontest component init
I0220 22:23:12.236104 11926 scheduler.cc:55] [mainboard]create croutine: common_/apollo/test
I0220 22:23:12.236408 11926 scheduler.cc:55] [mainboard]create croutine: common_/apollo/prediction
I0220 22:23:12.236531 11926 scheduler.cc:55] [mainboard]create croutine: common
I0220 22:25:09.937448 11936 common_component_example.cc:25] [mainboard]Start common component Proc [1] [64]
I0220 22:25:10.270659 11937 common_component_example.cc:25] [mainboard]Start common component Proc [2] [64]
I0220 22:25:10.603984 11934 common_component_example.cc:25] [mainboard]Start common component Proc [3] [65]
I0220 22:25:10.937593 11939 common_component_example.cc:25] [mainboard]Start common component Proc [4] [66]
I0220 22:25:11.270395 11935 common_component_example.cc:25] [mainboard]Start common component Proc [5] [66]
I0220 22:25:11.604032 11934 common_component_example.cc:25] [mainboard]Start common component Proc [6] [67]

6、查看节点名,common为component节点名字

root@in-dev-docker:/apollo# cyber_node list
Number of active nodes: 3
channel_test_writer
common
prediction_writer

三、其他

附表

Cyber和ROS对节点的一些操作类似,命令使用方法参考以下两个链接。对ROS系统不了解的同学可以从官网ROS教程熟悉ROS基本原理

Apollo 应用与源码分析:CyberRT-工具与命令
ROS教程

cyberROS
可视化通道信息cyber_visualizer
可视化cyber_monitor
记录数据cyber_recorderrosbag
通道/节点信息cyber_noderosnode
话题信息cyber_channelrostopic
服务信息cyber_servicerosservice
launch文件cyber_launchroslaunch

其他内容

Service、Param、Log、Timer、Record可参照教程自学,后续代码若遇到会继续补充。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Apollo Docker Quick Start Files是用于在Docker容器中快速启动Apollo配置中心的文件集合。Apollo配置中心是携程框架部门开发的分布式配置管理平台,用于实现配置集中管理和动态配置更新的需求。 使用Docker容器来快速启动Apollo配置中心可以提高开发和部署的效率,方便跨平台和环境的使用。Apollo Docker Quick Start Files包含了配置中心的相关配置文件、Dockerfile和启动脚本等,使用这些文件可以快速构建和启动配置中心的Docker容器。 在启动Docker容器之前,我们需要先配置好Apollo配置中心的相关信息,在配置文件中指定数据库、端口等参数。然后,使用Docker命令构建Docker镜像并生成Docker容器,通过运行启动脚本,让Docker容器启动并运行Apollo配置中心。 通过使用Apollo Docker Quick Start Files,可以方便地在各种环境中部署和启动Apollo配置中心,提高系统的可维护性和可扩展性。同时,通过Docker的特性,我们可以更好地管理和监控配置中心的运行状态,更灵活地进行配置的更新和维护。 总之,Apollo Docker Quick Start Files提供了一种便捷的方式来快速部署和启动Apollo配置中心,使得我们能够更加高效地管理和使用分布式配置,提高系统的稳定性和可靠性。 ### 回答2: Apollo是一个分布式配置中心,用于管理和配置分布式系统中的应用程序的配置信息。Docker是一种容器化平台,可以将应用程序打包成容器,并在不同的环境中快速部署和运行。 Apollo-Docker-Quick-Start-Files是一个用于快速开始使用Apollo和Docker的文件集合。它包含了一系列的配置文件和脚本,可以帮助用户快速搭建Apollo配置中心和使用Docker部署应用程序。 在这个文件集合中,用户可以找到一些配置文件示例,如application.properties和meta-server.properties,这些文件定义了Apollo的配置中心和元数据服务器的相关配置信息。用户可以根据自己的需要进行修改和定制。 此外,还有一些脚本文件,如docker-compose.yaml和Dockerfile。这些文件用于定义Docker容器的构建和部署规则。用户可以使用docker-compose命令,根据docker-compose.yaml文件一键启动Apollo配置中心和应用程序的Docker容器。 使用Apollo-Docker-Quick-Start-Files,用户可以轻松地搭建Apollo配置中心和部署应用程序。它提供了一种快捷的方式,帮助用户快速入门并使用Apollo和Docker进行分布式系统的配置和部署管理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值