ROS 2 Iron 教程 第一章 CLI Tools 第五节 理解服务
前言
本系列文章是由笔者翻译自ROS 2 官方教程。笔者水平有限,如有错误,还请读者指正。
目标
使用命令行工具学习并理解 ROS 2 中的服务概念。
背景
服务是 ROS 结构图中节点通信的另一种方式。相比于话题的发布者-订阅者模型,服务是基于调用-响应模型的。话题允许节点订阅数据流来得到连续地更新,然而服务只在被客户端调用的时候提供数据。
先决条件
在本节教程中提到的一些概念,例如:节点和话题,在上节教程中被提到过。
你将会需要 turtlesim 包。
任务
1 Setup (设置)
启动两个 turtlesim 节点, /turtlesim
和 /teleop_turtle
。
打开一个新终端并运行:
ros2 run turtlesim turtlesim_node
打开另一个新终端并运行:
ros2 run turtlesim turtle_teleop_key
2 ros2 service list (ROS 2 服务列表)
在一个新终端中运行 ros2 service list
命令,它将会返回当前系统中活跃的服务:
/clear
/kill
/reset
/spawn
/teleop_turtle/describe_parameters
/teleop_turtle/get_parameter_types
/teleop_turtle/get_parameters
/teleop_turtle/list_parameters
/teleop_turtle/set_parameters
/teleop_turtle/set_parameters_atomically
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/turtlesim/describe_parameters
/turtlesim/get_parameter_types
/turtlesim/get_parameters
/turtlesim/list_parameters
/turtlesim/set_parameters
/turtlesim/set_parameters_atomically
你将会看到这些节点都有相同的六个服务,而且它们的名字中都带有 parameters
。几乎 ROS 2 中的每一个节点有这些构建参数的基础服务。下一节教程将会详细介绍服务的概念,本节教程将不会讨论参数服务。
现在,让我们关注 turtlesim 的具体服务, /clear
,/kill
,/reset
,/spawn
,/turtle1/set_pen
, /turtle1/teleport_absolute
和 /turtle1/teleop_relative
。你可能会回忆起在 使用 turtlesim, ros 2 和 rqt 教程中使用 rqt 调用过其中几个服务。
3 ros2 service type (ROS 2 服务类型)
服务类型被用于描述请求和响应的数据结构。服务类型的定义与话题类型相似,除了服务类型有两个部分:一个请求的消息和一个响应的消息。
使用如下命令来查看服务类型:
ros2 service type <service_name>
让我们来查看一下 turtlesim 的 /clear 服务。在一个新的终端中,输入如下命令:
ros2 service type /clear
它应该返回:
std_srvs/srv/Empty
Empty
类型意味着调用服务既不需要请求数据,也没有返回数据。
3.1 ros2 service list -t
为了同时查看这些活跃的服务,你可以添加将 --show-type
操作,缩写为 -t
,添加到 list
命令中:
ros2 service list -t
它将会返回:
/clear [std_srvs/srv/Empty]
/kill [turtlesim/srv/Kill]
/reset [std_srvs/srv/Empty]
/spawn [turtlesim/srv/Spawn]
...
/turtle1/set_pen [turtlesim/srv/SetPen]
/turtle1/teleport_absolute [turtlesim/srv/TeleportAbsolute]
/turtle1/teleport_relative [turtlesim/srv/TeleportRelative]
...
4 ros2 service find (ROS 2 查找服务)
如果你想要查找特定服务类型的所有服务,你可以使用如下命令:
ros2 service find <type_name>
例如,你可以查找所有 Empty
类型的服务,使用如下命令:
ros2 service find std_srvs/srv/Empty
它将会返回:
/clear
/reset
5 ros2 interface show (ROS 2 接口信息)
你可以使用命令行调用服务,但你首先需要知道输入参数的格式。
ros2 interface show <type_name>
查看一下 Empty
类型的服务:
ros2 interface show std_srvs/srv/Empty
它将会返回:
---
短横线将上方的请求结构与下方的相应结构分隔开。但是,我们之前了解到, Empty 类型不接收或者发送任何数据。所以,它的结构便是空的。
让我们来查看一个发送和接收数据的服务,就像 /spwan
。在 ros2 service list -t
的结果中,我们知道 /spwan
的类型是 turtlesim/srv/Spawn
。
为了查看 /spwan
服务的请求和响应的参数,运行如下命令:
ros2 service list -t
它将会返回:
float32 x
float32 y
float32 theta
string name # Optional. A unique name will be created and returned if this is empty
---
string name
在 — 上面的信息告诉我们调用 /spawn 的参数:x y 和 theta 确定了海龟生成的 2D 姿势, name 则是可选的。
在这个例子中短横线下方的信息并不是那么重要,但它有助于让你了解调用服务后的返回信息。
6 ros2 service call (ROS 2 服务调用)
既然你已经知道了服务类型,也知道了如何查看服务类型,也知道如何找到服务类型参数,你可以使用如下命令调用服务:
ros2 service call <service_name> <service_type> <arguments>
<arguments>
部分是可选的。例如,你知道 Empty 类型的服务不需要任何参数:
ros2 service call /clear std_srvs/srv/Empty
这条命令所调用的服务将会清除海龟所留下的轨迹。
现在让我们调用 /spawn
并设置参数来生成一只新的海龟。在命令行中调用服务所输入的 <arguments>
需要符合 YMAL 格式。
输入如下命令:
ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2, name: ''}"
你将会首先得到当前操作的“方法”视图,然后是服务的响应:
requester: making request: turtlesim.srv.Spawn_Request(x=2.0, y=2.0, theta=0.2, name='')
response:
turtlesim.srv.Spawn_Response(name='turtle2')
在你的海龟视图中将会出现一直新生成的新乌龟:
总结
在 ROS 2 中,节点可以使用服务通信。与话题不同的是,话题是一种单向的通信模式,发布者节点的信息可以被一个或是多个订阅者接收,而服务是一种请求-响应模式,由客户端发起请求,服务节点处理并响应。
你通常不想要通过连续调用来使用服务;话题甚至动作将会是这种情况下更好的选择。
在本节教程中你使用了命令行工具来确认、查看、以及调用服务。