|
@@ -6,19 +6,14 @@
|
|
|
|
|
|
## 1.如何编写一个Python服务
|
|
|
|
|
|
-开始之前,我们先说一下创建ROS2服务端和客户端的基本步骤。
|
|
|
+开始之前,我们先说一下创建ROS2服务端基本步骤。
|
|
|
|
|
|
首先是服务端:
|
|
|
|
|
|
-- 创建与导入服务接口
|
|
|
-- 创建服务端并定义服务端回调函数
|
|
|
-- 编写回调函数处理数据并返回结果
|
|
|
-
|
|
|
-客户端
|
|
|
-
|
|
|
-- 导入服务接口
|
|
|
-- 创建客户端及客户端接收服务结果的回调函数
|
|
|
-- 在回调函数中处理服务端返回结果
|
|
|
+1. 导入服务接口
|
|
|
+2. 创建服务端回调函数
|
|
|
+3. 声明并创建服务端
|
|
|
+4. 编写回调函数逻辑处理请求
|
|
|
|
|
|
|
|
|
|
|
@@ -163,7 +158,7 @@ ros2 service list -t #服务列表带类型
|
|
|
|
|
|
接着我们使用命令行来手动调用服务,不知道你还是否记得4.7中我们手动调用服务将两个数字相加。
|
|
|
|
|
|
-这里我们手动调用服务用李三的名义来借5块钱。
|
|
|
+这里我们手动调用服务用李三的名义来借5块钱
|
|
|
|
|
|
```
|
|
|
source install/setup.bash
|
|
@@ -188,6 +183,15 @@ ros2 service call /borrow_money village_interfaces/srv/BorrowMoney "{name: 'li3
|
|
|
|
|
|
服务端搞定了后,我们来编写客户端李三这边的代码。
|
|
|
|
|
|
+编写服务通信的客户端的一般步骤:
|
|
|
+
|
|
|
+1. 导入服务接口
|
|
|
+2. 创建请求结果接收回调函数
|
|
|
+3. 声明并创建客户端
|
|
|
+4. 编写结果接收逻辑
|
|
|
+5. 调用客户端发送请求
|
|
|
+
|
|
|
+
|
|
|
### 4.1导入服务接口
|
|
|
|
|
|
第一步和服务端相同,导入对应的接口,因为李四和李三是在同一个包`village_li`内,所以不需要再次修改`package.xml`。
|
|
@@ -197,8 +201,19 @@ ros2 service call /borrow_money village_interfaces/srv/BorrowMoney "{name: 'li3
|
|
|
```
|
|
|
from village_interfaces.srv import BorrowMoney
|
|
|
```
|
|
|
+### 4.2创建请求结果接收回调函数
|
|
|
+
|
|
|
+编写`borrow_respoonse_callback`借钱结果回调函数,该函数的只有一个入口参数`response`
|
|
|
+
|
|
|
+```
|
|
|
+def borrow_respoonse_callback(self,response):
|
|
|
+ """
|
|
|
+ 借钱结果回调
|
|
|
+ """
|
|
|
+ pass
|
|
|
+```
|
|
|
|
|
|
-### 4.2创建客户端并定义完成时回调函数
|
|
|
+### 4.3创建客户端并定义结果回调函数
|
|
|
|
|
|
李三继承于Node,也具备了创建客户端的能力
|
|
|
|
|
@@ -206,7 +221,7 @@ from village_interfaces.srv import BorrowMoney
|
|
|
class BaiPiaoNode(Node): #BaiPiaoNode是继承于Node
|
|
|
```
|
|
|
|
|
|
-#### 4.2.1 创建客户端
|
|
|
+创建客户端
|
|
|
|
|
|
```
|
|
|
#在__init__函数中创建一个服务的客户端
|
|
@@ -217,9 +232,27 @@ self.borrow_money_client_ = self.create_client(BorrowMoney, "borrow_money")
|
|
|
|
|
|
> 这里的两个参数需和服务端的完全一致,方可通信。名字不一致,会找不到对应服务,数据类型不一致会导致无法通信。
|
|
|
|
|
|
-### 4.3 发送异步请求,并编写返回结果回调函数
|
|
|
+### 4.4 编写结果回调函数处理逻辑
|
|
|
|
|
|
-#### 4.3.1 编写发送请求函数
|
|
|
+根据结果说不同的话
|
|
|
+
|
|
|
+```
|
|
|
+ def borrow_respoonse_callback(self,response):
|
|
|
+ """
|
|
|
+ 借钱结果回调
|
|
|
+ """
|
|
|
+ # 打印一下信息
|
|
|
+ result = response.result()
|
|
|
+ if result.success == True:
|
|
|
+ self.get_logger().info("果然是亲弟弟,借到%d,吃麻辣烫去了" % result.money)
|
|
|
+ else:
|
|
|
+ self.get_logger().info("害,连几块钱都不借,我还是不是他亲哥了,世态炎凉呀")
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+### 4.5 编写发送请求逻辑
|
|
|
+
|
|
|
+#### 4.5.1创建发送请求函数
|
|
|
|
|
|
接着我们在`BaiPiaoNode中`编写一个函数用于创建发送的数据,并发送请求。
|
|
|
|
|
@@ -248,28 +281,10 @@ def borrow_money_eat(self):
|
|
|
- `wait_for_service(1.0)`用于等待服务上线,这是一种很优雅的做法,调用之前检测一下服务是否在线
|
|
|
- `call_async(request).add_done_callback`这里是代码的核心部分,用于发送请求,并且添加了一个任务完成时的回调函数`borrow_respoonse_callback`
|
|
|
|
|
|
-#### 4.3.2 编写回调函数
|
|
|
-
|
|
|
-编写`borrow_respoonse_callback`借钱结果回调函数,该函数的只有一个入口参数`response`
|
|
|
-
|
|
|
-我们可以从response中拿到数据并进行处理,该函数完整代码如下:
|
|
|
-
|
|
|
-```
|
|
|
- def borrow_respoonse_callback(self,response):
|
|
|
- """
|
|
|
- 借钱结果回调
|
|
|
- """
|
|
|
- # 打印一下信息
|
|
|
- result = response.result()
|
|
|
- if result.success == True:
|
|
|
- self.get_logger().info("果然是亲弟弟,借到%d,吃麻辣烫去了" % result.money)
|
|
|
- else:
|
|
|
- self.get_logger().info("害,连几块钱都不借,我还是不是他亲哥了,世态炎凉呀")
|
|
|
-```
|
|
|
|
|
|
-#### 4.2.3 修改main函数调用发送请求函数
|
|
|
+#### 4.5.2修改main函数调用发送请求函数
|
|
|
|
|
|
-因为发送请求的函数是李三的成员函数,所以我们直接调用李三来发送请求即可,可以将main函数做如下修改(其实只增加了一行代码而已)。
|
|
|
+因为发送请求的函数是BaiPiaoNode的成员函数,所以我们直接调用BaiPiaoNode来发送请求即可,可以将main函数做如下修改(其实只增加了一行代码而已)。
|
|
|
|
|
|
```
|
|
|
def main(args=None):
|
|
@@ -341,7 +356,7 @@ ros2 run village_li li4_node
|
|
|
|
|
|
/imgs/image-20210817105329996.png)
|
|
|
|
|
|
-从图片中可以看到,李三借钱失败了,虽然小鱼已经将李四账户里的钱的默认值从0元修改成了80元,但80*0.1=8<10,依然不能借给李三十块钱,那为了李三能够吃上麻辣烫,我们可以帮助李四赚钱——让王二过来进行知识付费。
|
|
|
+从图片中可以看到,李三借钱失败了,原因80*0.1=8<10,不能借给李三十块钱,符合李四做人原则,那为了李三能够吃上麻辣烫,我们可以帮助李四赚钱——让王二过来进行知识付费。
|
|
|
|
|
|
### 5.4运行王二过来知识付费
|
|
|
|
|
@@ -368,5 +383,4 @@ ros2 run village_li li3_node
|
|
|
|
|
|
|
|
|
|
|
|
-如果还有不明白的地方,欢迎加入鱼群交流。
|
|
|
-
|
|
|
+如果还有不明白的地方,欢迎加入鱼群交流。
|