机器人操作系统ROS2之理解动作

目标

在ROS2中对动作进行深入探究和分析。

背景知识

动作是ROS2中的一种通信类型,适用于长时间运行的任务。它们由三个部分组成:目标(goal)、反馈(feedback)和结果(result)。

动作是基于话题(topics)和服务(services)构建的。其功能与服务类似,不同之处在于动作可以被取消。它与只返回单个响应的服务相比,还能提供持续的反馈。

动作采用的是客户端/服务器模型,类似于发布者/订阅者模型(这在理解话题的文章中有描述)。一个 "动作客户端" 节点向一个 "动作服务器" 节点发送目标(goal),动作服务器节点会确认该目标(goal),并返回一系列反馈信息(feedback)和最终结果(result)。

前提条件

跟往常一样,在每次打开新终端时,别忘了对ROS2进行环境变量设置。

bash 复制代码
# Replace ".bash" with your shell if you're not using bash
# Possible values are: setup.bash, setup.sh, setup.zsh
source /opt/ros/jazzy/setup.bash

操作步骤

1. 环境设置

启动 turtlesim的两个节点:/turtlesim和 /teleop_turtle。 打开一个新终端并运行以下命令:

arduino 复制代码
ros2 run turtlesim turtlesim_node

再打开另一个终端并运行:

arduino 复制代码
ros2 run turtlesim turtle_teleop_key

2. 使用动作

当你启动 /teleop_turtle 节点时,你会在终端中看到以下消息:

css 复制代码
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 键会将乌龟的朝向旋转到左上角。

这时请留意运行 /turtlesim 节点的终端。每次按下这些键中的一个时,你就是在 /turtlesim 节点的一个动作服务器发送一个目标。该目标是将乌龟旋转到特定的方向。一旦乌龟完成旋转,应该会显示一条传达目标结果的消息:

css 复制代码
[INFO] [turtlesim]: Rotation goal completed successfully

按下 F 键将在目标执行过程中取消该目标。

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

css 复制代码
[INFO] [turtlesim]: Rotation goal canceled

不仅客户端(你在 teleop中的输入)可以停止一个目标,服务器端( /turtlesim 节点)也可以。当服务器端选择停止处理一个目标时,我们称其 "Abort" 了该目标。 尝试按下 D 键,然后在第一次旋转完成之前按下 G 键。在 /turtlesim 节点的终端中,你会看到以下消息:

less 复制代码
[WARN] [turtlesim]: Rotation goal received before a previous goal finished. Aborting previous goal

因为动作服务器收到了一个新目标,它选择中止第一个目标。它也可以选择其他操作,比如拒绝新目标或者在第一个目标完成后再执行第二个目标。需要注意的是,不要因为这次实验认为每个动作服务器在收到新目标时都会选择中止当前目标。

3. ros2 node info 命令

要查看一个节点(这里是 /turtlesim)所提供的动作列表,打开一个新终端并运行以下命令:

bash 复制代码
ros2 node info /turtlesim

该命令将返回 /turtlesim的订阅者、发布者、服务、动作服务器和动作客户端的列表:

bash 复制代码
/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动作属于 "动作服务器" 部分。这意味着 /turtlesim 对 /turtle1/rotate_absolute动作做出响应并提供反馈。

对应的,/teleop_turtle 节点在 "动作客户端" 部分则有会 /turtle1/rotate_absolute,这意味着它作为动作客户端发送这个动作目标。要查看这一点,可以运行以下命令:

bash 复制代码
ros2 node info /teleop_turtle

该命令将返回:

bash 复制代码
/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 图中的所有动作,需要运行以下命令:

复制代码
ros2 action list

该命令将返回:

bash 复制代码
/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

该命令将返回:

bash 复制代码
/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]

在每个动作名称(在这种情况下只有 /turtle1/rotate_absolute)右边的方括号中是动作类型 turtlesim/action/RotateAbsolute。当你想从命令行或代码中执行一个动作时,你就会需要这个动作类型。

5. ros2 action type 命令

如果你想检查某个动作的动作类型,运行以下命令:

bash 复制代码
ros2 action type /turtle1/rotate_absolute

该命令将返回:

