ROSのトピック通信
Simple Wiki Based Contents Management System
関心分野 >> Ros4Winのインストール >> ROSのトピック通信

ROSのトピック通信

このページでは、ROSのトピック通信について解説していきます。
ROSのトピック通信は、データを送信側をPublisher、データの受信側をSubscriberと言います。Publisherは、特定の名前を持つトピックに対してデータを送信し、Subscriberは、指定したトピックに流れてるデータを受信します。
ブロードキャストのデータ通信によく似ていますが、トピック名に基づき選択的にデータの送受信を行う仕組みです。
このデータ通信方式では、Publiserはどのノードがデータを受信しているのかを関知しませんし、Subscriberはどのノードからデータが送られてきているかも関知しません。
また、トピック通信のノード間の通信経路の決定には、roscoreが管理しています。

turtlesimの亀を操作する

では、トピック通信の様子をturtlesimを使って見ていきます。

roscoreの起動

ROSノードのページでも説明しましたが、ROSノードの操作、通信を行うにはroscoreが起動している必要がありますので起動してみましょう。
 > start roscore
すでにroscoreが起動しているばあには、エラーメッセージとともに終了します。原則として、roscoreは、1つのROSシステムで1つしか起動できません。

turtlesim_nodeの起動

次に、turtlesim_nodeを起動します。ROSノードのページと同様にrosrunコマンドでturtlesimを起動しましょう。
 > rosrun --start turtlesim turtlesim_node
これで先ほどと同じturtlesimの画面が表示されます。

キーボードによる亀の操作

次に、turtlesimの亀を操作するために turtle_teleop_keyを起動しましょう。turtlesim_nodeと同様にこのノードは、turtlesimパッケージにあります。
 > rosrun --start turtlesim turtle_teleop_key
このコマンドを実行すると下のようなターミナルウィンドウが表示されます。

これで準備が整いまいしたので、turtle_teleop_keyのウィンドウを選択して、矢印キーで捜査してください。左右のキーで回転、上下のキーで前後に亀が動くことを確認してください。キーは、1度押下すると一定量の移動を行うと思います。
キーを押下しても亀が動作しない場合には、turtle_teleop_keyのウィンドウが選択されていないと思いますので、ウィンドウのタイトルバーなどで再度確認してください。

動作が確認できたところで、この例でのバックグランドで動作しているトピック通信を見てきます。

ROSトピックの調査

上記の操作では、turtlesim_nodeとturtle_teleop_key のノードは、ROSトピックを介して通信を行っています。turtle_teleop_keyは、押されたキーコードを特定の名前のトピックに配信(Publish)しています。この時、turtlesim_nodeは、同じ名前のキーを購読(Subscribe)をすることで、押下されたキーコードを受信しています。この通信経路を可視化するために rqt_graphを使ってみましょう。

rqt_graphによる可視化

rqt_graphはROSシステムの進行状況、挙動を示す動的なグラフを生成し表示します。rqt_graphは、rqt_toolsパッケージの一部であり、Ros4Winではインストールされていると思います。
ターミナルウィンドウで、下のようにコマンド入力を行います。
 > rosrun --start rqt_graph
ここでrosrunコマンドでノード名が省略されていますが、rqt_graphコマンドは、同名のパッケージにありますので、Ros4Winでは省略可能です。(通常のROSでは、ノード名の省略はできません)
このコマンドを実行すると下記のような画面が表示されます。(起動に時間がかかることがありますので、しばらくお待ちください。)

この画面上の '/turtle1/cmd_vel'にマウスカーソルを乗せたと、下のようにROSのノードやトピックがハイライトされます。この画面は、'/teleop_turtle'と'/turtlesim'の2つのノードが '/turtle1/cmd_vel'というトピックで通信を行っていることを表しています。通常は、マウスカーソルを乗せた項目が赤になりますので、マウスカーソルを移動させて確認してみてください。

rostopicコマンドによる調査

次にrostopicコマンドでトピックの調査を行います。rostopicコマンドの使用方法は、-hオプションか引数なしで起動するとサブコマンドを調べることできます。
 >rostopic -h
rostopic is a command-line tool for printing information about ROS Topics.

Commands:
        rostopic bw     display bandwidth used by topic
        rostopic delay  display delay of topic from timestamp in header
        rostopic echo   print messages to screen
        rostopic find   find topics by type
        rostopic hz     display publishing rate of topic
        rostopic info   print information about active topic
        rostopic list   list active topics
        rostopic pub    publish data to topic
        rostopic type   print topic or field type

