• action通信机制


    service通信不能很好的完成任务时候, actionlib则可以比较适合实现长时间的通信过
    程, actionlib通信过程可以随时被查看过程进度, 也可以终止请求, 这样的一个特性, 使得它
    在一些特别的机制中拥有很高的效率。

    1、通信原理

    Action的工作原理是client-server模式, 也是一个双向的通信模式。 通信双方在ROS
    Action Protocol下通过消息进行数据的交流通信。 clientserver为用户提供一个简单的
    API来请求目标( 在客户端) 或通过函数调用和回调来执行目标( 在服务器端) 。
    工作模式的结构示意图如下:

    我们可以看到,客户端会向服务器发送目标指令和取消动作指令,而服务器则可以给客户端发送
    实时的状态信息,结果信息,反馈信息等等,从而完成了service没法做到的部分.

    2、Action 规范

    利用动作库进行请求响应, 动作的内容格式应包含三个部分, 目标、 反馈、 结果。
    目标
    机器人执行一个动作, 应该有明确的移动目标信息, 包括一些参数的设定, 方向、 角度、 速
    度等等。 从而使机器人完成动作任务。
    反馈
    在动作进行的过程中, 应该有实时的状态信息反馈给服务器的实施者, 告诉实施者动作完成
    的状态, 可以使实施者作出准确的判断去修正命令。
    结果
    当运动完成时, 动作服务器把本次运动的结果数据发送给客户端, 使客户端得到本次动作的
    全部信息, 例如可能包含机器人的运动时长, 最终姿势等等

    #include <ros/ros.h>
    #include <actionlib/server/simple_action_server.h>
    #include "learning_communication/DoDishesAction.h"
    
    typedef actionlib::SimpleActionServer<learning_communication::DoDishesAction> Server;
    
    // 收到action的goal后调用该回调函数
    void execute(const learning_communication::DoDishesGoalConstPtr& goal, Server* as)
    {
        ros::Rate r(1);
        learning_communication::DoDishesFeedback feedback;
    
        ROS_INFO("Dishwasher %d is working.", goal->dishwasher_id);
    
        // 假设洗盘子的进度,并且按照1hz的频率发布进度feedback
        for(int i=1; i<=10; i++)
        {
            feedback.percent_complete = i * 10;
            as->publishFeedback(feedback);
            r.sleep();
        }
    
        // 当action完成后,向客户端返回结果
        ROS_INFO("Dishwasher %d finish working.", goal->dishwasher_id);
        as->setSucceeded();
    }
    
    int main(int argc, char** argv)
    {
        ros::init(argc, argv, "do_dishes_server");
        ros::NodeHandle n;
    
        // 定义一个服务器
        Server server(n, "do_dishes", boost::bind(&execute, _1, &server), false);
        
        // 服务器开始运行
        server.start();
    
        ros::spin();
    
        return 0;
    }

    #include <actionlib/client/simple_action_client.h>
    #include "learning_communication/DoDishesAction.h"
    
    typedef actionlib::SimpleActionClient<learning_communication::DoDishesAction> Client;
    
    // 当action完成后会调用该回调函数一次
    void doneCb(const actionlib::SimpleClientGoalState& state,
            const learning_communication::DoDishesResultConstPtr& result)
    {
        ROS_INFO("Yay! The dishes are now clean");
        ros::shutdown();
    }
    
    // 当action激活后会调用该回调函数一次
    void activeCb()
    {
        ROS_INFO("Goal just went active");
    }
    
    // 收到feedback后调用该回调函数
    void feedbackCb(const learning_communication::DoDishesFeedbackConstPtr& feedback)
    {
        ROS_INFO(" percent_complete : %f ", feedback->percent_complete);
    }
    
    int main(int argc, char** argv)
    {
        ros::init(argc, argv, "do_dishes_client");
    
        // 定义一个客户端
        Client client("do_dishes", true);
    
        // 等待服务器端
        ROS_INFO("Waiting for action server to start.");
        client.waitForServer();
        ROS_INFO("Action server started, sending goal.");
    
        // 创建一个action的goal
        learning_communication::DoDishesGoal goal;
        goal.dishwasher_id = 1;
    
        // 发送action的goal给服务器端,并且设置回调函数
        client.sendGoal(goal,  &doneCb, &activeCb, &feedbackCb);
    
        ros::spin();
    
        return 0;
    }

  • 相关阅读:
    看了关于全职女性的文字,我想到了一些事情
    通过一个大型项目来学习分布式算法(6)
    IO模式——同步(堵塞、非堵塞)、异步
    湖南省第九届大学生计算机程序设计竞赛 高桥和低桥
    为什么我的ECSHOP出现报错改正确了还是没有反应?
    wxWidgets刚開始学习的人导引(2)——下载、安装wxWidgets
    1096. Consecutive Factors (20)
    POJ 2955 Brackets
    (转载)单调栈题目总结
    20140708郑州培训第二题Impossible Game
  • 原文地址:https://www.cnblogs.com/long5683/p/11644224.html
Copyright © 2020-2023  润新知