《精通ROS机器人编程(原书第2版) 》 —2.3 使用ROS服务

举报
华章计算机 发表于 2020/02/10 14:44:27 2020/02/10
【摘要】 本节书摘来自华章计算机《精通ROS机器人编程(原书第2版) 》 一书中第2章,第2.3.1节,作者是[印度]郎坦·约瑟夫(Lentin Joseph)[意大利]乔纳森·卡卡切(Jonathan Cacace),张新宇 张志杰 等译 。

2.3 使用ROS服务

在本节中,我们将创建两个ROS节点,它们使用我们已经自定义了的服务。我们创建的服务节点可以将一个字符串消息作为请求发送到服务器上,服务器节点将反馈另一条消息作为应答。

进入mastering_ros_demo_pkg/src文件夹,找到名为demo_service_server.cpp和demo_service_client.cpp的节点代码。

demo_service_server.cpp是服务器节点源码,定义如下:

 image.png

让我们看看代码的解释:

 image.png

这里包含了ros/ros.h头文件,它是编写ROS CPP节点代码必须要包含的头文件。mastering_ros_demo_pkg/demo_srv.h头文件是生成的一个头文件,它包含我们服务的定义,我们可以在代码中直接使用它。sstream.h是用于获取字符串流的头文件。

 image.png

这是在服务器节点上收到请求时执行的回调函数。服务器可以从客户端接收消息类型为mastering_ros_demo_pkg::demo_srv::Request的请求,也可以发送mastering_ros_demo_pkg:: demo_srv::Response类型的应答。

 image.png

在这段代码中,将字符串数据“Received Here”传递给服务的Response实例。在这里,out是我们在demo_srv.srv中给出的应答的字段名称。这个应答将反馈到服务客户端节点:

 image.png

这里创建了一个名为demo_service的服务,并在请求到达此服务时执行回调函数。回调函数名为demo_service_callback,我们在上一节中学过。

接下来,我们学习demo_service_client.cpp是如何工作的。

以下是此段代码的定义:

 image.png

 

我们来解释一下该代码:

 image.png

此行代码将创建一个服务客户端,其消息类型为mastering_ros_demo_pkg::demo_srv,它可以与名为demo_service的ROS服务器进行通信。

 image.png

此行代码将创建一个新的服务对象实例。

 image.png

将名为“Sending from Here”的字符串填充到请求实例中。

 image.png

这会将服务调用发送到服务器上。如果发送成功,将打印应答和请求。如果失败,则什么都不做。

 image.png

如果收到了应答,将打印请求和应答。

在讨论了这两个节点之后,现在我们讨论如何编译生成这两个节点。将以下代码添加到CMakeLists.txt就可以来编译生成这两个节点了:

 image.png

我们可以使用下面的命令来编译该代码:

 image.png

要启动节点,首先需要执行roscore命令,然后再使用下面的命令来启动节点,结果如图2-6所示:

 image.png

 image.png

图2-6 运行ROS服务客户端和服务器节点

我们可以使用的rosservice命令如下:

$ rosservice list:这将列出当前系统中的ROS服务。

$ rosservice type /demo_service:这将打印/demo_service的消息类型。

$ rosservice info /demo_service:这将打印/demo_service相关的信息。

2.3.1 使用ROS动作库

在ROS服务中,我们实现了两个节点间请求/应答式的交互,但是如果应答需要花费太多时间或者服务器没有完成指定的工作,那么我们就必须等待它完成。在等待请求的动作结束的过程中,主应用程序将被阻塞。此外,我们也可以通过调用客户端来监视远程进程的执行进度。这种情形下,我们应该使用actionlib来实现应用。ROS中的另一种用法是:如果请求没有像我们预期的那样按时完成,我们就可以抢占正在运行的请求,并发送另一个请求。actionlib软件包提供了实现这类抢占任务的标准方法。actionlib经常用在机器人手臂导航和移动机器人导航中。下面让我们来看看如何实现动作服务器和动作客户端。

与ROS服务一样,在actionlib中,我们也必须初始化动作规范。这个动作的规范存储在以.action结尾的文件中。该文件必须保存在ROS软件包内的action文件夹中。action文件包含以下各部分内容。

Goal(目标):动作客户端可以发送一个必须由动作服务器来执行的目标。这就类似于ROS服务中的请求。例如,如果机器人手臂关节想从45度转动到90度,那么这里的目标就是90度。

