机器人系统——ROS2文档—认识动作
目标:内省 ROS 2 中的动作。教程级别:入门级时间: 15 分钟
目录
- 背景
- 前置条件
- 任务
- 1 环境准备
- 2 使用动作
- 3 ros2 node info
- 4 ros2 action list
- 5 ros2 action type
- 6 ros2 action info
- 7 ros2 interface show
- 8 ros2 action send_goal
- 9 ros2 action echo
- 总结
- 后续步骤
- 相关资料
背景
动作是 ROS 2 中的一种通信类型,专为长时间运行的任务而设计。它们由三部分组成:目标、反馈和结果。
动作基于话题和服务构建。它们的功能类似于服务,但区别在于动作可以被取消。此外,动作提供持续的反馈,而服务只返回单个响应。
动作使用客户端–服务器模型,类似于发布–订阅模型(在话题教程中描述)。一个“动作客户端”节点向一个“动作服务器”节点发送目标,该服务器确认目标并返回一个反馈流和一个结果。

前置条件
本教程建立在之前教程中介绍的概念之上,如节点和话题。本教程使用turtlesim功能包。和往常一样,别忘了在打开的每个新终端中加载 ROS 2 环境。
任务
1 环境准备
启动两个 turtlesim 节点:/turtlesim和/teleop_turtle。
打开一个新终端并运行:
$ ros2 run turtlesim turtlesim_node
打开另一个终端并运行:
$ ros2 run turtlesim turtle_teleop_key
2使用动作
当你启动/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在美国 QWERTY 键盘上形成了围绕F键的一个“方框”(如果你不使用 QWERTY 键盘,请参阅此链接了解)。每个键相对于F的位置对应 turtlesim 中的那个方向。例如,E会使乌龟的方向旋转到左上角。
注意运行/turtlesim节点的终端。每次你按下这些键中的一个,你就在向一个动作服务器发送一个目标,该服务器是/turtlesim节点的一部分。目标是旋转乌龟使其面向特定方向。一旦乌龟完成旋转,一条传递目标结果的消息应该会显示出来:
[INFO] [turtlesim]: Rotation goal completed successfully
F键会在执行过程中取消一个目标。
尝试按下C键,然后在乌龟完成旋转之前按下F键。在运行/turtlesim节点的终端中,你会看到消息:
[INFO] [turtlesim]: Rotation goal canceled
不仅客户端(您在遥控终端中的输入)可以停止目标,服务器端(/turtlesim节点)也可以。当服务器端选择停止处理一个目标时,称为“中止”该目标。
尝试按下D键,然后在第一次旋转完成之前按下G键。在运行/turtlesim节点的终端中,你会看到消息:
[WARN] [turtlesim]: Rotation goal received before a previous goal finished. Aborting previous goal
该动作服务器选择中止第一个目标,因为它收到一个新目标。它本可以选择其他方式,比如拒绝新目标,或者在第一个目标完成后执行第二个目标。不要假定每个动作服务器在收到新目标时都会选择中止当前目标。
3 ros2 node info
要查看节点提供的动作列表,这里以/turtlesim为例,打开一个新终端并运行命令:
$ ros2 node info /turtlesim
/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_msgs/msg/Color
/turtle1/pose: turtlesim_msgs/msg/Pose
Service Servers:
/clear: std_srvs/srv/Empty
/kill: turtlesim_msgs/srv/Kill
/reset: std_srvs/srv/Empty
/spawn: turtlesim_msgs/srv/Spawn
/turtle1/set_pen: turtlesim_msgs/srv/SetPen
/turtle1/teleport_absolute: turtlesim_msgs/srv/TeleportAbsolute
/turtle1/teleport_relative: turtlesim_msgs/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_msgs/action/RotateAbsolute
Action Clients:
该命令返回/turtlesim的订阅者、发布者、服务、动作服务器和动作客户端的列表。
注意/turtlesim的/turtle1/rotate_absolute动作位于动作服务器下。这意味着/turtlesim响应并为/turtle1/rotate_absolute动作提供反馈。
/teleop_turtle节点在动作客户端下具有名称/turtle1/rotate_absolute,这意味着它发送该动作名称的目标。要查看这一点,请运行:
$ 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_msgs/action/RotateAbsolute
4 ros2 action list
要列出 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_msgs/action/RotateAbsolute]
在每个动作名称右侧的方括号中(这里只有/turtle1/rotate_absolute)是动作类型turtlesim_msgs/action/RotateAbsolute。当您想要从命令行或从代码执行动作时,将需要这个类型。
5 ros2 action type
如果您想检查动作的动作类型,运行命令:
$ ros2 action type /turtle1/rotate_absolute
turtlesim_msgs/action/RotateAbsolute
6 ros2 action info
您可以通过以下命令进一步内省/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得到的信息:/teleop_turtle节点有一个动作客户端,/turtlesim节点有一个动作服务器,用于/turtle1/rotate_absolute动作。
7 ros2 interface show
在您自己发送或执行动作目标之前,还需要了解的一件事是动作类型的结构。
回忆一下,在运行ros2 action list -t命令时,您识别出了/turtle1/rotate_absolute的类型。在终端中输入以下命令,带上动作类型:
$ ros2 interface show turtlesim_msgs/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
此消息中第一个---之上的部分是目标请求的结构(数据类型和名称)。下一个部分是结果的结构。最后一个部分是反馈的结构。
8 ros2 action send_goal
现在,让我们从命令行发送一个动作目标,使用以下语法:
$ ros2 action send_goal <action_name> <action_type> <values>
<values>需要使用 YAML 格式。
注意 turtlesim 窗口,然后在终端中输入以下命令:
$ ros2 action send_goal /turtle1/rotate_absolute turtlesim_msgs/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_msgs/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
您将持续收到反馈(剩余弧度),直到目标完成。
9 ros2 action echo
要查看动作客户端和动作服务器之间的数据通信,您可以使用以下命令echo动作数据:
$ ros2 action echo <action_name> <optional arguments/action_type>
ros2 action echo依赖于动作客户端和服务器的动作内省,该功能默认是禁用的。要启用它,用户必须在创建动作客户端或服务器后调用configure_introspection。
启动fibonacci_action_server和fibonacci_action_client,并为演示启用action_server_configure_introspection参数:
$ ros2 run action_tutorials_cpp fibonacci_action_server --ros-args -p action_server_configure_introspection:=contents
$ ros2 run action_tutorials_py fibonacci_action_client --ros-args -p action_client_configure_introspection:=contents
现在我们可以通过ros2 action echo查看fibonacci_action_server和fibonacci_action_client之间的动作通信。
$ ros2 action echo /fibonacci example_interfaces/action/Fibonacci --flow-style
interface: GOAL_SERVICE
info:
event_type: REQUEST_SENT
stamp:
sec: 1742070798
nanosec: 400435819
client_gid: [1, 15, 165, 231, 194, 197, 167, 157, 0, 0, 0, 0, 0, 0, 20, 4]
sequence_number: 1
request: [{goal_id: {uuid: [230, 96, 12, 6, 100, 69, 69, 70, 220, 205, 135, 251, 210, 2, 231, 110]}, goal: {order: 10}}]
response: []
---
interface: GOAL_SERVICE
info:
event_type: REQUEST_RECEIVED
stamp:
sec: 1742070798
nanosec: 400706446
client_gid: [1, 15, 165, 231, 194, 197, 167, 157, 0, 0, 0, 0, 0, 0, 20, 4]
sequence_number: 1
request: [{goal_id: {uuid: [230, 96, 12, 6, 100, 69, 69, 70, 220, 205, 135, 251, 210, 2, 231, 110]}, goal: {order: 10}}]
response: []
---
interface: RESULT_SERVICE
info:
event_type: REQUEST_SENT
stamp:
sec: 1742070798
nanosec: 401486678
client_gid: [1, 15, 165, 231, 194, 197, 167, 157, 0, 0, 0, 0, 0, 0, 24, 4]
sequence_number: 1
request: [{goal_id: {uuid: [230, 96, 12, 6, 100, 69, 69, 70, 220, 205, 135, 251, 210, 2, 231, 110]}}]
response: []
---
interface: FEEDBACK_TOPIC
goal_id:
uuid: [230, 96, 12, 6, 100, 69, 69, 70, 220, 205, 135, 251, 210, 2, 231, 110]
feedback:
sequence: [0, 1, 1]
---
interface: STATUS_TOPIC
status_list: [{goal_info: {goal_id: {uuid: [230, 96, 12, 6, 100, 69, 69, 70, 220, 205, 135, 251, 210, 2, 231, 110]}, stamp: {sec: 1742070798, nanosec: 401146752}}, status: 2}]
---
...
注意:此功能在 Kilted Kaiju 或更高版本中可用。
总结
动作类似于服务,但允许您执行长时间运行的任务,提供定期的反馈,并且可取消。
机器人系统很可能会使用动作进行导航。一个动作目标可以告诉机器人移动到某个位置。当机器人导航到该位置时,它可以沿途发送更新(即反馈),然后在到达目的地后发送最终结果消息。
Turtlesim有一个动作服务器,动作客户端可以向其发送目标来旋转乌龟。在本教程中,您内省了该动作/turtle1/rotate_absolute,以更好地理解动作是什么以及它们如何工作。
后续步骤
现在您已经涵盖了所有核心 ROS 2 概念。本系列的后面几个教程将向您介绍一些工具和技术,使 ROS 2 的使用更加容易,从使用 rqt_console 查看日志开始。
相关资料
您可以在此处阅读有关 ROS 2 中动作设计决策的更多信息。
本文档完整翻译自 ROS 2 Lyrical 官方文档,仅用于学习交流。
夜雨聆风