空飛ぶロボットのつくりかた

ロボットをつくるために必要な技術をまとめます。ロボットの未来についても考えたりします。

ROSサービスのお勉強

rosサービスの復習

全サービスを調べる

$ rosservice list 

あるノードが提供してるサービスを調べる

以下turtlesimを例に考える↓

$ rosndoe info turtlesim

あるサービスを提供するnodeを探したいとき

$ rosservice info /spawn

サービスの情報を調べる

アクティブになっているノードが提供している動的なインスタンスを扱うもの

$ rosservice info /spawn

サービスデータタイプの定義ファイルの中身などの静的な定義情報を扱うもの

$ rossrv show turtlesim/Spawn
float32 x
float32 y
float32 theta
string name
---
string name

上はサービス要求

下はサービス応答

サービスの利用

$ rosservice call /spawn 2.0 2.0 0.0 Indigo

サービスの作成

サービスのmsgの作成

$ roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv
$ rossrv show beginner_tutorials/AddTwoInts
int64 a
int64 b
---
int64 sum

上が入力、下が出力

package.xmlに以下を追加

<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>

CMakeLists.txtに以下を追加

find_package(catkin REQUIRED COMPONENTS
   rospy
   std_msgs
   message_generation #add
)
add_service_files(
  FILES 
   AddTwoInts.srv
)
generate_messages(
  DEPENDENCIES
  std_msgs
)

サービスサーバーの作成

#!/usr/bin/env python

from beginner_tutorials.srv import AddTwoInts
from beginner_tutorials.srv import AddTwoIntsResponse
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()

サービスクライアントの作成

#!/usr/bin/env python

import sys
import rospy
from beginner_tutorials.srv import AddTwoInts

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))

実行方法

$ rosrun beginner_tutorials add_two_ints_server.py
$ rosrun beginner_tutorials add_two_ints_client.py 4 5
Requesting 4+5
4 + 5 = 9

もしくは

$ rosservice call /add_two_ints 4 5 

rosserviceを使えばクライアントがなくても直接serviceが呼び出せる

参考: ja/ROS/Tutorials/WritingServiceClient(python) - ROS Wiki