ROS 2 Iron 教程 第一章 CLI Tools 第七节 理解动作
前言
本系列文章是由笔者翻译自ROS 2 官方教程。笔者水平有限,如有错误,还请读者指正。
目标
理解 ROS 2 中的动作(actions)。
背景
动作(actions)是 ROS 2 中的一种通信方式,它为长时间运行的任务而设计。它们由三个部分组成:一个目标,反馈,以及一个结果。
动作是基于话题和服务的。它们的机制类似于服务,与服务不同的是,动作可以被取消。它们同时会提供稳定的反馈,这与仅仅返回一个结果的服务相反。
动作使用客户端-服务端模型,与发布者-订阅者模型相似。一个“动作客户端”节点向”动作服务端“节点发送目标,”动作服务端“节点接受目标后会返回稳定的反馈流和一个结果。
先决条件
本节教程省略了节点和话题的概念介绍,它们在过去的教程中已经被提及。
本节教程使用 turtlesim 包。
一如既往,不要忘记在每个新终端中添加 ROS 2 启动文件。
任务
1 Setup (设置)
启动两个 turtlesim 节点, 和 </teleop_turtle> 。
打开一个新终端并运行:
ros2 run turtlesim turtlesim_node
打开另一个新终端并运行:
ros2 run turtlesim turtle_teleop_key
2 Use actions (使用动作)
当你启动/teleop_turtle
节点时,你将会在终端中看到如下内容:
Use arrow keys to move the turtle.
Use G|B|V|C|D|E|R|T keys to rotate to absolute orientations. 'F' to cancel a rotation.
让我们重点关注第二行,它对应于一个动作。(第一行指令对应于前面在主题教程中讨论的“cmd_vel”主题。)
你可能会发现 {G|B|V|C|D|E|R|T} 键在 US QWERTY 键位中围绕着F
键周围。每个按键相对于F
键的方位对应着海龟的朝向。例如,E
将会将海龟转向左上角。
请注意一下正在运行 /turtlesim
的终端。当你每次按下这些按键时,你会向 /turtlesim
节点的动作服务端发送一个目标。这个目标将海龟向特定的方向旋转。一条反映目标执行结果的消息将会在海龟完成转向后显示一次:
[INFO] [turtlesim]: Rotation goal completed successfully
F
键将会在执行过程中取消目标。
尝试按下C
键,然后在海龟完成旋转前按下F
键。在 /turtlesim
节点运行的终端中,你将会看见如下消息:
[INFO] [turtlesim]: Rotation goal canceled
不仅仅是客户端可以停止目标,服务端也可以停止目标。当服务端选择停止处理目标时,称为“中止”目标。
尝试按下D
键,然后在旋转完成之前按下G
键。在/turtlesim>
节点运行的终端中,你将会看见如下消息:
[WARN] [turtlesim]: Rotation goal received before a previous goal finished. Aborting previous goal
在这个例子中动作服务端选择停止处理第一个目标,这是因为它收到了一个新的目标。它也可能有另外的可能,像是拒绝新的目标或是在第一个目标执行完后执行第二个目标。请不要假设每一个动作服务端会在收到新目标时选择停止处理当前的目标。
3 ros2 node info (ROS 2 节点信息)
为了查看节点提供的动作,以/turtlesim
举例,打开一个新终端并运行:
ros2 node info /turtlesim
它将会返回/turtlseim
节点的订阅者,发布者,服务,动作服务端和动作客户端:
/turtlesim
Subscribers:
/parameter_events: rcl_interfaces/msg/ParameterEvent
/turtle1/cmd_vel: geometry_msgs/msg/Twist
Publishers:
/parameter_events: rcl_interfaces/msg/ParameterEvent
/rosout: rcl_interfaces/msg/Log
/turtle1/color_sensor: turtlesim/msg/Color
/turtle1/pose: turtlesim/msg/Pose
Service Servers:
/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
/turtlesim/describe_parameters: rcl_interfaces/srv/DescribeParameters
/turtlesim/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
/turtlesim/get_parameters: rcl_interfaces/srv/GetParameters
/turtlesim/list_parameters: rcl_interfaces/srv/ListParameters
/turtlesim/set_parameters: rcl_interfaces/srv/SetParameters
/turtlesim/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
Service Clients:
Action Servers:
/turtle1/rotate_absolute: turtlesim/action/RotateAbsolute
Action Clients:
你可能会发现 turtlesim
的/turtle1/rotate_absolute
动作在 Action Servers
下。这意味着/turtlesim
响应/turtle1/rotate_absolute
并提供反馈。
/teleop_turtle
节点的 /turtle1/rotate_absolute
动作在Action Clients
下。这意味着其向动作服务端发送目标。为了查看详细信息,运行:
ros2 node info /teleop_turtle
它将会返回:
/teleop_turtle
Subscribers:
/parameter_events: rcl_interfaces/msg/ParameterEvent
Publishers:
/parameter_events: rcl_interfaces/msg/ParameterEvent
/rosout: rcl_interfaces/msg/Log
/turtle1/cmd_vel: geometry_msgs/msg/Twist
Service Servers:
/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/list_parameters: rcl_interfaces/srv/ListParameters
/teleop_turtle/set_parameters: rcl_interfaces/srv/SetParameters
/teleop_turtle/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
Service Clients:
Action Servers:
Action Clients:
/turtle1/rotate_absolute: turtlesim/action/RotateAbsolute
4 ros2 action list (ROS 2 动作列表)
为了确定 ROS 结构图中的所有动作,运行如下命令:
ros2 action list
它将返回:
/turtle1/rotate_absolute
这是在当前 ROS 结构图中的唯一动作。正如你先前看到的,它控制着海龟的转向。你也通过使用 ros2 node info <node_name>
知道了在这里有一个动作客户端(/teleop_turtle
的一部分)和一个动作服务端(/turtlesim
的一部分)。
4.1 ros2 action list -t
与话题和服务相似的是,动作也有类型。为了了解/turtle1/rotate_absolute
的类型,运行命令:
ros2 action list -t
它将会返回:
/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]
在动作名右边的方括号内是动作类型(在这个例子中仅有/turtle1/rotate_absolute
)。在你想要通过命令行或是代码执行动作时,你将会需要知道动作的类型。
5 ros2 action info (ROS 2 动作信息)
你可以通过如下命令来了解有关/turtle1/rotate_absolute
动作的更多信息:
ros2 action info /turtle1/rotate_absolute
它将会返回:
Action: /turtle1/rotate_absolute
Action clients: 1
/teleop_turtle
Action servers: 1
/turtlesim
这和我们先前运行的ros2 node info
都告诉我们:对于动作/turtle1/rotate_absolute
来说/teleop_turtle
节点有一个动作客户端,/turtlesim
节点有一个动作服务端。
6 ros2 interface show (ROS 2 接口信息)
在你发送或执行动作目标之前,你还需要知道动作类型的结构。
在你运行ros2 action list -t
命令之后,你已经确定了/turtle1/rotate_absolute
的类型。在新打开的终端中运行如下命令:
ros2 interface show turtlesim/action/RotateAbsolute
它将会返回:
# The desired heading in radians
float32 theta
---
# The angular displacement in radians to the starting position
float32 delta
---
# The remaining rotation in radians
float32 remaining
在第一条---
前的消息区域,展示了请求的结构。下一个区域是结果的结构。最后一个区域是反馈的结构。
7 ros2 action send_goal (ROS 2 发送动作目标)
现在,让我们使用下列参数在命令行中发送动作目标:
ros2 action send_goal <action_name> <action_type> <values>
<values>
需遵从 YAML 语法。
注意观察 turtlesim 窗口,然后在终端中输入如下命令:
ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.57}"
你应该会看到海龟正在选装,以及你的终端中出现如下信息:
Waiting for an action server to become available...
Sending goal:
theta: 1.57
Goal accepted with ID: f8db8f44410849eaa93d3feb747dd444
Result:
delta: -1.568000316619873
Goal finished with status: SUCCEEDED
所有目标都有独一无二的ID,在返回的信息中将会被展现。你也可以看到字段名为delta
的结果,是与起始位置的角度差。
为了查看目标的反馈,在ros2 action send_goal
命令中添加--feedback
:
ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}" --feedback
终端将会返回如下信息:
Sending goal:
theta: -1.57
Goal accepted with ID: e6092c831f994afda92f0086f220da27
Feedback:
remaining: -3.1268222332000732
Feedback:
remaining: -3.1108222007751465
…
Result:
delta: 3.1200008392333984
Goal finished with status: SUCCEEDED
在目标完成之前,你会不断收到剩余角度的反馈信息。
总结
正如服务一样,动作(actions)可以被用来执行长时间任务,并提供反馈,而且它是可取消的。
一个机器人系统可能会在导航中使用动作。动作的目标是机器人的目标位置。当机器人导航前往目标位置的过程中,它可以发送位置的更新,一旦当它到达目标位置的时候,最终的结果信息将会被发送一次。
Turtlesim 有一个动作服务端,动作客户端可以将旋转海龟的目标发送到该服务端。在本节教程中,您查看了动作 /turtle1/rotate_absolute
,以便更好地了解什么是动作以及它们的工作原理。