服务(service)是另一种在节点之间传递数据的方法,服务其实就是同步的跨进程函数调用,它能够让一个节点调用运行在另一个节点中的函数。

我们就像之前消息类型一样定义这个函数的输入/输出。服务端(提供服务的节点)定义了一个回调函数来处理服务的请求,并声明这个服务。

客服端(进行服务请求的节点)通过一个本地的代理调用这个服务。

服务一般只是做哪些偶尔会做的事,或这当你需要同步的响应的时候,服务的回调函数中的计算应该较短,并能够在有限的时间中完成。

定义服务

例:WordCount.srv

string words
---
uint32 count

创建一个服务的第一步是定义服务调用的是输入和输出,定义服务文件就像消息定义文件一样,服务定义文件只是一个消息类型列表,这些类型可以是内建的。

文件中首先是服务调用的输入。直接使用ros内建的string类型,三个小短线(---)表示输入的末尾和输出的开始,我使用一个32位的无符号整数(uint32)作为输出,

这个包含服务定义的文件叫做WordCount.srv并且保存在包目录的一个叫做srv的子目录中(这个目录可以自己设置)

一旦写好文件了定义文件,我们就需要运行catkin_make来创建我们在与服务交互的时候真正会用到的代码和类定义,就像我们创建消息一样。

需要在package.xml文件中调加一些东西来表示对rospy和消息生成系统的依赖。如下

<build_depend>rospy</build_depend>
<evec_depend>rospy</exec_depend> <build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

需要修改CMakeLists.txt文件

其他修改和前面话题修改的一样,不同的是

需要在CMakeLists.txt文件中使用add_service_files()告诉那些服务定义文件需要编译

add_service_files(
FILES
WordCount.srv
)

最后要确保我们的服务定义文件的依赖已经被声明了,使用CMakeLists.txt文件中的generate_message()调用.

generation_message(
DEPENDENCIES
std_msgs
)

当所有的这些都完成了,运行catkin_make来生成三个类;WordCount、WordCountRequest和WordCountResponse.

然后使用rossev show WordCount命令可以检测服务的定义

qqtsj@qqtsj-Nitro-AN515-:~/catkin_ws/src/basic$ rossrv show WordCount
[basic/WordCount]:
string words
---
uint32 count

使用rossrv list 命令可查看所有提供服务的包

qqtsj@qqtsj-Nitro-AN515-:~/catkin_ws/src/basic$ rossrv list
basic/WordCount
control_msgs/QueryCalibrationState
control_msgs/QueryTrajectoryState
control_toolbox/SetPidGains
controller_manager_msgs/ListControllerTypes
controller_manager_msgs/ListControllers
controller_manager_msgs/LoadController
controller_manager_msgs/ReloadControllerLibraries
controller_manager_msgs/SwitchController
controller_manager_msgs/UnloadController
diagnostic_msgs/AddDiagnostics
diagnostic_msgs/SelfTest
dynamic_reconfigure/Reconfigure
gazebo_msgs/ApplyBodyWrench
gazebo_msgs/ApplyJointEffort
gazebo_msgs/BodyRequest
gazebo_msgs/DeleteLight
gazebo_msgs/DeleteModel
gazebo_msgs/GetJointProperties
gazebo_msgs/GetLightProperties
gazebo_msgs/GetLinkProperties
gazebo_msgs/GetLinkState
gazebo_msgs/GetModelProperties
gazebo_msgs/GetModelState
gazebo_msgs/GetPhysicsProperties
gazebo_msgs/GetWorldProperties
gazebo_msgs/JointRequest
gazebo_msgs/SetJointProperties
gazebo_msgs/SetJointTrajectory
gazebo_msgs/SetLightProperties
gazebo_msgs/SetLinkProperties
gazebo_msgs/SetLinkState
gazebo_msgs/SetModelConfiguration
gazebo_msgs/SetModelState
gazebo_msgs/SetPhysicsProperties
gazebo_msgs/SpawnModel
laser_assembler/AssembleScans
laser_assembler/AssembleScans2
map_msgs/GetMapROI
map_msgs/GetPointMap
map_msgs/GetPointMapROI
map_msgs/ProjectedMapsInfo
map_msgs/SaveMap
map_msgs/SetMapProjections
nav_msgs/GetMap
nav_msgs/GetPlan
nav_msgs/SetMap
nodelet/NodeletList
nodelet/NodeletLoad
nodelet/NodeletUnload
polled_camera/GetPolledImage
roscpp/Empty
roscpp/GetLoggers
roscpp/SetLoggerLevel
roscpp_tutorials/TwoInts
rospy_tutorials/AddTwoInts
rospy_tutorials/BadTwoInts
sensor_msgs/SetCameraInfo
std_srvs/Empty
std_srvs/SetBool
std_srvs/Trigger
tf/FrameGraph
tf2_msgs/FrameGraph
topic_tools/DemuxAdd
topic_tools/DemuxDelete
topic_tools/DemuxList
topic_tools/DemuxSelect
topic_tools/MuxAdd
topic_tools/MuxDelete
topic_tools/MuxList
topic_tools/MuxSelect
turtlesim/Kill
turtlesim/SetPen
turtlesim/Spawn
turtlesim/TeleportAbsolute
turtlesim/TeleportRelative

