将Apollo
中所用的Google buffer protocal转换为ros message。在gprotoc中一个协议文件可以定义多个类,而
一个ros的一个文件只可以定义一个类。本程序读取每个协议文件,将每个message
生成一个*.msg*文件。并且输出对应的c++
代码转换函数。
代码中提供了generate.sh将protocal中的所有协议输出到当前目录的message与transorm中。
这个程序很多地方是针对Apollo
以及我自己移植的目录结构而言的,代码中的protocal
是Apollo
中所有的gprotoc的协议文件,在
protocal目录中的build.sh文件,可以将这些文件编译为一个静态库。
./g2r.out -I ./protocal -o ./message -t ./transorm xxx.proto
- -I 设置include path 设置
google buffer protocal
所在目录,处理import
类似的语句 - -o 设置
rosmsg
要输出的目录 - -t 设置辅助转换**C++**源代码所在目录,生成类似代码
#include "g2r_Header.h"
void g2r_hdmap_Header(apollo::hdmap::Header& arg_gprotoc, ros_hdmap::Header::Header& arg_rosmsg) {
arg_rosmsg.version = arg_gprotoc.version();
arg_rosmsg.date = arg_gprotoc.date();
arg_rosmsg.projection = arg_gprotoc.projection();
arg_rosmsg.district = arg_gprotoc.district();
arg_rosmsg.generation = arg_gprotoc.generation();
arg_rosmsg.rev_major = arg_gprotoc.rev_major();
arg_rosmsg.rev_minor = arg_gprotoc.rev_minor();
arg_rosmsg.left = arg_gprotoc.left();
arg_rosmsg.top = arg_gprotoc.top();
arg_rosmsg.right = arg_gprotoc.right();
arg_rosmsg.bottom = arg_gprotoc.bottom();
arg_rosmsg.vendor = arg_gprotoc.vendor();
}
void r2g_hdmap_Header(ros_hdmap::Header::Header& arg_rosmsg, apollo::hdmap::Header& arg_gprotoc) {
arg_gprotoc.set_version(arg_rosmsg.version);
arg_gprotoc.set_date(arg_rosmsg.date);
arg_gprotoc.set_projection(arg_rosmsg.projection);
arg_gprotoc.set_district(arg_rosmsg.district);
arg_gprotoc.set_generation(arg_rosmsg.generation);
arg_gprotoc.set_rev_major(arg_rosmsg.rev_major);
arg_gprotoc.set_rev_minor(arg_rosmsg.rev_minor);
arg_gprotoc.set_left(arg_rosmsg.left);
arg_gprotoc.set_top(arg_rosmsg.top);
arg_gprotoc.set_right(arg_rosmsg.right);
arg_gprotoc.set_bottom(arg_rosmsg.bottom);
arg_gprotoc.set_vendor(arg_rosmsg.vendor);
}
在遇到map
类型时,会直接输出一个单独的*.msg文件。例如:map<int, string>
会生成一个名为MapIntStringEntry.msg*的ros message。原来的map
变量转换为rosmsg
时变为repeated MapIntStringEntry
一个队列变量。其对应文件内容为:
// MapIntStringEntry.msg
int key
string value
如果遇到oneof
类型,会将其中每个字段都直接作为rosmsg
中的字段,忽略oneof
本身。这样的转换至少在逻辑上是讲的通的。
遇到enum
则将直接作为一个单独的rosmsg
生成独立的*.msg*文件。
遇到message
中定义了message
,例如:
message xxx{
message yyy {
...
}
}
会将yyy
提取出来作为单独的*.msg*文件。
- flex
- bison
- tinyxml2
使用了flex与bison做了词语法分析器。因为要生成rosmsg
的package.xml所以使用了tinyxml2库。
flex ./g2r.l
bison -d ./g2r.y
g++ lex.yy.c g2r.tab.c makepkg.cc -ltinyxml2 -w -o ./g2r.out