在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

参考:

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. Memcache简单使用

    1:Memcache的下载https://pan.baidu.com/s/1dFnB3NV/08中 简单安装:直接点击文件夹中的memcached.exe文件即可.但是每次使用都需要双击,比较麻烦.所 ...

  2. mvc中简单的异常记录

    说明:异常处理 1.1 在WebApp的Model中 添加异常处理类 继承于HandleErrorAttribute using System; using System.Collections.Ge ...

  3. 《剑指offer》-判断对称二叉树

    题目描述 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. 思路上还是广度优先搜索(BFS)来做的.BFS是依托于STL的queue作为容 ...

  4. 开始写博客,学习Linq(3)

    为什么需要Linq?(摘自原文) 读者会发现LINQ着眼于解决编程语言和数据库之间广发存在的不统一问题. 1.常见的问题,使用.NET Framework Class Library(FCL)提供了A ...

  5. 鼠标hover元素scale/zoom中心点放大效果实例页面

    CSS代码: .box { /* 可见视觉区域 */ width: 480px; height: 250px; position: relative; overflow: hidden; cursor ...

  6. PhpStorm 中切换PHP版本

    PhpStorm 中默认的 PHP 版本是 PHP 5.4 ,PhpStorm 会以该版本对编辑器中的PHP文件进行自动校验.EX:PHP文件中,使用了 PHP 5.4 版本以上的新特性,由于 Php ...

  7. (数据分析)第02章 Python语法基础,IPython和Jupyter Notebooks.md

    第2章 Python语法基础,IPython和Jupyter Notebooks 当我在2011年和2012年写作本书的第一版时,可用的学习Python数据分析的资源很少.这部分上是一个鸡和蛋的问题: ...

  8. bzoj1722: [Usaco2006 Mar] Milk Team Select 产奶比赛 树形dp

    题目链接 bzoj1722: [Usaco2006 Mar] Milk Team Select 产奶比赛 题解 dp[i][j][0 / 1] 以i为根的子数中 相邻点对选了j个的最大价值 代码 #i ...

  9. [CC-PERMUTE]Just Some Permutations 3

    [CC-PERMUTE]Just Some Permutations 3 题目大意: \(T(T\le10^5)\)次询问,每次询问有多少长度为\(n(n\le10^6)\)的排列,满足任意相邻两个数 ...

  10. socket的几大异常以及其出现的原因

    1:我是模拟了一个客户端不断的向服务器发送消息,但是当某一时刻我把服务端断掉,客户端就出现了写异常 java.net.SocketException: Connection reset by peer ...