自定义话题消息:
在ROS的元功能包common_msgs中提供了许多不同消息类型的功能包,例如std_msgs(标准数据类型)、geometry_msgs(几何学数据类型)、sensor_msgs(传感器数据类型)等,这些功能包中提供了大量常用的消息类型,足以满足我们在一般场景下的常用消息。例如我们之前做的例程中,chatter话题的消息类型就是ROS中预定义的String。但是在很多情况下,我们仍然需要针对自己的机器人应用设计特定的消息类型,ROS也提供了一套语言无关的消息类型定义方法。
msg文件就是ROS中定义消息类型的文件,一般放置在功能包根目录下的msg文件夹中。在功能包编译过程中,可以使用msg文件生成不同编程语言使用的代码文件。在msg文件中还可以定义常量,这些常量在发布或者订阅消息数据时可以直接使用,相当于C++中的宏定义。
很多ROS消息定义中还会包含一个标准格式的头信息std_msgs/Header:
#Standard metadata for higher-lever flow data types
unit32 seq
time stamp
string frame_id
其中:seq是消息的顺序标识,不需要手动设置,Publisher在发布消息时会自动累加;stamp是消息中与数据相关联的时间戳,可以用于时间同步;frame_id是消息中与数据相关联的参考坐标系id。如果定义的消息类型较为简单,也可以不加头信息。
首先在功能包(catkin_ws/src/learnning_communication)中创建一个msg文件夹,这里面是用来放所以所有自定义消息的文件的。然后在其中创建一个PersonMsg.msg的文件,可以直接创建也可以用下面的命令创建,然后在里面放置我们所需要的内容:
$ touch PersonMsg.msg
如果要使用自定义的消息类型,还需要完成以下几步,对msg文件完成编译:
1.在package.xml中添加功能包依赖,打开功能包的package.xml文件,添加以下命令确保该文件中设置了编译和运行的相关依赖:
message_generation
message_runtime
这两条命令,前一条的编译依赖,后一条是运行依赖
2.在CMakeLists.txt中添加编译选项,打开CMakeLists.txt文件
2.1 在find_package中添加消息生成依赖的功能包message_generation,这样在编译时才能找到所需要的的文件:
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
std_srvs
message_generation
)
2.2 设置需要编译的msg文件,找到它们所在的位置然后添加进去:
add_message_files(
FILES
PersonMsg.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
在这两条指令中,前一条会将msg文件编译成不同语言的头文件,后一条是在添加它的依赖库。
2.3 在catkin_package中添加消息运行依赖的功能包message_runtime,找到这地方,然后打开注释添加功能包:
catkin_package(
......
CATKIN_DEPENDS roscpp rospy std_msgs std_srvs message_runtime
......
)
3.在以上配置工作都完成后,可以回到工作空间的根路径下,使用catkin_make命令进行编译了。编译成功后,可以使用如下命令查看自定义的PersonMsg.msg消息类型:
$ rosmsg show PersonMsg.msg
如果命令显示出错Could not find msg 'PersonMsg',那么是环境变量没有设置,如果没有将环境添加到.bashrc中,那就再source一下环境变量即可实现上面命令:
$ source devel/setup.bash
如果PersonMsg消息类型已经定义成功,那么在代码中就可以按照以上String类型的使用方法使用PersonMsg类型的消息了。
注:在编译后,会在devel/include/learning_communication中有个PersonMsg.h这样一个头文件,这是刚刚编译过程中动态产生的。
---------------------------------------------------------------------------------------------------------------------------------
自定义服务数据:
服务一般分为服务端(Server)和客户端(Client)两个部分,Client负责发布请求数据,等待Server处理;Server负责处理相应的功能,并且返回应答数据。
与自定义话题消息类似,ROS中的服务数据可以通过srv文件进行语言无关的接口定义,一般放置在功能目录下的srv文件夹中。该文件包含请求与应答两个数据域,数据域中的内容与话题消息的数据类型相似,只是在请求和应答的描述之间,需要使用“---”进行分割。
首先在功能包(catkin_ws/src/learnning_communication)中创建一个srv文件夹,这里面是用来放所有自定义服务数据的文件的。然后在其中创建一个PersonSrv.srv的文件,可以直接创建也可以用下面的命令创建,然后在里面放置我们所需要的内容:
$ touch PersonSrv.srv
如果要使用自定义的服务数据类型,还需要完成以下几步,对srv文件完成编译:
1.在package.xml中添加功能包依赖,打开功能包的package.xml文件,添加以下命令确保该文件中设置了编译和运行的相关依赖:
message_generation
message_runtime
这两条命令,前一条的编译依赖,后一条是运行依赖。如果在之前自定义话题消息时添加过了就不用重复添加了。
2.在CMakeLists.txt中添加编译选项,打开CMakeLists.txt文件
2.1 在find_package中添加消息生成依赖的功能包message_generation,这样在编译时才能找到所需要的的文件:
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
std_srvs
message_generation
)
如果在之前自定义话题消息时添加过了就不用重复添加了。message_generation包不仅可以针对话题消息产生相应的代码,还可以根据服务消息的类型描述文件产生相关的代码。
2.2 设置需要编译的srv文件,找到它们所在的位置然后添加进去:
add_service_files(
FILES
PersonSrv.srv
)
generate_messages(
DEPENDENCIES
std_msgs
)
在这两条指令中,前一条会将srv文件编译成不同语言的头文件,后一条是在添加它的依赖库。后一条如果在之前自定义话题消息时添加过就不用重复添加了。
2.3 在catkin_package中添加消息运行依赖的功能包message_runtime,找到这地方,然后打开注释添加功能包:
catkin_package(
......
CATKIN_DEPENDS roscpp rospy std_msgs std_srvs message_runtime
......
)
如果在之前自定义话题消息时添加过了就不用重复添加了。
3.在以上配置工作都完成后,可以回到工作空间的根路径下,使用catkin_make命令进行编译了。编译成功后,可以使用如下命令查看自定义的PersonSrv.srv消息类型:
$ rossrv show PersonSrv.srv
功能包编译成功后,在服务的Server节点和Client节点的代码实现中就可以直接调用这些定义好的服务消息了。
注:要先运行Server,然后再运行Client,否则会报错。