You're reading the documentation for a development version. For the latest released version, please have a look at Galactic.

理解 ROS2 服务

目标:了解 ROS 2 中使用命令行工具的服务。

Tutorial level: Beginner

Time: 10 minutes

背景

服务是 ROS graph 中节点通信的另一种方法。服务基于调用-响应(call-and-response)模型,而不是主题的发布者-订阅者(publisher-subscriber)模型。主题允许节点订阅数据流并获得持续更新,而服务只在客户端特别调用时提供数据。

../../_images/Service-SingleServiceClient.gif ../../_images/Service-MultipleServiceClient.gif

先决条件

本教程中提到的一些概念,如 节点主题,在本系列之前的教程中已经介绍过。

你需要 turtlesim 包

和往常一样,不要忘记在你 打开的每一个新终端 中都输入 ROS 2。

任务

1 设置

启动两个 turtlesim 节点 /turtlesim/teleop_turtle

打开一个新的终端并运行:

ros2 run turtlesim turtlesim_node

打开另一个终端并运行:

ros2 run turtlesim turtle_teleop_key

2 ros2 service list

在新终端中运行 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

您将看到两个节点都有相同的 6 个服务,它们的名称中带有 parameters。在 ROS 2 中,几乎每个节点都有这些基础设施服务,参数 是根据这些基础设施服务构建的。在下一个教程中将有更多关于参数的内容。在本教程中,参数服务将从讨论中省略。

现在,让我们关注 turtleim-specific 服务,/clear/kill/reset/spawn/turtle1/set_pen/turtle1/teleport_absolute/turtle1/teleport_relative。您可能还记得在 “介绍 turtlesim 和 rqt” 教程中使用 rqt 与其中一些服务进行交互。

3 ros2 service type

服务具有描述服务的请求和响应数据如何构造的类型。服务类型的定义类似于主题类型,只不过服务类型有两个部分:一个消息用于请求,另一个消息用于响应。

要查找服务的类型,使用以下命令:

ros2 service type <service_name>

让我们看看 turtlesim /clear 服务。在一个新的终端中,输入命令:

ros2 service type /clear

它应该返回:

std_srvs/srv/Empty

Empty 类型意味着服务调用在发出请求时不发送数据,在接收响应时不接收数据。

3.1 ros2 service list -t

要同时查看所有活动服务的类型,可以在 list 命令后面添加 --show-types 选项,缩写为 -t

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

如果需要查找特定类型的所有服务,可以使用命令:

ros2 service find <type_name>

例如,你可以像这样找到所有 Empty 类型的服务:

ros2 service find std_srvs/srv/Empty

这将返回:

/clear
/reset

5 ros2 interface show

您可以从命令行调用服务,但首先您需要知道输入参数的结构。

ros2 interface show <type_name>

/clear 服务类型为 Empty 的情况下运行此命令:

ros2 interface show std_srvs/srv/Empty

这将返回:

---

--- 将请求结构(上面)与响应结构(下面)分开。但是,如前所述,Empty 类型不发送或接收任何数据。所以,自然,它的结构是空白的。

让我们内省一个具有发送和接收数据类型的服务,比如 /spawn。由 ros2 service list -t 的结果可知 /spawn 的类型是 turtlesim/srv/Spawn

要查看 /spawn 调用和请求中的参数,运行命令:

ros2 interface show turtlesim/srv/Spawn

这将返回:

float32 x
float32 y
float32 theta
string name # Optional.  A unique name will be created and returned if this is empty
---
string name

--- 行上面的信息告诉我们调用 /spawn 所需的参数。xytheta 决定生成的海龟的位置,name 显然是可选的。

在本例中,这一行下面的信息不是您需要知道的,但它可以帮助您理解从调用中获得的响应的数据类型。

6 ros2 service call

现在,您已经知道了什么是服务类型、如何查找服务类型以及如何查找该类型参数的结构,您可以使用以下命令调用服务:

ros2 service call <service_name> <service_type> <arguments>

<arguments> 部分是可选的。例如,你知道 Empty 类型化服务没有任何参数:

ros2 service call /clear std_srvs/srv/Empty

此命令将清除 turtle 窗口中所绘制的任何线。

../../_images/clear.png

现在让我们通过调用 /spawn 和输入参数来生成一个新的海龟。命令行中的服务调用中的输入 <arguments> 需要使用 YAML 语法。

输入命令:

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')

你的 turtlesim 窗口会立即更新新生成的海龟:

../../_images/spawn.png

小结

节点可以通过 ROS2 中的服务进行通信。与主题不同——一种通信模式,其中一个节点发布信息,可以使用一个或多个用户服务请求/响应模式,客户端发出请求节点提供服务和服务处理请求并生成一个响应。

你通常不希望使用服务进行持续回调;主题 甚至 动作 会更合适。

在本教程中,您使用命令行工具来识别、详细说明和调用服务。

下一步

在下一个教程中,理解 ROS2 参数,你将学习配置节点设置的知识。