赞
踩
目标:使用命令行工具了解 ROS 2 中的服务。
教程级别:初学者
时间:10 分钟
目录
背景
先决条件
任务
设置
2 ros2 服务列表
三种 ros2 服务类型
4 ros2 服务信息
5 ros2 服务查找
6 ros2 接口显示
7 ros2 服务调用
8 ros2 服务回声
摘要
下一步
相关内容
服务是 ROS 图中节点间通信的另一种方法。服务基于呼叫-响应模型,与主题的发布-订阅模型不同。虽然主题允许节点订阅数据流并获取持续更新,但服务只在客户端明确调用时才提供数据。
在本教程中提到的一些概念,如节点和主题,在系列的前几个教程中已经介绍过了。
您将需要 turtlesim 包。
始终不要忘记在您打开的每个新终端中获取 ROS 2 的源。
启动两个 turtlesim 节点, /turtlesim
和 /teleop_turtle
。
打开一个新的终端并运行:
ros2 run turtlesim turtlesim_node
打开另一个终端并运行:
ros2 run turtlesim turtle_teleop_key
在新终端运行 ros2 service list
命令将返回系统中当前所有活动服务的列表:
- 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 与这些服务中的一些进行交互。
服务具有类型,这些类型描述了服务的请求和响应数据是如何结构化的。服务类型的定义与主题类型类似,不同之处在于服务类型有两部分:一个是请求的消息,另一个是响应的消息。
要查找服务的类型,请使用命令:
ros2 service type <service_name>
让我们看一下 turtlesim 的 /clear
服务。在新终端中,输入命令:
ros2 service type /clear
哪个应该返回:
- cxy@ubuntu2404-cxy:~$ ros2 service type /clear
- std_srvs/srv/Empty
Empty
类型意味着服务调用在发出请求时不发送数据,在接收响应时也不接收数据。
要同时查看所有活动服务的类型,您可以将 --show-types
选项(简写为 -t
)附加到 list
命令:
ros2 service list -t
将返回:
- 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]
要查看特定服务的信息,请使用以下命令:
ros2 service info <service_name>
这将返回服务类型以及服务客户端和服务器的数量。
例如,您可以找到 /clear
服务的客户端和服务器的数量:
ros2 service info /clear
将返回:
- cxy@ubuntu2404-cxy:~$ ros2 service info /clear
- Type: std_srvs/srv/Empty
- Clients count: 0
- Services count: 1
如果您想要查找特定类型的所有服务,您可以使用以下命令:
ros2 service find <type_name>
例如,您可以像这样找到所有 Empty
类型的服务:
ros2 service find std_srvs/srv/Empty
将返回:
- cxy@ubuntu2404-cxy:~$ ros2 service find std_srvs/srv/Empty
- /clear
- /reset
您可以从命令行调用服务,但首先您需要了解输入参数的结构。
ros2 interface show <type_name>
尝试在 /clear
服务的类型 Empty
上使用这个:将返回:
- cxy@ubuntu2404-cxy:~$ ros2 interface show std_srvs/srv/Empty
- ---
---
将请求结构(上面)与响应结构(下面)分开。但是,如你之前所学, Empty
类型不发送或接收任何数据。因此,自然地,它的结构是空的。
让我们内省一个发送和接收数据的服务类型,就像 /spawn
。从 ros2 service list -t
的结果中,我们知道 /spawn
的类型是 turtlesim/srv/Spawn
。
要查看 /spawn
服务的请求和响应参数,请运行命令:
ros2 interface show turtlesim/srv/Spawn
将返回:
- 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
所需的参数。 x
、 y
和 theta
决定了生成的乌龟的 2D 姿态,而 name
显然是可选的。
线下的信息在这种情况下你不需要知道,但它可以帮助你理解你从调用中得到的响应的数据类型。
现在您已经知道什么是服务类型,如何找到服务的类型,以及如何找到该类型参数的结构,您可以使用以下方式调用服务:
ros2 service call <service_name> <service_type> <arguments>
可选部分是 <arguments>
。例如,您知道 Empty
类型的服务没有任何参数:
ros2 service call /clear std_srvs/srv/Empty
此命令将清除 turtlesim 窗口中乌龟绘制的任何线条。
- 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 语法。
输入命令:
ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2, name: ''}"
您将获得这种方法风格的视图,了解正在发生的事情,然后是服务响应:
- 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 窗口将立即更新新生成的乌龟
要查看服务客户端和服务服务器之间的数据通信,您可以使用以下方法 echo
服务:
ros2 service echo <service_name | service_type> <arguments>
ros2 service echo
依赖于服务客户端和服务器的服务内省,该服务默认是禁用的。要启用它,用户必须在创建服务器客户端或服务器后调用 configure_introspection
。
启动 introspection_client
和 introspection_service
服务自检演示。
ros2 launch demo_nodes_cpp introspect_services_launch.py
打开另一个终端并运行以下命令以启用 introspection_client
和 introspection_service
的服务内省。
- ros2 param set /introspection_service service_configure_introspection contents
- ros2 param set /introspection_client client_configure_introspection contents
现在我们可以通过 ros2 service echo
看到 introspection_client
和 introspection_service
之间的服务通信。
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 服务的一个极好的现实应用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。