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/

results matching ""

    No results matching ""