ROS专题 · 2024年3月4日 0

ROS 2基础概念#7:动作(Action)| ROS 2学习笔记 

ROS 2 Actions是ROS 2中的一个重要概念,它提供了一种用于执行长时间运行的任务或目标的机制。Actions相当于一种高级的服务,允许节点向其他节点发送一个目标,然后接收有关该目标执行状态的反馈,并最终接收执行结果。在本文中,我们将详细介绍ROS 2 Actions的概念、结构和使用方法。

Action 概述

ROS 2 Actions是ROS 2中用于实现异步、长时间运行任务的机制。相比于ROS 1中的服务(Services)和话题(Topics),Actions更适合处理需要长时间运行、具有中间状态反馈的任务,例如路径规划、导航、抓取等。Actions的设计目标是提供更可靠、更灵活的方式来执行这些任务,并且能够有效地处理中断、取消等情况。

Action 结构

Actions的结构包括三个主要部分:动作(Action)、目标(Goal)和结果(Result)。下面是它们的简要描述:

  • 动作(Action):定义了一项具体的任务,例如路径规划、抓取等。每个动作动作由一个动作消息定义,其中包含了执行任务所需的所有信息,包括输入、输出和反馈。
  • 目标(Goal):表示执行某个动作的具体目标,包括任务的期望结果。目标消息通常包含了动作所需的输入参数。
  • 结果(Result):动作执行完成后返回的结果。结果消息包含了任务执行的状态信息以及可能的输出参数。

Action 与 Service对比

使用方法

使用ROS 2 Actions通常需要以下步骤:

  1. 定义动作消息:首先需要定义动作消息,即描述要执行的任务的消息类型。这通常在.action文件中完成,类似于服务(.srv)和消息(.msg)的定义。
  2. 实现动作服务器:编写一个动作动作服务器节点,用于接收目标并执行相应的任务。这个节点需要实现动作接口,并根据接收到的目标执行任务,发送反馈并最终发布结果。
  3. 编写动作客户端:编写一个动作客户端节点,用于向动作服务器发送目标,并根据接收到的反馈来监控任务的执行状态。客户端可以选择是否等待任务完成,并在任务完成后处理结果。
  4. 启动节点:启动动作服务器和客户端节点,使它们能够相互通信并执行任务。

使用示例

下面是一个简单的示例,演示了如何使用ROS 2 Actions执行一个假想的路径规划任务:

  • 动作消息定义(NavigateToGoal.action):
plaintextCopy code# 动作消息定义
geometry_msgs/PoseStamped target_pose
---
bool success
  • 动作服务器节点:接收目标并模拟路径规划任务的执行过程。
  • 动作客户端节点:向动作服务器发送目标,然后根据反馈监控任务的执行状态,并在任务完成后获取结果。

Action 命令行工具

准备工作

打开新的 Terminal 并运行如下命令来启动两个 turtlesim 节点: /turtlesim and /teleop_turtle.

ros2 run turtlesim turtlesim_node

打开另一个 Terminal 并运行:

ros2 run turtlesim turtle_teleop_key

当您启动 /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”主题。)

请注意,在 QWERTY 键盘上,字母键 G|B|V|C|D|E|R|T 在 F 键周围形成一个“框”。 F 周围每个键的位置对应于turtlesim 中的方向。 例如,E 会将 turtle 的方向旋转到左上角。

注意 /turtlesim 节点运行的终端。 每次您按下这些键之一,您就会将一个目标发送到属于 /turtlesim 节点一部分的操作服务器。 目标是旋转 turtle 以面向特定方向。 一旦 turtle 完成旋转,就会显示一条传达目标结果的消息:

[INFO] [turtlesim]: Rotation goal completed successfully

F 键将取消执行中的目标,展示了操作的可抢占功能。

尝试按 C 键,然后在 turtle 完成旋转前按 F 键。 在 /turtlesim 节点运行的终端中,您将看到以下消息:

