ROS2 学习笔记5:了解ROS2 服务Service
Background 背景
服务是ROS 中节点的另一种通讯方法。服务基于请求和响应模型,而不是话题的发布-订阅模型。话题订阅可以使订阅节点持续获取数据流,服务只对具体调用的客户端节点提供数据。
思考及疑问: 多个 Service Clients 使用相同 Service,Server 如何区分,Node ID? Src port?
Prerequisites 前提
略
Tasks 任务
1 Setup
启动两个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
,几乎每一个ros2节点的服务都是以参数parameters
为基础。下一个节课会深入了解参数paramters
,本课程省去参数服务的讨论。
现在,专注于turtlesim
服务,/clear
, /kill
, /reset
, /spawn
, /turtle1/set_pen
, /turtle1/teleport_absolute
,和/turtle1/teleport_relative
。之前课程中使用rqt
来展现了相关服务交互关系。
3 ros2 service type
服务类型描述的是,服务的 请求/响应 数据结构是怎样的。服务类型的定义类似话题类型,但服务类型有两部分组成:一个是请求,另一个是响应。
思考及疑问: service type 的具体定义方式
查看具体服务的类型,使用下面指令:
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 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.srv
返回:
---
---
将请求结构 (上) 与响应结构 (下) 分开。但是,如前所述, 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
决定者生成小乌龟的位置,而name
参数是可选的。
在---
下方的信息,不必了解,但其可以帮助你理解从请求中获取响应的数据类型。
6 ros2 service call
既然知道什么是服务类型,如何找到服务的类型,以及如何找到该类型参数的结构,您可以使用以下方法调用服务:
思考及疑问: rqt 中 call service 的本质:从一个节点发布请求服务
ros2 service call <service_name> <service_type> <arguments>
<arguments>
部分是可选的。例如,您知道 Empty
类型服务没有任何参数:
ros2 service call /clear std_srvs/srv/Empty
这个指令会清除小乌龟之前绘制的一些线条
通过调用 /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
窗口将立即更新新产生的海龟:
Summary 总结
在ros2里面,节点可通过服务进行通信。不像话题那样,一个节点发布消息可以被一个或多个订阅器接收的的通信方式;服务是一种请求/响应模式,客户端节点发出请求,服务端节点处理这个请求并给出响应。
通常,不会连续调用一个服务;话题,甚至动作更符合这种场景。
在本教程中,你使用了命令行工具去识别,详细说明和调用服务。
Next steps 下一步
下一节课,认识ros2参数parameters
,你会学习配置节点。
命令合集:
ros2 service -h #查看命令帮助
ros2 service list 罗列服务列表
ros2 service type <service_name> #展示指定服务的类型
ros2 service list -t #罗列带有类型的服务列表
ros2 service find <type_name> #查找特定类型的服务清单
ros2 interface show <type_name>.srv #类型详细参数查看
ros2 service call <service_name> <service_type> <arguments> #请求服务