最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

基本的な ROS メッセージの操作

メッセージは、ROS 内でデータを交換するための主要なコンテナーです。トピック (ROS のパブリッシャーおよびサブスクライバーとのデータ交換を参照) およびサービス (ROS サービスの呼び出しと提供を参照) は、メッセージを使用してノード間でデータをやり取りします。

データ構造を識別するために、各メッセージは "メッセージ タイプ" をもちます。たとえば、レーザー スキャナーからのセンサー データは、通常はタイプ sensor_msgs/LaserScan のメッセージで送信されます。各メッセージ タイプによって、メッセージに含まれているデータ要素が識別されます。メッセージ タイプの名前はすべて、パッケージ名、スラッシュ (/)、タイプ名を順に組み合わせたものです。

MATLAB® は、ロボット工学アプリケーションでよく使用される多数の ROS メッセージ タイプをサポートしています。この例では、MATLAB で ROS メッセージを作成し、確認し、データを入力する方法をいくつか調べます。

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

メッセージ タイプの確認

ROS マスターとグローバル ノードを初期化します。

rosinit
Initializing ROS master on http://bat6310glnxa64:40471/.
Initializing global node /matlab_global_node_33661 with NodeURI http://bat6310glnxa64:40973/

exampleHelperROSCreateSampleNetwork を使用して、ROS ネットワークに 3 つのノードとサンプルのパブリッシャーおよびサブスクライバーを追加します。

exampleHelperROSCreateSampleNetwork

ネットワーク上には、少数のトピックおよび関連付けられたパブリッシャーとサブスクライバーをもつさまざまなノードがあります。

rostopic list を呼び出すと、使用可能なトピックの完全なリストを表示できます。/scan は、リストに含まれるトピックの 1 つです。

rostopic list
/pose  
/rosout
/scan  

/scan トピックを介して送信されるデータ型の詳細を確認する場合は、rostopic info /scan コマンドを使用して調べます。/scan のメッセージ タイプは sensor_msgs/LaserScan です。

rostopic info /scan
Type: sensor_msgs/LaserScan
 
