このページは前リリースの情報です。該当の英語のページはこのリリースで削除されています。

ROS のパブリッシャーおよびサブスクライバーとのデータ交換

ROS ノードがデータを交換するための主なメカニズムは、"メッセージ" を送受信することです。メッセージは "トピック" 上で送信され、各トピックは ROS ネットワーク内で一意の名前をもちます。あるノードが情報を共有する場合、そのノードは "パブリッシャー" を使用してデータをトピックに送信します。その情報を受信するノードは、同じトピックの "サブスクライバー" を使用します。各トピックには一意の名前の他に "メッセージ タイプ" もあり、それによって送信可能なメッセージのタイプが決まります。

このパブリッシャーとサブスクライバーの通信には次のような特性があります。

  • トピックは多対多の通信に使用されます。多数のパブリッシャーが同じトピックにメッセージを送信でき、多数のサブスクライバーがそれらを受信できます。

  • パブリッシャーとサブスクライバーはトピックを通じて分離され、任意の順序で作成および破棄できます。アクティブなサブスクライバーがない場合でも、メッセージをトピックにパブリッシュできます。

トピック、パブリッシャーおよびサブスクライバーの概念を以下の図で説明します。

この例では、ROS ネットワーク内でトピックにパブリッシュおよびサブスクライブする方法を説明します。また、次の方法も示します。

  • 新しいメッセージを受信するまで待機する

  • コールバックを使用して、新しいメッセージをバックグラウンドで処理する

必要条件: ROS 入門ROS ネットワークへの接続

サブスクライブしてメッセージを待つ

MATLAB® で ROS マスターを起動して、複数のパブリッシャーおよびサブスクライバーを含むサンプルの ROS ネットワークを作成します。

rosinit
Initializing ROS master on http://bat572107glnxa64:33207/.
Initializing global node /matlab_global_node_23546 with NodeURI http://bat572107glnxa64:40387/
exampleHelperROSCreateSampleNetwork

rostopic list を使用して、使用可能なトピックを確認します。/scan トピックをサブスクライブすると仮定します。

rostopic list
/pose  
/rosout
/scan  

rostopic info を使用して、/scan トピックにパブリッシュしているノードがあるかどうかをチェックします。以下のコマンドは、node_3 がパブリッシュしていることを示しています。

rostopic info /scan
Type: sensor_msgs/LaserScan
 
