ROS actionlib学习(二)
在ROS actionlib学习(一)中的例子展示了actionlib最基本的用法,下面我们看一个稍微实际一点的例子,用actionlib计算斐波那契数列,并发布反馈(feedback)和结果(result)。斐波那契数列指的是这样一个数列:
- 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368........
这个数列从第3项开始,每一项都等于前两项之和。
首先在action文件中定义goal、result、feedback,其中goal是斐波那契数列的阶数,result为最终生成的数列,feedback为当前一步的中间结果(也是一个数列)。
- #goal definition
- int32 order
- ---
- #result definition
- int32[] sequence
- ---
- #feedback
- int32[] sequence
然后按照教程SimpleActionServer(ExecuteCallbackMethod)中所述的步骤,修改CMakeLists.txt以及package.xml文件,编译成功后会生成相应的消息文件以及头文件。
- $ cd ../.. # Go back to the top level of your catkin workspace
- $ catkin_make
- $ ls devel/share/actionlib_tutorials/msg/
- FibonacciActionFeedback.msg FibonacciAction.msg FibonacciFeedback.msg
- FibonacciResult.msg FibonacciActionGoal.msg FibonacciActionResult.msg FibonacciGoal.msg
- $ ls devel/include/actionlib_tutorials/
- FibonacciActionFeedback.h FibonacciAction.h FibonacciFeedback.h FibonacciResult.h
- FibonacciActionGoal.h FibonacciActionResult.h FibonacciGoal.h
下面编写服务端程序,用于处理客户端发送的请求。
- #include <ros/ros.h>
- #include <actionlib/server/simple_action_server.h>
- #include <actionlib_tutorials/FibonacciAction.h>
- class FibonacciAction
- {
- protected:
- ros::NodeHandle nh_;
- actionlib::SimpleActionServer<actionlib_tutorials::FibonacciAction> as_; // NodeHandle instance must be created before this line. Otherwise strange error occurs.
- std::string action_name_;
- // create messages that are used to published feedback/result
- actionlib_tutorials::FibonacciFeedback feedback_;
- actionlib_tutorials::FibonacciResult result_;
- public:
- FibonacciAction(std::string name) :
- as_(nh_, name, boost::bind(&FibonacciAction::executeCB, this, _1), false),
- action_name_(name)
- {
- as_.start(); // Explicitly start the action server
- }
- ~FibonacciAction(void)
- {
- }
- void executeCB(const actionlib_tutorials::FibonacciGoalConstPtr &goal)
- {
- // helper variables
- ros::Rate r();
- bool success = true;
- // push_back the seeds for the fibonacci sequence
- feedback_.sequence.clear();
- feedback_.sequence.push_back();
- feedback_.sequence.push_back();
- // publish info to the console for the user
- ROS_INFO("%s: Executing, creating fibonacci sequence of order %i with seeds %i, %i", action_name_.c_str(), goal->order, feedback_.sequence[], feedback_.sequence[]);
- // start executing the action
- for(int i=; i<=goal->order; i++)
- {
- // check that preempt has not been requested by the client
- if (as_.isPreemptRequested() || !ros::ok())
- {
- ROS_INFO("%s: Preempted", action_name_.c_str());
- // set the action state to preempted
- as_.setPreempted(); // signals that the action has been preempted by user request
- success = false;
- break;
- }
- feedback_.sequence.push_back(feedback_.sequence[i] + feedback_.sequence[i-]);
- // publish the feedback
- as_.publishFeedback(feedback_);
- // this sleep is not necessary, the sequence is computed at 1 Hz for demonstration purposes
- r.sleep();
- }
- if(success)
- {
- result_.sequence = feedback_.sequence;
- ROS_INFO("%s: Succeeded", action_name_.c_str());
- // set the action state to succeeded
- as_.setSucceeded(result_);
- }
- }
- };
- int main(int argc, char** argv)
- {
- ros::init(argc, argv, "fibonacci");
- FibonacciAction fibonacci("fibonacci");
- ros::spin();
- return ;
- }
客户端程序用于发送计算请求,服务器收到请求后会生成20阶的斐波那契数列。
- #include <ros/ros.h>
- #include <actionlib/client/simple_action_client.h>
- #include <actionlib/client/terminal_state.h>
- #include <actionlib_tutorials/FibonacciAction.h>
- int main (int argc, char **argv)
- {
- ros::init(argc, argv, "test_fibonacci");
- // the action client is constructed with the server name and the auto spin option set to true.
- 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
- ROS_INFO("Waiting for action server to start.");
- // 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)
- ac.waitForServer(); //will wait for infinite time
- ROS_INFO("Action server started, sending goal.");
- // send a goal to the action
- actionlib_tutorials::FibonacciGoal goal;
- goal.order = ;
- ac.sendGoal(goal); // the goal value is set and sent to the action serve
- //wait for the action to return
- 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.
- if (finished_before_timeout)
- {
- actionlib::SimpleClientGoalState state = ac.getState();
- ROS_INFO("Action finished: %s",state.toString().c_str());
- }
- else
- ROS_INFO("Action did not finish before the time out.");
- //exit
- return ;
- }
修改CMakeLists.txt后使用catkin_make编译上面两个程序。运行roscore开启ROS主节点,然后在两个新终端中分别输入下面命令分别运行server和client:
- rosrun actionlib_tutorials fibonacci_server
- rosrun actionlib_tutorials fibonacci_client
可以通过 rostopic echo /fibonacci/feedback 和 rostopic echo /fibonacci/result 命令查看斐波那契数列计算的反馈和结果:
最终的计算结果result如下:
- ---
- header:
- seq: 1
- stamp: 1250813759950015000
- frame_id:
- status:
- goal_id:
- stamp: 1250813739949752000
- id: 1250813739949752000
- status: 3
- text:
- result:
- 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抢占。
- 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
参考:
ROS actionlib学习(二)的更多相关文章
- ROS actionlib学习(三)
下面这个例子将展示用actionlib来计算随机变量的均值和标准差.首先在action文件中定义goal.result和feedback的数据类型,其中goal为样本容量,result为均值和标准差, ...
- ROS actionlib学习(一)
actionlib是ROS中一个很重要的功能包集合,尽管在ROS中已经提供了srevice机制来满足请求—响应式的使用场景,但是假如某个请求执行时间很长,在此期间用户想查看执行的进度或者取消这个请求的 ...
- emberjs学习二(ember-data和localstorage_adapter)
emberjs学习二(ember-data和localstorage_adapter) 准备工作 首先我们加入ember-data和ember-localstorage-adapter两个依赖项,使用 ...
- ReactJS入门学习二
ReactJS入门学习二 阅读目录 React的背景和基本原理 理解React.render() 什么是JSX? 为什么要使用JSX? JSX的语法 如何在JSX中如何使用事件 如何在JSX中如何使用 ...
- TweenMax动画库学习(二)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
- Hbase深入学习(二) 安装hbase
Hbase深入学习(二) 安装hbase This guidedescribes setup of a standalone hbase instance that uses the local fi ...
- Struts2框架学习(二) Action
Struts2框架学习(二) Action Struts2框架中的Action类是一个单独的javabean对象.不像Struts1中还要去继承HttpServlet,耦合度减小了. 1,流程 拦截器 ...
- Python学习二:词典基础详解
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...
- Quartz学习--二 Hello Quartz! 和源码分析
Quartz学习--二 Hello Quartz! 和源码分析 三. Hello Quartz! 我会跟着 第一章 6.2 的图来 进行同步代码编写 简单入门示例: 创建一个新的java普通工程 ...
随机推荐
- 《转》Web Service实践之——开始XFire
Web Service实践之——开始XFire 一.Axis与XFire的比较XFire是与Axis2 并列的新一代WebService平台.之所以并称为新一代,因为它:1.支持一系列Web Serv ...
- bootstrap改变上传文件按钮样式,并显示已上传文件名
参考博文: html中,文件上传时使用的<input type="file">的样式自定义 html中<input type="file"&g ...
- 结构型模式之Adapter模式
适配器模式把一个类的接口变换成客户端所期待的另一种接口. 在JDK中的体现 把一个接口或类变成另外一种. java.util.Arrays#asList()javax.swing.JTable(Tab ...
- [SDOI2012]拯救小云公主
题解: 是一个不错的题目 首先我们可以考虑二分答案 然后变成判定性问题 对于每个画一个圆 当其会被阻断时就是答案 阻断有四种情况 左下 上下 左右 右上 但是这样是n^2a(n)*logn的 考虑直接 ...
- [ZJOI2012]旅游
题目: 这题意...还以为他说的线段是路径 写了好久的dp..写不出来 看了网上的题解..才知道就是两点连线 然后就是一般的平面图转对偶图的思想 然后算一下边数发现是颗树,求一下直径就好了 代码: # ...
- POJ 2409 Let it Bead【Polya定理】(模板题)
<题目链接> 题目大意:用k种颜色对n个珠子构成的环上色,旋转.翻转后相同的只算一种,求不等价的着色方案数. 解题分析: 对于这种等价计数问题,可以用polay定理来解决,本题是一道pol ...
- 针对SSL/TLS的拒绝服务攻击以及使用ettercap进行DNS欺骗
一. thc-ssl-dos 1.简介 (1).SSL 协商加密对性能开销增加,大量握手请求会导致 DOS (2).利用 SSL secure Renegotiation 特性,在单一 TCP 连接中 ...
- P1356 数列的整数性
P1356 数列的整数性打的骗分,在多组数据的情况下还能骗到分,可以了.又TMD是dp.f[i][j]表示+-第i个数能否达到%p后的余数j,如果f[n][0]==true就可以. #include& ...
- SQL 查询存储过程
select distinct name from syscomments a,sysobjects b where a.id=b.id and b.xtype='p' --and text like ...
- SQL SERVER字符串中的空格去除
1.LTRIM 删除起始空格后返回字符表达式. 语法 LTRIM ( character_expression ) 参数 character_expression 是字符或二进制数据表达式 ...