1. 程式人生 > >ROS學習筆記19 (編寫簡單的伺服器和客戶端 (Python))

ROS學習筆記19 (編寫簡單的伺服器和客戶端 (Python))

1 編寫服務端節點

  • 我們會建立服務端節點 ("add_two_ints_server") ,節點接收兩個整型數字,並返回和
  • 進入beginner_tutorials包
$ roscd beginner_tutorials
  • 確保你確保已經在之前建立好AddTwoInts.srv

1.1 程式

  • 在beginner_tutorials包建立scripts/add_two_ints_server.py檔案
  • 內容如下:
#!/usr/bin/env python

from beginner_tutorials.srv import *
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()
  • 檔案更改為可執行許可權:
chmod +x scripts/add_two_ints_server.py

程式碼解釋

  • init_node()初始化節點,並宣告服務:
s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
  • 宣告一個名為add_two_ints新服務,使用AddTwoInts服務型別。
  • 所有請求傳遞到handle_add_two_ints函式處理,並傳遞例項AddTwoIntsRequest和返回AddTwoIntsResponse例項。
  • 類似訂閱例項,rospy.spin()會保持程式碼不退出,直到服務關閉

2 編寫客戶端

2.1 程式碼

  • 在beginner_tutorials包建立scripts/add_two_ints_client.py
  • 內容如下:
#!/usr/bin/env python

import sys
import rospy
from beginner_tutorials.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))
  • 設定為可執行:
$ chmod +x scripts/add_two_ints_client.py

程式碼解釋

  • 客戶端呼叫服務更簡單,甚至可以不呼叫init_node()來初始化節點
rospy.wait_for_service('add_two_ints')
  • 這是一種便利的阻塞方法,直到服務名為add_two_ints的服務生效。
  • 下一步建立例項來呼叫服務:
add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
  • 我們使用例項就如平常的函式一樣:
resp1 = add_two_ints(x, y)
return resp1.sum
  • 因為我們已宣告服務型別AddTwoInts,它生成AddTwoIntsRequest物件。
  • 返回值是一個AddTwoIntsResponse物件。
  • 如果呼叫失敗,rospy.ServiceException會丟擲異常,因此你應該建立適當的try/except程式碼塊

構建節點

  • 我們使用CMake作為構建系統,在Python也同樣使用作為構建系統,它能確保之前建立的訊息和服務能自動生成Python程式碼。
  • 進入catkin 工作空間,執行catkin_make
# In your catkin workspace
$ cd ~/catkin_ws
$ catkin_make

測試

  • 新終端,執行:
$ cd ~/catkin_ws
$ . devel/setup.bash
$ rosrun beginner_tutorials add_two_ints_server.py
  • 另開新終端,執行:
$ cd ~/catkin_ws
$ . devel/setup.bash
$ rosrun beginner_tutorials add_two_ints_client.py
  • 或執行:
/home/user/catkin_ws/src/beginner_tutorials/scripts/add_two_ints_client.py [x y]
  • 或執行:
$ rosrun beginner_tutorials add_two_ints_client.py 4 5
  • 服務端輸出效果:
Requesting 4+5
4 + 5 = 9
  • 客戶端輸出效果:
Returning [4 + 5 = 9]
  • 現在你已經學會如何編寫簡單的Service和Client,開始測試簡單的Service和Client吧。