独自のメッセージファイルの作り方

ROSチュートリアルの流れ

はじめに

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

独自のメッセージファイルをROSで使用するためには、 CMakeLists.txtpackage.xmlというファイルを編集します。

この2つのファイルは、ROSチュートリアルのROSパッケージの作り方でパッケージを作成したときに自動で出来たファイルです。 package.xmlはパッケージの設定が書いてあり、CMakeLists.txtはビルドする際の設定が書いてあります。

トピックの書き方ではUNIX時間を配信しましたが、この章では現在日時を送るものに改良したいと思います。

まず、現在日時を送るためのメッセージファイルから作成します。

メッセージファイルの作り方

メッセージファイルはmsgディレクトリに置きます。 無い場合はmsgディレクトリを作りましょう。

roscd ros_tutorial/
mkdir msg

日付と時間を送るためのメッセージをDate.msgとします。

vim msg/Date.msg

Date.msgの中は以下のように書きます。

int32 date
float64 time

1行目はint型32ビットのdateで、2行目はFloat型のtimeという名前にしています。

ここからが重要です。

まずpackage.xmlを編集します。

roscd ros_tutorial/
vim package.xml

40行目の<build_depend>message_generation</build_depend>と、46行目の<exec_depend>message_runtime</exec_depend>のコメントアウトを外します。

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

vim CMakeLists.txt

10行目のfind_packageに、14行目ようにmessage_generationを追加します。

51行目のadd_message_filesのコメントアウトを外し、53行目にDate.msgを追加する。

71行目から74行目のgenerate_massagesのコメントアウトを外します。

108行目のcatkin_packageCATKIN_DEPENDSのコメントアウトを外し、message_runtimeを追加します。

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

cd ~/catkin_ws
catkin_make

これで、ビルドが通れば正常にDate.msgが作成されたはずです。

確認してみましょう。 以下のように打ち込み、

rosmsg show ros_tutorial/Date

以下のように表示されたら完了です。

int32 date
float64 time

プログラムを改良

先程作成したメッセージファイルを使用して、プログラムを改良しましょう。 まずros_tutorialに移動します。

roscd ros_tutorial

パブリッシャ

time_pub2.pyという名前にします。

vim scripts/time_pub2.py
time_pub2.py
#!/usr/bin/env python                                                           
import rospy
from ros_tutorial.msg import Date    
from datetime import datetime

def talker():
    l = []
    d = Date()
    rate = rospy.Rate(10)
    while not rospy.is_shutdown():
        d.date = ''
        d.time = ''

        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(':',''))
        pub.publish(d)
        rate.sleep()

if __name__ == '__main__':
    rospy.init_node('time_pub')
    pub = rospy.Publisher('Date_and_Time', Date , queue_size=1)
    talker()
    rospy.spin()

実行権限を与えます。

chmod +x scripts/time_pub2.py

コード解説

#!/usr/bin/env python                                                           
import rospy
from ros_tutorial.msg import Date
from datetime import datetime

新たに、先程作成したDateをインポートしています。また現在日時を取得するために必要なモジュールdatetimeもインポートしています。

def talker():

talkerという名前の関数を定義しています。

    l = []
    d = Date()

l = []はリストの初期化を行っています。

d = Date()はメッセージのDatedという名前でインスタンス化しています。

    rate = rospy.Rate(10)
    while not rospy.is_shutdown():

シャットドウンされるまで10Hzでwhile内のコードを実行します。

        d.date = ''
        d.time = ''

Date.msgdatetimeを初期化しています。

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

現在日時を取得し、配列にしてlに渡しています。

        for i in range(0,10):
            d.date += l[i]
        for i in range(11,25):
            d.time += l[i]

for文で配列の0~10番目を日付としてdateに渡しています。同様に配列の11~25番目を時間としてtimeに渡しています。

しかし、このままだと-:の文字が含まれているため、

        d.date = int(d.date.replace('-', ''))
        d.time = float(d.time.replace(':',''))
        pub.publish(d)
        rate.sleep()

replaceを用いて-:の文字を取り除き、int型とfloat型にしてパブリッシュしています。

サブスクライバ

サブスクライバはほとんど変わらないため、time_sub.pyをコピーし、time_sub2.pyという名前で保存しましょう。

cp scripts/time_sub.py scripts/time_sub2.py
vim scripts/time_sub2.py

3行目と6行目、10行目に変更を加えます。

time_sub2.py

#!/usr/bin/env python
import rospy
from ros_tutorial.msg import Date  #changed

def callback(message):
    print("date : %d , time : %f" % (message.date,message.time) )  #changed

if __name__ == "__main__":
    rospy.init_node('time_sub')
    sub = rospy.Subscriber('Date_and_Time', Date , callback)  #changed
    rospy.spin()
chmod +x scripts/time_sub2.py

コード解説

変更点だけ解説していきます。

from ros_tutorial.msg import Date

Dateをインポートしています。

    print("date : %d , time : %f" % (message.date,message.time) )

dateはint型のため%dtimeはfloat型のため%fで表示しています。

    sub = rospy.Subscriber('Date_and_Time', Date , callback)

トピック名をメッセージの型をDateに変更しています。

実行方法

それぞれ別のターミナルで実行しましょう。

roscore
rosrun ros_tutorial time_pub2.py
rosrun ros_tutorial time_sub2.py

実行結果

$ rosrun ros_tutorial time_sub2.py 
date : 20181108 , time : 224947.85194
date : 20181108 , time : 224947.95175
date : 20181108 , time : 224948.05449
date : 20181108 , time : 224948.15677
date : 20181108 , time : 224948.25193
date : 20181108 , time : 224948.35248
date : 20181108 , time : 224948.45211
date : 20181108 , time : 224948.55515
date : 20181108 , time : 224948.6551
date : 20181108 , time : 224948.75641
date : 20181108 , time : 224948.85298
date : 20181108 , time : 224948.9519
date : 20181108 , time : 224949.05382
date : 20181108 , time : 224949.15634
date : 20181108 , time : 224949.25606
date : 20181108 , time : 224949.35245
date : 20181108 , time : 224949.45277
date : 20181108 , time : 224949.55351
date : 20181108 , time : 224949.65224
date : 20181108 , time : 224949.75421
date : 20181108 , time : 224949.8536
date : 20181108 , time : 224949.95257

2018年11月08日の22時49分49.95257秒を指しています。

Last updated