7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【図解】ROS2の基礎について分かりやすく解説する(ノード、トピック、メッセージ)

Posted at

お疲れ様です。秋並です。

今回は、ROS2の基礎的な概念である

  • ノード (node)
  • トピック (topic)
  • メッセージ (message)
  • パブリッシャー (publisher)
  • サブスクライバー (subscriber)

について、解説したいと思います。

動作環境

ubuntu 22.04
ROS humble

ノード

ノードとは、ロボットシステムにおける最小単位の機能モジュールを指します。

ノード間で通信することで、全体のシステムが構成されることになります。

言葉の説明だけでは分かりにくいと思うので、具体的な例を使って説明します。

例)ノード1→ノード2に情報を渡し、受け取った情報をもとにノード2が処理を行う

  • ノード1:カメラから得た画像情報を他のノードに受け渡すノード
  • ノード2:ノード1から取得した画像情報をもとにロボットアームを適切な位置に制御するノード

node_ex1.gif


ノードのイメージとしては上記の通りですが、

ここで、「カメラから取得した情報をもとに物体認識をしたい」という別の機能を実装したい場合を考えてみましょう。

それぞれのノードは独立しているので

  • ノード1はそのままで、ノード2のみを別のノードに取り換える

ことで、この機能を実装することが出来ます。

node_ex2.gif

このように、ノードを上手く構成することで

他の機能を実装するときに、ノードを使いまわすことが出来る

ことがうれしいポイントです。


そのため、既存のノードと自作のノードを組み合わせることで

一からノードを作成するのと比較して、効率的に開発を進めることが可能になります。

トピック、メッセージ、パブリッシャー、サブスクライバー

ここまでで、「ノード間で情報の受け渡しを行う」ことでシステムが構成されることを説明しましたが、

次に、情報の受け渡しを行う際に必要になる

  • トピック (topic)
  • メッセージ (message)

について説明します。

先ほどの図でいうと、「情報の受け渡しを行うためのパイプ」がトピック、「受け渡される情報」がメッセージになります。

image.png


この際に、「メッセージを特定のトピックに配信する機能」と「特定のトピックから流れてきたメッセージを購読する機能」が必要になるのですが、この機能を持つのが

  • パブリッシャー (publisher)
  • サブスクライバー (subscriber)

になります。

image.png

メッセージの型

トピックで配信/購読するメッセージには変数と同様に型があります。

メッセージの型には、

  • ROSで用意されているメッセージ
  • 自身で型を定義するカスタムメッセージ

の2種類が存在します。


ここでは、ROSで標準で用意されているメッセージについて説明したいと思います。

std_msgs

