raspimouse-sim-tutorial
  • Raspberry Pi Mouse Simulator's Tutorial
  • GitHub repository
  • はじめに
    • ROSとは
  • セットアップ
    • ROS Indigoのインストール方法(Ubuntu Trusty)
    • ROS Kineticのインストール方法(Ubuntu Xenial)
    • ROS Melodicのインストール方法(Ubuntu Bionic)
    • Raspberry Pi Mouse Simulatorのインストール方法
    • Raspberry Pi Mouse Simulatorの動作確認
  • ROSのチュートリアル
    • ROSパッケージの作り方
    • トピックの書き方
    • 独自のメッセージファイルの作り方
    • まとめて起動するやり方
    • サービスの書き方
    • 独自のサービスファイルの作り方
    • 付録
      • ROSでよく使用する用語
      • よく使用するROSコマンド
  • シミュレータのチュートリアル
    • シミュレータ上のラズパイマウスを動かす方法 Part1
    • シミュレータ上のラズパイマウスを動かす方法 Part2
    • シミュレータ上のラズパイマウスを動かす方法 Part3
    • シミュレータ上のラズパイマウスを動かす方法 Part4
    • シミュレータ上のラズパイマウスを動かす方法 Part5
    • シミュレータ上のラズパイマウスを動かす方法 Part6
  • ROSのトラブルシューティング
  • 利用者アンケート
Powered by GitBook
On this page
  • ROSチュートリアルの流れ
  • はじめに
  • サービスファイルの書き方
  • プログラムを改良
  • サーバ
  • コード解説
  • クライアント
  • コード解説
  • 実行方法
  • 実行結果

Was this helpful?

  1. ROSのチュートリアル

独自のサービスファイルの作り方

Previousサービスの書き方Next付録

Last updated 5 years ago

Was this helpful?

ROSチュートリアルの流れ

  1. ←今ここ

はじめに

この章では、独自のサービスファイルを作成し、ROSで使用する方法を解説します。

で作成した日付と時間を配信するトピックを改良して、日付と時間を返すサービスを作成してみたいと思います。

サービスファイルの書き方

独自のサービスファイルは、srvディレクトリに置きます。 無い場合はsrvディレクトリを作りましょう。

roscd ros_tutorial/
mkdir srv

要求に対し日時と時間を返すサービスを作成してみましょう。

vim srv/DateTrigger.srv

DateTrigger.srvの中はこのように書きます。

---
bool success
int32 date
float64 time

これは入力は何もなく、出力はboolのsuccessとint32のdate、float64のtimeを定義しています。

つまりサービスに対して、要求があったらsuccessとdate、timeを返すということです。

次にCMakeLists.txtを編集します。

roscd ros_tutorial/
vim CMakeLists.txt

57行目からのadd_service_filesのコメントアウトを外し、59行目にDateTrigger.srvを追加します。

catkin_wsに移動し、catkin_makeを行います。

cd ~/catkin_ws/
catkin_make

これで準備完了です。

DateTrigger.srvが使用できるか確認していきます。

rossrv show ros_tutorial/DateTrigger

以下のように表示されたら、正しく作成できています。

---
bool success
int32 date
float64 time

プログラムを改良

サーバ

まずros_tutorialパッケージに移動します。

roscd ros_tutorial

time_pub2.pyをコピーしてdate_server.pyという名前で保存しましょう。

cp scripts/time_pub2.py scripts/date_server.py
vim scripts/date_server.py

プログラムを以下のように改良します。

date_server.py
#!/usr/bin/env python                                                           
import rospy
from ros_tutorial.srv import DateTrigger, DateTriggerResponse
from datetime import datetime

def callback_srv(data):                                          #changed
    l = []
    d = DateTriggerResponse()                                                    
    d.date = ''                                                  #9~12 changed
    d.time = ''
    try:                                                         #add
        now = datetime.now()
        l = str(now)

        for i in range(0,10):
            d.date += l[i]
        for i in range(11,25):
            d.time += l[i]
        d.date = int(d.date.replace('-', ''))
        d.time = float(d.time.replace(':',''))
        d.success = True                                        #22~25 changed
    except:
        d.success = False
    return d

