ROS学习经历(5)——服务
本章主要讲述服务这一通讯机制。
1. 服务介绍
服务与话题不同,话题是没有返回的,只适用于单向或大量的数据传递。而服务是双向的,客户端发送请求,服务端相应客户端的请求。
在使用服务时,我们需要注意:
- 同一服务(名称相同)有且只能有一个节点来提供
- 同一服务可以被多个客户端调用
1.1 服务的常用指令
1)查看服务列表
ros2 service list
2)手动调用服务
ros2 service call /add_two_ints example_interfaces/srv/AddTwoInts "{a: 5,b: 10}"
3)查看服务接口类型
ros2 service type /add_two_ints
4)查看使用某一接口的服务
ros2 service find example_interfaces/srv/AddTwoInts
1.2 背景故事
之后,我们将用服务来实现一些故事:
1)李三借钱
李四写小说赚钱后,好心借村里人钱。但李四借钱是有自己规矩的:
- 借钱一定要写欠条
- 借的钱不能超过自己资金的10%
2)王二卖二手书
王二看完书后,想筹更多钱买,所以他开始向外借二手书,同样他借二手书也有两个要求:
- 必须一手交钱,一手交货
- 每次给多少钱,卖多少章,如果手中的存货不足,就继续等待
现在让我们来体验一下服务,如何实现这些功能吧。
2. 服务实现
2.1 创建借书服务接口
不同于话题接口的创建,服务是双向的。在创建服务接口时,我们需要去定义一去一回两种数据类型。
2.1.1 确定服务类型
在李三借钱的故事中:
去的数据类型:借钱人(客户端)根据李四的要求,需要写欠条,那欠条至少包含两种信息
- 借钱者名字,字符串类型,可以用string表示
*金额,整型,可以用uint32 表示
回的数据类型:借钱后,李四会表示什么?
- 是否出借:成功或失败,布尔类型,用bool表示
- 出借金额:钱,无符号整型,用uint32表示
2.1.2 创建srv文件夹以及BorrowMoney.srv消息文件
1)在village_interfaces下创建srv文件夹。
cd src/village_interfaces
mkdir srv && cd srv
touch BorrowMoney.srv
2)编写文件内容,注意格式
数据类型 + 名称
string name
uint32 money
---
bool success
uint32 money
3)修改CMakeLists.txt,在前面我们添加了依赖DEPENDENCIES和msg文件了,所以我们再添加一个srv.
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
#---msg---
"msg/Novel.msg"
#---srv---
"srv/BorrowMoney.srv"
DEPENDENCIES sensor_msgs
)
4)修改package.xml,我们前面也修改了
<build_depend>sensor_msgs</build_depend>
<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
2.1.3 编译
colcon build --packages-select village_interfaces
2.1.4 测试
source install/setup.bash
ros2 interface package village_interfaces
ros2 interface show village_interfaces/srv/BorrowMoney
ros2 interface proto village_interfaces/srv/BorrowMoney
2.2 创建买书服务接口
2.2.1 确定数据结构
在王二借书的故事中:
去数据类型:买书人(客户端)给钱就行了
- 买书的钱,无符号整型,uint32
回数据类型:王二收到钱后,则需要返回小说章节
- 小说,字符串类型,string
2.2.2 创建srv文件夹以及SellNovel.srv消息文件
由于srv文件夹已经创建,那么我们创建SellNoel.srv
cd src/village_interfaces
cd srv
touch SellNovel.srv
2.2.3 编写文件内容
uint32 money
---
string[] novels # 表示小说的数组
wang2收到钱后,返回多章小说
2.2.4 修改CMakeList.txt
添加一行代码"srv/SellNovel.srv"
即可
rosidl_generate_interfaces(${PROJECT_NAME}
#---msg---
"msg/Novel.msg"
#---srv---
"srv/BorrowMoney.srv"
"srv/SellNovel.srv"
DEPENDENCIES sensor_msgs
)
2.2.5 修改package.xml
上面已经修改
2.2.6 编译
编译一般在我们的工作空间下工作
colcon build --packages-select village_interfaces
2.2.7 测试
source install/setup.bash
ros2 interface package village_interfaces
ros2 interface show village_interfaces/srv/SellNovel
ros2 interface proto village_interfaces/srv/SellNovel
3 总结
在本章,我们讲了服务,创建了服务接口,下章我们将实现服务。