bash 复制代码
turtlesim/action/RotateAbsolute

6. ros2 action info 命令

你可以使用以下命令进一步深入探究 /turtle1/rotate_absolute 动作:

bash 复制代码
ros2 action info /turtle1/rotate_absolute

该命令将返回:

bash 复制代码
Action: /turtle1/rotate_absolute
Action clients: 1
    /teleop_turtle
Action servers: 1
    /turtlesim

从返回结果我们同样可以看到之前对每个节点运行 ros2 node info 所了解到的信息:/teleop_turtle 节点有一个针对 /turtle1/rotate_absolute 动作的动作客户端,而 /turtlesim 节点有一个针对该动作的动作服务器。

7. ros2 interface show 命令

在你自己发送或执行动作目标之前,还需要了解的一个信息是动作类型的结构。

回想一下,你在运行 ros2 action list -t 命令时, 确定了 /turtle1/rotate_absolute 的类型。在终端中输入以下带有动作类型的命令:

kotlin 复制代码
ros2 interface show turtlesim/action/RotateAbsolute

该命令将返回:

yaml 复制代码
# 以弧度为单位的航向
float32 theta
---
# 以弧度为单位的到起始位置的角位移
float32 delta
---
# 以弧度为单位的剩余旋转
float32 remaining

这条消息中第一个 --- 上面的部分是目标请求的定义(数据类型和名称)。接下来的部分是结果的定义。最后一部分是反馈的定义。

8. ros2 action send_goal 命令

现在让我们在命令行中使用以下语法发送一个动作目标:

xml 复制代码
ros2 action send_goal <action_name> <action_type> <values>

在这里需要采用 YAML 格式。

留意一下 turtlesim窗口,然后在终端中输入以下命令:

bash 复制代码
ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.57}"

你应该会看到乌龟在旋转,并且在终端中会看到以下消息:

yaml 复制代码
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选项:

bash 复制代码
ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}" --feedback

你的终端将会返回以下消息:

yaml 复制代码
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

你将会持续收到反馈,即剩余的弧度,直到目标完成。

总结

动作类似于服务,它允许你执行长时间运行的任务,提供定期反馈,并且可以被取消。 一个机器人系统很可能会使用动作来进行导航。一个动作目标可以告诉机器人前往某个位置。在机器人导航到该位置的过程中,它可以沿途发送更新(即反馈),然后在到达目的地时发送一个最终的结果消息。

Turtlesim有一个动作服务器,动作客户端可以向其发送用于旋转乌龟的目标。在本文中,你对 /turtle1/rotate_absolute 这个动作进行了深入探究,更好地理解了动作是什么,以及它们是如何工作的。


关注【智践行】公众号,发送 【机器人】 获得机器人经典学习资料

相关推荐
jndingxin7 分钟前
OpenCV CUDA模块中逐元素操作------数学函数
人工智能·opencv·计算机视觉
暴龙胡乱写博客9 分钟前
机器学习 --- KNN算法
人工智能·算法·机器学习
极新44 分钟前
极新携手火山引擎,共探AI时代生态共建的破局点与增长引擎
人工智能·火山引擎
是麟渊1 小时前
【大模型面试每日一题】Day 17:解释MoE(Mixture of Experts)架构如何实现模型稀疏性,并分析其训练难点
人工智能·自然语言处理·面试·职场和发展·架构
Poseidon、1 小时前
2025年5月AI科技领域周报(5.5-5.11):AGI研究进入关键验证期 具身智能开启物理世界交互新范式
人工智能·agi
天机️灵韵2 小时前
字节开源FlowGram与n8n 技术选型
人工智能·python·开源项目
jixunwulian2 小时前
AI边缘网关_5G/4G边缘计算网关厂家_计讯物联
人工智能·5g·边缘计算
腾讯云音视频2 小时前
AI实时对话的通信基础,WebRTC技术综合指南
人工智能·webrtc
暴龙胡乱写博客2 小时前
机器学习 --- 模型选择与调优
人工智能·机器学习
白熊1883 小时前
【计算机视觉】OpenCV实战项目:基于OpenCV与face_recognition的实时人脸识别系统深度解析
人工智能·opencv·计算机视觉