Publishers:
* /node_3 (http://bat6310glnxa64:32857/)
 
Subscribers:
* /node_2 (http://bat6310glnxa64:37565/)
* /node_1 (http://bat6310glnxa64:34423/)

コマンド出力から、どのノードがトピックにパブリッシュおよびサブスクライブしているかもわかります。パブリッシャーとサブスクライバーの詳細については、ROS のパブリッシャーおよびサブスクライバーとのデータ交換を参照してください。

  • トピックのメッセージ タイプの詳細を確認するには、同じタイプの空のメッセージを作成します。関数 rosmessage を使用します。rosmessage は、メッセージ タイプのタブ補完をサポートします。メッセージ タイプ名を補完するには、補完する名前の先頭の数文字を入力し、Tab キーを押します。

scandata = rosmessage('sensor_msgs/LaserScan')
scandata = 
  ROS LaserScan message with properties:

       MessageType: 'sensor_msgs/LaserScan'
            Header: [1x1 Header]
          AngleMin: 0
          AngleMax: 0
    AngleIncrement: 0
     TimeIncrement: 0
          ScanTime: 0
          RangeMin: 0
          RangeMax: 0
            Ranges: [0x1 single]
       Intensities: [0x1 single]

  Use showdetails to show the contents of the message

作成されたメッセージ scandata は、レーザー スキャナーから通常受信されるデータと関連する多数のプロパティをもちます。たとえば、最小検出距離は RangeMin プロパティに保存され、最大検出距離は RangeMax に保存されます。

トピックおよびサービスで使用できるすべてのメッセージ タイプの完全なリストを表示するには、rosmsg list を使用します。

メッセージ構造の調査とメッセージ データの取得

ROS メッセージはオブジェクトであり、メッセージ データはプロパティに保存されます。MATLAB® は、メッセージの内容を確認、調査するための便利な方法を備えています。

  • /pose トピックをサブスクライブすると、送信されるメッセージを受信し、調べることができます。

posesub = rossubscriber('/pose')
posesub = 
  Subscriber with properties:

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

  • receive を使用して、サブスクライバーからデータを取得します。新しいメッセージが受信されると、関数がそれを返し、変数 posedata に保存します (2 番目の引数は秒単位のタイムアウト)。

posedata = receive(posesub, 10)
posedata = 
  ROS Twist message with properties:

    MessageType: 'geometry_msgs/Twist'
         Linear: [1x1 Vector3]
        Angular: [1x1 Vector3]

  Use showdetails to show the contents of the message

メッセージのタイプは geometry_msgs/Twist です。メッセージには他に LinearAngular の 2 つのフィールドがあります。これらのメッセージ フィールドの値は、直接アクセスすることによって確認できます。

posedata.Linear
ans = 
  ROS Vector3 message with properties:

    MessageType: 'geometry_msgs/Vector3'
              X: 0.0315
              Y: 0.0406
              Z: -0.0373

  Use showdetails to show the contents of the message

posedata.Angular
ans = 
  ROS Vector3 message with properties:

    MessageType: 'geometry_msgs/Vector3'
              X: 0.0413
              Y: 0.0132
              Z: -0.0402

  Use showdetails to show the contents of the message

これらのメッセージ フィールドの値はそれぞれ、実際にはそれ自体がメッセージであることがわかります。これらのメッセージ タイプは geometry_msgs/Vector3 です。geometry_msgs/Twist は、2 つの geometry_msgs/Vector3 メッセージで構成される複合メッセージです。

これらの入れ子メッセージのデータ アクセスは、他のメッセージ内のデータにアクセスする場合とまったく同じ動作です。Linear メッセージの X コンポーネントにアクセスするには、次のコマンドを使用します。

xpos = posedata.Linear.X
xpos = 0.0315

メッセージに含まれているすべてのデータの簡単な概要を確認する場合は、関数 showdetails を呼び出します。showdetails は、どんなタイプのメッセージに対しても機能し、すべてのメッセージ データ プロパティを再帰的に表示します。

showdetails(posedata)
  Linear     
    X :  0.03147236863931789
    Y :  0.04057919370756193
    Z :  -0.03730131837064939
  Angular    
    X :  0.04133758561390194
    Y :  0.01323592462254095
    Z :  -0.04024595950005905

showdetails は、デバッグ中およびメッセージの内容をすばやく調査する場合に役立ちます。

メッセージ データの設定

メッセージのプロパティ値も設定できます。タイプ geometry_msgs/Twist のメッセージを作成します。

twist = rosmessage('geometry_msgs/Twist')
twist = 
  ROS Twist message with properties:

    MessageType: 'geometry_msgs/Twist'
         Linear: [1x1 Vector3]
        Angular: [1x1 Vector3]

  Use showdetails to show the contents of the message

このメッセージの数値プロパティは、既定では "0" に初期化されます。このメッセージのプロパティをどれでも変更できます。Linear.Y エントリを 5 に等しくなるように設定します。

twist.Linear.Y = 5;

メッセージ データを表示して、変更が有効になったことを確認できます。

twist.Linear
ans = 
  ROS Vector3 message with properties:

    MessageType: 'geometry_msgs/Vector3'
              X: 0
              Y: 5
              Z: 0

  Use showdetails to show the contents of the message

メッセージにデータが入力されたら、それをパブリッシャー、サブスクライバーおよびサービスで使用できます。ROS のパブリッシャーおよびサブスクライバーとのデータ交換およびROS サービスの呼び出しと提供の例を参照してください。

メッセージのコピー

メッセージの内容をコピーするには、次の 2 つの方法があります。

  • コピーと元のメッセージが同じデータを共有する "参照コピー" を作成できる

  • コピーと元のメッセージがそれぞれ独自のデータをもつ "ディープ コピー" を作成できる

参照コピーは、異なる関数またはオブジェクトの間でメッセージ データを共有する場合に便利です。一方で、ディープ コピーは、メッセージの独立したコピーが必要な場合に必須です。

'=' 記号を使用して、メッセージの "参照コピー" を作成します。これにより、元の変数と同じメッセージの内容を参照する変数が作成されます。

twistCopyRef = twist
twistCopyRef = 
  ROS Twist message with properties:

    MessageType: 'geometry_msgs/Twist'
         Linear: [1x1 Vector3]
        Angular: [1x1 Vector3]

  Use showdetails to show the contents of the message

twistCopyRefLinear.Z フィールドを変更し、それによって twist の内容も変更されることを確認します。

twistCopyRef.Linear.Z = 7;
twist.Linear
ans = 
  ROS Vector3 message with properties:

    MessageType: 'geometry_msgs/Vector3'
              X: 0
              Y: 5
              Z: 7

  Use showdetails to show the contents of the message

元のデータに影響を与えずに内容を変更できるように、twist の "ディープ コピー" を作成します。関数 copy を使用して、新しいメッセージ twistCopyDeep を作成します。

twistCopyDeep = copy(twist)
twistCopyDeep = 
  ROS Twist message with properties:

    MessageType: 'geometry_msgs/Twist'
         Linear: [1x1 Vector3]
        Angular: [1x1 Vector3]

  Use showdetails to show the contents of the message

twistCopyDeepLinear.X プロパティを変更し、twist の内容に変化がないことを確認します。

twistCopyDeep.Linear.X = 100;
twistCopyDeep.Linear
ans = 
  ROS Vector3 message with properties:

    MessageType: 'geometry_msgs/Vector3'
              X: 100
              Y: 5
              Z: 7

  Use showdetails to show the contents of the message

twist.Linear
ans = 
  ROS Vector3 message with properties:

    MessageType: 'geometry_msgs/Vector3'
              X: 0
              Y: 5
              Z: 7

  Use showdetails to show the contents of the message

メッセージの保存と読み込み

メッセージを保存して、後から使用できるように内容を保管しておくことができます。

サブスクライバーから新しいメッセージを取得します。

posedata = receive(posesub,10)
posedata = 
  ROS Twist message with properties:

    MessageType: 'geometry_msgs/Twist'
         Linear: [1x1 Vector3]
        Angular: [1x1 Vector3]

  Use showdetails to show the contents of the message

MATLAB の関数 save を使用して、姿勢のデータを .mat ファイルに保存します。

save('posedata.mat','posedata')

ファイルをワークスペースに再度読み込む前に、変数 posedata をクリアします。

clear posedata

これで、関数 load を呼び出してメッセージ データを読み込むことができます。これにより、上記の posedatamessageData 構造体に読み込まれます。posedata は構造体のデータ フィールドです。

messageData = load('posedata.mat')
messageData = struct with fields:
    posedata: [1x1 Twist]

messageData.posedata を調べてメッセージの内容を確認します。

messageData.posedata
ans = 
  ROS Twist message with properties:

    MessageType: 'geometry_msgs/Twist'
         Linear: [1x1 Vector3]
        Angular: [1x1 Vector3]

  Use showdetails to show the contents of the message

これで、MAT ファイルを削除できます。

delete('posedata.mat')

メッセージ内のオブジェクト配列

ROS からの一部のメッセージはオブジェクト配列 (MATLAB)に保存されます。これらは、通常のデータ配列とは異なる方法で処理しなければなりません。

ワークスペース内で、変数 tf にはサンプル メッセージが含まれています (exampleHelperROSCreateSampleNetwork スクリプトが変数を作成)。この場合、このメッセージのタイプは tf/tfMessage で、座標変換に使用されます。

tf
tf = 
  ROS tfMessage message with properties:

    MessageType: 'tf/tfMessage'
     Transforms: [53x1 TransformStamped]

  Use showdetails to show the contents of the message

tf は 2 つのフィールドをもちます。MessageType には標準のデータ配列が含まれ、Transforms にはオブジェクト配列が含まれます。Transforms には 53 個のオブジェクトが保存されており、すべて同じ構造をもっています。

Transforms 内の tf を展開して構造を確認します。

tf.Transforms
ans = 
  53x1 ROS TransformStamped message array with properties:

    MessageType
    Header
    ChildFrameId
    Transform

Transforms 内のオブジェクトはそれぞれ 4 つのプロパティをもっています。展開して、TransformsTransform フィールドを確認できます。

tformFields = tf.Transforms.Transform

メモ: コマンド出力は 53 個の異なる回答を返します。これは、オブジェクトが個々に評価され、それぞれの Transform フィールドの値が返されるためです。この形式は必ずしも便利ではないため、次のコマンドを使用して cell 配列に変換できます。

cellTransforms = {tf.Transforms.Transform}
cellTransforms = 1x53 cell array
  Columns 1 through 4

    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}

  Columns 5 through 8

    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}

  Columns 9 through 12

    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}

  Columns 13 through 16

    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}

  Columns 17 through 20

    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}

  Columns 21 through 24

    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}

  Columns 25 through 28

    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}

  Columns 29 through 32

    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}

  Columns 33 through 36

    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}

  Columns 37 through 40

    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}

  Columns 41 through 44

    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}

  Columns 45 through 48

    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}

  Columns 49 through 52

    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}    {1x1 Transform}

  Column 53

    {1x1 Transform}

これにより、53 個すべてのオブジェクト エントリが 1 つの cell 配列にまとめられ、インデックスを使用してアクセスできるようになります。

さらに、オブジェクト配列要素には、標準の MATLAB ベクトルと同じ方法でアクセスできます。

tf.Transforms(5)
ans = 
  ROS TransformStamped message with properties:

     MessageType: 'geometry_msgs/TransformStamped'
          Header: [1x1 Header]
    ChildFrameId: '/imu_link'
       Transform: [1x1 Transform]

  Use showdetails to show the contents of the message

個々の配列要素のプロパティにアクセスします。

tf.Transforms(5).Transform.Translation
ans = 
  ROS Vector3 message with properties:

    MessageType: 'geometry_msgs/Vector3'
              X: 0.0599
              Y: 0
              Z: -0.0141

  Use showdetails to show the contents of the message

これにより、53 個のリストで 5 番目の変換の並進コンポーネントが表示されます。

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

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

exampleHelperROSShutDownSampleNetwork

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

rosshutdown
Shutting down global node /matlab_global_node_33661 with NodeURI http://bat6310glnxa64:40973/
Shutting down ROS master on http://bat6310glnxa64:40471/.

次のステップ