Type rostopic <command> -h for more detailed usage, e.g. 'rostopic echo -h'

rostopic echoを使う

rostopic echoコマンドは、トピックに配信されているデータを表示することができます。ここでは、トピック '/turtle1/cmd_vel' に流れているデータを見てみましょう。
下のコマンドを実行してみてください。
 > start rostopic echo /turtle1/cmd_vel
新しいターミナルウィンドウが表示されると思います。この状態では、画面には何も表示されないままですが、それは'/turtle1/cmd_vel'に何もデータが流れていないことを意味しています。では、turtle_teleop_keyのウィンドウを選択して、何かキーを押してみてください。turtlesimの亀が動き rostopicのターミナルに下のようなデータが表示されると思います。(下の例は、右、上、右の順にキーを押した場合です)
linear:
  x: 0.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: -2.0
---
linear:
  x: 2.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0
---
linear:
  x: 0.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: -2.0
---
rostopicコマンドが トピック '/turtle1/cmd_vel'を購読しているかどうかを確認するために、rqt_graphを見てみましょう。左上の'Refresho ROS Graph'アイコンをクリックして、グラフの更新を行ってみてください。
すると下のように新たに '/rostopic_XXX_XXXXX' というノードが '/teleop_turtle'ノードと '/turtle1/cmd_vel' というトピックで通信していることがわかると思います。

rostopic listを使う

次に、現在どのようなトピックが配信、購読されているかを調査してみましょう。現在、利用されているトピックの全リストは、rostopic listコマンドで調べることができます。rostopic listの使用方法は、下記の通りです。
 >rostopic list -h
Usage: rostopic list [/namespace]

Options:
  -h, --help            show this help message and exit
  -b BAGFILE, --bag=BAGFILE
                        list topics in .bag file
  -v, --verbose         list full details about each topic
  -p                    list only publishers
  -s                    list only subscribers
  --host                group by host name
ここでは、全トピックの詳細も表示したいと思いますので、 '-v'オプションを付加して実行します。
 >rostopic list -v

Published topics:
 * /rosout_agg [rosgraph_msgs/Log] 1 publisher
 * /rosout [rosgraph_msgs/Log] 4 publishers
 * /turtle1/pose [turtlesim/Pose] 1 publisher
 * /turtle1/color_sensor [turtlesim/Color] 1 publisher
 * /turtle1/cmd_vel [geometry_msgs/Twist] 1 publisher

Subscribed topics:
 * /rosout [rosgraph_msgs/Log] 1 subscriber
 * /turtle1/cmd_vel [geometry_msgs/Twist] 2 subscribers
 * /statistics [rosgraph_msgs/TopicStatistics] 1 subscriber
このように現在利用されているトピックの一覧がメッセージ型とともに表示されると思います。

ROSメッセージ

ROSシステムにおけるノード間のトピック通信では、Publisherからのデータ配信によって通信が生じます。このとき特定のトピックは、ある特定のメッセージ型を持っています。上記の例では、/turtle1/cmd_vel というトピックでは、 'geometry_msgs/Twist' というメッセージ型を持っていました。
このようにノード間のトピック通信では、PublisherとSubscriberが同じメッセージ型のデータを送受信する必要があります。すなわち、トピック通信において同じトピック名であれば同じメッセージ型である必要があることを意味しています。
トピック上で送受信されるメッセージ型の詳細は、rostopic typeコマンドで確認することができます。

rostopic typeを使う

rostopic typeコマンドは、配信されているあらゆるトピックのメッセージ型を参照することができます。コマンドの使い方は、下の通りです。
 >rostopic type -h
usage: rostopic type [-h] topic_or_field

positional arguments:
  topic_or_field  Topic or field name

optional arguments:
  -h, --help      show this help message and exit
では、現在配信されているトピック '/turtle1/cmd_vel' を見てみましょう。
 >rostopic type /turtle1/cmd_vel
geometry_msgs/Twist
このように トピック '/turtle1/cmd_vel'のメッセージ型は、'geometry_msgs/Twist' であることがわかります。しかし、'geometry_msgs/Twist'というメッセージ型が一体どのようなデータ型なのかがはっきりわかりません。
そこで、メッセージ型の詳細を調べるために rosmsgコマンドを使用します。
 >rosmsg show geometry_msgs/Twist
geometry_msgs/Vector3 linear
  float64 x
  float64 y
  float64 z
geometry_msgs/Vector3 angular
  float64 x
  float64 y
  float64 z
