Apollo Cyber RT下话题通信的实现

为什么引入话题通信

        为了接收如:摄像头,雷达这些外设发布的数据信息并进行二次处理,Cyber RT提供了话题通信的机制,其主要功能就是以发布订阅的方式实现不同节点之间数据交互的通信模式,简而言之通过话题机制将发布方与接受方链接在一起,实现数据传递。这种机制应用于不断更新且少数据交互的通信模式。

基本实现流程

  •       编写消息载体文件(protobuf)
    • 编写发布方代码 &话题
    • 编写接收方代码
    • 编译并执行

实列测试

        功能:创建一个发布订阅模型,发布方周期性的发布消息,订阅方接收学生信息,并输出终端。

消息载体文件(protobuf)编写

        什么是protobuf

        序列号数据常用的数据格式,类似于XML,JSON。但是protobuf的优势是体积更小,速度更快可以被编译为C++、Python、Java、C#等等,方便实现对数据流的读写或者操作,不需要进行特殊的解析工作。

总体而言,我们可以将数据的格式存入Protobuf文件中,需要时转换为我们能够处理的文件类型。

第一个Protobuf代码

        创建protobuf项目文件 demo_base_probuf,在该文件夹下面编写proto源文件以及build源文件

需求:在protobuf中添加学生信息:姓名,年龄,身高,课程

//使用的 proto版本,cyber RT中目前是proto2
syntax = "proto2";
//包
package apollo.demo.cyber.proto;

//消息 --message 是关键字,student消息名称 可以当成类去理解
message Student {
//字段
//字段格式:字段规则 数据类型 字段名称 字段编号
    required string   name    =1; //必须的 类型是string
    optional uint64   age     =2;  //可选项 无符号整形
    optional double   height  =3;
    repeated string   myclass =4;  //可重复的
}

        创建build文件

load("//tools:python_rules.bzl", "py_proto_library")

package(default_visibility = ["//visibility:public"])

proto_library(
    name = "student_proto",
    srcs = ["stuProto.proto"],
)

cc_proto_library(
    name = "student_cc_proto",
    deps = [":student_proto"],
)

编写发布方代码

创建demo_cc文件夹,新建BUILD文件,demo_talker.cc文件。

/****
 * 包含头文件
 * 初始化cyber框架
 * 创建节点
 * 创建发布方
 * 组织并发布数据
 * 等待节点关闭,释放资源
 * *****/
#include "demo/cyber/proto/stuProto.pb.h"

#include "cyber/cyber.h"

//使用student这个类

using apollo::demo::cyber::proto::Student;

int main(int argc, char* argv[]) {
  apollo::cyber::Init(argv[0]);  // argv[0]指代的是当前文件

  /*std::unique_ptr<Node> apollo::cyber::
   *CreateNode(const std::string& node_name, const std::string& name_space ="");
   *node_name:节点名称,全局唯一标识符
   *name_space:节点所在空间的名称
   *name_space默认为空。
   *它是与node_name串联的空间的名称。格式为/namespace/node_name
   */
  auto talker_node = apollo::cyber::CreateNode("talk_Node");
  // create node函数创建节点
  //参数
  //intput一个string类型的nodename(给当前的这个节点起一个名字,注意不能呢个重复)
  //返回值是一个指针
  //创建发布方 发布方依赖于节点
  auto talker = talker_node->CreateWriter<Student>("message_trans");

  // message_trans是话题 channel
  // create writer<类名>(话题名称,作用是将订阅者与话题关联到一起的关键字)
  // createwriter 创建一个写出对象

  //循环发布数据
  //频率函数 单位 次/s
  //需要调用rate.sleep();进行休眠,每次循化执行休眠一段时间
  apollo::cyber::Rate rate(0.5);

  uint64_t seq = 0;

  while (apollo::cyber::OK())  //判断节点是否在运行
  {
    seq++;
    AINFO << "第" << seq << "条数据";

    //组织数据,创建一个student类的指针
    auto stu_ptr = std::make_shared<Student>();

    stu_ptr->set_name("bobo_demo");
    stu_ptr->set_age(seq);
    stu_ptr->set_height(174.5);

    // repeated 用add
    stu_ptr->add_myclass("yu wen");
    stu_ptr->add_myclass("shue xue");

    //发布数据,通过发布指针来调用他的发布函数
    talker->Write(stu_ptr);  //这个write可以传递student模板的指针或者变量
    rate.Sleep();
  }

  //等待关闭
  apollo::cyber::WaitForShutdown();

  return 0;
}

 编写接收方代码

