ROS2 Humble 动作(Action)保姆级教程:从海龟旋转到自定义圆周运动

张开发
2026/4/7 16:55:54 15 分钟阅读

分享文章

ROS2 Humble 动作(Action)保姆级教程:从海龟旋转到自定义圆周运动
ROS2 Humble动作机制深度实战从官方示例到自定义圆周运动开发引言在机器人开发领域任务执行往往不是瞬间完成的简单操作而是需要持续监控和可能中断的复杂过程。想象一下让机器人手臂完成抓取动作或者让移动机器人导航到指定位置——这些场景都需要实时掌握执行进度并在必要时进行干预。ROS2的动作Action机制正是为解决这类需求而设计的强大工具。与话题Topic和服务Service相比Action提供了更完整的任务管理框架。它融合了服务的请求-响应模式和话题的持续发布特性同时增加了取消执行和进度反馈等关键功能。这种设计使得开发者能够专注于业务逻辑而不必自己实现复杂的状态管理。本文将带您从ROS2 Humble版本的小海龟示例出发逐步构建一个完整的自定义圆周运动Action。不同于简单的概念讲解我们会深入探讨Action的设计哲学、实现细节和实际应用技巧。无论您是刚接触ROS2的新手还是希望系统掌握Action机制的开发者都能通过这个保姆级教程获得实用知识。1. 理解ROS2 Action机制1.1 Action的核心组成ROS2的Action机制建立在三个核心概念之上Goal表示一个动作请求比如旋转到90度或移动3米Feedback动作执行过程中定期发送的进度更新Result动作完成时返回的最终状态这种三元组结构完美匹配了长时间运行任务的管理需求。与Service相比Action更适合处理那些需要持续数秒甚至更长时间的操作。1.2 Action与Topic/Service的对比特性TopicServiceAction通信模式发布/订阅请求/响应目标/反馈/结果实时反馈是否是执行中断不支持不支持支持适用场景传感器数据流瞬时操作长时间运行任务典型延迟低中等取决于任务复杂度1.3 Action的底层实现虽然Action提供了高级抽象但其底层实际上是由多个Topic和Service组合实现的Goal Topic客户端发送动作目标Cancel Topic客户端请求取消执行Status Topic服务器报告动作状态Feedback Topic服务器发送进度更新Result Service动作完成后返回最终结果这种设计既保持了接口的简洁性又提供了丰富的功能。开发者无需关心这些底层细节可以直接使用Action提供的高级API。2. 小海龟Action示例深度解析2.1 启动小海龟仿真环境首先让我们启动经典的turtlesim仿真环境# 终端1启动turtlesim节点 ros2 run turtlesim turtlesim_node # 终端2启动键盘控制节点 ros2 run turtlesim turtle_teleop_key2.2 探索旋转Action小海龟示例提供了一个/turtle1/rotate_absolute动作让我们通过命令行工具来探索它# 列出所有可用动作 ros2 action list # 查看动作详细信息 ros2 action info /turtle1/rotate_absolute # 发送旋转目标180度 ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute {theta: 3.14} # 带反馈的旋转命令 ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute {theta: 1.57} --feedback2.3 动作执行过程分析当发送旋转命令时小海龟会经历以下状态变化ACCEPTED动作被服务器接受EXECUTING开始执行旋转SUCCEEDED旋转完成如果在执行过程中按下键盘的F键动作会进入CANCELED状态。这种状态机管理是Action的核心价值之一。3. 自定义圆周运动Action开发3.1 定义Action接口创建MoveCircle.action文件定义我们的圆周运动接口# Goal定义 bool enable # 启动圆周运动的指令 --- # Result定义 bool finish # 是否成功完成 --- # Feedback定义 int32 state # 当前角度位置(0-359)3.2 配置构建系统在CMakeLists.txt中添加Action定义find_package(rosidl_default_generators REQUIRED) rosidl_generate_interfaces(${PROJECT_NAME} action/MoveCircle.action )3.3 实现Action服务器以下是Python实现的Action服务器核心代码import time import rclpy from rclpy.action import ActionServer from rclpy.node import Node from learning_interface.action import MoveCircle class MoveCircleServer(Node): def __init__(self): super().__init__(move_circle_server) self._action_server ActionServer( self, MoveCircle, move_circle, self.execute_callback) async def execute_callback(self, goal_handle): self.get_logger().info(开始圆周运动...) feedback MoveCircle.Feedback() for angle in range(0, 360, 10): if goal_handle.is_cancel_requested: goal_handle.canceled() self.get_logger().info(动作被取消) return MoveCircle.Result() feedback.state angle goal_handle.publish_feedback(feedback) time.sleep(0.1) goal_handle.succeed() result MoveCircle.Result() result.finish True return result3.4 实现Action客户端对应的Python客户端实现import rclpy from rclpy.action import ActionClient from rclpy.node import Node from learning_interface.action import MoveCircle class MoveCircleClient(Node): def __init__(self): super().__init__(move_circle_client) self._action_client ActionClient(self, MoveCircle, move_circle) def send_goal(self): goal_msg MoveCircle.Goal() goal_msg.enable True self._action_client.wait_for_server() self._send_goal_future self._action_client.send_goal_async( goal_msg, feedback_callbackself.feedback_callback) self._send_goal_future.add_done_callback(self.goal_response_callback) def goal_response_callback(self, future): goal_handle future.result() if not goal_handle.accepted: self.get_logger().info(目标被拒绝) return self.get_logger().info(目标已接受) self._get_result_future goal_handle.get_result_async() self._get_result_future.add_done_callback(self.get_result_callback) def get_result_callback(self, future): result future.result().result self.get_logger().info(f结果: {result.finish}) def feedback_callback(self, feedback_msg): feedback feedback_msg.feedback self.get_logger().info(f当前角度: {feedback.state}°)4. 高级应用与调试技巧4.1 动作取消实现在实际应用中动作取消是常见需求。以下是实现优雅取消的要点服务器端定期检查is_cancel_requested客户端调用cancel_goal_async()正确处理取消后的资源释放4.2 动作超时处理为动作添加超时限制可以防止无限等待# 客户端设置超时 self._action_client.wait_for_server(timeout_sec5.0) # 服务器端执行超时 start_time self.get_clock().now() while not finished: if (self.get_clock().now() - start_time).nanoseconds 1e9 * timeout: return None4.3 多目标优先级管理当多个客户端发送动作目标时服务器需要实现优先级策略队列策略先进先出(FIFO)抢占策略新目标中断当前执行优先级策略根据目标属性决定执行顺序4.4 动作可视化调试使用rqt_action工具可以直观地监控动作状态ros2 run rqt_action rqt_action这个GUI工具允许查看所有可用动作发送动作目标监控反馈和结果取消正在执行的动作5. 实际项目集成指南5.1 工业机器人应用案例在工业机器人控制中Action可用于轨迹跟踪反馈当前执行进度装配操作允许中途调整质检流程支持人工干预5.2 移动机器人导航实现典型的导航Action接口设计# Goal geometry_msgs/Pose target_pose --- # Result bool success float32 final_distance --- # Feedback int32 current_step float32 distance_to_goal5.3 性能优化建议反馈频率根据需求平衡实时性和性能消息大小保持反馈消息精简并发处理使用异步API避免阻塞5.4 常见问题排查问题1动作服务器不响应检查动作名称是否匹配确认服务器节点已正确启动使用ros2 action list验证问题2反馈延迟严重检查网络延迟降低反馈频率优化处理逻辑问题3取消请求无效确认服务器定期检查取消标志检查取消消息是否正常发送验证动作状态机实现在开发真实机器人项目时我发现动作的反馈机制特别适合需要人机交互的场景。比如在一次机械臂演示中我们通过Action实现了操作员可以随时调整臂展长度的功能这比传统的服务调用方式要直观和灵活得多。

更多文章