ROSで簡単なc++パッケージを作成する(初心者向け)でc++のパッケージの作成方法を説明しましたが、今回はpythonでの作成方法を説明します。
作成する内容は上記の記事と同じなので、ここでは違いがあるところだけ説明します。
最も大きな違いはsrc
フォルダではなくscripts
フォルダを作成し、そこにpythonのソースコードをおくところです。
今回作成するもの
説明 | |
---|---|
sample_py_publisher | データを送信するノード |
sample_py_subscriber | データを受信するノード |
sample_message | ノード間でやりとりするメッセージ |
今回作成するファイルおよび編集するファイルは以下になります。(自動生成されるファイルの一部は省略しています)
catkin_ws
`- src
`- sample_c
|- msg
| `- sample_message.msg
|- scripts
| |- sample_py_publisher.py
| `- sample_py_subscriber.py
|- package.xml
`- CMakeLists.txt
パッケージを作成する
$ cd ~/catkin_ws/src
$ catkin_create_pkg sample_py rospy std_msgs
このコマンドを実行すると、sample_py
というディレクトリとその中にpackage.xml
、CMakeLists.txt
が生成されます
メッセージを作成する
メッセージファイルを作成します。
$ cd ~/catkin_ws/src/sample_py
$ mkdir msg
$ cd msg
$ touch sample_message.msg
作成したファイルを編集し内部に含むデータを定義します。今回はstringと32byte unsigned intを含むこととします。
string message
uint32 count
このファイルよりメッセージを定義したpythonファイルをする必要があります。そのために、CMakeLists.txt
を編集します。
CMakeLists.txt
を開くと、様々な設定が記載されており一部がコメントアウトされています。今回は以下の箇所だけ編集すればよいです。
find_package(catkin REQUIRED COMPONENTS
rospy
std_msgs
message_generation
)
add_message_files(
FILES
sample_message.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
CATKIN_DEPENDS message_runtime rospy std_msgs
)
次にpackage.xml
を開いて編集します。以下2行がコメントアウトされているのでコメントタグを外します。
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
最後にビルドし、pythonファイルを生成します。
$ cd ~/catkin_ws
$ catkin_make
ビルドが成功するとcatkin_ws/devel/lib/python2.7/dist-packages/sample_py/msg/_sample_message.py
というファイルが生成されます。
送信側(publisher)を作成する
ファイルを生成し、以下のように実装します。
$ cd ~/catkin_ws/src/sample_py
$ mkdir scripts
$ cd scripts
$ touch sample_py_publisher.py
$ chmod +x sample_py_publisher.py
# !/usr/bin/env python
# license removed for brevity
import rospy
# 生成したメッセージのヘッダファイル
from sample_py.msg import sample_message
def publisher():
# 初期化し、ノードの名前を"sample_c_publisher"とする
rospy.init_node('sample_py_publisher', anonymous=True)
# sample_messageというメッセージを"sample_topic"というトピックに送信する
pub = rospy.Publisher('sample_topic', sample_message, queue_size=10)
# 1秒間に2回データを送信する
rate = rospy.Rate(2)
count = 0
while not rospy.is_shutdown():
str = "hello world"
rospy.loginfo("message = %s, count = %d" %(str, count))
# 送信するメッセージの作成
msg = sample_message()
msg.message = str
msg.count = count
# 送信
pub.publish(msg)
rate.sleep()
count += 1
if __name__ == '__main__':
try:
publisher()
except rospy.ROSInterruptException: pass
受信側(subscriber)を作成する
ファイルを生成し、以下のように実装します。
$ cd ~/catkin_ws/src/sample_py/scripts
$ touch sample_py_subscriber.py
$ chmod +x sample_py_subscriber.py
# !/usr/bin/python
# -*- coding: utf-8 -*-
import rospy
from sample_py.msg import sample_message
def callback(msg):
# 受信したデータを出力する
rospy.loginfo("I heard: message = [%s], count = [%d]" % (msg.message, msg.count));
def subscriber():
# 初期化し、ノードの名前を"sample_py_subscriber"とする
rospy.init_node('sample_py_subscriber', anonymous=True)
# "sample_topic"というトピックからsample_messageというメッセージを受信する
rospy.Subscriber('sample_topic', sample_message, callback)
rospy.spin()
if __name__ == '__main__':
subscriber()
作成したノードをビルド
$ cd ~/catkin_ws
$ catkin_make
ROSを実行する
コンソールを3つ立ち上げ、それぞれ以下を実行します
$ roscore
$ rosrun sample_py sample_py_publisher.py
$ rosrun sample_py sample_c_subscriber.py
コンソールに以下の内容が出力されたら成功です。
[INFO] [1550978255.110806]: message = hello world, count = 0
[INFO] [1550978255.611362]: message = hello world, count = 1
[INFO] [1550978256.111434]: message = hello world, count = 2
...
[INFO] [1550978260.112100]: I heard: message = [hello world], count = [10]
[INFO] [1550978260.612253]: I heard: message = [hello world], count = [11]
[INFO] [1550978261.112563]: I heard: message = [hello world], count = [12]
...
sample_py_subscriber.pyの実行タイミングによってカウンタの値がずれます。
また、こちらで作成したc++のパッケージとメッセージの内容が同じなのでc++との通信もできます。
$ rosrun sample_c sample_c_publisher
$ rosrun sample_py sample_c_subscriber.py