ROS服务端(Server)和客户端(Client)的python编程实现(保姆级教程)
ROS服务端(Server)和客户端(Client)的python编程实现
引言
这个教程是和之前的有些联系的,基础以及重复的知识我就不做讲解啦,本身这个内容也不是太难,关于之前的话题通信以及怎么创建msg或者srv大家可以看之前的教程。
传送门:
ROS发布者(Publisher)和订阅者(Subscriber)的python编程实现(讲解超级详细)
创建ROS消息(msg)和服务(srv)
接下来让我们进入正题吧!
一、创建功能包
我们在之前的工作空间创建一个service的功能包,用来存放这个教程的所有文件:
让我们先整体看一下这个功能包的文件,主要有一个客户端和一个服务端程序,然后还有一个srv文件:
AddTwoInts.srv
内容如下:
int64 A
int64 B
---
int64 Sum
二、编写服务端节点
我们将创建简单的服务端节点add_two_ints_server
,该节点将接收两个整数,并返回它们的和。
整体代码如下:
#!/usr/bin/env python
from __future__ import print_function
from service.srv import AddTwoInts,AddTwoIntsResponse #注意是功能包名.srv
import rospy
def handle_add_two_ints(req):
print("Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b)))
return AddTwoIntsResponse(req.a + req.b)
def add_two_ints_server():
rospy.init_node('add_two_ints_server')
s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
print("Ready to add two ints.")
rospy.spin()
if __name__ == "__main__":
add_two_ints_server()
我们使用rospy.init_node()
声明我们的节点,然后再声明我们的服务:
s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
这声明了一个名为add_two_ints
的新服务,其服务类型为AddTwoInts
。所有的请求(request)都传递给了handle_add_two_ints
函数。handle_add_two_ints
被AddTwoIntsRequest
的实例调用,返回AddTwoIntsResponse
实例。就像订阅者中的例子一样,rospy.spin()
可以防止程序在服务关闭之前退出。
如何实现一个服务端节点?
1.初始化ROS节点;
2.创建Server实例;
3.循环等待服务请求,进入回调函数;
4.在回调函数中完成服务功能的处理,并反馈应答数据。
二、编写客户端节点
整体代码如下:
#!/usr/bin/env python
from __future__ import print_function
import sys
import rospy
from service.srv import * #注意是功能包名.srv
def add_two_ints_client(x, y):
rospy.wait_for_service('add_two_ints')
try:
add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
resp1 = add_two_ints(x, y)
return resp1.sum
except rospy.ServiceException as e:
print("Service call failed: %s"%e)
def usage():
return "%s [x y]"%sys.argv[0]
if __name__ == "__main__":
if len(sys.argv) == 3:
x = int(sys.argv[1])
y = int(sys.argv[2])
else:
print(usage())
sys.exit(1)
print("Requesting %s+%s"%(x, y))
print("%s + %s = %s"%(x, y, add_two_ints_client(x, y)))
对于客户端来说不需要调用init_node()。我们首先调用:
rospy.wait_for_service('add_two_ints')
这是一种很方便的方法,可以让在add_two_ints服务可用之前一直阻塞。
add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
这里我们为服务的调用创建了一个句柄(handle)。
resp1 = add_two_ints(x, y)
return resp1.sum
然后我们可以使用这个句柄,就像普通的函数一样调用它。
因为我们已经将服务的类型声明为AddTwoInts
,它会为你生成AddTwoIntsRequest
对象。如果调用失败,rospy.ServiceException
将会抛出,所以应该编写一个合适的try/except
部分(异常处理)。
如何实现一个客户端节点?
1.初始化ROS节点;
2.创建一个Client实例;
3.发布服务请求数据;
4.等待Server处理之后的应答结果。
三、编译
我们需要在package.xml
添加如下内容:
CMakeLists.txt
整体如下:
然后进行编译。
这些内容之前都有讲解,这里就不一一赘述啦。
四、运行结果
五、服务通信机制
六、话题与服务区别
本文内容参考:
ROS官方wiki:http://wiki.ros.org
古月——ROS入门21讲
《ROS机器人开发实践》
如有错误或者不足之处,欢迎大家留言指正!
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)