实验简介
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进行读操作
该通信方式适合于持续性通信的应用场景,比如雷达信号,摄像头图像信息等数据传输,数据交互路径如下图所示:
前提条件:进入docker环境中,在apollo_workspace目录下执行以下所有命令
注意:如果Apollo本地上没有examples的文件结构,需要按照云实验里面examples文件夹结构进行本地配置
一、编写代码
1.在/apollo_workspace/examples/proto下创建打开car1.proto文件,用于保存车的车身信息
vim /apollo_workspace/examples/proto/car1.proto
在打开的car1.proto中输入自定义的车身信息
syntax = "proto2";
package apollo.cyber.examples.proto; //定义包名,在cc文件中调用
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("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();
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& 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(
"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"
],
)
二、编译程序
//回到 /apollo_workspace目录下编译
cd /apollo_workspace
bash scripts/apollo_neo.sh build --packages examples/communication
三、运行通信程序
打开新终端运行talker1程序
//设置将输出结果到控制台
export GLOG_alsologtostderr=1
//编译产生的可执行文件在 /opt/apollo/neo/packages/examples-dev/local/bin
cd /opt/apollo/neo/packages/examples-dev/local/bin
//执行talker1
./talker1
运行结果
talker1会一直给listener1发送实时速度信息
打开新终端运行listener1程序
//设置将输出结果到控制台
export GLOG_alsologtostderr=1
//编译产生的可执行文件在 /opt/apollo/neo/packages/examples-dev/local/bin
cd /opt/apollo/neo/packages/examples-dev/local/bin
//执行listener1
./listener1