[INFO] [turtlesim]: Rotation goal canceled

用户不仅可以在客户端(您在 teleop 中的输入)阻止目标,在服务器端(/turtlesim 节点)也可以。 当服务器端选择停止处理某个目标时,就称为“中止”该目标。

尝试按 D 键,然后在完成第一次旋转前按 G 键。 在 /turtlesim 节点运行的终端中,您将看到以下消息:

[WARN] [turtlesim]: Rotation goal received before a previous goal finished. Aborting previous goal 

服务器端因第一个目标被中断而中止。

获得节点动作信息

要查看节点提供的操作列表(在本例中为 /turtlesim),请打开一个新终端并运行以下命令:

ros2 node info /turtlesim

它将返回 /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/msg/Color
    /turtle1/pose: turtlesim/msg/Pose
  Services:
    /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
  Action Servers:
    /turtle1/rotate_absolute: turtlesim/action/RotateAbsolute
  Action Clients:

请注意,/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
  Services:
    /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
  Action Servers:

  Action Clients:
    /turtle1/rotate_absolute: turtlesim/action/RotateAbsolute

获得动作列表

要识别 ROS 2 graph 中的所有Action,请运行以下命令:

ros2 action list

将得到如下的返回结果:

/turtle1/rotate_absolute

这是目前 ROS graph 中唯一的操作。 正如您之前所见,它控制 turtle 的旋转。 通过使用 ros2 node info 命令,该动作有一个客户端(/teleop_turtle 的一部分)和一个服务器(/turtlesim 的一部分)。

获得动作类型

类似主题和服务,动作也有类型。 要查找 /turtle1/rotate_absolute 的类型,请运行以下命令:

ros2 action list -t

将获得如下的结果:

/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]

每个动作名称右侧的中括号中(在本例中仅 /turtle1/rotate_absolute)是动作类型,turtlesim/action/RotateAbsolute。 当您想从命令行或代码执行操作时,您将需要它。

获得动作信息

可以使用以下命令进一步获得 /turtle1/rotate_absolute 操作信息:

ros2 action info /turtle1/rotate_absolute

将获得如下的结果:

Action: /turtle1/rotate_absolute
Action clients: 1
    /teleop_turtle
Action servers: 1
    /turtlesim

这告诉我们动作的详细信息:/teleop_turtle 节点有一个动作客户端,/turtlesim 节点有一个动作服务器,它们用于 /turtle1/rotate_absolute 动作。

获得动作接口

在发送或执行某个动作之前,还需要了解该动作的类型和接口数据结构。回想一下,在运行命令 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

此消息中第一部分(第一个 --- 上方的部分)是目标请求(request)的结构(数据类型和名称)。 第二部分(两个 --- 中间的部分)是结果(result)的结构。 最后一部分(第二个 --- 下方的部分)是反馈(feedback)的结构。

发送目标

使用以下语法从命令行发送动作目标,<value> 为YAML格式:

ros2 action send_goal <action_name> <action_type> <values>

密切关注 turtlesim 窗口,然后在终端中输入以下命令:

ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.57}"

您应该看到 turtle 在旋转,并在终端中看到以下消息:

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 的字段,它是到起始位置的位移。

要查看此目标的反馈,请将 –feedback 添加到您运行的最后一个命令中。 首先,确保更改 theta 的值。 运行上一个命令后,turtle 的方向已经是 1.57 弧度,因此除非您传递新的 theta,否则它不会移动。

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

您将继续收到反馈、剩余的弧度,直到目标完成。

总结

ROS 2 Actions提供了一种强大而灵活的机制来处理长时间运行任务,例如路径规划、导航、抓取等。通过动作、目标和结果的结构,Actions能够有效地处理任务的执行状态反馈,并提供可靠的执行结果。虽然使用Actions可能会增加一些复杂性,但它为ROS 2系统提供了更加健壮和可扩展的任务执行机制。