LoginSignup
20
16

More than 5 years have passed since last update.

ROS2入門[Python3] - Publisher

Last updated at Posted at 2018-06-09

序章

大学のサークルでROS2を使ってロボットの開発をすることにした。
基本は備忘録としてQiitaに投稿することが主な目的ではあるが、もっとROS2が流行るといいなと思い書くことにした。

環境は、
Python3 -- 3.6.5
macOS -- High Sierra 10.13.4

ROS2(Publisher)

〜動作順〜

1. rclpy.init()でRCL(ROS Client Library)の初期化?を実行
2. rclpy.node.Node(node_name)はnode_nameを渡してインスタンス化
3. rclpy.node.Node.create_publisher(msg_type, topic)でmsg_typeとtopicを指定してpublisherを作成
4. std_msgs.msgから用途に合わせた型を選ぶ。
5. std_msgs.msg.dataにデータを格納する
6. rclpy.node.Node.publish(std_msgs.msg)で格納されたデータが送信される。
7. rclpy.spin(rclpy.node.Node)をすることでrclpyはループに入り処理を繰り返す。
8. rclpy.node.Node.destroy_node()でNodeを破壊する。
9. rclpy.shutdown()でRCLをシャットダウンする

これがわかる方は相当ROS関連を触っている方なのでは?
色々と教えてもらいたい。

〜プログラム(python3)〜

+簡易プログラム+

では、上の動作順に従ってプログラムを構築していきましょう。
すると下記のようなプログラムになります。

talker.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import String

# rclpy.init()でRCLの初期設定を実行
rclpy.init()

# 引数node_nameに名前を渡してインスタンス化
node = Node("talker")

# 引数msg_typeとtopicにメッセージタイプとtopicネームを渡す
pub = node.create_publisher(String, "chatter")

# データタイプStringをインスタンス化
msg = String()

# データを格納
msg.data = "Hello"

# データを公開
pub.publish(msg)

# ループで処理を続ける
rclpy.spin(node)

# ノードをきちんと破壊
node.destroy_node()

# ROSをシャットダウン
rclpy.shutdown()

python3 talker.py
でプログラムを実行してください。
今回は何も表示されなければ成功です。しかし、実際にはmsgはしっかりと公開され、subscribeできるようになっています。
(subscribeは次回の記事で紹介します。)

+汎用プログラム+

では、classを使用し汎用性の高いプログラムに書き換えてみましょう。

talker.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import String

# Nodeクラスを継承
class Talker(Node):
    def __init__(self):
        # Node.__init__を引数node_nameにtalkerを渡して継承
        super().__init__("talker")
        self.count = 0

        # Node.create_publisher(msg_type, topic)に引数を渡してpublisherを作成
        self.pub = self.create_publisher(String, "chatter")
        self.time_period = 1.0

        # Node.create_timer(timer_period_sec, callback)に引数を渡してタイマーを作成
        self.tmr = self.create_timer(self.time_period, self.callback)

    def callback(self):
        self.count += 1

        # std_msgs.msg.Stringのインスタンス化
        msg = String()

        # msg.dataにデータを格納
        msg.data = "HELLO PUBLISHER! [{0}]".format(self.count)

        # Node.get_logger().info(message)で表示したい内容を引数messageに渡す
        self.get_logger().info("Publishing: {0}".format(msg.data))

        # msgを公開
        self.pub.publish(msg)


def main():
    # rclpy.init()でRCLを初期化
    rclpy.init(args=args)

    # Nodeのインスタンス化
    node = Talker()

    # Node処理をループさせ実行
    rclpy.spin(node)

    # Nodeを破壊
    node.destroy_node()

    # RCLを終了
    rclpy.shutdown()

if __name__ == "__main__":
    main()

今回は
[INFO] [talker]: Publishing: HELLO PUBLISHER! [1]
1の部分が+1づつ表示されていったら成功です。

まとめ

アルゴリズムさえ守っていればcallback関数(汎用プログラム)内を書き換えて、より複雑な動作も書くことが可能となります。

次回

次回はSubscriberについて投稿します。
Publisherよりも簡単なアルゴリズムとなっています。
https://qiita.com/l1sum/items/b7393c34fb0127826f74

20
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
16