在本节中,我们将学习如何在当前软件包中创建自定义的消息和服务。消息的定义存储在.msg文件中,服务的定义存储在.srv文件中。这些定义告知ROS从节点发送的数据类型和数据名称。当添加自定义消息时,ROS会将其定义转换为等价的C++代码,这样我们就可以将这些代码包含在节点中。
首先我们来介绍消息定义。这些消息定义必须写在.msg文件中,且必须保存在软件包内的msg文件夹中。现在我们创建一个名为demo_msg.msg的消息文件,定义如下:
到目前为止,我们一直使用的都是标准消息定义。现在,我们已经可以创建自定义的消息了,并能学会如何在我们的代码中使用它们。
第一步是编辑当前软件包中的package.xml文件,取消注释:<build_depend>message_generation</build_depend>和<exec_depend>message_runtime</exec_depend>。
编辑当前的CMakeLists.txt并添加message_generation行,如下所示:
取消下面这些行代码的注释并添加自定义消息文件:
完成这些步骤后,我们就可以编译和生成软件包了:
要检查消息是否已正确构建,我们可以使用rosmsg命令:
如果执行命令后显示的内容和定义一样,那说明创建自定义消息的过程是正确的。
如果我们想测试自定义的消息,可以使用名为demo_msg_publisher.cpp和demo_msg_subscriber.cpp的自定义消息类型生成发布者和订阅者来测试节点。在mastering_ros_demo_pkg/1文件夹中可以获取到这些代码。
我们可以通过在CMakeLists.txt中添加以下代码来测试自定义消息:
这个编辑过的CMakeLists.txt文件与旧文件的一个重要区别是对mastering_ros_demo_pkg中生成消息的依赖项说明。此依赖项是通过add_dependencies指令指定的。请注意,如果忘记包含此指令,ROS系统将在生成消息之前开始编译CPP源代码。这样一来,由于找不到自定义消息的头文件,就会产生一个编译错误。现在,我们已经准备好构建功能包了。
使用catkin_make来编译生成软件包,并使用以下命令测试这些节点。
运行roscore:
启动自定义消息的发布者节点:
启动自定义消息的订阅者节点:
发布者节点将发布一条带有字符串和一个整数的消息,订阅者节点订阅该主题并打印这些内容。输出内容和通信图如图2.4所示。
图2.4 使用自定义消息运行发布者和订阅者
节点间通信的主题名为/demo_msg_topic。图2.5是两个节点之间的通信图。
图2.5 消息发布者和订阅者之间的通信图
接下来,我们可以在软件包中添加srv文件。首先在当前软件包的文件夹中创建一个名为srv的新文件夹,然后添加一个名为demo_srv.srv的srv文件。该文件的定义如下:
这里的请求(Request)和应答(Response)都是字符串类型。
下一步,我们需要取消package.xml文件中的以下两行注释,和我们在ROS消息中所做的一样:
打开CMakeLists.txt文件并在catkin_package()中添加message_runtime:
我们需要遵循与生成ROS消息相同的过程来生成服务。除此之外,我们还需要取消其他部分注释,如下所示:
做了这些修改后,我们就可以使用catkin_make来编译生成软件包了。使用下面的命令验证整个过程是否正确:
如果我们看到输出内容与服务文件中定义的内容一样,就可以确认创建自定义服务的过程是正确的。ROS服务已经编译完,现在可以在ROS工作区中使用。在下一节中,我们将尝试在ROS节点中使用此服务。