实现服务

下面举一个例子(一个简单的实现了单词计数服务的服务端程序)

例:service_server.py

  #!/usr/bin/env python
import rospy
from basic.srv import WordCount,WordCountResponse def count_words(request):
return WordCountResponse(len(request.words.split()))
rospy.init_node('service_server')
service=rospy.Service('word_count',WordCount,count_words)
rospy.spin()

第一.首先需要导入catkin生成的代码:

from basic.src import WordCount,WordCountResponse

注意需要同时导入WordCount和WordCountRseponse.

第二.回调函数只接受一个WordCountRequest类型的参数并返回一个WordCountResponse类型的值:

def count_words(request):

return WordCountResponse(len(request.words.split()))

WordCountResponse的构造函数接受与服务定义文件中的类型相匹配的参数。

第三.我们声明这个服务,并且给他一个名字(word_count)和一个类型(WordCount),同时指定实现这一服务的回调函数:

service=rospy.Service('word_count',WordCount,count_words)

最后,我们调用rospy.spin(),将程序的执行转交给ros,只有当节点即将要退出的时候才会返回。

使用rospy.spin()是一种方便的方式来保证节点直到需要退出的时候才退出。

检查一切是否工作正常

首先在一个终端运行:roscore

然后在另一个终端运行服务节点:rosrun basic service_server.py

另一个终端查看服务:rosservice list

qqtsj@qqtsj-Nitro-AN515-:~/catkin_ws/src/basic$ rosservice list
/rosout/get_loggers
/rosout/set_logger_level
/service_server/get_loggers
/service_server/set_logger_level
/word_count

使用服务

使用时都需要运行服务节点: rosrun basic service_server.py

使用服务最简单的方式使用rosservice命令直接调用它,对于我们这个单词计数服务,如下

qqtsj@qqtsj-Nitro-AN515-:~/catkin_ws/src/basic$ rosservice call word_count 'one two three'
count:

这个命令使用的是call子命令,服务名字,以及参数。尽管这种方式允许我们调用服务并确认他在正常工作,但是他不如直接运行在另一个节点中调用有用。

我们创建一个客服端节点

例:service_client.py

  #!/usr/bin/env python
import rospy
from basic.srv import WordCount
import sys rospy.init_node('service_client') rospy.wait_for_service('word_count') word_counter =rospy.ServiceProxy('word_count',WordCount) words=''.join(sys.argv[:]) word_count=word_counter(words) print words,'->',word_count.count

首先等待服务端声明这个服务:rospy.wait_for_service('word_count')

如果我们尝试在服务被声明之前使用它,这个调用会失败,并抛出异常,这是话题和服务的一个主要区别。即使一个人话题还没声明,我们也可以订阅他,一旦服务被声明,我们可以给他配置一个本地代理;

word_counter= rospy.ServiceProxy('word_count',WordCount)

我们需要指定服务的名字(word_count)和类型(WordCount)

然后使用catkin_make命令和source devel/setup.bash命令编译并配置文件

再运行服务节点和客服端节点

qqtsj@qqtsj-Nitro-AN515-:~/catkin_ws/src/basic$ rosrun basic service_server.py 
qqtsj@qqtsj-Nitro-AN515-:~/catkin_ws/src/basic$ rosrun basic service_client.py 'one two three five'
one two three five ->

服务就实现了

小结

在这之前,已经学会话题发布和订阅消息,现在已经了解了关于服务的一切内容,这是ROS中的第二种的主要通信机制。服务只是进程间的同步调用并且允许显示的节点间双向通信。

服务一般只是做哪些偶尔会做的事,或这当你需要同步的响应的时候,服务的回调函数中的计算应该较短,并能够在有限的时间中完成。

