实验前提
- Apollo10.0已经安装完毕
- Vscode及相关插件安装完成
- 启动容器并进入
- 在Vscode连接进入到Apollo工作空间下学习资料
部分配置如实验一https://blog.csdn.net/weixin_60062799/article/details/145029669?spm=1001.2014.3001.5501
学习资料
- Apollo7.0或其他版本可以参考B站赵虚左老师的教学视频
- Apollo9.0或Apollo10.0可以参考Apollo的在线学堂
Cyber专项课(9.0)https://apollo.baidu.com/community/online-course/839
基础知识
和ROS中的订阅/发布模式相同,不同的是定义的消息步骤,以及通信过程中双方的称呼发生了改变。

实验步骤
-
在Vscode中已经进入到Apollo的工作空间
-
在Vscode中打开终端,执行下面命令
## 生成component模板 # 其中communication是生成的目录, # 要想生成的目录在指定文件夹下,比如为cyber文件夹下可以写成 cyber/communication # 注意注意注意!使用该命令生成的目录下的文件不可以直接在Vscode中拖动到其他文件夹下使用,否则会出现路径不匹配问题 buildtool create --template component communication
-
找到自己创建的文件夹,创建两个文件,如下红框所示
-
编写发布的消息格式和内容,打开communication/proto 目录下的communication.proto 文件,内容如下:
syntax = "proto2"; package apollo.communication.proto; // 定义一个车的消息,包括车的型号、车主、车牌号、已行驶公里数、车数 message Car { optional string plate = 1; optional string type = 2; optional string owner = 3; optional uint64 kilometers = 4; optional uint64 speed = 5; };
-
编写发布者文件,文件名为talker.cc,为自己创建的源文件
//注意这里如果要在其他目录下,#include包含的头文件目录也需要进行修改 #include "communication/proto/communication.pb.h" #include "cyber/cyber.h" #include "cyber/time/rate.h" // Car数据定义的引用 using apollo::communication::proto::Car; 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>("car_speed"); AINFO << "I'll start telling you the current speed of the car."; // 设置速度为0,之后速度每次增加5 uint64_t speed = 0; while (apollo::cyber::OK()) // 节点存活 { auto msg = std::make_shared<Car>(); msg->set_speed(speed); speed += 5; talker->Write(msg); sleep(1); } return 0; }
-
编写订阅者文件,文件名为listener.cc,为自己创建的源文件
//注意这里如果要在其他目录下,#include包含的头文件目录也需要进行修改 #include "communication/proto/communication.pb.h" #include "cyber/cyber.h" // Car数据定义的引用 using apollo::communication::proto::Car; // 接收消息的响应函数 void message_callback(const std::shared_ptr<Car>& msg) { AINFO << "now speed is: " << msg->speed(); } int main(int argc, char* argv[]) { // 初始化一个cyber框架 apollo::cyber::Init(argv[0]); // 创建listener节点 auto listener_node = apollo::cyber::CreateNode("listener"); // 监听响应读取消息 auto listener = listener_node->CreateReader<Car>("car_speed", message_callback); apollo::cyber::WaitForShutdown(); return 0; }
-
修改 communication 目录下的BUILD文件,内容如下(注意要和自己的源文件名字对应),使用源码构建在apollo_cc_binary中的name不是使用talker和listener,因为会和给出的示例文件名发生冲突。如果在其他目录下创建,deps依赖中的communication路径也要进行修改:
load("//tools:apollo_package.bzl", "apollo_cc_library", "apollo_cc_binary", "apollo_package", "apollo_component") load("//tools:cpplint.bzl", "cpplint") package(default_visibility = ["//visibility:public"]) apollo_cc_binary( name = "talker_demo", srcs = ["talker.cc"], deps = [ "//cyber", "//communication/proto:communication_proto", ], linkstatic = True, ) apollo_cc_binary( name = "listener_demo", srcs = ["listener.cc"], deps = [ "//cyber", "//communication/proto:communication_proto", ], linkstatic = True, ) apollo_package() cpplint()
-
做完上述工作之后,在终端中使用buildtool工具进行编译
# -p 后面跟着需要进行编译的文件目录 buildtool build -p communication/ # 注意这一步可能因为没有切换到用户下报错 先 su 用户名 然后 buildtool build -p communication/
-
编译完成后,打开两个终端
# 执行下面命令,能够在终端中打印消息 export GLOG_alsologtostderr=1
-
分别运行可执行文件
# 第一个终端执行 # 生成的可执行文件在bazel-bin目录下,对着自己创建的目录找就行 bazel-bin/communication/talker_demo # 第二个终端执行 # 生成的可执行文件在bazel-bin目录下,对着自己创建的目录找就行 bazel-bin/communication/listener_demo
至此实验结束
