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

Simulink® での ROS 入門

この例では、Simulink ブロックを ROS 用に使用してローカルの ROS ネットワークでメッセージを送受信する方法を説明します。

はじめに

Robot Operating System (ROS) に対する Simulink サポートを使用すると、ROS ネットワークに対応する Simulink モデルを作成できます。ROS は、ロボット システムのさまざまなコンポーネント間での "メッセージ" 形式による情報交換を可能にする通信レイヤーです。コンポーネントは、"/odometry" など特定の "トピック" に "パブリッシュ" することによってメッセージを送信します。他のコンポーネントは、そのトピックに "サブスクライブ" することによってメッセージを受信します。

ROS に対する Simulink サポートには、指定したトピックのメッセージを送受信するための Simulink ブロックのライブラリが含まれます。モデルをシミュレートすると、Simulink は ROS ネットワークに接続しますが、その実行場所は Simulink と同じマシン上でも、リモート システム上でもかまいません。この接続が確立されると、シミュレーションが終了されるまで、Simulink は ROS ネットワークとメッセージを交換します。Simulink Coder™ がインストールされている場合は、スタンドアロンの ROS コンポーネント、つまり "ノード" 用に、Simulink モデルから C++ コードを生成することもできます。

この例では、次の方法について説明します。

  • ROS 環境の設定

  • ROS メッセージを送受信する Simulink モデルの作成および実行

  • ROS メッセージ内のデータの処理

必要条件

Simulink または ROS をはじめて使用する場合は、以下を確認することを推奨します。

モデル

Simulink を使用して、ロボットの (x,y) 位置をパブリッシュします。また、同じ location トピックをサブスクライブして、受信した (x,y) 位置を表示します。

この例では、以下のモデルを作成します。

open_system('robotROSGetStartedExample');

ROS の初期化

どの ROS ネットワークにも、ROS ネットワークのすべての部分の取りまとめを行う "ROS マスター" があります。この例では、MATLAB® を使用して、ローカル システム上に ROS マスターを作成します。Simulink は、ローカルの ROS マスターを自動的に検出して使用します。

MATLAB コマンド ラインで、以下を実行します。

rosinit

タスク 1 - パブリッシャーの作成

このタスクでは、"geometry_msgs/Point" メッセージを "/location" ("/" は標準の ROS 構文) という名前のトピックに送信するブロックを構成します。

  • MATLAB ツールストリップから、[ホーム]、[新規作成]、[Simulink モデル] を選択して新しい Simulink モデルを開きます。

  • モデル ウィンドウから、[ツール表示]、[ライブラリ ブラウザー] を選択して Simulink ライブラリ ブラウザーを開きます。[Robotics System Toolbox] タブをクリックします (MATLAB コマンド ウィンドウに robotlib と入力することもできます)。

  • Publish ブロックをモデルにドラッグ アンド ドロップします。ブロックをダブルクリックしてトピックとメッセージ タイプを構成します。

  • [Topic source] フィールドで [Specify your own] を選択し、[Topic] フィールドに /location と入力します。

  • [Message type] フィールドの横の [Select] をクリックします。ポップアップ ウィンドウが表示されます。"geometry_msgs/Point" を選択し、[OK] をクリックしてポップアップ ウィンドウを閉じます。

タスク 2 - ROS メッセージの作成

このタスクでは、空白の ROS メッセージを作成し、ロボット パスの (x,y) 位置を入力します。次に、更新された ROS メッセージを ROS ネットワークにパブリッシュします。

ROS メッセージは、Simulink では "バス信号" として表現されます。バス信号とは複数の Simulink 信号をまとめたもので、他のバス信号を含めることもできます (概要については Simulink バス信号 (Simulink) の例を参照)。ROS の Blank Message ブロックは、ROS メッセージに対応する Simulink バス信号を出力します。

  • Simulink ライブラリ ブラウザーで [Robotics System Toolbox] タブをクリックするか、MATLAB コマンド ラインで robotlib と入力します。

  • Blank Message ブロックをモデルにドラッグ アンド ドロップします。ブロックをダブルクリックしてブロック マスクを開きます。

  • [Message type] フィールドの横の [Select] をクリックし、表示されるポップアップ ウィンドウから "geometry_msgs/Point" を選択します。[OK] をクリックしてブロック マスクを閉じます。

  • ライブラリ ブラウザーの [Simulink]、[Signal Routing] タブから、Bus Assignment ブロックをドラッグ アンド ドロップします。

  • Blank Message ブロックの出力端子を Bus Assignment ブロックのバス入力端子に接続します。Bus Assignment ブロックの出力端子を ROS Publish ブロックの入力端子に接続します。

  • Bus Assignment ブロックをダブルクリックします。X、Y および Z (geometry_msgs/Point メッセージを構成する信号) が左側に表示されます。右側のリストボックスで "??? signal1" を選択して [削除] をクリックします。左側のリストボックスで X と Y の両方の信号を選択して [選択 >>] をクリックします。[OK] をクリックしてブロック マスクを閉じます。