ROS之服务的更多相关文章

  1. ROS 创建服务和请求

    教程 维基 http://wiki.ros.org/cn/ROS/Tutorials 快速过程 创建包 $ cd ~/catkin_ws $ mkdir ~/catkin_ws/src $ cd ~/ ...

  2. 一个ROS的服务,使机器人向前移动指定距离

    源代码有点长,放文末链接里了. 服务描述及代码现在的服务是:请求时携带要前进的距离,然后底盘前进相应距离.代码如下,改动很小: #!/usr/bin/env python import rospyfr ...

  3. 理解ros服务和参数 ---- 7

    原创博客:转载请表明出处:http://www.cnblogs.com/zxouxuewei/  周学伟 Description: 本教程介绍了ROS 服务和参数的知识,以及命令行工具rosservi ...

  4. ROS Learning-013 beginner_Tutorials (编程) 编写ROS服务版的Hello World程序(Python版)

    ROS Indigo beginner_Tutorials-12 编写ROS服务版的Hello World程序(Python版) 我使用的虚拟机软件:VMware Workstation 11 使用的 ...

  5. ROS之VPN服务器设置教程.

    关于ROS系统的安装此处将不再累述,可以自行谷歌,百度搜索“ROS 安装配置教程”. (安装方法可以使用光盘安装,USB引导安装,硬盘写入.) 好了,演示创建VPN服务器的方法: 1.使用WinBox ...

  6. ROS是Robot Operating System

    ROS是Robot Operating System 机器人操作系统ROS | 简介篇   同样,从个人微信公众号Nao(ID:qRobotics)搬运. 前言 先放一个ROS Industrial一 ...

  7. 机器人操作系统ROS | 简介篇

    同样,从个人微信公众号Nao(ID:qRobotics)搬运. 前言 先放一个ROS Industrial一周年剪辑视频. ROS已经发布八周年了,在国外科研机构中非常受欢迎.目前,以美国西南研究院为 ...

  8. ROS新闻 Towards ROS-native drones 无人机支持方案

    PX4/Firmware:https://github.com/PX4/Firmware PXFmini An open autopilot daughter-board for the Raspbe ...

  9. ROS_Kinetic_05 ROS基础内容(二)

    ROS_Kinetic_05 ROS基础内容(二) 1. ROS节点node 官网教程:http://wiki.ros.org/cn/ROS/Tutorials/UnderstandingNodes ...

随机推荐

  1. 调用第三方库时需注意MD/MT的链接编译方式(遇到的坑记录)

    MD与/MT编译 1./MD是动态库链接方式编译 (DEBUG版本是/MDd) 2./MT是静态库链接方式编译 (DEBUG版本是/MTd) 编译器不会检查到的问题 我今天遇到的记录下来 当你调用第三 ...

  2. The Annual Summary Of 2019

    Time is flying, it arrives at the end of year again. This is my first year working in PinDuoDuo inc ...

  3. [02]java数据类型和运算符等知识

    00 Java中的注释 为了方便程序的阅读,Java语言允许程序员在程序中写上一些说明性的文字,用来提高程序的可读性,这些文字性的说明就称为注释.注释不会出现在字节码文件中,即Java编译器编译时会跳 ...

  4. 从0开发3D引擎(四):搭建测试环境

    目录 上一篇博文 了解自动化测试 单元测试 集成测试 端对端测试 通过打印日志来调试 了解运行测试 断点调试 通过Spector.js测试WebGL 通过log调试Shader 移动端测试 了解性能测 ...

  5. 初学者的API测试技巧

    API(应用程序编程接口)测试是一种直接在API级别执行验证的软件测试.它是集成测试的一部分,它确认API是否满足测试人员对功能.可靠性.性能和安全性的期望.与UI测试不同,API测试是在没有GUI层 ...

  6. SpringBoot系列之集成Dubbo的方式

    SpringBoot系列之集成Dubbo的方式 本博客介绍Springboot框架集成Dubbo实现微服务的3种常用方式,对于Dubbo知识不是很熟悉的,请先学习我上一篇博客:SpringBoot系列 ...

  7. Spring HTTP invoker简介

    Spring HTTP invoker简介 Spring HTTP invoker是spring框架中的一个远程调用模型,执行基于HTTP的远程调用(意味着可以通过防火墙),并使用java的序列化机制 ...

  8. Linux上的Tomcat地址映射,且404错误解决

    问题:现在想要加一个下载文件功能,但是文件地址不在tomcat的webapps下,需要通过地址映射到tomcat下面再通过链接执行下载文件功能. 解决方法有两种: 方法一: 用方法一的前提是不用启动服 ...

  9. Spring Boot2 系列教程 (十二) | 整合 thymeleaf

    前言 如题,今天介绍 Thymeleaf ,并整合 Thymeleaf 开发一个简陋版的学生信息管理系统. SpringBoot 提供了大量模板引擎,包含 Freemarker.Groovy.Thym ...

  10. enum sizeof typedef分析

    1.枚举类型的使用方法 enum是C语言中的一种自定义类型 enum值是可以根据需要自定义的整型值 第一个定义的enum值默认为0 默认情况下的enum值是在前一个定义值的基础上加1 enum类型的变 ...