if __name__ == '__main__':
    rospy.init_node('date_server')                              #changed
    srv = rospy.Service('date_call', DateTrigger, callback_srv) #changed
    rospy.spin()

実行権限を与えます。

chmod +x scripts/date_server.py

コード解説

time_pub2.pyから変更したところを解説していきます。

from ros_tutorial.srv import DateTrigger, DateTriggerResponse

今回作成したサービスファイルをインポートします。

def callback_srv(data):

callback_srvという関数名で定義してます。

d = DateTriggereResponse()

DateTriggereResponseをdという名前でインスタンス化しています。

    try:
        now = datetime.now()
        l = str(now)

        for i in range(0,10):
            d.date += l[i]
        for i in range(11,25):
            d.time += l[i]
        d.date = int(d.date.replace('-', ''))
        d.time = float(d.time.replace(':',''))
        d.success = True

処理自体は同じですが、最後にreturn dでDateTriggerResponseを返しています。

    except:
        d.success = False
    return d

失敗の場合はFalseを返します。

クライアント

10カウントごとに時刻を取得するプログラムを書きます。

date_client.pyという名前で作成しましょう。

vim scripts/date_client.py
date_client.py
#!/usr/bin/env python                                                           
import rospy
from ros_tutorial.srv import DateTrigger

class Client():
    def __init__(self):
        self.call = rospy.ServiceProxy('date_call', DateTrigger)
        self.res = ""

    def call(self):
        for i in  range(11):
            print(i)
            rospy.sleep(0.1)
        self.res = self.call()
        print("~~~~~~~~~~~~~~~~~~~~~~")
        print(self.res)
        print("~~~~~~~~~~~~~~~~~~~~~~")
        rospy.sleep(1)

if __name__ == '__main__':
    rospy.init_node("date_client")
    rospy.wait_for_service("date_call")
    c = Client()
    rate = rospy.Rate(10)
    while not rospy.is_shutdown():
        c.call()
        rate.sleep()

実行権限を与えます。

chmod +x scripts/date_client.py

コード解説

まずClientクラスから説明していきます。

    def __init__(self):
        self.call = rospy.ServiceProxy('date_call', DateTrigger)
        self.res = ""

__init__関数では今回呼び出すサービスのdate_callをself.callという名前で宣言しています。 self.resはself.callで呼び出したサービスのレスポンスを受け取るための変数です。

    def call(self):
        for i in  range(11):
            print(i)
            rospy.sleep(0.1)
        self.res = self.call()
        print("~~~~~~~~~~~~~~~~~~~~~~")
        print(self.res)
        print("~~~~~~~~~~~~~~~~~~~~~~")
        rospy.sleep(1)

date_call関数では10カウントした後、self.res = self.call()で結果を受け取り表示させています。

if __name__ == '__main__':
    rospy.init_node("date_client")
    rospy.wait_for_service("date_call")

date_clientというノード名で宣言し、date_callが立ち上がるのを待っています。

    c = Client()
    rate = rospy.Rate(10)
    while not rospy.is_shutdown():
        c.call()
        rate.sleep()

Clientクラスをcという名前でインスタンス化し、プログラムが終了するまでcall関数を呼び出しています。

実行方法

それぞれ別のターミナルで実行してください。

roscore
rosrun ros_tutorial date_server.py
rosrun ros_tutorial date_client.py

実行結果

date_client.pyを実行したターミナルで以下のように表示されたら正しく実行できています。

0
1
2
3
4
5
6
7
8
9
10
~~~~~~~~~~~~~~~~~~~~~~
success: True
date: 20181114
time: 123304.60767
~~~~~~~~~~~~~~~~~~~~~~

2018年11月14日の12時33分4.60767秒を指しています。

ROSパッケージの作り方
トピックの書き方
独自のメッセージファイルの作り方
まとめて起動するやり方
サービスを書き方
独自のサービスファイルの作り方
独自のメッセージファイルの作り方