//包含头文件
//初始化 cyber 框架
//创建节点
//创建订阅者
//解析数据
//等待节点关闭,释放资源

#include "demo/cyber/proto/stuProto.pb.h"

#include "cyber/cyber.h"

using apollo::demo::cyber::proto::Student;

void cb(const std::shared_ptr<Student>& stu) {
  //解析学生并打印
  AINFO << "name =  " << stu->name();
  AINFO << "age =  " << stu->age();
  AINFO << "height =  " << stu->height();

  for (int i = 0; i < stu->myclass_size(); i++) {
    AINFO << "calss =  "
          << stu->myclass(i);  //内部数据较多情况下使用index去索引
  }

  AINFO << "----------------------------------";
}

//实现消息订阅并进行打印
int main(int argc, char* argv[]) {
  //初始化框架
  apollo::cyber::Init(argv[0]);
  //创建节点
  auto listener_node = apollo::cyber::CreateNode("lis_Node");

  //创建订阅者
  //这个reader是网络中用于接收消息的基本工具。创建reader时,必须将其绑定到回调函数。
  //当新消息到达频道时,将调用回调。reader是由CreateReader节点类的接口创建的。
  auto listener = listener_node->CreateReader<Student>("message_trans", cb);

  //释放操作
  apollo::cyber::WaitForShutdown();

  return 0;
}

编写build文件

package(default_visibility = ["//visibility:public"])

# https://docs.bazel.build/versions/master/be/c-cpp.html#cc_binary
cc_binary(
    name = "talker",
    srcs = ["talk.cc"],
    deps = [
        "//cyber",
        "//demo/cyber/proto:student_cc_proto",
    ],
)

cc_binary(
    name = "listener",
    srcs = ["lis.cc"],
    deps = [
        "//cyber",
        "//demo/cyber/proto:student_cc_proto",
    ],
)

 编写执行脚本 .sh文件,可以不写,直接在终端执行

这个是lis的脚本

#!/bin/sh

cd  /apollo

source  cyber/setup.bash   

./bazel-bin/demo/cyber/talk_lis/listener  

 这个是talker的脚本

#!/bin/sh

cd  /apollo

source  cyber/setup.bash   

./bazel-bin/demo/cyber/talk_lis/talker

最终效果图

Apollo Cyber RT是基于Apollo自动驾驶开放平台的一种实时仿真工具。它能够对自动驾驶算法进行快速的模拟测试和验证。 Apollo Cyber RT可以在没有物理车辆的情况下,使用虚拟仿真环境对自动驾驶系统进行全面的测试。它提供了高度逼真的虚拟场景,包括各种路况、天气条件、道路标志和交通规则。用户可以在这个仿真环境中,验证自动驾驶算法在各种复杂情况下的性能和稳定性。 Apollo Cyber RT还提供了丰富的仿真工具和API接口,可以进行车辆动力学仿真、传感器数据仿真、车辆控制仿真等。用户可以根据实际需求,快速搭建自己的仿真场景,并通过API接口与自己的自动驾驶算法进行集成。这样,用户就可以在不同场景下进行大规模的仿真测试,测试自动驾驶系统对各种情况的应对能力。 与传统的实地测试相比,Apollo Cyber RT的优势在于它可以大大缩短测试周期和降低测试成本。传统的实地测试需要耗费大量的时间和资源,并且受到地理和气候等限制。而Apollo Cyber RT可以在任何时间和地点进行仿真测试,同时还可以通过调整仿真参数、重复测试等方式,快速地验证和迭代自动驾驶算法。 总之,Apollo Cyber RT是一种基于Apollo开放平台的实时仿真工具,它能够帮助用户快速测试和验证自动驾驶算法。它提供了丰富的虚拟场景和仿真工具,可以满足用户在不同场景下的测试需求,同时还能显著缩短测试周期和降低测试成本。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值