ROS中的服务service是一问一答的形式,你来查询了,我就返给你要的信息。
action也有服务的概念,但是它不一样的地方是:不是一问一答,而多了一个反馈,它会不断反馈项目进度。

如navigation下的move_base

package,你设定了目标点,反馈信息可能是机器人在规划路径上的即时位姿,

直到机器人到达目标点,返回SUCCEEDED消息。

上面所述的 ActionClient 和 ActionServer 通过 ROS Action Protocol (ROS Action 协议,建立在ROS messages的基础上)来通信。

Client&Server 为用户提供了简单的API,通过函数的调用和回调,用来在client端request一个目标,或者,在server端来执行达成一个目标。

下图说明这个机制如何运行:

Action Specification: Goal, Feedback, & Result

Goal

为了用actions机制完成一个任务,我们引入了the notion of a goal, 这个goal可以被ActionClient发送到ActionServer. 比如在move base

这个案例中,它的类型是PoseStamped,包含了机器人应该到达的哪里的信息。在激光扫描云台控制案例中,the goal会包含扫描的参数

(min angle, max angle, speed 等)

Feedback

Feedback是server用来告诉ActionClient goal执行过程中的各种情况。在moving_base案例中,它是机器人现在的位姿;

在controlling the tilting laser scanner案例中, this might be the time left until the scan completes(扫描剩余时间).

Result

执行结果,比如在move_base中的结果和机器人pose;在云台激光扫描中的一个请求的点云数据。等

下面写一个actionlib的c++例程

catkin_create_pkg actionlib_tutorials roscpp rospy actionlib actionlib_msgs message_generation

在包中添加action文件夹在里面新建一个 Fibonacci.action文件

#goal definition
int32 order
---
#result definition
int32[] sequence
---
#feedback definition
int32[] sequence

修改package.xml添加

  <run_depend>message_generation</run_depend>

修改 CMakeLists.txt删除添加;编译cpp文件根据自己的添加

add_action_files(
DIRECTORY action
FILES Fibonacci.action
)
generate_messages(DEPENDENCIES
actionlib_msgs
)
CATKIN_DEPENDS actionlib actionlib_msgs message_generation roscpp rospy

简单的client.cpp

#include <ros/ros.h>
#include <actionlib/client/simple_action_client.h>
#include <actionlib_tutorials/FibonacciAction.h> using namespace actionlib_tutorials;
typedef actionlib::SimpleActionClient<FibonacciAction> Client; int main (int argc, char **argv)
{
ros::init(argc, argv, "test_fibonacci_callback"); // Create the action client
Client ac("fibonacci", true); ROS_INFO("Waiting for action server to start.");
ac.waitForServer();
ROS_INFO("Action server started, sending goal."); // Send Goal
FibonacciGoal goal;
goal.order = 10;
ac.sendGoal(goal);
bool finish_before_timeout=ac.waitForResult(ros::Duration(15)); if(finish_before_timeout)
{
actionlib::SimpleClientGoalState state = ac.getState();
ROS_INFO("action finish : %s",state.getState().toString().c_str());
}else
{
ROS_INFO("TIMEOUT");
} ros::spin();
return 0;
}

带回调显示的clientprocess.cpp

#include <ros/ros.h>
#include <actionlib/client/simple_action_client.h>
#include <actionlib_tutorials/FibonacciAction.h> using namespace actionlib_tutorials;
typedef actionlib::SimpleActionClient<FibonacciAction> Client; // Called once when the goal completes
void doneCb(const actionlib::SimpleClientGoalState& state,
const FibonacciResultConstPtr& result)
{
ROS_INFO("Finished in state [%s]", state.toString().c_str());
ROS_INFO("Answer: %i", result->sequence.back());
ros::shutdown();
} // Called once when the goal becomes active
void activeCb()
{
ROS_INFO("Goal just went active");
} // Called every time feedback is received for the goal
void feedbackCb(const FibonacciFeedbackConstPtr& feedback)
{
ROS_INFO("Got Feedback of length %lu", feedback->sequence.size());
} int main (int argc, char **argv)
{
ros::init(argc, argv, "test_fibonacci_callback"); // Create the action client
Client ac("fibonacci", true); ROS_INFO("Waiting for action server to start.");
ac.waitForServer();
ROS_INFO("Action server started, sending goal."); // Send Goal
FibonacciGoal goal;
goal.order = 20;
ac.sendGoal(goal, &doneCb, &activeCb, &feedbackCb); ros::spin();
return 0;
}

server.cpp

#include <ros/ros.h>
#include <actionlib/server/simple_action_server.h>
#include <actionlib_tutorials/FibonacciAction.h> typedef actionlib::SimpleActionServer<actionlib_tutorials::FibonacciAction> Server; class FibonacciAction
{
protected: ros::NodeHandle nh_;
Server 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();
} ~FibonacciAction(void)
{
} void executeCB(const actionlib_tutorials::FibonacciGoalConstPtr &goal)
{
// helper variables
ros::Rate r(1);
bool success = true; // push_back the seeds for the fibonacci sequence
feedback_.sequence.clear();
feedback_.sequence.push_back(0);
feedback_.sequence.push_back(1); // 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[0], feedback_.sequence[1]); // start executing the action
for(int i=1; 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();
success = false;
break;
}
feedback_.sequence.push_back(feedback_.sequence[i] + feedback_.sequence[i-1]);
// 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 0;
}

编译后运行

rosrun actionlib_tutorials client
rosrun actionlib_tutorials sever

在设置时间内服务完成则状态输出完成,否则反馈失败,这种等待模式效率太低

rosrun actionlib_tutorials clientprocess

rosrun actionlib_tutorials sever

将动作完成过程实时的将状态反馈回来,直到动作完成或失败

actionlib学习的更多相关文章

  1. ROS actionlib学习(三)

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

  2. ROS actionlib学习(二)

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

  3. ROS actionlib学习(一)

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

  4. ROS机器人操作系统相关书籍、资料和学习路径

    作者:Top Liu链接:https://zhuanlan.zhihu.com/p/30391098来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 本文是易科机器人实验 ...

  5. 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代

    2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...

  6. Angular2学习笔记(1)

    Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...

  7. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  8. 消息队列——RabbitMQ学习笔记

    消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...

  9. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

随机推荐

  1. java性能调优02

    1.字符串优化处理 1.1 常量池的优化:当String对象拥有相同的值时,他们只引用常量池的同一个拷贝. String a="123"; String b="123&q ...

  2. python 数据压缩

    zlib 压缩 import zlib import this s = this.s.encode('utf8')*10 for i in range(10): data = zlib.compres ...

  3. ZOJ 3795 Grouping(scc+最长路)

    Grouping Time Limit: 2 Seconds      Memory Limit: 65536 KB Suppose there are N people in ZJU, whose ...

  4. Hibernate4教程二:基本配置(3)

    被映射的类必须定义对应数据库表主键字段.大多数类有一个JavaBeans风格的属性, 为每一个实例包含唯一的标识.<id> 元素定义了该属性到数据库表主键字段的映射. java代码: &l ...

  5. nginx信号及平滑升级

    1.nginx信号 nginx进程处理命令: kill -signals PID PID即nginx进程ID signals的参数解释如下所示: TERM,INT快速关闭进程 QUIT优雅的关闭,如果 ...

  6. 【Redis】分布式锁RedLock

    普通实现 说道Redis分布式锁大部分人都会想到: 1.setnx+lua, 2.setkey value px milliseconds nx. - 获取锁(unique_value可以是UUID等 ...

  7. 【LeetCode 1】两数之和

    描述 [题解] 用个map的话就是O(N)级别的了. [代码] class Solution { public: unordered_map<int,int> mymap; vector& ...

  8. windows系统使用

    1.访问局域网共享的文件,用 \\ip号 2.电脑的硬件名称(设备管理器中)是可以用软件修改的. 3.电脑中每一个连接网络的设备都有一个网卡地址(MAC地址),如无线网卡地址.有线网卡地址. 4.wi ...

  9. 使用python发送163邮件 qq邮箱

    使用python发送163邮件 def send_email(title, content): import smtplib from email.mime.multipart import MIME ...

  10. sklearn中standardscaler中fit_transform()和transform()有什么区别,应该怎么使用?

    在根据机器学习书中提供的实例中,看到需要对训练和测试的特征数据进行标准化. 但是使用的是有两个函数, 对于训练数据,使用的是fit_transform()函数 对于测试数据,使用的是tansform( ...