013Action的客户端节点(c++)

ROS 中 Action 的客户端节点(C++ 实现)

客户端(Client)是主动发起任务的部分,流程如下:

  1. 连接服务端
  2. 发送任务目标(Goal)
  3. 接收反馈(Feedback)
  4. 等待并获取最终结果(Result)
  5. 可选择取消任务(Cancel)

使用 actionlib 提供的 SimpleActionClient 模板类。


基本结构

引入头文件

#include 
#include 

定义类型别名

typedef actionlib::SimpleActionClient<your_package::DoDishesAction> Client;

通信流程图

Client --> 发送 Goal ---------> Server
       <--   接收 Feedback <----
       <--   接收 Result   <----

完整 C++ 客户端节点示例

假设你已经有一个 .action 文件如下:

# DoDishes.action
int32 dish_count
---
bool success
string result_message
---
float32 progress

那么客户端代码如下:

#include 
#include 
#include 

typedef actionlib::SimpleActionClient<your_package::DoDishesAction> Client;

void doneCb(const actionlib::SimpleClientGoalState& state,
            const your_package::DoDishesResultConstPtr& result) {
  ROS_INFO("任务完成,状态:%s", state.toString().c_str());
  ROS_INFO("成功:%d,结果:%s", result->success, result->result_message.c_str());
}

void activeCb() {
  ROS_INFO("目标已发送,服务器开始处理任务...");
}

void feedbackCb(const your_package::DoDishesFeedbackConstPtr& feedback) {
  ROS_INFO("收到反馈:进度 = %.2f%%", feedback->progress * 100);
}

int main(int argc, char** argv) {
  ros::init(argc, argv, "do_dishes_client");

  // 创建客户端对象,true 表示会自动连接服务器
  Client ac("do_dishes", true);

  ROS_INFO("等待 Action Server 启动...");
  ac.waitForServer();
  ROS_INFO("Action Server 已连接!");

  // 构造并发送目标
  your_package::DoDishesGoal goal;
  goal.dish_count = 5;

  ac.sendGoal(goal, &doneCb, &activeCb, &feedbackCb);

  // 可选:等待任务结果(阻塞式)
  bool finished_before_timeout = ac.waitForResult(ros::Duration(30.0));

  if (finished_before_timeout) {
    actionlib::SimpleClientGoalState state = ac.getState();
    ROS_INFO("最终状态:%s", state.toString().c_str());
  } else {
    ROS_WARN("任务超时,主动取消!");
    ac.cancelGoal();
  }

  return 0;
}

超详细回调函数说明

doneCb:任务完成后调用

void doneCb(const actionlib::SimpleClientGoalState& state,
            const your_package::DoDishesResultConstPtr& result);
  • 显示任务最终状态
  • 读取结果数据 result->successresult->result_message

activeCb:服务器开始执行任务时调用

void activeCb();
  • 用于确认目标已被服务器接收
  • 通常用于打印状态或记录日志

feedbackCb:服务器执行中反馈调用

void feedbackCb(const your_package::DoDishesFeedbackConstPtr& feedback);
  • 实时获取执行进度,如 feedback->progress

⏳ 超时与取消机制

等待结果 + 设置超时:

ac.waitForResult(ros::Duration(30.0));

超时后取消任务:

ac.cancelGoal();

CMakeLists.txt 配置

add_executable(do_dishes_client src/do_dishes_client.cpp)
target_link_libraries(do_dishes_client ${catkin_LIBRARIES})
add_dependencies(do_dishes_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

总结:Action Client C++ 的关键函数

函数 作用
sendGoal(goal) 发送目标任务
waitForResult(timeout) 等待任务结果
getState() 获取最终状态
cancelGoal() 主动取消任务
register callbacks 设置反馈/完成回调

数学表达举例

设目标洗 n n n 个碗,已洗第 i i i 个,进度反馈为:

progress = i n \text{progress} = \frac{i}{n} progress=ni

客户端通过 feedbackCb 实时接收该值。


调试技巧

  • rqt_graph 查看客户端与服务端连接情况
  • rosrun rqt_action rqt_action 实时监控任务
  • 使用 rostopic echo /do_dishes/feedback 查看进度

进阶建议

  • 使用 SimpleActionClient 之外的 ActionClient 自定义状态机
  • 支持多个客户端并发发送任务
  • 结合动态参数配置任务内容

你可能感兴趣的:(ROS,c++,ROS,机器人)