2009年12月22日火曜日

サービスとクライアントを作る(python)

今回はサービスとクライアントをPythonで作ります。

http://www.ros.org/wiki/ROS/Tutorials/WritingServiceClient(python)

作るサービスは2つの数値をうけとり、その合計を返す、というものです。

$ roscd beginner_tutorial

以前のチュートリアルで
srv/AddTwoInts.srv
を作りましたね?
今回はその続きからになります。

では以下をnodes/add_two_ints_server.pyとして保存してください。


#!/usr/bin/env python
import roslib; roslib.load_manifest('beginner_tutorials')

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 nodes/add_two_ints_server.py
も忘れずに。

では中身を見ていきましょう。
もう大体分かっちゃいますね。
 s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
 でサービスの初期化をしています。サブスクライバーと同じで2つ目がサービスタイプ、3つ目がコールバックですね。
コールバックは引数としてAddTwoIntsRequestのインスタンスをもらい、AddTwoIntsResponseを返します。AddTwoIntsメッセージ型から自動で型が作られるんでしょうか?

ではサービスを使うクライアントにいきましょう。

nodes/add_two_ints_client.pyとして以下を保存します。

#!/usr/bin/env python
import roslib; roslib.load_manifest('beginner_tutorials')

import sys
import string
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 = string.atoi(sys.argv[1])
        y = string.atoi(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 nodes/add_two_ints_client.py
します。

ではコードを見ていきましょう。
クライアントではinit_node()しません。まず以下のようにしてサービスにつなぎに行きます。
rospy.wait_for_service('add_two_ints')
 次に以下のようにしてサービスへのハンドラを取得します。
add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
 あとはこれを関数のようにして呼び出すことができます。
resp1 = add_two_ints(x, y)
return resp1.sum
 なんか、ros.orgの最後のほうの記述がおかしいですね。
とりあえず
$ make
しておきましょう。

では試してみます。以下をすべて別のターミナルで実行しましょう。
$ roscore
$ rosrun beginner_tutorials add_two_ints_server.py
して準備完了。

$ rosrun beginner_tutorials add_two_ints_client.py 1 3

Requesting 1+3
1 + 3 = 4
おー、計算結果が返って来ました!
これでサービスが使えるようになりましたね。

これでビギナーレベルのチュートリアルはおしまいです。

次回はC++版も軽く試してみます。

0 件のコメント:

コメントを投稿