【ROS2】初级:CLI工具-理解服务

理解服务

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

教程级别:初学者

时间:10 分钟

目录

  • 背景

  • 先决条件

  • 任务

    • 设置

    • 2 ros2 服务列表

    • 三种 ros2 服务类型

    • 4 ros2 服务信息

    • 5 ros2 服务查找

    • 6 ros2 接口显示

    • 7 ros2 服务调用

    • 8 ros2 服务回声

  • 摘要

  • 下一步

  • 相关内容

背景

服务是 ROS 图中节点间通信的另一种方法。服务基于呼叫-响应模型,与主题的发布-订阅模型不同。虽然主题允许节点订阅数据流并获取持续更新,但服务只在客户端明确调用时才提供数据。

先决条件

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

您将需要 turtlesim 包。

始终不要忘记在您打开的每个新终端中获取 ROS 2 的源。

任务

1. 设置

启动两个 turtlesim 节点, /turtlesim/teleop_turtle

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

nginx 复制代码
ros2 run turtlesim turtlesim_node

打开另一个终端并运行:

nginx 复制代码
ros2 run turtlesim turtle_teleop_key

2 ros2 服务列表 

在新终端运行 ros2 service list 命令将返回系统中当前所有活动服务的列表:

perl 复制代码
cxy@ubuntu2404-cxy:~$ ros2 service list
/clear
/kill
/reset
/spawn
/teleop_turtle/describe_parameters
/teleop_turtle/get_parameter_types
/teleop_turtle/get_parameters
/teleop_turtle/get_type_description
/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/get_type_description
/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/teleport_relative 。您可能还记得在使用 turtlesim、ros2 和 rqt 教程中通过 rqt 与这些服务中的一些进行交互。

3 ros2 服务类型

服务具有类型,这些类型描述了服务的请求和响应数据是如何结构化的。服务类型的定义与主题类型类似,不同之处在于服务类型有两部分:一个是请求的消息,另一个是响应的消息。

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

bash 复制代码
ros2 service type <service_name>

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

bash 复制代码
ros2 service type /clear

哪个应该返回:

typescript 复制代码
cxy@ubuntu2404-cxy:~$ ros2 service type /clear
std_srvs/srv/Empty

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

3.1 ros2 服务列表 -t

要同时查看所有活动服务的类型,您可以将 --show-types 选项(简写为 -t )附加到 list 命令:

cpp 复制代码
ros2 service list -t

将返回:

sql 复制代码
cxy@ubuntu2404-cxy:~$ ros2 service list -t
/clear [std_srvs/srv/Empty]
/kill [turtlesim/srv/Kill]
/reset [std_srvs/srv/Empty]
/spawn [turtlesim/srv/Spawn]
/teleop_turtle/describe_parameters [rcl_interfaces/srv/DescribeParameters]
/teleop_turtle/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
/teleop_turtle/get_parameters [rcl_interfaces/srv/GetParameters]
/teleop_turtle/get_type_description [type_description_interfaces/srv/GetTypeDescription]
/teleop_turtle/list_parameters [rcl_interfaces/srv/ListParameters]
/teleop_turtle/set_parameters [rcl_interfaces/srv/SetParameters]
/teleop_turtle/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]
/turtle1/set_pen [turtlesim/srv/SetPen]
/turtle1/teleport_absolute [turtlesim/srv/TeleportAbsolute]
/turtle1/teleport_relative [turtlesim/srv/TeleportRelative]
/turtlesim/describe_parameters [rcl_interfaces/srv/DescribeParameters]
/turtlesim/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
/turtlesim/get_parameters [rcl_interfaces/srv/GetParameters]
/turtlesim/get_type_description [type_description_interfaces/srv/GetTypeDescription]
/turtlesim/list_parameters [rcl_interfaces/srv/ListParameters]
/turtlesim/set_parameters [rcl_interfaces/srv/SetParameters]
/turtlesim/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]

4 ros2 服务信息

要查看特定服务的信息,请使用以下命令:

nginx 复制代码
ros2 service info <service_name>

这将返回服务类型以及服务客户端和服务器的数量。

例如,您可以找到 /clear 服务的客户端和服务器的数量:

nginx 复制代码
ros2 service info /clear

将返回:

properties 复制代码
cxy@ubuntu2404-cxy:~$ ros2 service info /clear
Type: std_srvs/srv/Empty
Clients count: 0
Services count: 1

5 ros2 服务查找

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

xml 复制代码
ros2 service find <type_name>

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

nginx 复制代码
ros2 service find std_srvs/srv/Empty

将返回:

perl 复制代码
cxy@ubuntu2404-cxy:~$ ros2 service find std_srvs/srv/Empty
/clear
/reset

6 ros2 接口显示

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

kotlin 复制代码
ros2 interface show <type_name>

