10.1 撰寫service node
現在來寫一個service node, 其會接收兩個int並且return the sum
記得我們之前在第6節中已經有了srv/AddTwoIntsResponse
rosed beginner_tutorials
vim scripts/add_two_ints_server.py
1 #!/usr/bin/env python
2
3 from beginner_tutorials.srv import *
4 import rospy
5
6 def handle_add_two_ints(req):
7 print "Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b))
8 return AddTwoIntsResponse(req.a + req.b)
9
10 def add_two_ints_server():
11 rospy.init_node('add_two_ints_server')
12 s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
13 print "Ready to add two ints."
14 rospy.spin()
15
16 if __name__ == "__main__":
17 add_two_ints_server()
接下來解釋code
3 from beginner_tutorials.srv import *
從srv中import所有服務, 即所有python node
6 def handle_add_two_ints(req):
7 print "Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b))
8 return AddTwoIntsResponse(req.a + req.b)
此會接收到request這個data後將其中的數字丟給srv/AddTwoIntsResponse中並回傳sum
10 def add_two_ints_server():
11 rospy.init_node('add_two_ints_server')
12 s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
13 print "Ready to add two ints."
14 rospy.spin()
首先先初始化一個名稱為add_two_ints_server的node, 讓其可以跟master的網路連接上 接下來建立一個名為add_two_ints的service node, 其會接收類型為AddTwoInts的service, 當service接收到AddTwoInts的service type之後, 就會將其送到handle_add_two_ints這個函數當中
10.2 撰寫client node
vim scripts/add_two_ints_client.py
1 #!/usr/bin/env python
2
3 import sys
4 import rospy
5 from beginner_tutorials.srv import *
6
7 def add_two_ints_client(x, y):
8 rospy.wait_for_service('add_two_ints')
9 try:
10 add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
11 resp1 = add_two_ints(x, y)
12 return resp1.sum
13 except rospy.ServiceException, e:
14 print "Service call failed: %s"%e
15
16 def usage():
17 return "%s [x y]"%sys.argv[0]
18
19 if __name__ == "__main__":
20 if len(sys.argv) == 3:
21 x = int(sys.argv[1])
22 y = int(sys.argv[2])
23 else:
24 print usage()
25 sys.exit(1)
26 print "Requesting %s+%s"%(x, y)
27 print "%s + %s = %s"%(x, y, add_two_ints_client(x, y))
chmod +x scripts/add_two_ints_client.py
以下解釋code
7 def add_two_ints_client(x, y):
8 rospy.wait_for_service('add_two_ints')
9 try:
10 add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
11 resp1 = add_two_ints(x, y)
12 return resp1.sum
13 except rospy.ServiceException, e:
14 print "Service call failed: %s"%e
在client中不需要init_node() 首先我們先wait for service named 'add_two_ints' wait的含義在於如果'add_two_ints'這個service尚未建立, 那麼我們要block這個service直到它被建立
一旦所需的service被建立, 接下來我們就能夠利用rospy.ServiceProxy來呼叫service, 注意要指定好srv, 即AddTwoInts
接下來建立一個變數respl來接service所回傳的結果
service回傳的東西是一個AddTwoInisResponse的物件, 如果呼叫失敗, 則會thrown rospy.ServiceException
10.3 測試server and client
首先先build
cd your_catkin_ws
catkin_make
source devel/setup.bash
將server node建立
# new terminal
rosrun beginner_tutorials add_two_ints_server.py
run client
# new terminal
rosrun begginner_tutorials add_two_ints_client.py 2 3
將會看到輸出, 而注意到因為client並不是node的關係, 所以我們實際上不會有一直在busy下, 而是執行一次, 回傳結果後就結束
更多的例子可以看https://github.com/fairlight1337/ros_service_examples/