ROS学习之路与——第七章:Action通信

一、action通信

1.概念

应用于机器人导航过程,在行进的过程中连续反馈当前机器人的状态信息。当导航终止时,再返回最终的执行结果。

2.功能包

提供有actionlib功能包集

3.action图解:

 二、自定义action文件

1.创建action文件

(1)功能包有roscpp,rospy,std_msgs,actionlib,actionlib_msgs

(2)添加.action文件

2.编辑配置文件

(1)解除第66行注释,并改正.action文件

(2)解除第73行注释(生成消息时需要的功能包)

(3)解除第111行注释(执行时的依赖)

3.编译生成中间文件

三、编写C++文件

1.修改c_cpp_properies.json文件

(1)在集成终端中打开devel下的include文件,输入pwd获取该文件的路径

(2)添加到c_cpp_properies.json文件中

 

2.编写action服务端

#include "ros/ros.h"
#include "actionlib/server/simple_action_server.h"//创建服务端对象需要用到的头文件
#include "action_work/Action_infoAction.h"

/*
    1.包含头文件
    2.初始化ROS节点
    3.创建NodeHandle
    4.创建action服务对象
    5.请求处理(回调函数)
        a.解析客户端提交的目标值
        b.服务端产生连续反馈
        c.最终结果响应
    6.spin()回旋
*/
//服务对象宏定义为Server
typedef actionlib::SimpleActionServer<action_work::Action_infoAction> Server;

void Check_Callback(const action_work::Action_infoGoalConstPtr &goal,Server* server)
{
    int goal_num= goal -> num;
    ROS_INFO("零件数为: %d",goal_num);
    ros::Rate rate(1);  //1Hz,一秒检查一次
    int finished=0;
    //响应的过程
    for(int i=1;i<=goal_num;i++)
    {
        finished ++;
        rate.sleep();
        //产生连续反馈
        //void publishFeedback(const action_work::Action_infoFeedback &feedback)
        action_work::Action_infoFeedback fb;
        ROS_INFO("检测%d个零件",i);
        fb.percent = (i / (double)goal_num) * 100;
        server->publishFeedback(fb);
    }
    //最终响应结果
    action_work::Action_infoResult checkresult;
    checkresult.result = finished;
    server->setSucceeded(checkresult);
}

int main(int argc, char *argv[])
{
    /* code */
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"check_server");
    ros::NodeHandle nh;
    //创建服务对象
    //actionlib::SimpleActionServer<action_work::Action_infoAction>;
    /*参数: (ros::NodeHandle n, 
            话题名称 std::string name, 
            回调函数 boost::function<void (const action_work::Action_infoGoalConstPtr &)> execute_callback, 
                (boost::bind用于绑定,包括绑定的函数,要传入的参数:_1表示回调函数的第一个参数)
            是否自动启动 bool auto_start)
    */
    Server server(nh,"check_parts",boost::bind(&Check_Callback,_1,&server),false);
    server.start();  //如果上方选择了false,那么需要手动调用该函数来启动服务
    ROS_INFO("服务端启动完毕!");
    ros::spin();
    return 0;
}

3.编写action客户端

#include "ros/ros.h"
#include "actionlib/client/simple_action_client.h"//创建客户端对象所需要的文件
#include "action_work/Action_infoAction.h"

/*
    1.包含头文件
    2.初始化ROS节点
    3.创建NodeHandle
    4.创建action客户端对象
    5.发送请求
        a.连接建立    --- 回调函数
        b.处理连续反馈 --- 回调函数
        c.处理最终响应 --- 回调函数
    6.spin()回旋
*/

//处理最终响应的回调函数:包括状态state和结果result两个参数
void done_cb(const actionlib::SimpleClientGoalState &state, const action_work::Action_infoResultConstPtr &result)
{
    if(state.state_ == state.SUCCEEDED)
    {
        ROS_INFO("检测完成");
    }
    else{
        ROS_INFO("检测失败");
    }
}

//处理连接建立的回调函数:
void active_cb() 
{
    ROS_INFO("客户端和服务端连接建立...");
}

//处理连续反馈的回调
void feedback_cb(const action_work::Action_infoFeedbackConstPtr &feedback)
{
    char symbol='%';
    ROS_INFO("当前进度为:%.1f%c", feedback->percent,symbol);
   
}


int main(int argc, char *argv[])
{
    /* code */
    setlocale(LC_ALL,"");
    ros::init(argc, argv ,"check_client");
    ros::NodeHandle nh;
    //创建客户端对象:<>内是功能包下的action文件
    actionlib::SimpleActionClient<action_work::Action_infoAction> client(nh,"check_parts");
    //发送请求
    //等待服务
    ROS_INFO("等待服务器启动...");
    client.waitForServer();
    /*
    void sendGoal(const action_work::Action_infoGoal &goal, 
                  处理最终响应 boost::function<void (const actionlib::SimpleClientGoalState &state, const action_work::Action_infoResultConstPtr &result)> done_cb, 
                  处理连接建立 boost::function<void ()> active_cb, 
                  处理连续反馈 boost::function<void (const action_work::Action_infoFeedbackConstPtr &feedback)> feedback_cb)
    开始根据参数来设置
    */
    action_work::Action_infoGoal goal;
    goal.num = 40;

    client.sendGoal(goal, &done_cb, &active_cb, &feedback_cb);

    ros::spin();
    return 0;
}

4.编辑CMakeList.txt

(1)第139行和第151行,更换文件名

(2)第149行,更换文件名

5.编译并执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值