1、编写代码前的准备工作
在前面已经介绍了如何创建一个ROS空间,以及如何创建自定义的消息和服务,在这里默认你已经掌握了上述内容。假设我已经在自己的用户目录下创建了一个名为ROSworkspace的工作空间,在工作空间的src文件夹下已经创建了一个名为newpackage的软件包(功能包)。在软件包内的srv文件夹下创建了一个名为Addtwoints.srv的服务文件,服务文件的内容如下所示:
int64 a
int64 b
---
int64 sum
并且已经将上述所有代码进行了一次编译。
2、服务端节点
在~/ROSworkspace/src/newpackage/src目录下(一般一个软件包的节点可执行文件都放在这个目录下),创建一个Add_two_ints_server.py文件,文件内的代码如下所示:
#!/usr/bin/env python
#coding:utf-8
from newpackage.srv import *
import rospy
#服务提供的具体内容,通过使用请求数据,最后返回一个结果
def handle_add_two_ints(req):
print "Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b))
return 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()
创建成功后,不要忘记把.py文件变为可执行文件:(这一步非常重要。默认当前在该文件所在路径下,否则应该在文件名前面加上路径)
chmod +x Add_two_ints_server.py
使用该指令后可以用ls列出文件,可以发现文件名颜色与之前比发生了变化。
3、客户端节点
在~/ROSworkspace/src/newpackage/src目录下,创建一个Add_two_ints_client.py文件,文件内的代码如下所示:
#!/usr/bin/env python
#coding:utf-8
import sys
import rospy
from newpackage.srv import *
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, 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)
创建成功后,不要忘记把.py文件变为可执行文件:
chmod +x Add_two_ints_client.py
4、编译工程,并运行上述节点
回到工作空间目录下,并且编译工程:
cd ~/ROSworkspace
catkin_make
首先运行节点/rosout
roscore
然后打开一个新的终端,运行服务端节点Add_two_ints_server.py
rosrun newpackage Add_two_ints_server.py
结果如图:
再次重新打开一个终端,运行客户端节点Add_two_ints_client.py,并给出两个数值。
rosrun newpackage Add_two_ints_client.py 2 3
结果如图:
5、遇到问题
自己在创建完整个工程,并且编译成功后,直接在该窗口中运行节点可能会出现下面提示的错误:
No module named newpackage.srv...
将之前在建立工程的所有终端全部关闭,并且开启新的终端来运行节点,就OK了...感觉很奇怪....