2.2.4 服务通信自定义srv调用B(Python)
需求:
编写服务通信,客户端提交两个整数至服务端,服务端求和并响应结果到客户端。
分析:
在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:
- 服务端
- 客户端
- 数据
流程:
- 编写服务端实现;
- 编写客户端实现;
- 为python文件添加可执行权限;
- 编辑配置文件;
- 编译并执行。
0.vscode配置
需要像之前自定义 msg 实现一样配置settings.json 文件,如果以前已经配置且没有变更工作空间,可以忽略,如果需要配置,配置方式与之前相同:
{
"python.autoComplete.extraPaths": [
"/opt/ros/noetic/lib/python3/dist-packages",
]
}
1.服务端
#! /usr/bin/env python
"""
需求:
编写两个节点实现服务通信,客户端节点需要提交两个整数到服务器
服务器需要解析客户端提交的数据,相加后,将结果响应回客户端,
客户端再解析
服务器端实现:
1.导包
2.初始化 ROS 节点
3.创建服务对象
4.回调函数处理请求并产生响应
5.spin 函数
"""
# 1.导包
import rospy
from demo03_server_client.srv import AddInts,AddIntsRequest,AddIntsResponse
# 回调函数的参数是请求对象,返回值是响应对象
def doReq(req):
# 解析提交的数据
sum = req.num1 + req.num2
rospy.loginfo("提交的数据:num1 = %d, num2 = %d, sum = %d",req.num1, req.num2, sum)
# 创建响应对象,赋值并返回
# resp = AddIntsResponse()
# resp.sum = sum
resp = AddIntsResponse(sum)
return resp
if __name__ == "__main__":
# 2.初始化 ROS 节点
rospy.init_node("addints_server_p")
# 3.创建服务对象
server = rospy.Service("AddInts",AddInts,doReq)
# 4.回调函数处理请求并产生响应
# 5.spin 函数
rospy.spin()
2.客户端
#! /usr/bin/env python
"""
需求:
编写两个节点实现服务通信,客户端节点需要提交两个整数到服务器
服务器需要解析客户端提交的数据,相加后,将结果响应回客户端,
客户端再解析
客户端实现:
1.导包
2.初始化 ROS 节点
3.创建请求对象
4.发送请求
5.接收并处理响应
优化:
加入数据的动态获取
"""
#1.导包
import rospy
from demo03_server_client.srv import *
import sys
if __name__ == "__main__":
#优化实现
if len(sys.argv) != 3:
rospy.logerr("请正确提交参数")
sys.exit(1)
# 2.初始化 ROS 节点
rospy.init_node("AddInts_Client_p")
# 3.创建请求对象
client = rospy.ServiceProxy("AddInts",AddInts)
# 请求前,等待服务已经就绪
# 方式1:
# rospy.wait_for_service("AddInts")
# 方式2
client.wait_for_service()
# 4.发送请求,接收并处理响应
# 方式1
# resp = client(3,4)
# 方式2
# resp = client(AddIntsRequest(1,5))
# 方式3
req = AddIntsRequest()
# req.num1 = 100
# req.num2 = 200
#优化
req.num1 = int(sys.argv[1])
req.num2 = int(sys.argv[2])
resp = client.call(req)
rospy.loginfo("响应结果:%d",resp.sum)
3.设置权限
终端下进入 scripts 执行:chmod +x *.py
4.配置 CMakeLists.txt
CMakeLists.txt
catkin_install_python(PROGRAMS
scripts/AddInts_Server_p.py
scripts/AddInts_Client_p.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
5.执行
流程:
需要先启动服务:
rosrun 包名 服务
然后再调用客户端 :
rosrun 包名 客户端 参数1 参数2
结果:
会根据提交的数据响应相加后的结果。