ROS服务
理解ROS服务
认识服务的基本概念
消息传递机制尽管是 ROS 系统中节点通信的主要方法,但确实受到了一定的限制,因此引入另一种通信的方法,称之为服务调用(service calls),服务调用与消息的区别主要体现在两个方面:
- 服务调用是双向的,一个节点给另一个节点发送信息并等待响应,因此信息流是双向的。作为对比, 当消息发布后,并没有响应的概念,甚至不能保证系统内有节点订阅了这些消息
- 服务调用实现的是一对一通信。每一个服务由一个节点发起,对这个服务的响应返回同一个节点。 对于消息传递来说,每一个消息都和一个话题相关,这个话题可能有很多的发布者和订阅者
简单来理解消息传递和服务调用区别的话就是:
- 通过话题来传递消息的机制就雷同于通过发送微信公众号来广播消息,不管有没有人订阅ROS小课堂我都会往公众号里发布教程,你愿意学习ROS你就订阅查看,没人订阅不影响我发教程
- 服务调用就雷同于你给我打电话询问问题,等我接通电话后询问你的问题后,然后我经过思考后再把答案告诉你,我们之间的通信是一对一的,而且是及时的。不同于发话题,如果没有发公众号你想看教程都没有
服务调用的基本信息流如下图所示
其过程是:
- 客户端(client)节点发送一些称为请求(request)的数据到一个服务器(server)节点, 并且等待回应。
- 服务器节点接收到请求后,采取一些行动(计算、配置软件或硬 件、改变自身行为等),然后发送一些称为响应(response)的数据给客户端节点
实例编写一个ROS服务
我们创建一个可以查询机器人当前电量的服务来进行演示
我们首先来创建存放srv的目录
myTestSrv.srv写入内容
- 一个srv文件描述一项服务。它包含两个部分:请求和响应
- srv文件分为请求和响应两部分,由
---
分隔- 上面的
int32 index
是服务的请求 - 下面的
int32 result
是服务的响应反馈
- 上面的
修改配置文件,使其可以正常编译
使用catkin_make
编译整个工作空间,当编译成功后开始利用rossrv list
查看有没有我们自定义的服务
rossrv
命令介绍
接下来修改发布者的代码,增加服务端代码
修改订阅者代码,增加服务的客户端代码
最后编译整个工作空间,然后运行查看效果
使用命令行工具来查看当前系统中服务
actionlib
理解ROS的actionlib软件包
认识actionlib存在的意义
- 在一个复杂的ROS系统中我们会需要各种各有的服务要求,向某个节点发送请求执行某一个任务, 并返回相应的执行结果,这种用ROS的服务(services)完成
- 然而有一些情况服务执行的时间很长,在执行中想要获得任务处理的进度,或可能取消执行任务,actionlib就能实现这样的功能,它是ROS的一个非常重要的库,算是对service在某些情况下能力不足的一种补充
- 在前面介绍过服务,因为它在执行的过程中是阻塞的,会阻止程序进一步执行,必须等待服务器返回结果才会继续执行后面的程序,对于一些计算量较轻的任务使用服务是可以满足的。
- 但是对于一些负载的任务,例如让机器人从房间的某一点A运动到指定的地点B,在此运动过程中需要花费的时间未定,任务时间较长而且中途会遇到各种情况,例如机器人电量不足时,这就需要取消或暂停当前任 务等待机器人充满电再继续该任务
action client和server交互流程简图
服务端描述
goal是在ActionClient端启动的,一旦ActionServer接收到goal请求,它就会为这个goal创建一个状态机来追踪goal的状态转换:
这些状态的转换大多是服务器端触发的:
setAccepted
:收到有goal之后,决定开始处理它setRejected
:收到goal后,决定不去处理它,因为它是个无效请求(溢出,资源不可用,无效等)setSucceeded
:告知goal被正确执行setAborted
:告知goal在处理时遇到了问题不得不被终止了setCanceled
:告知因cancle请求,goal不再被执行了
action client也能异步触发状态转换:
CancelRequest
:客户端通知server它要server停止处理这个goal服务端状态
服务端状态:
-
中间状态
Pending
:goal还没有被ActionServer处理,等待处理中Active
:goal正在被ActionServer处理Recalling
:goal没有被处理,但客户端已发送取消请求,但ActionServer还不确定goal已经被取消了Preempting
:goal正在被处理,从AC端收到了取消请求,但AS还不确定goal已经被取消了
-
终点状态
Rejected
:ActionClient没有发cancle请求,goal被ActionServer不处理直接拒绝了Succeeded
:goal被ActionServer成功实现Aborted
:goal被ActionServer终止没有ActionClient的cancle请求Recalled
:在ActionServer开始执行之前这个goal被另一个goal或者cancle请求取消了Preempted
:处理中的goal被另一个goal或者ActionClient的取消请求给取消了
客户端描述
Actionlib的框架实际是一种特殊的客户-服务的模式。除了服务请求的功能外,还可以实时获取服务器执行任务的进度状态,以及强制中断服务的功能
ActionClient 和ActionServer之间使用action protocol通信,action protocol就是预定义的一组ROS message,这些message被放到ROS topic上,在ActionClient和ActionServer之间进行传实现二者的沟通
上图中:
goal
:给服务器发送新的目标cancel
:给服务器发送取消命令status
:通知当前状态下系统中所有goal
的状态feedback
:给客户端定期发送反馈信息result
:在goal
完成后给客户端发送一次信息
实例编写一个actionlib
- 我们通过创建一个斐波那契数列来演示如何在计算过程中使用actionlib
- 首先需要先认识一下该数列的特点,这个数列从第三项开始,每一项都等于前两项之和:
- action server的设定如下
goal
:需要计算的fibonacci数列长度feedback
:反馈当前正在计算的数列序列result
:返回指定要求长度而计算得到的数列序列
创建软件包
创建action消息但是该消息是由.action文件自动来生成的,那就需要先创建.action文件
修改配置文件CMakeLists.txt,准备编译action消息
修改package.xml
使用命令catkin_make
编译工作空间,查看编译结果
编写服务器代码 server.cpp