メモ: X、Y および Z がリストに表示されない場合は、Bus Assignment ブロックのブロック マスクを閉じ、[シミュレーション]、[ブロック線図の更新] をクリックして、バス情報が正常に伝播されていることを確認します。"Bus Assignment ブロックで選択された信号 'signal1' が見つかりません" というエラーが表示される場合は、バス情報が伝播されていないことを示します。診断ビューアーを閉じて、上記の手順を繰り返します。

これで、バス信号にロボットの位置を指定できるようになりました。

  • ライブラリ ブラウザーの [Simulink]、[Sources] タブから、2 つの Sine Wave ブロックをモデルにドラッグ アンド ドロップします。

  • Sine Wave ブロックの出力端子を、Bus Assignment ブロックの割り当て入力端子 X および Y に接続します。

  • 入力端子 X に接続されている Sine Wave ブロックをダブルクリックします。[位相] パラメーターを -pi/2 に設定して [OK] をクリックします。

パブリッシャーは次のようになります。

この時点で、モデルは ROS ネットワークにメッセージをパブリッシュするように設定されています。このことは以下の手順で検証できます。

  • ツール バーで、シミュレーション終了時間を inf に設定します。

  • [再生] ボタンをクリックしてシミュレーションを開始します。Simulink は、このモデル専用の ROS ノードと、Publish ブロックに対応する ROS パブリッシャーを作成します。

  • シミュレーションを実行中に、MATLAB コマンド ウィンドウで rosnode list と入力します。ROS ネットワークで使用可能なすべてのノードのリストが表示され、そこには "/untitled_81473" (モデルの名前に、一意にするための乱数を付けたもの) のような名前のノードが含まれています。

  • シミュレーションを実行中に、MATLAB コマンド ウィンドウで rostopic list と入力します。ROS ネットワークで使用可能なすべてのトピックのリストが表示され、そこには "/location" が含まれます。

ベース MATLAB ワークスペースに、"SL_Bus_" で始まる名前の変数が 1 つ以上含まれていることを確認します。これらは Simulink によって作成された一時的なバス オブジェクトで、変更はできません。ただし、必要な場合は再作成されるため、ワークスペースからクリアしても問題ありません。

  • [停止] ボタンをクリックしてシミュレーションを停止します。Simulink が ROS ノードと ROS パブリッシャーを削除します。一般的に、モデルの ROS ノードおよび関連するパブリッシャーとサブスクライバーはシミュレーション終了時に自動的に削除されます。追加のクリーンアップ手順は不要です。

タスク 3 - サブスクライバーの作成

このタスクでは、Simulink を使用して、"/location" トピックに送信されたメッセージを受信します。メッセージから (x,y) 位置を抽出し、XY 平面でプロットします。

  • ライブラリ ブラウザーの [Robotics System Toolbox] タブから、Subscribe ブロックをモデルにドラッグ アンド ドロップします。ブロックをダブルクリックします。

  • [Topic source] フィールドで [Specify your own] を選択し、[Topic] フィールドに /location と入力します。

  • [Message type] フィールドの横の [Select] をクリックし、ポップアップ ウィンドウから "geometry_msgs/Point" を選択します。[OK] をクリックしてブロック マスクを閉じます。

Subscribe ブロックは Simulink バス信号を出力するため、そこから X 信号と Y 信号を抽出する必要があります。

  • ライブラリ ブラウザーの [Simulink]、[Signal Routing] タブから、Bus Selector ブロックをモデルにドラッグ アンド ドロップします。

  • Subscribe ブロックの Msg 出力を Bus Selector ブロックの入力端子に接続します。

  • [シミュレーション]、[ブロック線図の更新] をクリックして、バス情報が伝播されていることを確認します。"Bus Selector ブロック 'untitled/Bus Selector' で選択された信号 'signal1' が入力のバス信号で見つかりません" というエラーが表示される場合があります。このエラーは予期されるものであり、次の手順で解決されます。

  • Bus Selector ブロックをダブルクリックします。右側のリストボックスで "??? signal1" および "??? signal2" を選択して [削除] をクリックします。左側のリストボックスで X と Y の両方の信号を選択して [選択 >>] をクリックします。[OK] をクリックします。

