在ROS actionlib学习(一)中的例子展示了actionlib最基本的用法,下面我们看一个稍微实际一点的例子,用actionlib计算斐波那契数列,并发布反馈(feedback)和结果(result)。斐波那契数列指的是这样一个数列:

  1. 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233377610987159725844181676510946177112865746368........

  这个数列从第3项开始,每一项都等于前两项之和。

  首先在action文件中定义goal、result、feedback,其中goal是斐波那契数列的阶数,result为最终生成的数列,feedback为当前一步的中间结果(也是一个数列)。

  1. #goal definition
  2. int32 order
  3. ---
  4. #result definition
  5. int32[] sequence
  6. ---
  7. #feedback
  8. int32[] sequence

  然后按照教程SimpleActionServer(ExecuteCallbackMethod)中所述的步骤,修改CMakeLists.txt以及package.xml文件,编译成功后会生成相应的消息文件以及头文件。

  1. $ cd ../.. # Go back to the top level of your catkin workspace
  2. $ catkin_make
  3. $ ls devel/share/actionlib_tutorials/msg/
  4. FibonacciActionFeedback.msg FibonacciAction.msg FibonacciFeedback.msg
  5. FibonacciResult.msg FibonacciActionGoal.msg FibonacciActionResult.msg FibonacciGoal.msg
  6. $ ls devel/include/actionlib_tutorials/
  7. FibonacciActionFeedback.h FibonacciAction.h FibonacciFeedback.h FibonacciResult.h
  8. FibonacciActionGoal.h FibonacciActionResult.h FibonacciGoal.h

  下面编写服务端程序,用于处理客户端发送的请求。

  1. #include <ros/ros.h>
  2. #include <actionlib/server/simple_action_server.h>
  3. #include <actionlib_tutorials/FibonacciAction.h>
  4.  
  5. class FibonacciAction
  6. {
  7. protected:
  8.  
  9. ros::NodeHandle nh_;
  10. actionlib::SimpleActionServer<actionlib_tutorials::FibonacciAction> as_; // NodeHandle instance must be created before this line. Otherwise strange error occurs.
  11. std::string action_name_;
  12. // create messages that are used to published feedback/result
  13. actionlib_tutorials::FibonacciFeedback feedback_;
  14. actionlib_tutorials::FibonacciResult result_;
  15.  
  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(); // Explicitly start the action server
  23. }
  24.  
  25. ~FibonacciAction(void)
  26. {
  27. }
  28.  
  29. void executeCB(const actionlib_tutorials::FibonacciGoalConstPtr &goal)
  30. {
  31. // helper variables
  32. ros::Rate r();
  33. bool success = true;
  34.  
  35. // push_back the seeds for the fibonacci sequence
  36. feedback_.sequence.clear();
  37. feedback_.sequence.push_back();
  38. feedback_.sequence.push_back();
  39.  
  40. // publish info to the console for the user
  41. ROS_INFO("%s: Executing, creating fibonacci sequence of order %i with seeds %i, %i", action_name_.c_str(), goal->order, feedback_.sequence[], feedback_.sequence[]);
  42.  
  43. // start executing the action
  44. for(int i=; i<=goal->order; i++)
  45. {
  46. // check that preempt has not been requested by the client
  47. if (as_.isPreemptRequested() || !ros::ok())
  48. {
  49. ROS_INFO("%s: Preempted", action_name_.c_str());
  50. // set the action state to preempted
  51. as_.setPreempted(); // signals that the action has been preempted by user request
  52. success = false;
  53. break;
  54. }
  55. feedback_.sequence.push_back(feedback_.sequence[i] + feedback_.sequence[i-]);
  56. // publish the feedback
  57. as_.publishFeedback(feedback_);
  58. // this sleep is not necessary, the sequence is computed at 1 Hz for demonstration purposes
  59. r.sleep();
  60. }
  61.  
  62. if(success)
  63. {
  64. result_.sequence = feedback_.sequence;
  65. ROS_INFO("%s: Succeeded", action_name_.c_str());
  66. // set the action state to succeeded
  67. as_.setSucceeded(result_);
  68. }
  69. }
  70.  
  71. };
  72.  
  73. int main(int argc, char** argv)
  74. {
  75. ros::init(argc, argv, "fibonacci");
  76.  
  77. FibonacciAction fibonacci("fibonacci");
  78. ros::spin();
  79.  
  80. return ;
  81. }

  客户端程序用于发送计算请求,服务器收到请求后会生成20阶的斐波那契数列。

  1. #include <ros/ros.h>
  2. #include <actionlib/client/simple_action_client.h>
  3. #include <actionlib/client/terminal_state.h>
  4. #include <actionlib_tutorials/FibonacciAction.h>
  5.  
  6. int main (int argc, char **argv)
  7. {
  8. ros::init(argc, argv, "test_fibonacci");
  9. // the action client is constructed with the server name and the auto spin option set to true.
  10. actionlib::SimpleActionClient<actionlib_tutorials::FibonacciAction> ac("fibonacci", true); //The action client is templated on the action definition, specifying what message types to communicate to the action server with
  11.  
  12. ROS_INFO("Waiting for action server to start.");
  13. // wait for the action server to start (Since the action server may not be up and running, the action client will wait for the action server to start before continuing)
  14. ac.waitForServer(); //will wait for infinite time
  15.  
  16. ROS_INFO("Action server started, sending goal.");
  17. // send a goal to the action
  18. actionlib_tutorials::FibonacciGoal goal;
  19. goal.order = ;
  20. ac.sendGoal(goal); // the goal value is set and sent to the action serve
  21.  
  22. //wait for the action to return
  23. bool finished_before_timeout = ac.waitForResult(ros::Duration(30.0)); // The timeout on the wait is set to 30 seconds, this means after 30 seconds the function will return with false if the goal has not finished.
  24.  
  25. if (finished_before_timeout)
  26. {
  27. actionlib::SimpleClientGoalState state = ac.getState();
  28. ROS_INFO("Action finished: %s",state.toString().c_str());
  29. }
  30. else
  31. ROS_INFO("Action did not finish before the time out.");
  32.  
  33. //exit
  34. return ;
  35. }

  修改CMakeLists.txt后使用catkin_make编译上面两个程序。运行roscore开启ROS主节点,然后在两个新终端中分别输入下面命令分别运行server和client:

  1. rosrun actionlib_tutorials fibonacci_server
  2.  
  3. rosrun actionlib_tutorials fibonacci_client

  可以通过 rostopic echo /fibonacci/feedback 和 rostopic echo /fibonacci/result 命令查看斐波那契数列计算的反馈和结果:

  最终的计算结果result如下:

  1. ---
  2. header:
  3. seq: 1
  4. stamp: 1250813759950015000
  5. frame_id:
  6. status:
  7. goal_id:
  8. stamp: 1250813739949752000
  9. id: 1250813739949752000
  10. status: 3
  11. text:
  12. result:
  13. sequence: (0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946)

  在一个新终端中输入下面命令,运行另一个客户端节点(重命名为client2)。如果在原fibonacci_client节点的请求还没完成时就运行client2,那么服务将会被client2抢占。

  1. rosrun actionlib_tutorials fibonacci_client __name:=client2

  效果如下图所示,如果前一个client发送的请求还没计算完成,新的goal就到达,server会重新开始计算数列:

  SimpleActionServer在ActionServer类上实现了single goal policy,就是在某一时刻只能有一个goal是处于active状态,并且新的goal可以抢占先前的goal:

  • Only one goal can have an active status at a time
  • New goals preempt previous goals based on the stamp in their GoalID field (later goals preempt earlier ones)
  • An explicit preempt goal preempts all goals with timestamps that are less than or equal to the stamp associated with the preempt
  • Accepting a new goal implies successful preemption of any old goal and the status of the old goal will be changed automatically to reflect this