尝试在 /clear 服务的类型 Empty 上使用这个:将返回:

sql 复制代码
cxy@ubuntu2404-cxy:~$ ros2 interface show std_srvs/srv/Empty
---

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

让我们内省一个发送和接收数据的服务类型,就像 /spawn 。从 ros2 service list -t 的结果中,我们知道 /spawn 的类型是 turtlesim/srv/Spawn

要查看 /spawn 服务的请求和响应参数,请运行命令:

kotlin 复制代码
ros2 interface show turtlesim/srv/Spawn

将返回:

sql 复制代码
cxy@ubuntu2404-cxy:~$ 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 决定了生成的乌龟的 2D 姿态,而 name 显然是可选的。

线下的信息在这种情况下你不需要知道,但它可以帮助你理解你从调用中得到的响应的数据类型。

7 ros2 服务调用

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

xml 复制代码
ros2 service call <service_name> <service_type> <arguments>

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

sql 复制代码
ros2 service call /clear std_srvs/srv/Empty

此命令将清除 turtlesim 窗口中乌龟绘制的任何线条。

makefile 复制代码
cxy@ubuntu2404-cxy:~$ ros2 service call /clear std_srvs/srv/Empty
requester: making request: std_srvs.srv.Empty_Request()


response:
std_srvs.srv.Empty_Response()

现在让我们通过调用 /spawn 并设置参数来生成一个新的乌龟。从命令行进行服务调用时,输入 <arguments> 需要采用 YAML 语法。

输入命令:

nginx 复制代码
ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2, name: ''}"

您将获得这种方法风格的视图,了解正在发生的事情,然后是服务响应:

sql 复制代码
cxy@ubuntu2404-cxy:~$ 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 窗口将立即更新新生成的乌龟

8 ros2 服务回声

查看服务客户端和服务服务器之间的数据通信 ,您可以使用以下方法 echo 服务:

xml 复制代码
ros2 service echo <service_name | service_type> <arguments>

ros2 service echo 依赖于服务客户端和服务器的服务内省,该服务默认是禁用的。要启用它,用户必须在创建服务器客户端或服务器后调用 configure_introspection

启动 introspection_clientintrospection_service 服务自检演示。

css 复制代码
ros2 launch demo_nodes_cpp introspect_services_launch.py

打开另一个终端并运行以下命令以启用 introspection_clientintrospection_service 的服务内省。

sql 复制代码
ros2 param set /introspection_service service_configure_introspection contents
ros2 param set /introspection_client client_configure_introspection contents

现在我们可以通过 ros2 service echo 看到 introspection_clientintrospection_service 之间的服务通信。

properties 复制代码
cxy@ubuntu2404-cxy:~$ ros2 service echo --flow-style /add_two_ints
info:
  event_type: REQUEST_SENT
  stamp:
    sec: 1720065556
    nanosec: 372663510
  client_gid: [1, 15, 189, 33, 116, 40, 126, 14, 0, 0, 0, 0, 0, 0, 21, 3]
  sequence_number: 291
request: [{a: 2, b: 3}]
response: []
---
info:
  event_type: REQUEST_RECEIVED
  stamp:
    sec: 1720065556
    nanosec: 373104543
  client_gid: [1, 15, 189, 33, 116, 40, 126, 14, 0, 0, 0, 0, 0, 0, 20, 4]
  sequence_number: 291
request: [{a: 2, b: 3}]
response: []
---
info:
  event_type: RESPONSE_SENT
  stamp:
    sec: 1720065556
    nanosec: 373481609
  client_gid: [1, 15, 189, 33, 116, 40, 126, 14, 0, 0, 0, 0, 0, 0, 20, 4]
  sequence_number: 291
request: []
response: [{sum: 5}]
---
info:
  event_type: RESPONSE_RECEIVED
  stamp:
    sec: 1720065556
    nanosec: 373846318
  client_gid: [1, 15, 189, 33, 116, 40, 126, 14, 0, 0, 0, 0, 0, 0, 21, 3]
  sequence_number: 291
request: []
response: [{sum: 5}]
---

摘要

节点可以使用 ROS 2 中的服务进行通信。与主题不同------主题是一种单向通信模式,节点发布的信息可以被一个或多个订阅者消费------服务是一种请求/响应模式,客户端向提供服务的节点发出请求,服务节点处理请求并生成响应。

通常,您不会希望使用服务来进行连续呼叫;主题或甚至行动会更合适。

在本教程中,您使用命令行工具来识别、内省和调用服务。

下一步

在下一个教程中,了解参数https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Parameters/Understanding-ROS2-Parameters.html,您将学习如何配置节点设置。

相关内容

查看这个教程;这是使用 Robotis 机器人臂的 ROS 服务的一个极好的现实应用。