Subscribe ブロックは、タイム ステップごとにトピックが直近で受信したメッセージを出力します。IsNew 出力は、前のタイム ステップ中にメッセージが受信されたかどうかを示します。現在のタスクに関しては、IsNew 出力は不要なため、次を行います。

  • ライブラリ ブラウザーで [Simulink]、[Sinks] タブをクリックします。Terminator ブロックをモデルにドラッグ アンド ドロップします。

  • Subscribe ブロックの IsNew 出力を Terminator ブロックの入力に接続します。

残りの手順では、抽出された X 信号と Y 信号の表示を構成します。

  • ライブラリ ブラウザーの [Simulink]、[Sinks] タブから、XY Graph ブロックをモデルにドラッグ アンド ドロップします。Bus Selector ブロックの出力端子を XY Graph ブロックの入力端子に接続します。

  • ライブラリ ブラウザーの [Simulink]、[Sinks] タブから、2 つの Display ブロックをモデルにドラッグ アンド ドロップします。Bus Selector ブロックの各出力を各 Display ブロックに接続します。

モデル全体は以下のようになります。

  • モデルを保存します。

タスク 4 - モデルの構成と実行

このタスクでは、モデルを構成して実行します。

  • [シミュレーション]、[モデル コンフィギュレーション パラメーター] をクリックします。[ソルバー] ペインで、[タイプ][固定ステップ][固定ステップ サイズ]0.01 に設定します。

  • シミュレーションの [終了時間] を 10.0 に設定します。

  • [再生] ボタンをクリックしてシミュレーションを開始します。XY プロットが表示されます。

Simulink でモデルをはじめて実行するときは、ROS ライブラリの読み込みによる遅延のため、XY プロットが上の Figure よりも粗く見える場合があります。シミュレーションを数回再実行すると、プロットは滑らかになります。

シミュレーションは、実時間、つまり "リアル" タイムでは動作しません。モデル内のブロックはループで評価されます。このループは時間の進行のみをシミュレートするものであり、実際のクロック時間を追跡することは意図されていません (詳細については、シミュレーション ループ フェーズ (Simulink)を参照)。

タスク 5 - 新規メッセージのみに反応するようにモデルを変更

上記のモデルでは、Subscribe ブロックはタイム ステップごとにメッセージ (バス信号) を出力します。メッセージをまったく受信していない場合は、空白のメッセージ (ゼロ値をもつメッセージ) を出力します。その結果、(X,Y) 座標は、最初は (0,0) にプロットされます。

このタスクでは、Enabled Subsystem を使用するようにモデルを変更し、新しいメッセージを受信したときにのみ位置をプロットするようにします (詳細については、Enabled Subsystem の使用 (Simulink)を参照)。付属の事前設定されたモデルを使用すると便利です。

  • モデル内で、クリックしてドラッグし、Bus Selector ブロックと XY Graph ブロックを選択します。選択を右クリックして [選択からサブシステムを作成] を選択します。

  • ライブラリ ブラウザーの [Simulink]、[Ports & Subsystems] タブから、Enable ブロックを、新規に作成したサブシステムにドラッグ アンド ドロップします。

  • 以下の図に示すように、Subscribe ブロックの IsNew 出力を、サブシステムの有効にされた入力に接続します。Terminator ブロックを削除します。"IsNew" 出力は、前のタイム ステップ中に新しいメッセージを受信した場合にのみ有効であることに注目してください。

  • モデルを保存します。

  • [再生] ボタンをクリックしてシミュレーションを開始します。以下の XY プロットが表示されます。

Enabled Subsystem 内のブロックは、Subscribe ブロックが新しい ROS メッセージを受信したときにのみ実行されます。したがって、初期の (0,0) 値は XY プロットには表示されません。

まとめ

この例では、ROS トピックにメッセージを送信し、同じメッセージを受信する Simulink モデルを作成するワークフローを紹介しました。新しい ROS メッセージを作成してデータを入力し、また、ROS メッセージから信号を抽出しました。