ROS学习(二)server和client的编写总结
东南大学 ZSCSEU
今天,总结了一下ROS中使用python编写服务端和客户端的栗子。
首先,定义了一个名为add.srv的文件,里面的内容如下:
然后,编写add_two.py(服务端)代码如下
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
from beginner_test.srv import *
class add_ser():
def __init__(self):
rospy.init_node('add_s',anonymous=False)
r=rospy.Rate(10)
rospy.on_shutdown(self.shutdown)
self.add_two()
def add_two(self):
rospy.loginfo('Ready...')
self.s=rospy.Service('add2',add,self.handle)
def handle(self,req):
print '结果是[%s+%s=%s]'%(req.a,req.b,(req.a+req.b))
return addResponse(req.a+req.b)
def shutdown(self):
rospy.loginfo('Stop...')
rospy.sleep(1)
if __name__=='__main__':
try:
add_ser()
rospy.spin()
except:
rospy.loginfo('Error...')
我觉得有必要对代码做一些解释,因为自己写的时候由于是初学者,感觉很乱。可能是编程能力低的缘故,我觉得梳理一下会比较清楚。
首先,我们先定义一个add_ser()的类,并在__init__()函数里做一些初始化;
后面就是一些类成员函数了:
(1)self.s=rospy.Service('add2',add,self.handle)
这句话我们定义了一个名为“add2”的服务,数据类型是add,这与我们定义的.srv文件是同名的。因为在catkin_make的时候会创建程需要的头文件【这些头文件放在/工作空间/devel/include/包/目录下,与 .srv文件同名,所以第二个参数必需与之同名】,最后一个参数是此服务调用的函数句柄。
(2)关于函数 handle()
这个函数是服务add2调用的函数,处理从客户端传输过来的参数;
注意return时,addResponse也必须要和“/工作空间/devel/include/包/”目录下的名字对应一致。
完成了服务器的编写,下面我们要进行客户端的编程,代码如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
import sys
#from std_msgs.msg import int64
from beginner_test.srv import *
class client():
def __init__(self):
rospy.init_node('cli',anonymous=False)
r=rospy.Rate(10)
rospy.on_shutdown(self.shutdown)
self.add_two()
def add_two(self):
rospy.wait_for_service('add2')
if len(sys.argv)==3:
x=int(sys.argv[1])
y=int(sys.argv[2])
print x,y
else:
rospy.loginfo('failed...')
try:
self.add1=rospy.ServiceProxy('add2',add)
self.res=self.add1(x,y)
print self.res.sum
return self.res.sum
except:
rospy.loginfo('service call failed!')
# def use(self):
# return "%s [x,y]"%sys.argv[0]
#
def shutdown(self):
rospy.loginfo('Stop..')
rospy.sleep(1)
if __name__=='__main__':
try:
client()
rospy.spin()
except:
rospy.loginfo('baba')
客户端代码主要注意add_two()函数,首先等待服务可用,之后判断客户端输入的参数是否符合条件:
注意python中sys.argv的用法,比方说你在运行节点的时候输入的参数是4 5 6三个数,则程序会报错。
之后再调用服务求解结果并将结果返回。
总结:
通过这样的总结反思,比较详细的了解了编写过程。我觉得,有时候官网的教程如果直接照着搬过来的话理解可能不深入(编程大神自动跳过),所以自己把变量还有编程形式改一改,可能会更有助于理解程序,为以后的开发打好基础。【比如,我就是把官网的python教程豆试用面向对象的思想重新写了一遍!附上官网链接:http://wiki.ros.org/rospy_tutorials/Tutorials/WritingServiceClient】