Feedback(反馈):动作客户端向动作服务器发送目标后,将开始执行回调函数。反馈只是简单地给出回调函数内当前操作的进度。通过使用反馈,我们可以获得当前任务的进度。在前面的例子中,机器人手臂关节必须移动到90度,在这种情况下,反馈就是机械臂从45度转动到90度之间的中间值。

Result(结果):完成目标后,动作服务器将发送完成的最终结果,它可以是计算结果或者一个确认。在前面的例子中,如果关节转动到90度,则完成了目标任务,结果就是可以表示目标完成的任何形式。

在此,我们讨论一个演示动作服务器和动作客户端。动作客户端将发送一个数字作为目标。动作服务器收到目标后,将从0开始计数,每秒加1,加到给定数字。如果在给定的时间内完成计数累加,它将发送结果,否则,该任务将被客户端抢占。这里的反馈是计算的进度。该任务的动作文件如下,动作文件名为Demo_action.action:

 image.png

这里的count值是目标,服务器必须从0开始增加到该值。final_count是结果,即任务完成后最终的结果值。current_number是反馈值(即当前的计数值),表示任务的进度。

进入mastering_ros_demo_pkg/src文件夹,你就可以看到动作服务器节点的源码文件demo_action_server.cpp和动作客户端节点的源码文件demo_action_client.cpp。

创建ROS动作服务器

在本节中,我们将讨论demo_action_server.cpp。这个动作服务器将接收一个整型目标值。当服务器得到此目标值后,它将从0开始计数,直到该值。如果计数完成了,它将成功地完成动作。如果在完成任务之前被抢占,动作服务器将寻找另一个目标。

这段代码有点长,所以我们就只讨论这段代码的重要部分:

首先我们来看头文件:

 image.png

第一个头文件是用于实现动作服务器节点的标准动作库。第二个头文件是由存储的action文件生成的。它包含了我们的动作定义。

 image.png

这个类包含了动作服务器的定义。

 image.png

这是使用我们自定义的动作消息类型创建的一个简单的动作服务器实例。

 image.png

创建一个反馈实例以便在操作过程中可以发送反馈。

 image.png

创建一个结果实例来发送最终的结果。

 image.png

这是一个动作构造函数,这里创建的动作服务器还包含了一些参数,例如Nodehandle、action_name和executeCB,其中executeCB是所有动作完成后的回调函数。

 image.png

这行代码是当动作被抢占时注册一个回调函数。preemtCB是动作客户端发出抢占请求时执行的回调函数名。

 image.png

这是回调函数的定义。当动作服务器接收到目标值后就会执行该回调函数。它只有在检查了动作服务器的活动状态和是否已经被抢占后,才会执行该回调函数。

 image.png

这个循环在目标值到达之前将会一直执行。它将不断地发送当前任务的进度作为反馈。

 image.png

在此循环内部,将检查动作服务器是处于活动状态还是处于被抢占状态。如果未处于活动状态,或者处于被抢占状态,该函数将返回。

 image.png

如果当前值到达了目标值,那么它将发布最终的结果。

 image.png

在main( )函数中,我们创建了一个Demo_actionAction的实例,它将启动动作服务器。

创建ROS动作客户端

在本节中,我们将讨论动作客户端的工作方式。demo_action_client.cpp是动作客户端节点的源文件,它负责发送目标值,即作为目标的一个数值。客户端从命令行的参数中获取目标值。客户端的第一个命令行参数是目标值,第二个参数是此任务的完成时间。

该目标值将被发送到服务器上,客户端将一直等待,直到到达指定的时间。时间以秒为单位。在等待指定时间后,客户端将检查任务是否完成,如果未完成,客户端将抢占该动作。

客户端代码有点长,因此我们仅讨论代码的重要部分:

 image.png

在动作客户端中,我们需要包含 actionlib/client/simple_action_client.h来获取动作客户端的API,这些API是用来实现动作客户端的。

 image.png

这行代码将创建一个动作客户端实例。

 image.png

如果在系统上没有运行任何动作服务器,那么这行代码将等待无限长时间。只有在系统上运行了动作服务器时才会退出。

 image.png

创建一个目标的实例,并从第一个命令行参数获取需要发送的目标值。

 image.png

此行将等待服务器的结果,一直到指定的等待秒数。

 image.png

如果还没有完成,该动作将被强占。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。