最初に、最もシンプルなメッセージが用意されている std_msgsについて説明します(ドキュメントリンク

例えば、 std_msgs/msg/Int16.msg は以下のような構成になっています(ドキュメントリンク

int16 data

メッセージの中身を確認すると、 int16 型の data という名前の変数で構成されていることが分かります。

sensor_msgs

次に、センサー関連のメッセージが用意されている sensor_msgs について説明します(ドキュメントリンク

例えば、sensor_msgs/msg/Image.msg は以下のような構成になっています(ドキュメントリンク

std_msgs/msg/Header header
uint32 height
uint32 width
string encoding
uint8 is_bigendian
uint32 step
uint8[] data

メッセージの中身を確認すると、 画像の高さ height 、画像の幅 width のような、画像に必要ないくつかのデータで構成されていることが分かります。


ここで、上記メッセージの std_msgs/msg/Header header という箇所に着目してみると、型が std_msgs/msg/Header というメッセージの型になっていることが分かります。

このように、

  • メッセージの定義の中で、他のメッセージの型の変数を定義することが出来る

ということも抑えておくとよいと思います。

パブリッシャーとサブスクライバーについては、以下の点に注意が必要です。

  • 配信する側の「トピックの名前」「メッセージの型」と、購読する側の「トピックの名前」「メッセージの型」が同じでないと、メッセージのやり取りができない

image.png

テストノードを動かして確認してみる

ここからは実際にROS2を動かして、流れを確認してみましょう。

ターミナルにて以下のコマンドを実行して下さい。(テストコードはここで公開されています)

source /opt/ros/humble/setup.bash
ros2 run demo_nodes_py talker

ターミナルをもう一つ開き以下コマンドを実行して下さい。(テストコードはここで公開されています)

source /opt/ros/humble/setup.bash
ros2 run demo_nodes_py listener

listenerを起動したターミナルで以下のように表示されていたらOKです。

[INFO] [1704025540.482092194] [listener]: I heard: [Hello World: 0]
[INFO] [1704025541.449221536] [listener]: I heard: [Hello World: 1]
[INFO] [1704025542.448992738] [listener]: I heard: [Hello World: 2]
[INFO] [1704025543.453376645] [listener]: I heard: [Hello World: 3]
[INFO] [1704025544.449385635] [listener]: I heard: [Hello World: 4]

実行したノードの処理の流れは以下のようになります。

  1. talker(ノード1)側で、メッセージに「Hello World: %d」というデータを格納(%dには0からカウントされていく整数が代入される)
  2. talker(ノード1)がchatter(トピック)にメッセージを配信 (Publish)
  3. listener(ノード2)はchatter(トピック)から流れてきたメッセージを受信 (Subscribe)
  4. 受信したメッセージのデータをlistener(ノード2)側で表示

node_ex3.gif

ノード、トピック、メッセージを確認する

ros2にはノードやトピックの状態を確認するために便利なコマンドが用意されています。

たくさんの種類のコマンドがありますが、ここでは頻繁に使用するコマンドを紹介したいと思います

ros2 node

ros2 node コマンドはノードに関する情報を確認することが出来ます。

試しに、(2つのテストノードは起動したままの状態で)新しいターミナルを起動し以下のコマンドを入力してみてください。

ros2 node list

コマンドを実行すると以下のように、「現時点で存在しているノード」の一覧を確認することが出来ます。

/listener
/talker

ros2 node info コマンドは、ノードがどのようなパブリッシャーやサブスクライバーを保有しているか等の「ノードの構成」について確認することが出来ます。

ros2 node info /talker

コマンドを実行すると以下のように表示されます。

Subscribers:

  Publishers:
    /chatter: std_msgs/msg/String
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
  Service Servers:
    /talker/describe_parameters: rcl_interfaces/srv/DescribeParameters
    /talker/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
    /talker/get_parameters: rcl_interfaces/srv/GetParameters
    /talker/list_parameters: rcl_interfaces/srv/ListParameters
    /talker/set_parameters: rcl_interfaces/srv/SetParameters
    /talker/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
  Service Clients:

  Action Servers:

  Action Clients:

ros2 topic

ros2 topic は、トピックに関する情報を確認できるコマンドです。

ros2 topic listコマンドは、「現時点で存在するトピックの一覧」を確認することが出来ます( /rosout/parameter_events は常に存在するトピックになります)

ros2 topic list
/chatter
/parameter_events
/rosout

ros2 node info コマンドは、「トピックに関する情報」を確認することが出来ます。

ros2 topic info /chatter

コマンドを実行すると以下のように表示されます。

Type: std_msgs/msg/String
Publisher count: 1
Subscription count: 1

上記の場合 std_msgs/msg/String という型のメッセージが流れるトピックであるということが分かります。


最後に、以下のコマンドを実行してみてください。

ros2 topic echo /chatter

コマンドを実行すると、以下のような表示が続くと思います。

data: 'Hello World: 0'
---
data: 'Hello World: 1'
---
data: 'Hello World: 2'
---
data: 'Hello World: 3'
---
data: 'Hello World: 4'

これは、 /chatter トピックから流れてきたメッセージをリアルタイムで表示しており、トピックからどのようなメッセージが流れてきているかを確認するときに使用できます。

逆に、 ros2 topic echo /トピック名 を実行しても何も表示されない場合は「指定したトピックにメッセージが上手く配信できていない」ということになります。

listener ノードではこのメッセージの中の data という情報を表示しています。

ros2 interface

ros2 interface は、メッセージに関する情報を確認できるコマンドです。

ros2 interface show コマンドは、メッセージの内容について確認することが出来ます。

ros2 interface show std_msgs/msg/String

コマンドを実行すると以下のように表示され、 std_msgs/msg/Stringstring という型の data という変数で構成されていることが分かります。

# This was originally provided as an example message.
# It is deprecated as of Foxy
# It is recommended to create your own semantically meaningful message.
# However if you would like to continue using this please use the equivalent in example_msgs.

string data

最後に

今回は、

  • ROS2の基礎

について解説しました。

この記事が少しでも皆さんのお役に立てれば幸いです。

7
5
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
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?