[ROS] Action 通信,ActionClient 创建

[ROS] Action 通信,ActionClient 创建




1. Action Client 完整代码

//
// Created by jacob on 12/02/20.
//


#include <iostream>
#include <ros/ros.h>

#include <actionlib/client/action_client.h>
#include <demo_action_msgs/CountNumberAction.h>

typedef actionlib::ClientGoalHandle <demo_action_msgs::CountNumberAction> GoalHandle;
typedef const demo_action_msgs::CountNumberFeedbackConstPtr FeedbackConstPtr;
typedef actionlib::ActionClient <demo_action_msgs::CountNumberAction> ActionClient;


//typedef boost::function<void (GoalHandle)> TransitionCallback;
//typedef boost::function<void (GoalHandle, const FeedbackConstPtr &)> FeedbackCallback;
void TransitionCallback(GoalHandle handle) {
    ROS_INFO_STREAM("client: TransitionCallback");

    /*
    transition: 包含了 server端响应的各个阶段的状STATE
    两张类型的 state 1. ACTIVE, 2. DONE
    可以判断出来,当前server执行阶段的过程状态(Active,Done)
    */

    const actionlib::CommState &commState = handle.getCommState();
    if (commState == commState.ACTIVE) {
        ROS_INFO_STREAM("state active.");
    } else if (commState == commState.DONE) {
        ROS_INFO_STREAM("state done.");

        //可以判断出来,当前server执行完成后,结果的状态(Result state)
        const actionlib::TerminalState &state = handle.getTerminalState();
        if (state == state.SUCCEEDED) {
            // server干完活了
            ROS_INFO_STREAM("SUCCEEDED.");
        } else if(state == state.PREEMPTED) {
            // client取消了
            ROS_INFO_STREAM("PREEMPTED.");
        } else if(state == state.ABORTED) {
            // server中断操作
            ROS_INFO_STREAM("ABORTED.");
        } else if(state == state.REJECTED) {
            // server接收到的goal存在问题
            ROS_INFO_STREAM("REJECTED.");
        }
    }
}

void FeedbackCallback(GoalHandle handle, FeedbackConstPtr &feedback) {
    ROS_INFO_STREAM("client: FeedbackCallback" << feedback->percent);
}


int main(int argc, char **argv) {

    /* 1. 初始化节点 */
    std::string nodeName = "cpp_action_client_node";
    ros::init(argc, argv, nodeName);

    /* 2. 创建节点 */
    ros::NodeHandle node;

    // 需要在子线程中运行?
    ros::AsyncSpinner spinner(1);
    spinner.start();

    /* 3. 创建 action client)*/
    std::string actionName = "/hello/action";
    ActionClient client(node, actionName);

    // 2. 等待 sever 功能启动
    client.waitForActionServerToStart();

    // 创建 goal 消息并赋值
    demo_action_msgs::CountNumberGoal goal;
    goal.max = 100;
    goal.duration = 0.1;

    // client 向 server 发送 goal消息
    /*
     * 需要创建对象进行接收,不然被销毁
    GoalHandle sendGoal(const Goal & goal,
                        TransitionCallback transition_cb = TransitionCallback(),
                        FeedbackCallback feedback_cb = FeedbackCallback())
    */
    const actionlib::ActionClient<demo_action_msgs::CountNumberAction>::GoalHandle &clientGoalHandle = client.sendGoal(
            goal,
            boost::bind(TransitionCallback, _1),
            boost::bind(FeedbackCallback, _1, _2));


    /* 4. 阻塞进程, 获得数据 */
//    ros::spin();
    ros::waitForShutdown();     // 防止整个线程结束

    return 0;
}



2. 调试验证(与 Action Server 联调)(见 Action Server)


*. todo

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ROS2中引入了action通信机制,通过action通信可以实现更复杂和灵活的交互式任务处理,相比于ROS1中的service通信机制,action通信可以处理需要长时间运行、中间结果反馈以及取消请求的任务。 实现一个ROS2 action通信的demo可以遵循以下步骤: 1. 创建一个名为my_package的ROS2 package,并在该package中创建一个名为my_actionaction文件,用于定义action的目标和反馈消息。 2. 在package的CMakeLists.txt文件中添加对action接口的依赖,确保action文件正确编译。 3. 编写一个名为action_server.cpp的节点程序作为action服务器,用于接收action请求并生成结果。 4. 在action_server.cpp中,包含自动生成的action接口头文件,并在main函数中创建一个相应的action服务器。 5. 在action服务器的回调函数中处理action请求,并根据需要更新并发送反馈消息。 6. 编写一个名为action_client.cpp的节点程序作为action客户端,用于向action服务器发送请求并获取结果。 7. 在action_client.cpp中,包含自动生成的action接口头文件,并在main函数中创建一个相应的action客户端。 8. 在action客户端的回调函数中发送action请求,并根据需要处理和显示从action服务器接收到的反馈消息和结果。 9. 使用colcon编译并运行action服务器和action客户端节点,观察是否可以成功进行action通信,并获取到相应的反馈和结果。 通过实现这个简单的demo,可以理解和体验ROS2中action通信的使用方法和优势,为自己更复杂的机器人任务处理和交互设计提供参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值