了解服务
目标: 使用命令行工具了解 ROS 2 中的服务。
教程级别: 初学者
时间: 10 分钟
背景
服务是 ROS 图中节点的另一种通信方法。 服务基于调用和响应模型,而非主题的发布者-订阅者模型。 虽然主题允许节点订阅数据流并获得持续更新,但服务仅在客户端专门调用时才提供数据。
先决条件
本教程中提到的一些概念,如 Nodes 和 Topics,已在本系列之前的教程中介绍过。
您将需要 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
您将看到两个节点都具有相同的六个服务,其名称中带有“parameters”。 ROS 2 中的几乎每个节点都具有这些基础架构服务,参数就是基于这些服务构建的。 下一个教程中将有更多关于参数的内容。 在本教程中,参数服务将从讨论中省略。
现在,让我们关注 turtlesim 特定的服务,/clear
、/kill
、/reset
、/spawn
、/turtle1/set_pen
、/turtle1/teleport_absolute
和 /turtle1/teleport_relative
。
您可能还记得在 使用 turtlesim、ros2 和 rqt 教程中使用 rqt 与其中一些服务进行交互。
3 ros2 服务类型
服务具有描述服务请求和响应数据的结构方式的类型。 服务类型的定义与主题类型类似,但服务类型有两个部分:一个消息用于请求,另一个消息用于响应。
要找出服务的类型,请使用以下命令:
ros2 service type <service_name>
我们来看看 turtlesim 的 /clear
服务。
在新的终端中,输入命令:
ros2 service type /clear
应该返回:
std_srvs/srv/Empty
Empty
类型表示服务调用在发出请求时不发送任何数据,在收到响应时不接收任何数据。
3.1 ros2 service list -t
要同时查看所有活动服务的类型,可以将 --show-types
选项(缩写为 -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 info
要查看特定服务的信息,请使用以下命令:
ros2 service info <service_name>
这将返回服务类型以及服务客户端和服务器的数量。
例如,您可以找到“/clear”服务的客户端和服务器数量:
ros2 service info /clear
它将返回:
Type: std_srvs/srv/Empty
Clients count: 0
Services count: 1
5 ros2 service find
如果要查找特定类型的所有服务,可以使用以下命令:
ros2 service find <type_name>
例如,您可以像这样找到所有“空”类型的服务:
ros2 service find std_srvs/srv/Empty
它将返回:
/clear
/reset
6 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
所需的参数。
x
、y
和 theta
确定生成的海龟的 2D 姿势,而 name
显然是可选的。
在这种情况下,您不需要知道行下方的信息,但它可以帮助您了解从调用中获得的响应的数据类型。
7 ros2 service call
现在您知道了什么是服务类型、如何查找服务类型以及如何查找该类型参数的结构,您可以使用以下方式调用服务:
ros2 service call <service_name> <service_type> <arguments>
<arguments>
部分是可选的。
例如,您知道 Empty
类型的服务没有任何参数:
ros2 service call /clear std_srvs/srv/Empty
此命令将清除 turtlesim 窗口中乌龟所画的所有线条。
现在让我们通过调用“/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 窗口将立即更新新生成的海龟:
8 ros2 service 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”之间的服务通信。
ros2 service echo --flow-style /add_two_ints
info:
event_type: REQUEST_SENT
stamp:
sec: 1709408301
nanosec: 423227292
client_gid: [1, 15, 0, 18, 250, 205, 12, 100, 0, 0, 0, 0, 0, 0, 21, 3]
sequence_number: 618
request: [{a: 2, b: 3}]
response: []
---
info:
event_type: REQUEST_RECEIVED
stamp:
sec: 1709408301
nanosec: 423601471
client_gid: [1, 15, 0, 18, 250, 205, 12, 100, 0, 0, 0, 0, 0, 0, 20, 4]
sequence_number: 618
request: [{a: 2, b: 3}]
response: []
---
info:
event_type: RESPONSE_SENT
stamp:
sec: 1709408301
nanosec: 423900744
client_gid: [1, 15, 0, 18, 250, 205, 12, 100, 0, 0, 0, 0, 0, 0, 20, 4]
sequence_number: 618
request: []
response: [{sum: 5}]
---
info:
event_type: RESPONSE_RECEIVED
stamp:
sec: 1709408301
nanosec: 424153133
client_gid: [1, 15, 0, 18, 250, 205, 12, 100, 0, 0, 0, 0, 0, 0, 21, 3]
sequence_number: 618
request: []
response: [{sum: 5}]
---
摘要
节点可以使用 ROS 2 中的服务进行通信。 与主题(一种单向通信模式,其中节点发布可由一个或多个订阅者使用的信息)不同,服务是一种请求/响应模式,其中客户端向提供服务的节点发出请求,服务处理请求并生成响应。
您通常不想使用服务进行连续调用;主题甚至操作更适合。
在本教程中,您使用命令行工具来识别、自省和调用服务。
下一步
在下一个教程 了解参数 中,您将了解如何配置节点设置。
相关内容
查看 本教程;这是使用 Robotis 机械臂的 ROS 服务的出色现实应用。