このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。
ROS のパブリッシャーおよびサブスクライバーとのデータ交換
ROS ノードがデータを交換するための主なメカニズムは、"メッセージ" を送受信することです。メッセージは "トピック" 上で送信され、各トピックは ROS ネットワーク内で一意の名前をもちます。あるノードが情報を共有する場合、そのノードは "パブリッシャー" を使用してデータをトピックに送信します。その情報を受信するノードは、同じトピックの "サブスクライバー" を使用します。各トピックには一意の名前の他に "メッセージ タイプ" もあり、そのトピックで送信可能なメッセージのタイプが決まります。
このパブリッシャーとサブスクライバーの通信には、次のような特性があります。
トピックは多対多の通信に使用されます。多数のパブリッシャーが同じトピックにメッセージを送信でき、多数のサブスクライバーがそれらを受信できます。
パブリッシャーとサブスクライバーはトピックを通じて分離され、任意の順序で作成および破棄できます。アクティブなサブスクライバーがない場合でも、メッセージをトピックにパブリッシュできます。
トピック、パブリッシャーおよびサブスクライバーの概念を次の図に示します。
この例では、ROS ネットワーク内でトピックにパブリッシュおよびサブスクライブする方法を説明します。また、次の方法も示します。
新しいメッセージを受信するまで待機する
コールバックを使用して、新しいメッセージをバックグラウンドで処理する
前提条件:ROS 入門、ROS ネットワークへの接続
サブスクライブしてメッセージを待つ
rosinit
コマンドを使用して MATLAB® で ROS マスターを起動します。
rosinit
Launching ROS Core... Done in 0.38694 seconds. Initializing ROS master on http://172.29.218.107:52150. Initializing global node /matlab_global_node_29809 with NodeURI http://dcc892853glnxa64:44169/ and MasterURI http://localhost:52150.
提供された補助関数 exampleHelperROSCreateSampleNetwork
を使用して、複数のパブリッシャーおよびサブスクライバーを含むサンプルの ROS ネットワークを作成します。
exampleHelperROSCreateSampleNetwork
rostopic
list
を使用して、使用可能なトピックを確認します。
rostopic list
/pose /rosout /scan /tf
rostopic info
を使用して、/scan
トピックにパブリッシュしているノードがあるかどうかをチェックします。以下のコマンドは、node_3
がパブリッシュしていることを示しています。
rostopic info /scan
Type: sensor_msgs/LaserScan Publishers: * /node_3 (http://dcc892853glnxa64:34399/) Subscribers: * /node_1 (http://dcc892853glnxa64:42737/) * /node_2 (http://dcc892853glnxa64:34473/)
rossubscriber
を使用して /scan
トピックをサブスクライブします。このケースのように、ROS ネットワーク内にトピックが既に存在する場合、メッセージ タイプは rossubscriber
で自動的に検出されるため、指定する必要はありません。メッセージを struct 形式で使用すると効率性が向上します。
laser = rossubscriber("/scan","DataFormat","struct"); pause(2)
receive
を使用して新しいメッセージを待ちます (2 番目の引数は秒単位のタイムアウト)。出力 scandata
に、受信したメッセージ データが含まれます。
scandata = receive(laser,10)
scandata = struct with fields:
MessageType: 'sensor_msgs/LaserScan'
Header: [1x1 struct]
AngleMin: -0.5467
AngleMax: 0.5467
AngleIncrement: 0.0017
TimeIncrement: 0
ScanTime: 0.0330
RangeMin: 0.4500
RangeMax: 10
Ranges: [640x1 single]
Intensities: []
一部のメッセージ タイプには、可視化機能が関連付けられています。LaserScan メッセージの場合は、rosPlot
がスキャン データをプロットします。MaximumRange
の名前と値のペアは、最大プロット範囲を指定します。
figure
rosPlot(scandata,"MaximumRange",7)
コールバック関数を使用したサブスクライブ
receive
を使用してデータを取得する代わりに、新しいメッセージを受信したときに呼び出される関数を指定できます。これにより、サブスクライバーが新しいメッセージを待っている間に他の MATLAB コードを実行できます。複数のサブスクライバーを使用する場合は、コールバックが不可欠です。
コールバック関数 exampleHelperROSPoseCallback
を使用して、/pose
トピックをサブスクライブします。
robotpose = rossubscriber("/pose",@exampleHelperROSPoseCallback,"DataFormat","struct")
robotpose = Subscriber with properties: TopicName: '/pose' LatestMessage: [] MessageType: 'geometry_msgs/Twist' BufferSize: 1 NewMessageFcn: @exampleHelperROSPoseCallback DataFormat: 'struct'
メインのワークスペースとコールバック関数の間でデータを共有する方法の 1 つは、グローバル変数を使用することです。2 つのグローバル変数 pos
と orient
を定義します。
global pos global orient
グローバル変数 pos
および orient
は、/pose
トピックで新しいメッセージ データが受信されたときに、関数 exampleHelperROSPoseCallback
内で代入されます。
数秒間待機して、サブスクライバーがメッセージを受信できることを確認します。変数 pos
および orient
には、常に最新の位置と向きのデータが保存されます。
pause(2) pos
pos = 1×3
-0.0011 0.0079 -0.0263
orient
orient = 1×3
-0.0041 0.0463 0.0047
コマンド ラインで pos
と orient
を数回入力すると、値が継続的に更新されることを確認できます。
サブスクライバー変数をクリアして pose サブスクライバーを停止します。
clear robotpose
メモ: グローバル変数を使用する以外にも、コールバック関数から情報を抽出する方法があります。たとえば、ハンドル オブジェクトを追加の引数としてコールバック関数に渡すことができます。コールバック関数の定義の詳細については、グラフィックス オブジェクトのコールバックの作成ドキュメンテーションを参照してください。
メッセージのパブリッシュ
ROS 文字列メッセージを /chatter
トピックに送信するパブリッシャーを作成します (Work with Basic ROS Messagesを参照)。
chatterpub = rospublisher("/chatter","std_msgs/String","DataFormat","struct")
chatterpub = Publisher with properties: TopicName: '/chatter' NumSubscribers: 0 IsLatching: 1 MessageType: 'std_msgs/String' DataFormat: 'struct'
pause(2) % Wait to ensure publisher is registered
/chatter
トピックに送信する ROS メッセージを作成して入力します。
chattermsg = rosmessage(chatterpub);
chattermsg.Data = 'hello world'
chattermsg = struct with fields:
MessageType: 'std_msgs/String'
Data: 'hello world'
rostopic list
を使用して、ROS ネットワークで /chatter
トピックが使用可能であることを確認します。
rostopic list
/chatter /pose /rosout /scan /tf
/chatter
トピックのサブスクライバーを定義します。新しいメッセージを受信すると exampleHelperROSChatterCallback
が呼び出され、メッセージ内の文字列の内容が表示されます。
chattersub = rossubscriber("/chatter",@exampleHelperROSChatterCallback,"DataFormat","struct")
chattersub = Subscriber with properties: TopicName: '/chatter' LatestMessage: [] MessageType: 'std_msgs/String' BufferSize: 1 NewMessageFcn: @exampleHelperROSChatterCallback DataFormat: 'struct'
/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_29809 with NodeURI http://dcc892853glnxa64:44169/ and MasterURI http://localhost:52150. Shutting down ROS master on http://172.29.218.107:52150.
次のステップ
MATLAB での ROS メッセージの処理方法の詳細については、Work with Basic ROS MessagesおよびWork with Specialized ROS Messagesを参照してください。
ROS サービスを調べるには、Call and Provide ROS Servicesを参照してください。