トピックの書き方
ROSチュートリアルの流れ
トピックの書き方 ←今ここ
はじめに
ROSでは、使用するプログラム言語として主にPythonとC++が用いられますが、このチュートリアルではPythonを使用したいと思います。
ROSの通信方式は主にトピック、サービス、アクションの3つあります。この章では最も使用されることが多いトピックから説明していきます。
まず、トピックで使用されるパブリッシャ(publisher)とサブスクライバ(subscriber)ついて説明します。
この2つは、ノード間をトピックを介してデータをやり取りするときに使用され、 簡易的に説明するとこうなります。
パブリッシャ : データを配信
サブスクライバ : データを受け取る

やり取りするデータはメッセージの指定された型に入れ配信されます。
詳しくはROSでよく使用する用語を御覧ください。
メッセージは、標準パッケージのstd_msgsの他に、自分で定義することもできます。
それではパブリッシャとサブスクライバを書いていきましょう。
まずROSパッケージの作り方で作成したros_tutorial
に移動します。ディレクトリ移動にはroscd
という便利なコマンドがあります。このコマンドはどこからでも指定のパッケージに移動できます。
詳しくはよく使用するROSコマンドのroscdを御覧ください。
roscd ros_tutorial
Pythonのプログラムはscriptsディレクトリの中で作成します。 scriptsディレクトリが無い場合は作成しましょう。
mkdir scripts
パブリッシャ
今回は、現在時刻を送るプログラムを書いていきます。
プログラム名はtime_pub.py
とします。
vim scripts/time_pub.py
#!/usr/bin/env python
import rospy
from std_msgs.msg import Float64
rospy.init_node('time_pub')
pub = rospy.Publisher('UnixTime', Float64 , queue_size=1)
rate = rospy.Rate(10)
while not rospy.is_shutdown():
now = rospy.get_time()
pub.publish(now)
rate.sleep()
書いたプログラムには以下のコマンドを実行してください。
chmod +x scripts/time_pub.py
これはプログラムに実行権限を与えています。
Pythonの場合は、プログラムに対しchmod +x <プログラム名>
を行い、一度実行権限を与えれば、変更のたびにcatkin_make
は必要ありません。
コード解説
#!/usr/bin/env python
Pythonでプログラムを書くときのお約束で、シバンといいます。
import rospy
rospy
というモジュールをインポートしています。rospy
はPythonでROSを扱うときに使用します。
from std_msgs.msg import Float64
std_msgs
のFloat64
という型のメッセージをインポートしています。Float64
は浮動小数点変数の64ビットという意味です。
rospy.init_node('time_pub')
time_pub
というノードを定義しています。
pub = rospy.Publisher('UnixTime', Float64 , queue_size=1)
UnixTime
というトピック名、Float64
というメッセージの型、queue_size
が1のパブリッシャを定義しています。queue_size
はバッファの数で、10 [Hz]周期でパブリッシュするときは1でも大丈夫です。10 [Hz]以上の周期でパブリッシュするときや複数のメッセージをパブリッシュするときは大きい値にするといいでしょう。
rate = rospy.Rate(10)
while not rospy.is_shutdown():
now = rospy.get_time()
pub.publish(now)
rate.sleep()
now = rospy.get_time()
はnow
という変数に現在のUnixTimeを代入しています。
pub.publish(now)
はnow
をパブリッシュしています。
シャットダウンされるまで10 [Hz] 周期で上記の2つを行っています。
サブスクライバ
次にサブスクライバを書きます。
サブスクライバはtime_sub.py
とします。
vim scripts/time_sub.py
#!/usr/bin/env python
import rospy
from std_msgs.msg import Float64
def callback(message):
print(message.data)
if __name__ == "__main__":
rospy.init_node('time_sub')
sub = rospy.Subscriber('UnixTime', Float64 , callback)
rospy.spin()
パブリッシャと同様に以下のコマンドを実行してください。
chmod +x scripts/time_sub.py
コード解説
#!/usr/bin/env python
import rospy
from std_msgs.msg import Float64
ここまでパブリッシャと同じです。
def callback(message):
print(message.data)
callback関数を定義しています。
message.data
というのは、Float64の中のdataを参照するという意味です。
if __name__ == "__main__":
Pythonではプログラムがインポートされた場合、関数を自動で実行してしまいますが、 このif文内に書いた関数は自動で実行されなくなります。
rospy.init_node('time_sub')
time_sub
というノードを定義しています。
sub = rospy.Subscriber('UnixTime', Float64 , callback)
サブスクライバの宣言をしています。
パブリッシャがUnixTime
という名前のトピック、Float64
という型で配信しているため、こちらも合わせる必要があります。
最後のcallback
は、受け取ったFloat64
型のデータを渡す関数を書く部分であり、今回はcallback関数に渡しています。
rospy.spin()
プログラムを終了させないようにしています。
相関図

実行方法
それぞれ別のターミナルでそれぞれを起動します。
roscore
rosrun ros_tutorial time_pub.py
rosrun ros_tutorial time_sub.py
実行結果
time_sub.py
を起動したとき、以下のように出力されたら正常に動作しています。
$ rosrun ros_tutorial time_sub.py
1540459203.78
1540459203.88
1540459203.98
1540459204.08
1540459204.18
1540459204.28
1540459204.38
1540459204.48
1540459204.58
1540459204.68
1540459204.78
1540459204.88
1540459204.98
1540459205.08
1540459205.18
︙
出力されているこの数値はUNIX時間というもので、 1970年1月1日午前0時0分0秒からの経過秒数になります。
Last updated
Was this helpful?