理解 ROS 2 服务
目标:了解 ROS 2 中服务的工作原理,以及如何使用命令行工具与服务交互。
难度级别:初学者
预计时间:15 分钟
目录
- 背景
- 前提条件
- 任务
- 设置
- ros2 service list
- ros2 service type
- ros2 service find
- ros2 interface show
- ros2 service call
- 总结
背景
服务是 ROS 2 中另一种节点间通信的方式。服务基于请求-响应模型,而不是话题的发布-订阅模型。虽然话题允许节点持续交换消息,但服务只在客户端专门调用时才提供数据。


前提条件
前几篇教程介绍了节点和话题,本教程将在此基础上进行。
和往常一样,不要忘记在每个新打开的终端中执行 ROS 2 的 setup 文件。
任务
1. 设置
启动 turtlesim 以查看服务的实际应用:
打开一个新终端并运行:
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
你会注意到每个节点(/teleop_turtle、/turtle1、/turtlesim)都有与其相关的服务,以及一些独立的服务如 /clear、/kill 等。
服务名称的命名约定与话题类似:以节点名称为前缀,如 /turtle1/set_pen。
3. ros2 service type
服务有类型,就像话题有类型一样。服务类型描述了请求和响应的数据结构。
要查找服务的类型,使用命令:
ros2 service type <service_name>
让我们查看 /clear 服务的类型。在新终端中输入:
ros2 service type /clear
返回结果:
std_srvs/srv/Empty
Empty 类型意味着服务调用不发送或接收任何数据——它只是触发一个事件(在本例中是清除 turtlesim 窗口)。
4. ros2 service find
你也可以按类型查找服务。使用命令:
ros2 service find <type_name>
例如,查找所有类型为 std_srvs/srv/Empty 的服务:
ros2 service find std_srvs/srv/Empty
返回结果:
/clear
/reset
这意味着 /clear 和 /reset 服务都不使用任何数据,只触发事件。
5. ros2 interface show
服务类型决定了请求和响应的数据结构。要了解特定服务类型的结构,使用命令:
ros2 interface show <type_name>
让我们检查一下 /spawn 服务的类型。首先,找出它的类型:
ros2 service type /spawn
返回结果:
turtlesim/srv/Spawn
现在查看该类型的结构:
ros2 interface show turtlesim/srv/Spawn
返回结果:
float32 x
float32 y
float32 theta
string name # 可选,如未提供则自动生成
---
string name
--- 上方的部分是请求的数据结构,下方是响应的数据结构。
/spawn 服务需要 x、y 坐标和 theta(旋转角度)来放置新乌龟。你可以选择给乌龟命名;如果不命名,会自动生成一个名字。响应将包含新乌龟的名称。
6. ros2 service call
要从命令行调用服务,使用命令:
ros2 service call <service_name> <service_type> <arguments>
<arguments> 是符合服务类型结构的请求数据,以 YAML 格式提供。
让我们调用 /spawn 服务在 turtlesim 窗口中创建一只新乌龟。
基于上一节中 turtlesim/srv/Spawn 的结构,我们需要提供 x、y、theta 和可选的 name。
在新终端中输入:
ros2 service call /spawn turtlesim/srv/Spawn "{x: 2.0, y: 2.0, theta: 0.0, name: 'turtle2'}"
你应该会在 turtlesim 窗口中看到一只新乌龟出现在 (2, 2) 位置。
终端会返回服务响应:
requester: making request: turtlesim.srv.Spawn_Request(x=2.0, y=2.0, theta=0.0, name='turtle2')
response:
turtlesim.srv.Spawn_Response(name='turtle2')
如果不指定 name 参数,例如:
ros2 service call /spawn turtlesim/srv/Spawn "{x: 5.0, y: 5.0, theta: 0.0}"
响应将包含系统生成的名称,如 turtle3。
现在尝试调用 /clear 服务。我们知道它的类型是 std_srvs/srv/Empty,这意味着它不需要任何参数:
ros2 service call /clear std_srvs/srv/Empty
turtlesim 窗口中的轨迹将被清除。
总结
服务是节点间另一种通信方式,基于请求-响应模型,适用于不需要持续数据流的场景。
在本教程中,你学习了如何使用命令行工具列出服务、查看服务类型、查找特定类型的服务、检查服务类型的结构,以及调用服务。
下一步
接下来,你将通过《理解参数》教程学习 ROS 2 中另一种重要的通信机制。
301

被折叠的 条评论
为什么被折叠?



