为什么需要 Action 通信?

回顾 Topic 与 Service 的不足

  • 话题(Topic)

    • 单向、持续、异步广播通信;
    • 适合传感器高频持续发布数据(GPS、雷达、相机);
    • 无反馈、不可取消、无法确认执行结果;
    • 复杂控制任务需要多 Topic,结构混乱。
  • 服务(Service)

    • 同步请求 - 响应,一次连接一次通信;
    • 有最终执行结果反馈;
    • 缺点:执行过程无进度反馈、不可中途取消、耗时任务会阻塞等待,无法满足长时任务。

典型长时任务需求(以机器人导航 / 机械臂控制为例)

  • 任务是延时耗时操作,不是立刻完成;
  • 需要实时进度反馈(剩余距离、执行百分比);
  • 需要最终结果通知
  • 需要中途取消任务能力;
  • 属于异步请求 - 过程反馈 - 最终结果模式。

→ 以上需求 Topic 和 Service 都无法满足,因此需要 Action 通信

一、Action 通信概述

1. 定义

Action 是 ROS 中用于长时、异步、可中断、带连续反馈的通信机制,基于 actionlib 功能包实现。

2. 核心特点

  • 客户端发送请求(Goal);
  • 服务端执行任务,持续反馈进度(Feedback)
  • 任务结束返回最终结果(Result)
  • 客户端可主动取消任务(Cancel)
  • 全程可感知通信状态(State)。

3. 适用场景

  • 机器人导航到目标点
  • 机械臂运动到指定位姿
  • 长时间数据计算、图像处理
  • 需过程监控 + 可取消的任务

三种通信机制对比

特性

Topic(话题)

Service(服务)

Action(动作)

通信模式

异步,单向发布/订阅

同步,请求-响应

异步,带状态监控的请求-响应

数据流

单向流(发布者→订阅者)

一次请求,一次响应

一次请求,持续反馈,最终结果

反馈机制

❌ 无反馈

❌ 仅最终结果反馈

实时进度反馈

耗时任务支持

不适用(无反馈)

不适用(客户端会阻塞)

完美支持

任务取消

不适用

❌ 不支持

支持中途取消

适用场景

传感器数据流(激光雷达、相机等)

即时命令(开灯、计算等)

导航、机械臂控制等耗时任务


二、Action 通信的核心价值

1. 解决了什么问题?

  • Service 的痛点:执行耗时任务时,客户端“盲等”,无法感知进度,无法取消

  • Topic 的不足:虽然能持续传输,但缺乏请求-响应的控制结构

2. 核心特点

  • 异步执行:客户端发送目标后不被阻塞

  • 进度反馈:服务端定期向客户端报告执行进度

  • 可取消:客户端可随时取消正在执行的任务

  • 结果返回:任务完成后返回最终结果

三、Action 通信模型详解

1. 通信双方角色

  • Action Client:发送目标请求,接收反馈和结果

  • Action Server:接收目标,执行任务,发送反馈和结果

2. 五个核心消息类型

消息类型

方向

说明

Goal

Client → Server

客户端请求执行的任务目标

Cancel

Client → Server

客户端请求取消任务

Feedback

Server → Client

服务器定期发送的进度反馈

Result

Server → Client

任务完成后的最终结果

Status

Server → Client

通信状态(进行中、完成、取消等)

3. 通信流程

四、自定义 Action 消息规范

1. 文件结构

demo_action_msgs/
├── action/
│   └── CountNumber.action
├── CMakeLists.txt
├── package.xml

2. Action 消息文件格式

# Goal 部分:客户端发送的请求
int64 max
float64 duration
---
# Result 部分:服务器返回的最终结果
int64 count
---
# Feedback 部分:服务器返回的进度反馈
float64 percent

3. 关键配置步骤

  • package.xml​ 添加依赖:

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
  • CMakeLists.txt​ 关键配置:

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  actionlib_msgs
  message_generation
)

add_action_files(FILES CountNumber.action)

generate_messages(DEPENDENCIES actionlib_msgs std_msgs)

catkin_package(CATKIN_DEPENDS actionlib_msgs roscpp rospy)
  • 编译后生成的头文件

CountNumberAction.h- 完整 Action 定义

CountNumberGoal.h- Goal 部分

CountNumberResult.h- Result 部分

CountNumberFeedback.h- Feedback 部分

五、案例实现:累加和计算

1. 案例需求

  • Client:发送目标 N(整数)

  • Server:计算 1 到 N 的累加和

  • 耗时模拟:每次累加耗时 0.1 秒

  • 进度反馈:计算过程中实时反馈完成百分比

2. Action 定义(CountNumber.action)

# Goal
int64 max
---
# Result
int64 result
---
# Feedback
float64 percent_complete
string status_message

3. Server 端实现关键逻辑

// 接收到目标后的回调函数
void executeCallback(const demo_action_msgs::CountNumberGoalConstPtr& goal) {
    int64_t max = goal->max;
    int64_t sum = 0;
    
    // 执行计算并反馈进度
    for (int i = 1; i <= max; i++) {
        // 检查是否被取消
        if (action_server.isPreemptRequested() || !ros::ok()) {
            action_server.setPreempted();
            return;
        }
        
        sum += i;
        
        // 创建并发送反馈
        demo_action_msgs::CountNumberFeedback feedback;
        feedback.percent_complete = (float)i / max * 100.0;
        feedback.status_message = "Processing number " + std::to_string(i);
        action_server.publishFeedback(feedback);
        
        // 模拟耗时
        ros::Duration(0.1).sleep();
    }
    
    // 发送最终结果
    demo_action_msgs::CountNumberResult result;
    result.result = sum;
    action_server.setSucceeded(result);
}

4. Client 端实现关键逻辑

// 发送目标
demo_action_msgs::CountNumberGoal goal;
goal.max = 100;
action_client.sendGoal(goal, 
    &doneCallback,    // 完成回调
    &activeCallback,  // 激活回调
    &feedbackCallback // 反馈回调
);

// 反馈回调函数
void feedbackCallback(
    const demo_action_msgs::CountNumberFeedbackConstPtr& feedback) {
    ROS_INFO("Progress: %.2f%% - %s", 
        feedback->percent_complete, 
        feedback->status_message.c_str());
}

六、Action 通信的适用场景

✅ 推荐使用 Action 的场景:

  1. 机器人导航:发送目标点,获取实时位置反馈

  2. 机械臂控制:控制机械臂运动,获取实时位姿

  3. 长时间计算任务:需要进度反馈的复杂计算

  4. 需要可取消的任务:用户可能中途改变主意的操作

❌ 不适用 Action 的场景:

  1. 即时响应操作:如开关灯、读取传感器瞬时值(用 Service)

  2. 持续数据流:如相机图像、激光雷达数据(用 Topic)

七、核心要点总结

  1. Action = Service + Topic 的优势组合

    • 具有 Service 的请求-响应结构

    • 具有 Topic 的持续数据流特性

    • 增加了进度反馈和任务取消功能

  2. 三阶段通信模型

    • 请求阶段:Client 发送 Goal

    • 执行阶段:Server 发送 Feedback

    • 完成阶段:Server 发送 Result

  3. 消息定义的三个部分

    • Goal:客户端要做什么

    • Result:最终结果是什么

    • Feedback:执行进度如何

  4. 适用场景特征

    • 任务执行需要较长时间

    • 需要实时了解任务进度

    • 可能需要中途取消任务

    • 需要知道最终执行结果

Action 通信是 ROS 中处理复杂、耗时机器人任务的理想选择,它在保持响应性的同时提供了对任务执行过程的完全可视化和控制能力。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