参考:

actionlib-Tutorials

ROS actionlib学习(一)

ROS actionlib学习(二)的更多相关文章

  1. ROS actionlib学习(三)

    下面这个例子将展示用actionlib来计算随机变量的均值和标准差.首先在action文件中定义goal.result和feedback的数据类型,其中goal为样本容量,result为均值和标准差, ...

  2. ROS actionlib学习(一)

    actionlib是ROS中一个很重要的功能包集合,尽管在ROS中已经提供了srevice机制来满足请求—响应式的使用场景,但是假如某个请求执行时间很长,在此期间用户想查看执行的进度或者取消这个请求的 ...

  3. emberjs学习二(ember-data和localstorage_adapter)

    emberjs学习二(ember-data和localstorage_adapter) 准备工作 首先我们加入ember-data和ember-localstorage-adapter两个依赖项,使用 ...

  4. ReactJS入门学习二

    ReactJS入门学习二 阅读目录 React的背景和基本原理 理解React.render() 什么是JSX? 为什么要使用JSX? JSX的语法 如何在JSX中如何使用事件 如何在JSX中如何使用 ...

  5. TweenMax动画库学习(二)

    目录            TweenMax动画库学习(一)            TweenMax动画库学习(二)            TweenMax动画库学习(三)            Tw ...

  6. Hbase深入学习(二) 安装hbase

    Hbase深入学习(二) 安装hbase This guidedescribes setup of a standalone hbase instance that uses the local fi ...

  7. Struts2框架学习(二) Action

    Struts2框架学习(二) Action Struts2框架中的Action类是一个单独的javabean对象.不像Struts1中还要去继承HttpServlet,耦合度减小了. 1,流程 拦截器 ...

  8. Python学习二:词典基础详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...

  9. Quartz学习--二 Hello Quartz! 和源码分析

    Quartz学习--二  Hello Quartz! 和源码分析 三.  Hello Quartz! 我会跟着 第一章 6.2 的图来 进行同步代码编写 简单入门示例: 创建一个新的java普通工程 ...