これで、 '/turtle1/cmd_vel'というトピックが6個のint64(64ビットの整数型)でデータ通信していることがわかりました。

rostopic pubを使う

具体的なデータ構成がわかれば、直接 /turtlesim にメッセージを配信することができます。これには、rostopic pubコマンドを使用します。このコマンドの使用方法は下記の通りです。
 >rostopic pub -h
Usage: rostopic pub /topic type [args...]

Options:
  -h, --help            show this help message and exit
  -v                    print verbose output
  -r RATE, --rate=RATE  publishing rate (hz).  For -f and stdin input, this
                        defaults to 10.  Otherwise it is not set.
  -1, --once            publish one message and exit
  -f FILE, --file=FILE  read args from YAML file (Bagy)
  -l, --latch           enable latching for -f, -r and piped input.  This
                        latches the first message.
  -s, --substitute-keywords
                        When publishing with a rate, performs keyword ('now'
                        or 'auto') substitution for each message
では、rostopic pubコマンドで、/turtlesimに 並進速度 2.0 角速度 1.8で移動する指令を与えてみましょう。
 >rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- "[2.0, 0.0, 0.0]" "[0.0, 0.0, 1.8]"
publishing and latching message for 3.0 seconds
このように単一のメッセージが '/turtlesim'ノードに送信され、亀が円弧状に移動したと思います。
このコマンドでは、1つのメッセージが送信されただけでしたので亀が1秒間だけ動いて止まってしまったと思います。上記の使用方法からもわかるようにrostopic pubコマンドは、'-r'オプションを使うことで定期的に同じコマンドを配信することもできます。
では、1Hz周期で先ほどのメッセージを配信してみましょう。
 >rostopic pub -r 1 /turtle1/cmd_vel geometry_msgs/Twist -- "[2.0, 0.0, 0.0]" "[0.0, 0.0, 1.8]"
このコマンドを実行すると亀は移動し続けることがわかると思います。
では、現在の状態をrqt_graphで見てみましょう。

このように新たに '/rostopic_YYY_YYYY'ノードが /turtlesim ノードにメッセージを配信していることが確認できると思います。
rostopic pubコマンドの周期メッセージ配信を止める場合には、rostopic pubコマンドを実行しているターミナルを選択してCtrl+Cを入力してください。

rostopic hzを使う

rostopicコマンドのその他利用法として、rostopic hzコマンドがあります。このコマンドは、配信されたデータの更新頻度を調べることができます。
rostopic listコマンドで調べたときに '/turtlesim'ノードから '/turtle1/pose'が配信されていました。これは、 /turtlesimノードの亀の位置と姿勢のデータを配信しているものです。
では、'/turtlesim'ノードの'/turtle1/pose'の配信頻度を調べてみます。
 >rostopic hz /turtle1/pose
subscribed to [/turtle1/pose]
no new messages
no new messages
no new messages
no new messages
no new messages
average rate: 62.608
        min: 0.015s max: 0.017s std dev: 0.00036s window: 60
average rate: 62.528
        min: 0.015s max: 0.017s std dev: 0.00040s window: 122
average rate: 62.522
        min: 0.015s max: 0.017s std dev: 0.00042s window: 185
average rate: 62.526
        min: 0.013s max: 0.019s std dev: 0.00054s window: 247
average rate: 62.519
        min: 0.013s max: 0.019s std dev: 0.00054s window: 310
 …
このように60Hz程度で配信されていることがわかります。また、この時の通信状態をrqt_graphで見ると下のようになっています。

ROSシステムでは、トピック通信の状態や配信されているメッセージ型などの情報を様々なコマンドを使って確認することができます。

rqt_plotによる可視化

ここまで、rostopicコマンドやrosmsgコマンドを使ってトピック通信について調べてきました。これらのコマンドは、ターミナルで実行し文字ベースの情報しかわかりませんでした。'/turtle1/pose'のような情報は、ターミナルのみの処理ではわかりずらいので、ここでは、rqt_plotを使ったデータの可視化を行っていきます。rostopic pubコマンドで円運動をさせている状態で下のコマンドを実行してみてください。
 > rosrun --start ros_plot
下のような画面が表示され、亀の位置がリアルタイムで表示されると思います。

グラフが表示されない場合には、左上のテキストボックスにトピック名を入力すれば、’+’ボタンが有効化されますので、それを押下することでグラフを追加することができます。
これでこのセクションは終わりです。rostopic pubコマンドを Ctrl+Cで終了させて、次のROSのサービスとパラメータに進んでください。