Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9418392
  • 博文数量: 1748
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 20070
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1748)

文章存档

2024年(24)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: 其他平台

2019-01-07 15:30:38

一般情况下,建议将消息文件msg和服务文件srv制作成一个只包含消息文件的单独的包,而不是将其包含在可执行节点中的目录中.

  1. 生成功能包
  2.     catkin_create_pkg ros_tutorials_action message_generation std_msgs actionlib_msgs actionlib roscpp
改写 CMakeLists.txt
    add_action_files(FILES Fibonacci.action)
    $ roscd ros_tutorials_action  → 移动到功能包目录
    $ mkdir action  → 在功能包中创建一个名为action的动作目录
    $ cd action → 移至创建的action目录
    $ gedit Fibonacci.action → 创建Fibonacci.action文件并修改内容
    
  1. #goal definition
  2. int32 order
  3. ---
  4. #result definition
  5. int32[] sequence
  6. ---
  7. #feedback
  8. int32[] sequence
动作的5种基本消息    
    
除目标(goal)、结果(result)和反馈(feedback)外,动作还用额外的消息:取消(cancel)和状态(status)
    取消
(cancel)消息使用actionlib_msgs/GoalID,它在动作运行时可以取消动作客户端和
单独节点上的动作的执行。
    状态(status)消息可以根据状态转换(如PENDING、
ACTIVE、PREEMPTED和SUCCEEDED 12 )检查当前动作的状态。


修改 CMakeLists.txt
    add_executable(action_server src/action_server.cpp) 

点击(此处)折叠或打开

  1. #include <ros/ros.h> // ROS的基本头文件
  2. #include <actionlib/server/simple_action_server.h> // 动作库头文件
  3. #include <ros_tutorials_action/FibonacciAction.h> // FibonacciAction动作头文件(生成后自动生成)
  4. class FibonacciAction
  5. {
  6. protected:
  7.     // 声明节点句柄
  8.     ros::NodeHandle nh_;
  9.     // 声明动作服务器
  10.     actionlib::SimpleActionServer<ros_tutorials_action::FibonacciAction> as_;
  11.     // 用作动作名称
  12.     std::string action_name_;
  13.     // 声明用于发布的反馈及结果
  14.     ros_tutorials_action::FibonacciFeedback feedback_;
  15.     ros_tutorials_action::FibonacciResult result_;
  16. public:
  17.     // 初始化动作服务器(节点句柄、动作名称、动作后台函数)
  18.     FibonacciAction(std::string name) :
  19.         as_(nh_, name, boost::bind(&FibonacciAction::executeCB, this, _1), false),
  20.         action_name_(name)
  21.     {
  22.         as_.start();
  23.     }
  24.     ~FibonacciAction(void)
        {
        }
        // 接收动作目标(goal)消息并执行指定动作(此处为斐波那契数列)的函数。
        void executeCB(const ros_tutorials_action::FibonacciGoalConstPtr &goal)
        {
            ros::Rate r(1); // 循环周期:1 Hz
            bool success = true; // 用作保存动作的成功或失败的变量
            // 斐波那契数列的初始化设置,也添加了反馈的第一个(0)和第二个消息(1)
            feedback_.sequence.clear();
            feedback_.sequence.push_back(0);
            feedback_.sequence.push_back(1);
            // 将动作名称、目标和斐波那契数列的两个初始值通知给用户
            ROS_INFO("%s: Executing, creating fibonacci sequence of order %i with seeds %i, %i", action_name_.c_str(), goal->order, feedback_.sequence[0], feedback_.sequence[1]);
            // 动作细节
            for(int i=1; i<=goal->order; i++)
            {
                // 从动作客户端得知动作取消
                if (as_.isPreemptRequested() || !ros::ok())
                {
                    ROS_INFO("%s: Preempted", action_name_.c_str());  // 通知动作取消
                    as_.setPreempted(); // 取消动作
                    success = false;  // 看作动作失败并保存到变量
                    break;
                }
                // 除非有动作取消或已达成动作目标
                // 将当前斐波纳契数字加上前一个数字的值保存到反馈值。
                feedback_.sequence.push_back(feedback_.sequence[i] + feedback_.sequence[i-1]);
                as_.publishFeedback(feedback_);  // 发布反馈。
                r.sleep();  // 按照上面定义的循环周期调用暂歇函数。
            }
            // 如果达到动作目标值,则将当前斐波那契数列作为结果值传输。
            if(success)
            {
                result_.sequence = feedback_.sequence;
                ROS_INFO("%s: Succeeded", action_name_.c_str());
                as_.setSucceeded(result_);
            }
        }
    };
    int main(int argc, char** argv)  // 节点主函数
    {
        ros::init(argc, argv, "action_server");  // 初始化节点名称
        FibonacciAction fibonacci("ros_tutorial_action");  // 声明Fibonacci (动作名: ros_tutorial_action)
        ros::spin(); // 等待动作目标
        return 0;
    }

#创建动作客户端节点
    #添加 CMakeLists.txt
    add_executable(action_client src/action_client.cpp)
  1. #include <ros/ros.h> // ROS的基本头文件
  2. #include <actionlib/client/simple_action_client.h> // 动作库头文件
  3. #include <actionlib/client/terminal_state.h> // 动作目标状态头文件
  4. #include <ros_tutorials_action/FibonacciAction.h> // FibonacciAction动作头文件(构建后自动生成)
  5. int main (int argc, char **argv) // 节点主函数
  6. {
  7.     ros::init(argc, argv, "action_client"); // 初始化节点名称
  8.     // 声明动作客户端(动作名称:ros_tutorial_action)
  9.     actionlib::SimpleActionClient<ros_tutorials_action::FibonacciAction> ac("ros_tutorial_action",true);
  10.     ROS_INFO("Waiting for action server to start.");
  11.     ac.waitForServer(); // 等待动作服务器启动
  12.     ROS_INFO("Action server started, sending goal.");
  13.     ros_tutorials_action::FibonacciGoal goal; // 声明动作目标
  14.     goal.order = 20; // 指定动作目标(进行20次斐波那契运算)
  15.     ac.sendGoal(goal); // 发送动作目标
  16.     // 设置动作完成时间限制(这里设置为30秒)
  17.     bool finished_before_timeout = ac.waitForResult(ros::Duration(30.0));
  18.     // 在动作完成时限内收到动作结果值时
  19.     if (finished_before_timeout)
  20.     {
  21.         // 获取动作目标状态值并将其显示在屏幕上
  22.         actionlib::SimpleClientGoalState state = ac.getState();
  23.         ROS_INFO("Action finished: %s",state.toString().c_str());
  24.     }
  25.     else
  26.         ROS_INFO("Action did not finish before the time out."); // 超过了动作完成时限的情况
  27.     //exit
  28.     return 0;
  29. }
#cd ~/catkin_ws && catkin_make → 转到catkin目录并运行catkin构建

#运行
    roscore
    rosrun ros_tutorials_action action_server
    rosrun ros_tutorials_action action_client
阅读(1454) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~