Publishers:
* /node_3 (http://bat572107glnxa64:37989/)
 
Subscribers:
* /node_2 (http://bat572107glnxa64:40339/)
* /node_1 (http://bat572107glnxa64:42273/)

rossubscriber を使用して /scan トピックをサブスクライブします。このケースのように、ROS ネットワーク内にトピックが既に存在する場合、メッセージ タイプは rossubscriber が自動的に検出するため、指定する必要はありません。

laser = rossubscriber('/scan')
laser = 
  Subscriber with properties:

        TopicName: '/scan'
      MessageType: 'sensor_msgs/LaserScan'
    LatestMessage: [0x1 LaserScan]
       BufferSize: 1
    NewMessageFcn: []

を使用して新しいメッセージを待ちます (2 番目の引数は秒単位のタイムアウト)。出力 scandata に、受信したメッセージ データが含まれます。

scandata = receive(laser,10)
scandata = 
  ROS LaserScan message with properties:

       MessageType: 'sensor_msgs/LaserScan'
            Header: [1x1 Header]
          AngleMin: -0.5216
          AngleMax: 0.5243
    AngleIncrement: 0.0016
     TimeIncrement: 0
          ScanTime: 0.0330
          RangeMin: 0.4500
          RangeMax: 10
            Ranges: [640x1 single]
       Intensities: [0x1 single]

  Use showdetails to show the contents of the message

一部のメッセージ タイプには、便利な視覚化機能が関連付けられています。LaserScan メッセージの場合は、plot がスキャン データをプロットします。MaximumRange の名前と値のペアは、最大プロット範囲を指定します。

figure
plot(scandata,'MaximumRange',7)

コールバック関数を使用したサブスクライブ

を使用してデータを取得する代わりに、新しいメッセージを受信したときに呼び出される関数を指定できます。これにより、サブスクライバーが新しいメッセージを待っている間に他の MATLAB コードを実行できます。複数のサブスクライバーを使用する場合は、コールバックが不可欠です。

  • コールバック関数 exampleHelperROSPoseCallback を使用して、/pose トピックをサブスクライブします。メインのワークスペースとコールバック関数の間でデータを共有する方法の 1 つは、グローバル変数を使用することです。2 つのグローバル変数 posorient も定義します。

robotpose = rossubscriber('/pose',@exampleHelperROSPoseCallback)
robotpose = 
  Subscriber with properties:

        TopicName: '/pose'
      MessageType: 'geometry_msgs/Twist'
    LatestMessage: [0x1 Twist]
       BufferSize: 1
    NewMessageFcn: @exampleHelperROSPoseCallback

global pos
global orient

グローバル変数 pos および orient は、/pose トピックで新しいメッセージ データが受信されたときに、関数 exampleHelperROSPoseCallback に代入されます。

数秒間待機して、サブスクライバーがメッセージを受信できることを確認します。変数 pos および orient には、常に最新の位置と向きのデータが保存されます。

pause(2) 
pos
pos = 1×3

    0.1151    0.0436   -0.0411

orient
orient = 1×3

    0.0303   -0.0253    0.1623

コマンド ラインで posorient を数回入力すると、値が継続的に更新されることを確認できます。

サブスクライバー変数をクリアして pose サブスクライバーを停止します。

clear robotpose

メモ: グローバル変数を使用する他にも、コールバック関数から情報を抽出する方法があります。たとえば、ハンドル オブジェクトを追加の引数としてコールバック関数に渡すことができます。コールバック関数の定義の詳細については、コールバック定義 (MATLAB)ドキュメンテーションを参照してください。

メッセージのパブリッシュ

ROS 文字列メッセージを /chatter トピックに送信するパブリッシャーを作成します (基本的な ROS メッセージの操作を参照)。

chatterpub = rospublisher('/chatter', 'std_msgs/String')
chatterpub = 
  Publisher with properties:

         TopicName: '/chatter'
        IsLatching: 1
    NumSubscribers: 0
       MessageType: 'std_msgs/String'

pause(2) % Wait to ensure publisher is registered

/chatter トピックに送信する ROS メッセージを作成して入力します。

chattermsg = rosmessage(chatterpub);
chattermsg.Data = 'hello world'
chattermsg = 
  ROS String message with properties:

    MessageType: 'std_msgs/String'
           Data: 'hello world'

  Use showdetails to show the contents of the message

rostopic list を使用して、ROS ネットワークで /chatter トピックが使用可能であることを確認します。

rostopic list
/chatter
/pose   
/rosout 
/scan   

/chatter トピックのサブスクライバーを定義します。新しいメッセージを受信すると exampleHelperROSChatterCallback が呼び出され、メッセージ内の文字列の内容が表示されます。

chattersub = rossubscriber('/chatter', @exampleHelperROSChatterCallback)
chattersub = 
  Subscriber with properties:

        TopicName: '/chatter'
      MessageType: 'std_msgs/String'
    LatestMessage: [0x1 String]
       BufferSize: 1
    NewMessageFcn: @exampleHelperROSChatterCallback

/chatter トピックにメッセージをパブリッシュします。サブスクライバーのコールバックによって文字列が表示されることを確認します。

send(chatterpub,chattermsg)
pause(2)
ans = 
'hello world'

文字列メッセージをパブリッシュするとすぐに、関数 exampleHelperROSChatterCallback が呼び出されました。

ROS ネットワークのシャットダウン

サンプル ノード、パブリッシャーおよびサブスクライバーを ROS ネットワークから削除します。また、グローバル変数 pos および orient をクリアします。

exampleHelperROSShutDownSampleNetwork
clear global pos orient

ROS マスターをシャットダウンしてグローバル ノードを削除します。

rosshutdown
Shutting down global node /matlab_global_node_23546 with NodeURI http://bat572107glnxa64:40387/
Shutting down ROS master on http://bat572107glnxa64:33207/.

次のステップ