ROS服务通信机制实操Python
- 步骤流程
- vscode配置
- 服务端
- 客户端
- 编辑配置文件
- 编译并执行
- 优化
- 实现参数的动态提交
- 优化先启动客户端后启动服务端
ROS服务通信的理论查阅:ROS服务通信流程理论
ROS服务通信的自定义srv数据的准备可以查阅:ROS服务通信自定义srv
在模型实现中,ROS master不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:
- 服务端
- 客户端
- 数据
步骤流程
实现ROS服务通信的步骤分为以下5步:
- 1.vscode配置;
- 2.编写服务端;
- 3.编写客户端;
- 4.编辑配置文件;
- 5.编译并执行。
vscode配置
为了方便代码提示以及误抛异常,需要先配置 vscode,将前面自定义数据格式生成的 python 文件路径配置进 settings.json
服务端
-
基本流程
服务端:解析客户端请求,产生响应。- 1.导包;
- 2.初始化 ROS 节点;
- 3.创建服务端对象;
- 4.处理逻辑(回调函数);
- 5.spin()
-
代码实现
```python#! /usr/bin/env python3import rospyfrom plumbing_server_client.srv import AddInts, AddIntsRequest, AddIntsResponse"""服务端:解析客户端请求,产生响应。1.导包;2.初始化 ROS 节点;3.创建服务端对象;4.处理逻辑(回调函数);5.spin()"""def doAdd(request):num1 = request.num1num2 = request.num2sum = num1 + num2response = AddIntsResponse()response.sum = sumrospy.loginfo("服务器解析的数据: num1 = %d num2 = %d 响应的结果sum = %d",num1, num2, sum)return responseif __name__ == "__main__":# 2.初始化 ROS 节点;rospy.init_node("heiShui") # 保洁公司# 3.创建服务端对象;server = rospy.Service("addInts", AddInts, doAdd) # 参数1:话题名称 参数2:消息对应的类型 参数3:回调函数rospy.loginfo("服务器已启动!!!")# 4.处理逻辑(回调函数);# 5.spin()rospy.spin()```
-
添加可执行权限
进入到 scripts 文件下,打开Terminal,执行 chmod +x *.py 对demo_server_p.py文件添加可执行的权限
-
验证是否有问题
-
编辑配置文件
修改 plumbing_server_client 功能包下的CMakeLists.txt,找到catkin_install_python,修改成如图所示: -
按快捷键
ctrl + shift + B
编译 -
开启一个Terminal,运行 roscore 命令;再开启一个新的Terminal,运行 source ./devel/setup.bash rosrun plumbing_server_client demo_server_p.py ;再开启一个Terminal,运行 rosservice call addInts “num1: 1 num2: 2” (num1 num2是按Tab键自动补齐,然后修改数字),查看服务请求数据并响应
-
客户端
-
基本流程
客户端:组织并提交请求,处理服务端响应。- 1.导包;
- 2.初始化 ROS 节点;
- 3.创建客户端对象;
- 4.组织请求数据,并发送请求;
- 5.处理响应。
-
代码实现
#! /usr/bin/env pythonimport rospy from plumbing_server_client.srv import AddInts, AddIntsRequest, AddIntsResponse""" 客户端:组织并提交请求,处理服务端响应。1.导包;2.初始化 ROS 节点;3.创建客户端对象;4.组织请求数据,并发送请求;5.处理响应。 """if __name__ == "__main__":# 2.初始化 ROS 节点;rospy.init_node("daZhuang")# 3.创建客户端对象;client = rospy.ServiceProxy("addInts", AddInts) # 参数1:话题名称 参数2:消息对应的类型# 4.组织请求数据,并发送请求;reponse = client.call(30, 50)# 5.处理响应。rospy.loginfo("响应的数据: %d",reponse.sum)
-
添加可执行权限
进入到 scripts 文件下,打开Terminal,执行 chmod +x *.py 对demo_client_p.py文件添加可执行的权限
编辑配置文件
修改 plumbing_server_client 功能包下的CMakeLists.txt,找到catkin_install_python,修改成如图所示:
编译并执行
-
按快捷键 ctrl + shift + B 编译
-
执行代码
-
1.启动 roscore;
开启一个Terminal,启动 roscore
-
2.启动服务端;
开启一个新的Terminal -
3.启动客户端;
开启一个新的Terminal
-
优化
实现参数的动态提交
前面响应的数据都是写死的,将数据实现动态的输入,主要是修改客户端代码,服务端不用修改。
格式:rosrun xxxxx xxxxxx num1 num2
代码实现
#! /usr/bin/env python3import rospy
from plumbing_server_client.srv import AddInts, AddIntsRequest, AddIntsResponse
import sys"""
客户端:组织并提交请求,处理服务端响应。1.导包;2.初始化 ROS 节点;3.创建客户端对象;4.组织请求数据,并发送请求;5.处理响应。
"""if __name__ == "__main__":# 判断传入的参数个数if len(sys.argv) != 3:rospy.loginfo("传入参数的个数不对!!!")sys.exit(1)# 2.初始化 ROS 节点;rospy.init_node("daZhuang")# 3.创建客户端对象;client = rospy.ServiceProxy("addInts", AddInts) # 参数1:话题名称 参数2:消息对应的类型# 4.组织请求数据,并发送请求;# 解析传入的参数num1 = int(sys.argv[1])num2 = int(sys.argv[2])reponse = client.call(num1, num2)# 5.处理响应。rospy.loginfo("响应的数据: %d",reponse.sum)
编译后,启动 roscore 和服务端,然后启动客户端,同时输入请求的参数 num1 和 num2,如图所示:
优化先启动客户端后启动服务端
客户端先于服务端启动,会抛出异常
如果有先启动客户端,挂起等待服务端启动后再请求的需求。就需要调用ROS的内置等待函数 client.wait_for_service()和 rospy.wait_for_service(“服务话题”) 。
代码实现
#! /usr/bin/env python3import rospy
from plumbing_server_client.srv import AddInts, AddIntsRequest, AddIntsResponse
import sys"""
客户端:组织并提交请求,处理服务端响应。1.导包;2.初始化 ROS 节点;3.创建客户端对象;4.组织请求数据,并发送请求;5.处理响应。
"""if __name__ == "__main__":# 判断传入的参数个数if len(sys.argv) != 3:rospy.loginfo("传入参数的个数不对!!!")sys.exit(1)# 2.初始化 ROS 节点;rospy.init_node("daZhuang")# 3.创建客户端对象;client = rospy.ServiceProxy("addInts", AddInts) # 参数1:话题名称 参数2:消息对应的类型rospy.loginfo("客户端启动")# 4.组织请求数据,并发送请求;# 解析传入的参数num1 = int(sys.argv[1])num2 = int(sys.argv[2])# 等待服务端启动# client.wait_for_service()rospy.wait_for_service("addInts") # 参数:话题名称reponse = client.call(num1, num2)# 5.处理响应。rospy.loginfo("响应的数据: %d",reponse.sum)
启动客户端后,没有启动服务端,在等待服务端启动,没有抛出异常,结果如图所示:
再启动服务端后,请求进行响应,结果如图所示: