# 4.1 Service
## 4.1.1 Service
上一章我们介绍了ROS的通信方式中的topic\(主题\)通信,我们知道topic是ROS中的一种单向的异步通信方式。然而有些时候单向的通信满足不了通信要求,比如当一些节点只是临时而非周期性的需要某些数据,如果用topic通信方式时就会消耗大量不必要的系统资源,造成系统的低效率高功耗。
这种情况下,就需要有另外一种请求-查询式的通信模型。这节我们来介绍ROS通信中的另一种通信方式——service\(服务\)。
## 4.1.2 工作原理
### 简介
为了解决以上问题,service方式在通信模型上与topic做了区别。Service通信是双向的,它不仅可以发送消息,同时还会有反馈。所以service包括两部分,一部分是请求方(Clinet),另一部分是应答方/服务提供方(Server)。这时请求方(Client)就会发送一个request,要等待server处理,反馈回一个reply,这样通过类似“请求-应答”的机制完成整个服务通信。
这种通信方式的示意图如下:
Node B是server(应答方),提供了一个服务的接口,叫做`/Service`,我们一般都会用string类型来指定service的名称,类似于topic。Node A向Node B发起了请求,经过处理后得到了反馈。
![](https://img.kancloud.cn/c2/ed/c2ed52513cb16183a8a933f69488ce75_1026x206.png)
### 过程
Service是同步通信方式,所谓同步就是说,此时Node A发布请求后会在原地等待reply,直到Node B处理完了请求并且完成了reply,Node A才会继续执行。Node A等待过程中,是处于阻塞状态的成通信。这样的通信模型没有频繁的消息传递,没有冲突与高系统资源的占用,只有接受请求才执行服务,简单而且高效。
## 4.1.3 topic VS service
我们对比一下这两种最常用的通信方式,加深我们对两者的理解和认识,具体见下表:
| 名称 | Topic | Service |
| :---: | :---: | :---: |
| 通信方式 | 异步通信 | 同步通信 |
| 实现原理 | TCP/IP | TCP/IP |
| 通信模型 | Publish-Subscribe | Request-Reply |
| 映射关系 | Publish-Subscribe\(多对多\) | Request-Reply(多对一) |
| 特点 | 接受者收到数据会回调(Callback) | 远程过程调用(RPC)服务器端的服务 |
| 应用场景 | 连续、高频的数据发布 | 偶尔使用的功能/具体的任务 |
| 举例 | 激光雷达、里程计发布数据 | 开关传感器、拍照、逆解计算 |
**注意:**远程过程调用\(Remote Procedure Call,RPC\),可以简单通俗的理解为在一个进程里调用另一个进程的函数。
## 4.1.4 操作命令
在实际应用中,service通信方式的命令时`rosservice`,具体的命令参数如下表:
| rosservice 命令 | 作用 |
| :---: | :---: |
| `rosservice list` | 显示服务列表 |
| `rosservice info` | 打印服务信息 |
| `rosservice type` | 打印服务类型 |
| `rosservice uri` | 打印服务ROSRPC uri |
| `rosservice find` | 按服务类型查找服务 |
| `rosservice call` | 使用所提供的args调用服务 |
| `rosservice args` | 打印服务参数 |
## 4.1.5 测试实例
1. 首先依然是打开我们教材的模拟场景`roslaunch robot_sim_demo robot_spawn.launch`。
2. 输入`rosservice list`,查看当前运行的服务。
3. 随机选择`/gazebo/delete_light`服务,观察名称,是删除光源的操作。
4. 输入`rosservice info /gazebo/delete_light`查看属性信息。可以看到信息,Node:/gazebo,Type:gazebo\_msgs/DeleteLight, Args:Light\_name。这里的类型type也就是下文介绍的srv,传递参数Light\_name
5. 输入`rosservice call /gazebo/delete_light sun`,这里的sun 是参数名,使我们模拟场景中的唯一光源太阳。操作完成后可以看到场景中的光线消失。
6. 可以看到终端的回传信息:success: True和sun successfully deleted。这就是双向通信的信息反馈,通知操作已经成功完成。
## 小结
本节我们详细介绍了service通信方式,建议与topic通信方式进行对比记忆,这样我们能更深的理解这两种通信方式,也能在以后的学习工作中更加合理使用每个通信方式,获得更高的效率。
- 前言
- 第一章 ROS简介
- 机器人时代的到来
- ROS发展历程
- 什么是ROS
- 安装ROS
- 安装ROS-Academy-for-Beginners教学包
- 二进制与源码包
- 安装RoboWare Studio
- 单元测试一
- 第二章 ROS文件系统
- Catkin编译系统
- Catkin工作空间
- Package软件包
- CMakeLists.txt
- package.xml
- Metapacakge软件元包
- 其他常见文件类型
- 单元测试二
- 第三章 ROS通信架构(一)
- Node & Master
- Launch文件
- Topic
- Msg
- 常见msg类型
- 单元测试三
- 第四章 ROS通信架构(二)
- Service
- Srv
- Parameter server
- Action
- 常见srv类型
- 常见action类型
- 单元测试四
- 第五章 常用工具
- Gazebo
- RViz
- Rqt
- Rosbag
- Rosbridge
- moveit!
- 单元测试五
- 第六章 roscpp
- Client Library与roscpp
- 节点初始、关闭与NodeHandle
- Topic in roscpp
- Service in roscpp
- Param in roscpp
- 时钟
- 日志与异常
- 第七章 rospy
- Rospy与主要接口
- Topic in rospy
- Service in rospy
- Param与Time
- 第八章 TF与URDF
- 认识TF
- TF消息
- tf in c++
- tf in python
- 统一机器人描述格式
- 附录:TF数学基础
- 三维空间刚体运动---旋转矩阵
- 三维空间刚体运动---欧拉角
- 三维空间刚体运动---四元数
- 第九章 SLAM
- 地图
- Gmapping
- Karto
- Hector
- 第十章 Navigation
- Navigation Stack
- move_base
- costmap
- Map_server & Amcl
- 附录:Navigation工具包说明
- amcl
- local_base_planner
- carrot_planner
- clear_costmap_recovery
- costmap_2d
- dwa_local_planner
- fake_localization
- global_planner
- map_server
- move_base_msg
- move_base
- move_slow_and_clear
- navfn
- nav_core
- robot_pose_ekf
- rotate_recovery