apollo_logo
5
0

Cyber之talker-listener通信

1、实验简介

假设我们想要一直获取车的速度,该需求不需要向发送方返回什么消息,也不需要发送方对消息进行进一步处理。该种情况下,我们可以选择Listener-Talker通信方式实现该功能。

Listener-Talker通信一方主动送消息,一方被动接收。Listener-Talker通信首先创建了两个Node,分别是Talker Node和 Listener Node。每个Node实例化Writer类和Reader类对Channel进行消息的读写。Writer和Reader通过Topic连接,对同一块共享内存(Channel)进行读写处理。在这里,Talker Node 为了实现其“诉说”的功能,选择实例化Writer,通过Writer来对Channel进行消息写操作。而Listener Node为了实现其“聆听”功能,选择实例化reader类,通过Reader来对channel进行读操作。该通信方式适合于持续性通信的应用场景,比如雷达信号,摄像头图像信息这类数据的传输。数据交互路径如下图所示:

2、实验步骤

2.1 编写代码

1、在/apollo_workspace/examples/proto下创建car1.proto文件,用于保存车的车身信息。

vim /apollo_workspace/examples/proto/car1.proto

在car1.proto中输入自定义的车身信息。

syntax = "proto2";
//定义包名,在cc文件中调用
package apollo.cyber.examples.proto;
//定义一个车的消息,车的型号,车主,车的车牌号,已跑公里数,车速
message Car1{
optional string plate = 1;
optional string type = 2;
optional string owner = 3;
optional uint64 kilometers = 4;
optional uint64 speed = 5;
};

2、打开 BUILD文件,在BUILD文件末尾补充car1.proto信息,以便系统能正常编译car1.proto。

vim /apollo_workspace/examples/proto/BUILD

在BUILD文件末尾补充car1.proto信息。

proto_library(
name = "car1_proto",
srcs = ["car1.proto"],
)
cc_proto_library(
name = "car1_cc_proto",
deps = [
":car1_proto",
],
)

3、进入到/apollo_workspace/examples/communication目录下,创建编写talker1.cc来实现主动对话

vim /apollo_workspace//examples/communication/talker1.cc

在talker1.cc中输入以下代码

//头文件引用
#include "examples/proto/car1.pb.h"
#include "cyber/cyber.h"
#include "cyber/time/rate.h"
//car数据定义的引用,可以看出其定义来源于一个proto
using apollo::cyber::examples::proto::Car1;
int main(int argc, char *argv[]) {
// 初始化一个cyber框架
apollo::cyber::Init(argv[0]);
// 创建talker节点
auto talker_node = apollo::cyber::CreateNode("talker");
// 从节点创建一个Topic,来实现对车速的查看
auto talker = talker_node->CreateWriter<Car1>("car_speed");
AINFO << "I'll start telling you the current speed of the car.";
//设置初始速度为0,然后速度每秒增加5km/h
uint64_t speed = 0;
while (apollo::cyber::OK()) {
auto msg = std::make_shared<Car1>();
msg->set_speed(speed);
//假设车速持续增加
speed += 5;
talker->Write(msg);
sleep(1);
}
return 0;
}

4、在同目录下,创建编写一个listener1.cc来实现对talker1发送过来的内容进行接收

vim /apollo_workspace//examples/communication/listener1.cc

在talker1.cc中输入以下代码

#include "examples/proto/car1.pb.h"
#include "cyber/cyber.h"
using apollo::cyber::examples::proto::Car1;
//接收到消息后的响应函数
void message_callback(
const std::shared_ptr<Car1>& msg) {
AINFO << "now speed is: " << msg->speed();
}
int main(int argc, char* argv[]) {
//初始化cyber框架
apollo::cyber::Init(argv[0]);
//创建监听节点
auto listener_node = apollo::cyber::CreateNode("listener");
//创建监听响应进行消息读取
auto listener = listener_node->CreateReader<Car1>(
"car_speed", message_callback);
apollo::cyber::WaitForShutdown();
return 0;
}

5、修改同目录下的BUILD文件,将刚刚创建的talker1.cc和listener1.cc加入到编译文件中

vim /apollo_workspace/examples/communication/BUILD

在BUILD文件中补充内容

//添加两个cc_binary
cc_binary(
name = "talker1",
srcs = ["talker1.cc"],
deps = [
"//cyber",
"//examples/proto:car1_cc_proto",
],
linkstatic = True,
)
cc_binary(
name = "listener1",
srcs = ["listener1.cc"],
deps = [
"//cyber",
"//examples/proto:car1_cc_proto",
],
linkstatic = True,
)
//在install中将自己创建的talker1和listener1程序加入进去
install(
name = "install",
runtime_dest = "examples/bin",
targets = [
":talker",
":listener",
":server",
":client",
":param_client",
":param_server",
":talker1", //添加
":listener1" //添加
],
)

2.2编译程序

//回到 /apollo_workspace目录下编译
cd /apollo_workspace
bash scripts/apollo_neo.sh build --packages examples/communication

编译成功后显示如下信息

2.3运行通信程序

2.3.1 运行talker1程序

打开新的终端,执行以下命令。

//设置将输出结果到控制台
export GLOG_alsologtostderr=1
//编译产生的可执行文件在 /opt/apollo/neo/packages/examples-dev/local/bin
cd /opt/apollo/neo/packages/examples-dev/local/bin
//执行talker1
./talker1

2.3.2 运行listener1程序

再次打开一个新的终端,执行以下命令。

//设置将输出结果到控制台
export GLOG_alsologtostderr=1
//编译产生的可执行文件在 /opt/apollo/neo/packages/examples-dev/local/bin
cd /opt/apollo/neo/packages/examples-dev/local/bin
//执行listener1
./listener1

2.4 运行结果

talker1会一直给listener1发送实时速度信息。

listener1收到后会将速度输出到控制台

原创声明,本文由作者授权发布于Apollo开发者社区,未经许可,不得转载。
发表评论已发表 0 条评论
登录后可评论,请前往 登录
暂无评论~快去发表自己的独特见解吧!
目录
1、实验简介
2、实验步骤
2.1 编写代码
2.2编译程序
2.3运行通信程序
2.3.1 运行talker1程序
2.3.2 运行listener1程序
2.4 运行结果