How to add a new message
一. 简要
原生的ROS使用的是其自带的Msg格式来定义的通信协议,但是Msg协议有一个明显的缺点,由于使用了MD5校验,使得Msg的后向兼容不好,如果后续的版本稍微改动一点Msg的格式,就会让双方不能通信了,除非双方都修改XXX.msg
文件。鉴于此Apollo使用的是Google的Protocol Buffer简称Proto.关于Proto的介绍以及使用我就不多说了,可以看这个Google Protocol Buffer 的使用和原理,我这里要分享的是如何在Apollo里面增加一个新的Proto消息格式。
二. 构建
-
增加proto文件
-
在平级的proto目录下添加一个xxx.proto文件。我这里是在为了在perception里面使用,所以添加在modules/perception/proto/,在这里增加了一个zuo_test_msg.proto文件。
//-- Zuo added on 2018-04-11 for Doc 'How to add a new msg' //-- This is a test msg syntax = "proto2"; package apollo.perception; message ZuoTestMsg{ optional int32 x = 1; optional int32 y = 2; optional string info = 3; }
-
-
编译,生成消息类
-
然后修改对应的BUILD文件。相信看了上一篇How to add a subnode的同学应该已经熟悉bazel的风格,就是每一级对应一个BUILD文件,一般来说,需要修改本级和上一级两个BUILD,本级是为了编译,上一级是为了增加依赖。先从编译开始,在*/apollo-master/modules/perception/proto/BUILD*里面,增加如下代码:
cc_proto_library( name = "zuo_test_proto", deps = [ ":zuo_test_proto_lib", ], ) proto_library( name = "zuo_test_proto_lib", srcs = [ "zuo_test_msg.proto", ], )
-
在进行了上一步之后,重新编译bash apollo.sh build,完成后可以看到在*/home/zuo/.cache/bazel/_bazel_zuo/540135163923dd7d5820f3ee4b306b32/execroot/apollo/bazel-out/local-dbg/genfiles/modules/perception/proto/*生成了zuo_test_msg.pb.h、zuo_test_msg.pb.cc文件。但是现在还不能直接#include,这样会报错,还需要在相应的地方增加对新msg的依赖关系。
-
-
增加相关的依赖
-
在上一层BUILD目录增加依赖。但是现在还不能使用,还需要在相关的地方增加依赖项,首先是整个perception模块,在perception同级的BUILD文件里面增加对新msg的依赖。我这里是在*/apollo-master/modules/perception/BUILD*里面做如下改动:
load("//tools:cpplint.bzl", "cpplint") package(default_visibility = ["//visibility:public"]) cc_library( name = "perception_lib", srcs = ["perception.cc"], hdrs = [ "perception.h", ], deps = [ ...... "//modules/perception/proto:perception_proto", "//modules/perception/proto:zuo_test_proto", "//modules/perception/traffic_light/onboard", "@com_google_protobuf//:protobuf", "@ros//:ros_common", ], )
-
其次,还要在相应的使用此msg的subnode里面增加依赖。因为我打算在上次新增的subnode里面进行发送新消息的实验,所以需要在那个subnode的BUILD依赖项里面加上这个proto,看了上一篇的应该还有印象,我这里是在*/apollo-0326/modules/perception/obstacle/onboard/BUILD*增加如下代码:
cc_library( name = "zuo_test_subnode", srcs = [ "zuo_test_subnode.cc", ], hdrs = [ "zuo_test_subnode.h", "object_shared_data.h", ], deps = [ ":perception_obstacle_shared_data", "//modules/common:log", ...... "//modules/perception/proto:zuo_test_proto", ...... "@ros//:ros_common", ], )
-
-
增加头文件
-
这个时候可以在
zuo_test_subnode.h
里面增加bazel根据proto协议生成的头文件了。#include "modules/perception/proto/zuo_test_msg.pb.h"
-
-
增加消息别名
- 在message_manager.h里面增加对新消息的
NameAdapter
形式的别名,这是为了适配器的代码复用,前面几篇我们提到过。using ZuoTestMsgAdapter = Adapter<apollo::perception::ZuoTestMsg>;
- 并且,如果要将ROS自带的msg格式添加到Apollo里来,也是在这里用别名处理。例如:
using PointCloudAdapter = Adapter<::sensor_msgs::PointCloud2>;
- 到这里,新消息就增加进来了,接下来结合前面几篇的内容将消息发送出去即可。
- 在message_manager.h里面增加对新消息的