ROS2 动作通信 Action 学习实战教程
提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档文章目录目录前言一、Action 动作通信是什么解决了什么问题二、使用步骤1.应用场景2.Action 核心优势3. Action 三层底层结构二、整体实战流程总览三、第一部分自定义 Action 消息接口 base_interfaces_demo1.创建.action 动作消息文件2.配置 package.xml3.配置 CMakeLists.txt4.配置 setup.pyPython 接口包必配否则编译产物缺失5.编译 验证自定义接口四、第二部分C 动作通信 cpp03_action 服务端 客户端开发1.创建 C 动作功能包2.动作服务端 demo01_action_server.cpp3.动作客户端 demo02_action_client.cpp4.cpp03_action 编译配置 CMakeLists.txt5.package.xml 依赖校验五、编译与终端运行完整测试1.分步编译规避 Python 接口包与 C 包并行编译报错2.双终端运行程序六、踩坑避坑总结七、Action、Topic、Service 三者核心对比总结前言提示这里可以添加本文要记录的大概内容本文章仅个人学习过程见解记录在ROS2机器人开发中话题通信Topic适合周期性持续数据传输服务通信Service适用于单次问答式交互但在机器人导航、机械臂运动、批量运算、长时间任务执行等场景下传统通信方式存在明显短板服务通信无法反馈任务执行进度、不支持中途取消话题通信没有请求应答机制无法完成带结果的任务交互。为此ROS2 提供了动作通信Action机制它整合了服务通信的请求应答特性与话题通信的持续发布能力拥有目标请求Goal、实时进度反馈Feedback、最终结果返回Result三段式交互结构同时支持任务取消是 ROS2 中处理长耗时任务的核心通信方案。提示以下是本篇文章正文内容下面案例可供参考一、Action 动作通信是什么解决了什么问题示例pandas 是基于NumPy 的一种工具该工具是为了解决数据分析任务而创建的。二、使用步骤1.应用场景机器人导航、长时间运算、机械臂运动这类耗时任务如果只用普通 Service 服务通信会有致命缺陷 服务通信是单次请求 - 单次响应任务执行全程客户端收不到任何进度反馈界面卡死且中途无法取消任务用户体验极差。2.Action 核心优势Action 动作通信基于服务 话题封装分为三段式交互Goal目标请求客户端向服务端下发任务例如计算 1~N 累加N10Feedback实时连续反馈任务执行中服务端持续推送进度0.1、0.2 … 1.0Result最终结果任务完成后返回最终运算结果 额外支持任务中途取消完美适配长时间执行的业务场景。3. Action 三层底层结构Goal/Result基于 Service 服务通信封装Feedback基于 Topic 话题通信封装 一套通信机制同时兼具服务的请求应答、话题的持续消息推送能力。二、整体实战流程总览本次案例需求客户端传入整数 N服务端累加 1~N每计算一步推送进度结束返回总和。 完整分为两大模块自定义 Action 消息接口包base_interfaces_demo定义.action消息载体C 动作通信功能包cpp03_action动作服务端 客户端业务代码 完整执行链路自定义接口→编写服务 / 客户端源码→配置编译文件→编译→终端运行调试。三、第一部分自定义 Action 消息接口 base_interfaces_demo1.创建.action 动作消息文件在src/base_interfaces_demo下新建action文件夹创建Progress.actionaction 固定三段分隔格式---分别对应 Goal、Result、Feedbackplaintext# Goal 客户端请求 int64 num --- # Result 最终返回结果 int64 sum --- # Feedback 实时进度反馈 float64 progress含义客户端传入 num服务端累加 1~num进度 0~1 浮点反馈完成返回总和 sum。2.配置 package.xml在依赖区添加动作通信编译依赖xml!-- 动作接口编译工具依赖 -- buildtool_dependrosidl_default_generators/buildtool_depend !-- action动作基础消息依赖 -- dependaction_msgs/dependexport标签内添加接口分组标识xmlexport build_typeament_python/build_type member_of_grouprosidl_interface_packages/member_of_group /export3.配置 CMakeLists.txt接口包必须通过rosidl_generate_interfaces将 action 文件编译为 C/Python 可用代码cmakecmake_minimum_required(VERSION 3.8) project(base_interfaces_demo) find_package(rosidl_default_generators REQUIRED) # 注册自定义action文件 rosidl_generate_interfaces(${PROJECT_NAME} action/Progress.action ) # 导出依赖给其他功能包调用 ament_export_dependencies(rosidl_default_runtime) ament_package()4.配置 setup.pyPython 接口包必配否则编译产物缺失文件顶部导入模块pythonimport os from glob import glob2.修改 data_files注册 action 文件夹保证编译后安装接口文件pythondata_files[ (share/ament_index/resource_index/packages, [resource/ package_name]), (share/ package_name, [package.xml]), (os.path.join(share, package_name, action), glob(action/*.action)), ],5.编译 验证自定义接口1.清空缓存编译接口包bashcd ~/Desktop/ros2_wes rm -rf build install log colcon build --packages-select base_interfaces_demo2.刷新环境变量校验接口是否生成成功bashsource install/setup.bash ros2 interface show base_interfaces_demo/action/Progress终端完整打印 Progress.action 三段内容即代表接口创建成功。四、第二部分C 动作通信 cpp03_action 服务端 客户端开发1.创建 C 动作功能包bashros2 pkg create cpp03_action --build-type ament_cmake --dependencies rclcpp rclcpp_action base_interfaces_demo自动生成基础依赖rclcpp (C 核心)、rclcpp_action (动作通信库)、自定义接口包。2.动作服务端 demo01_action_server.cpp路径cpp03_action/src/demo01_action_server.cpp功能逻辑接收客户端目标数字循环累加每轮推送进度结束返回总和支持取消任务。 核心头文件引入cpp#include rclcpp/rclcpp.hpp #include rclcpp_action/rclcpp_action.hpp #include base_interfaces_demo/action/progress.hpp核心流程继承 rclcpp::Node 创建节点创建 Action 服务端绑定目标处理、取消任务、生成反馈回调收到目标 num 后循环累加计算进度并通过 feedback 持续推送运算完成封装 Result 返回客户端3.动作客户端 demo02_action_client.cpp路径cpp03_action/src/demo02_action_client.cpp功能逻辑下发目标请求实时打印服务端推送的进度接收最终求和结果。 核心头文件与别名简化cpp#include rclcpp/rclcpp.hpp #include rclcpp_action/rclcpp_action.hpp #include base_interfaces_demo/action/progress.hpp using base_interfaces_demo::action::Progress; using GoalHandleProgress rclcpp_action::ClientGoalHandleProgress;核心流程创建 Action 客户端封装 Goal 请求数据传入累加上限 N10绑定三个回调目标接收回调、实时进度反馈回调、最终结果回调阻塞等待任务完成打印全部进度与最终求和结果。4.cpp03_action 编译配置 CMakeLists.txtcmakecmake_minimum_required(VERSION 3.8) project(cpp03_action) # 查找全部依赖包 find_package(rclcpp REQUIRED) find_package(rclcpp_action REQUIRED) find_package(base_interfaces_demo REQUIRED) # 编译动作服务端可执行文件 add_executable(demo01_action_server src/demo01_action_server.cpp) ament_target_dependencies( demo01_action_server rclcpp rclcpp_action base_interfaces_demo ) # 编译动作客户端可执行文件 add_executable(demo02_action_client src/demo02_action_client.cpp) ament_target_dependencies( demo02_action_client rclcpp rclcpp_action base_interfaces_demo ) # 安装程序到install目录ros2 run才能识别 install(TARGETS demo01_action_server demo02_action_client DESTINATION lib/${PROJECT_NAME} ) ament_package()5.package.xml 依赖校验创建包时已自动生成依赖缺失则手动补充xmldependrclcpp/depend dependrclcpp_action/depend dependbase_interfaces_demo/depend五、编译与终端运行完整测试1.分步编译规避 Python 接口包与 C 包并行编译报错1.1清空全部缓存bashcd ~/Desktop/ros2_wes rm -rf build install log1.2先编译自定义接口包生成接口配置文件bashcolcon build --packages-select base_interfaces_demo source install/setup.bash1.3再编译 C 动作包bashcolcon build --packages-select cpp03_action source install/setup.bash2.双终端运行程序终端 1启动动作服务端bashsource install/setup.bash ros2 run cpp03_action demo01_action_server日志输出等待客户端请求收到数字后打印每一步进度、任务完成提示。终端 2启动动作客户端bashsource install/setup.bash ros2 run cpp03_action demo02_action_client日志输出发送请求、打印 20%/30%…100% 实时进度最后输出 1~N 累加总和。六、踩坑避坑总结坑 1C 包 find_package (base_interfaces_demo) 找不到配置文件原因base_interfaces_demo是 ament_python 类型接口包不会生成 C 识别的xxxConfig.cmake。 解决方案分步编译中间刷新环境变量先单独编译接口包执行 source 再编译 C 包禁止一次性同时编译两个包。坑 2编译提示 ament_target_dependencies 找不到 base_interfaces_demo原因CMakeLists.txt 中删除了find_package(base_interfaces_demo REQUIRED)语法不匹配。 解决方案保留find_package全部依赖查找语句CMake 规则依赖写入 ament_target_dependencies 前必须先 find_package 加载。坑 3ros2 interface show 找不到自定义 Action原因base_interfaces_demo 的 setup.py 未注册 action 文件夹编译后接口文件未安装。 解决方案setup.py 补充 glob 导入与 action 目录 data_files 注册。坑 4运行 ros2 run 提示 Package not found原因编译失败、未执行source install/setup.bash刷新环境变量。 解决方案编译无报错后每个新开终端都要执行 source 加载工作空间环境。七、Action、Topic、Service 三者核心对比通信类型适用场景核心特性Topic 话题通信持续周期性数据传感器、图像单向发布订阅无应答无结果反馈Service 服务通信瞬时单次请求开关、单次查询一问一答执行中无进度反馈不可取消Action 动作通信长时间耗时任务导航、批量运算目标下发 实时进度反馈 最终结果支持中途取消总结Action 是 ROS2 专为长耗时任务设计的通信模型三段式 Goal-Feedback-Result 架构弥补了服务通信无进度、不可取消的短板开发分两步先独立封装自定义消息接口包再编写业务功能包调用接口Python 类型接口包与 C 业务包存在编译兼容问题必须分步编译并刷新环境完整流程覆盖消息定义、源码编写、CMake/xml 配置、编译、运行全链路可直接复用至机器人导航、运动控制等实际项目。