服务(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. 看完知乎上500条答案,我为大家整理了这21个B站学习类UP主

    原文之前发在我的知乎,转载请注明出处. ​ 虽然,今天算法文章还没更新┏(゜ロ゜;)┛,但还是溜过来跑个题~ 之前看到了博客上有小伙伴在分享自己的B站资源,才突然意识到自己其实也积攒了很多优秀UP的资 ...

  2. 用c++ 给易语言写支持库学习记录

    废话我就不对说 直接开始 易语言官方下载的易语言安装路径下 有一个SDK文件夹 我们点进入cpp文件夹里面提供是c++的SDK elib文件夹里就是sdk 我们新建一个win32项目 这里我用的是VS ...

  3. $51nod\ 1522$ 上下序列 $dp$

    正解:$dp$ 解题报告: 传送门$QwQ$ 一年过去了$gql$还是不咋会这题,,,好菜昂我的$NOIp$必将惨败了$kk$ 考虑从大到小枚举两个相同的数填哪儿,根据那个限制,十分显然的是这两个数必 ...

  4. Django 链接MySQL及数据操作

    Django 链接MySQL Django创建的项目自带的数据库是SQLite3,我们想要链接MySQL的话,需要更改settings.py中的配置 1.在MySQL中创建好数据库,Django项目不 ...

  5. 1054 求平均值 (20 分)C语言

    本题的基本要求非常简单:给定 N 个实数,计算它们的平均值.但复杂的是有些输入数据可能是非法的.一个"合法"的输入是 [−1000,1000] 区间内的实数,并且最多精确到小数点后 ...

  6. Linux下离线安装gdb及常用命令汇总

    以redhat6.5虚拟机作为例子,由于工作性质,大部分情况linux的软件安装,是采用离线方式的. 1.离线安装gdb 像gcc.g++或者gdb这种常用的工具软件,一般虚拟机都会安装的,如未安装, ...

  7. 一条SQL注入引出的惊天大案

    前情回顾: WAF公司拦截到一个神秘的HTTP数据包,在这个包的表单字段中发现了SQL语句.目标指向80端口,而这正是nginx公司的地盘.详情参见:一个HTTP数据包的奇幻之旅 虚拟机的世界 一个安 ...

  8. docker练习-群

    了解Swarm集群 群集是一组运行Docker并加入群集的计算机.在此之后,继续运行使用的Docker命令,但现在它们由群集管理器在群集上执行.群中的机器可以是物理的或虚拟的.加入群组后,它们被称为节 ...

  9. docker+mysql 更改配置后重启不了的解决方案

    docker+mysql 更改配置后重启不了的解决方案 前提:在最近的项目中,决定将项目改造成数据库读写分离的架构,于是擅自更改生产环境的数据库的配置文件my.cnf,由于我是用docker进行部署的 ...

  10. 微信小程序之双重循环(包含左滑删除,以及数据各项处理)

    <view wx:for="{{hommer}}" wx:for-item="item" wx:for-index="index" w ...