python3
ROS2

ROS2入門[Python3] - Part1

序章

大学のサークルで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