protobuf基础知识及跨文件夹import实例
本文为个人项目开发中关于使用proto的一些总结,主要记录了一种跨文件夹import *.proto文件的方法。如有错误之处,恳请各位大佬指正。
从事自动驾驶项目开发中,上下游自检不可避免需要信息交互,比如障碍物融合与规划之间存在多个障碍物的信息(比如障碍物类型、航向、速度以及预测轨迹等),需要上下游模块之间确定好对应的数据协议;此外,数据协议尽量需要考虑完备可增减,这样能够确保历史log数据能够长时适配适用。
接下来将对proto的一些基础知识做简单介绍。
一、protobuf简介
- protbuf是Google提供一个高效的协议数据交互格式工具个,类似于Json,相对于Json,Protobuf拥有更高度转化效率,时间和空间效率是Json的数倍(3-5)。
二、protobuf优点
- 时间开销小,性能高
protobuf在序列化和反序列化做了优化,空间和时间开销减小很多(相较于json) - 支持向前和向后兼容
这个特点很重要,在上游段增加新的字节信息,不一样下游接收使用 - 有代码生成机制
可以自定义写message - 支持多种变成语言(c++/java/python)
三、proto简单写法
以obstacle.proto为例,定义如下结构
syntax = "proto2";
package add.perception;
message TrajPoint {
optional float x = 1;
optional float y = 2;
optional float theta = 3;
}
message obstacle {
optional int32 id = 1;
optional float velocity_x = 2;
optional float velocity_y = 3;
repeated TrajPoint traj_point = 4;
}
四、protoc 生成协议文件
接下来,我们将使用protoc指令生成对应 pb.h和 pb.cc协议文件。
不跨文件夹import其他文件
protoc -I=$SRC_DIR --cpp_out=$DST_DIR /path/*.proto
还是以obstacle.proto为例
执行protoc -I=. --cpp_out=./ obstacle.proto
,则会生成obstacle.pb.h和 obstacle.pb.cc文件,如下图显示:
同样,我们可以分离 proto文件和 pb.h/pb.cc文件。
将pb.h和pb.cc文件生成至output目录下protoc -I=. --cpp_out=./output/ obstacle.proto
结果如下
跨文件夹import其他文件
目前,从我个实践而言,好像只能import当前目录及当前目录的子目录中的proto文件,比如import父目录中的文件时编译会报错(Import “…/xxxx.proto” was not found or had errors.),使用绝对路径也不行,尚不清楚原因。(如果有哪位大神清楚,请不吝赐教!)
如下图所示,存在如下proto目录层级
trajectory.proto结构如下
syntax = "proto2";
package add.planning;
import "pnc_point.proto";
import "obstacle.proto"
message Frame {
optional double timestamp = 1;
repeated add.perception.obstacle obstacles = 2;
}
message ADCTrajectory {
optional double timestamp = 1;
repeated add.common.TrajectoryPoint traj_points = 2;
}
trajectory.proto 导入 obstacle.proto 和pnc_point.proto,最后将trajectory.proto编译后文件在output路径中输出,指令如下protoc --proto_path=./base_proto/ --proto_path=./perception/ --proto_path=./planning/ --cpp_out=./output/ ./planning/*.proto
结果如下:
还是以planning import obstacle和 pnc_point为例,只需要在Planning模块编译链加入这两对应 pb.h和pb.cc路径。
本项目中我这边使用CMAKE编译,只需在CMakeLists.txt中加入其对应的路径。
INCLUDE_DIRECTORIES(/${PROT_DIR}/name*.proto)
以上,如有错误,恳请各位不吝赐教。