随机推荐

  1. 《转》Web Service实践之——开始XFire

    Web Service实践之——开始XFire 一.Axis与XFire的比较XFire是与Axis2 并列的新一代WebService平台.之所以并称为新一代,因为它:1.支持一系列Web Serv ...

  2. bootstrap改变上传文件按钮样式,并显示已上传文件名

    参考博文: html中,文件上传时使用的<input type="file">的样式自定义 html中<input type="file"&g ...

  3. 结构型模式之Adapter模式

    适配器模式把一个类的接口变换成客户端所期待的另一种接口. 在JDK中的体现 把一个接口或类变成另外一种. java.util.Arrays#asList()javax.swing.JTable(Tab ...

  4. [SDOI2012]拯救小云公主

    题解: 是一个不错的题目 首先我们可以考虑二分答案 然后变成判定性问题 对于每个画一个圆 当其会被阻断时就是答案 阻断有四种情况 左下 上下 左右 右上 但是这样是n^2a(n)*logn的 考虑直接 ...

  5. [ZJOI2012]旅游

    题目: 这题意...还以为他说的线段是路径 写了好久的dp..写不出来 看了网上的题解..才知道就是两点连线 然后就是一般的平面图转对偶图的思想 然后算一下边数发现是颗树,求一下直径就好了 代码: # ...

  6. POJ 2409 Let it Bead【Polya定理】(模板题)

    <题目链接> 题目大意:用k种颜色对n个珠子构成的环上色,旋转.翻转后相同的只算一种,求不等价的着色方案数. 解题分析: 对于这种等价计数问题,可以用polay定理来解决,本题是一道pol ...

  7. 针对SSL/TLS的拒绝服务攻击以及使用ettercap进行DNS欺骗

    一. thc-ssl-dos 1.简介 (1).SSL 协商加密对性能开销增加,大量握手请求会导致 DOS (2).利用 SSL secure Renegotiation 特性,在单一 TCP 连接中 ...

  8. P1356 数列的整数性

    P1356 数列的整数性打的骗分,在多组数据的情况下还能骗到分,可以了.又TMD是dp.f[i][j]表示+-第i个数能否达到%p后的余数j,如果f[n][0]==true就可以. #include& ...

  9. SQL 查询存储过程

    select distinct name from syscomments a,sysobjects b where a.id=b.id and b.xtype='p' --and text like ...

  10. SQL SERVER字符串中的空格去除

    1.LTRIM 删除起始空格后返回字符表达式. 语法 LTRIM   (   character_expression   ) 参数 character_expression 是字符或二进制数据表达式 ...