Connext DDSによる高スループットと低遅延の実現

はじめに

RTI Connext DDSは、高性能車両監視とレーダー追跡システムの要件に適合するピアツーピア ミドルウェアです。RTI Connext DDSでは、ネットワークに合わせたデータストリームの微調整と、遅延とスループットのトレードオフの評価をすべて設定を通して行うことができます。そのため、ソースを変更することなくパフォーマンスと拡張性を得ることができます。これにより、多くの車両の更新情報を送信し、これらの更新情報の高速送信に対応するようにシステムを調整できます。

このユースケースは、車両の位置またはレーダーの追跡データを以下のようなシステムに配信する必要がある場合に適用されます:

  • 航空管制システム
  • 状況認識システム
  • Nextgen航空管制システム
  • 警告システム
  • 自衛システム
  • 地域防衛システム
  • ロギング システム
  • 衝突防止システム
  • 緊急車両追跡システム
  • レール追跡システム
  • バスと運搬アプリケーション

次のセクションでは、フライトデータを送信するアプリケーションにおいてConnext DDSを使用したコーディング例を示します。ただし、ここで観察するパターンは航空管制システムのみに特定されません。緊急車両追跡システムには、航空管制システムと部分的に共通した基本要件があります。これらの各システムで重要な考慮事項は、多くの固有の車両を表す必要があるうえ、それらに関する更新情報を頻繁に送信する必要があることです。

車両追跡アプリケーションとレーダーアプリケーションにおけるRTI Connext

RTI Connext DDSは、航空管制システムから地域防衛システムまでを含む、さまざまな車両追跡システムやレーダーシステムにおける基幹通信インフラストラクチャです。RTI Connext DDSは、実質的なリアルタイムのパフォーマンス、サービス品質 (QoS) を通した柔軟な調整、そしてデータとサービスの自動検出によるシンプルな展開を提供します。さらに、RTI Connext DDSでは、個々のアプリケーションにおいてどのパフォーマンスが最も重要であるかを決めるためのトレードオフの設定を行うことができます。多数の車両の更新情報を送信するために、利用可能な最大限のスループットを必要としていますか?タイムリーな決断を行うために、衝突防止システムでの最小限の遅延を必要としていますか?加えて、RTI Connext DDSでは大規模なシステムへの対応が可能なため、数十から数十万という車両の更新を行うことができます。

このサンプルでは、追跡の更新情報を返すレーダー、飛行計画を提供する飛行計画パブリッシャー、そして着陸中の航空機を表示するUIを使用して、シンプルな航空管制の例を示します。このサンプルを通して、アーキテクチャ、コード、設定について説明していきたいと思います。ソースコードを参照してサンプルを独自に構築することもできれば、設定のみに興味がある場合は、事前にビルド済みのアプリケーションを実行し、XMLの設定のみを参照することもできます。

このサンプルで説明すること

このサンプルでは、3つのアプリケーションについて説明します。これらのアプリケーションは、同じマシン、または同じネットワーク内の異なるマシン上で実行できます。このサンプルではレーダー追跡を示しますが、概念と品質サービス (QoS) の調整はその他の車両追跡ユースケースにも適用できます。このサンプルにおけるデータモデルは、「データモデルの考慮事項」のセクションで記載されている車両追跡ユース ケースのデータモデルと多少の違いがあります。

3つのアプリケーションは、以下のとおりです:

device-data-replay.png

飛行計画ジェネレータ (FlightPlanGenerator):

  • 航空機用の飛行計画を提供します
device-data-replay.png

レーダー ジェネレータ (RadarGenerator):

  • レーダー ジェネレータ (RadarGenerator):
  • 飛行計画ジェネレータから飛行計画を受信します
  • 飛行計画が利用可能な場合、飛行計画からの飛行IDをレーダー追跡に関連付けます
device-data-replay.png

航空管制GUI (TrackGui):

  • レーダー追跡と飛行計画を受信します
  • レーダー追跡を表示します
  • レーダー追跡に関連付けられた飛行IDが含まれている場合、飛行計画を検索し、追跡情報を含む計画を表示します

サンプルの実行

サンプルをダウンロード

サンプルファイルをダウンロードし [ Linux  |  Windows ] 、選択した場所に解凍します。このドキュメントの場所をEXAMPLE_HOMEとして参照します。

あらかじめビルドされた実行可能ファイル無しにサンプルのソースコードを表示してダウンロードするには、 RTI Community DDS使用例リポジトリGitHubをご利用ください。

このダウンロードには以下が含まれます:

  • 再構築せずに構成および実行できる事前構築済みのサンプル アプリケーション
  • WindowsおよびLinux用のソースファイルとプロジェクト ファイルのサンプル

RTI Connext DDS Professionalのダウンロード

RTI Connext DDS Professionalをまだインストールしていない場合は、ダウンロードしてインストールしてください。30日間の試用ライセンス で、製品を試すことができます。  ダウンロードには、サンプルを実行するために必要なライブラリと、分散システムの可視化およびデバッグに使用できるツールが含まれています。

サンプルの実行

Air Traffic Control GUI Application

Windowsシステムでは、EXAMPLE_HOME\ExampleCode\scriptsディレクトリに移動します。このディレクトリには、アプリケーションを起動する3つの個別のバッチ ファイルがあります。これらは以下のとおりです:

  • FlightPlanGenerator.bat
  • RadarGenerator.bat
  • TrackGui.bat

Linuxシステムでは、EXAMPLE_HOME/ExampleCode/scriptsディレクトリに移動します。このディレクトリでは、アプリケーションを起動する3つの個別のスクリプト ファイルがあります:

  • FlightPlanGenerator.sh
  • RadarGenerator.sh
  • TrackGui.sh

これらのスクリプトまたはバッチファイルは、同じマシンで実行することも、このサンプルをコピーして複数のマシンで実行することもできます。 同じマシンで実行すると、共有メモリ トランスポートを介して通信します。 複数のマシンで実行すると、UDPを介して通信します。

航空管制GUIで追跡データと飛行計画情報を参照できることに注目してください。すべてのアプリケーションを単一のマシンで実行している場合、このデータは共有メモリを介して送信されます。

同じネットワークの複数のマシンにアクセスできる場合は、これらのアプリケーションを別々のマシンで実行してください。 注意:ネットワークにマルチキャストがない場合に、マルチキャストなしで実行するように設定変更する方法の詳細については、 マルチキャストなしでサンプルを実行する を参照してください。

 

How to run the Air Traffic Control Example on Windows [Download video file]

個々の要件に応じてスループットと遅延を設定する

分散システム内の個々の車両追跡またはレーダー追跡アプリケーションでは、データ遅延またはスループットに対して異なる要件が定められています。衝突防止システムまたは自衛システムでは、低遅延に関して厳格な要件が定められている可能性があります。記録またはロギングシステムでは、高スループットの車両位置データまたはレーダー追跡データを記録する必要がある可能性がありますが、その他のアプリケーションにおいては低遅延で受信する必要がない可能性があります。

RTI Connext DDSでは、XML形式でサービス品質 (QoS) パラメータを調整することができます。そのためネットワーク機能からアプリケーションロジックを分離することができ、新しい展開シナリオに適したアプリケーションの迅速な再設定を行うことができます。

このサンプルでは、遅延を犠牲にしてスループットを最大化するか、スループットを犠牲にして遅延を最小化するように、アプリケーションを設定する方法を示します。

増加したスループットと増加した遅延でサンプルを実行する

デフォルトでは、レーダージェネレータアプリケーションは最小限の遅延で動作します。遅延を犠牲にして増加したスループットで実行するには、以下のパラメータを使用します:

scripts\RadarGenerator.bat --high-throughput

また起動時にアプリケーションが送信する追跡数を増やしたり、新しい追跡を作成する頻度、一度に送信できる最大追跡数、更新する速度を設定したりすることもできます:

--start-tracks [[数値]
ジェネレータが起動時に生成すべき追跡数
--max-tracks [[数値]
ジェネレータが一度に送信する最大追跡数
--run-rate [[数値]
リアルタイムで、より速く、またはより遅く実行する デフォルトの速度では、すべての追跡は100ms(ミリ秒)毎に更新されます。これを2に設定すると、ジェネレータは2倍の速度で動作し、すべての追跡を50ms(ミリ秒)毎に更新します。
--creation-rate [[数値]
新しい追跡を作成する速度。

複数のレーダージェネレータを実行する

RadarGeneratorアプリケーションはレーダーの位置を更新する独自のセンサとしての機能を果たします。 データ モデルの考慮事項 のセクションで後ほど説明しますが、RadarGeneratorアプリケーションはそれぞれ固有のIDを必要とします。複数のRadarGeneratorアプリケーションを実行する場合、以下のオプションで実行する必要があります:

scripts\RadarGenerator.bat --radar-id [number]

マルチキャストなしでサンプルを実行する

ネットワークがマルチキャストをサポートしていない場合、ユニキャストデータのみを使用してこのサンプルを実行できます。ユニキャストのみで実行するには、次の2つの手順を実行する必要があります。

  • パラメータ「--no-multicast」を使用して、3つのすべてのアプリケーションを実行します。  これにより、アプリケーションはネットワークのマルチキャストに依存しない.xmlファイルをロードします。
  • 通信したいマシンのアドレスを追加するように、 base_profile_no_multicast.xmlファイルを編集します。これらのアドレスは、有効なUDPv4またはUDPv6アドレスです。
<discovery>
  <initial_peers>
    <!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
    <!-- Insert addresses here of machines you want     -->
    <!-- to contact                                     -->
    <!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
    <element>127.0.0.1</element>
    <!-- <element>192.168.1.2</element>-->
  </initial_peers>
</discovery>

サンプルのビルド

ディレクトリの概要

EXAMPLE_HOME
|-- Docs
`-- ExampleCode
    |-- make
    |-- win32
    |-- scripts
    `-- src
        |-- CommonInfrastructure
        |-- Config
        |-- Generated
        |-- Idl
        `-- . . .

ソースコードは次のように分かれています:

  • make - Linux makefiles
  • win32 - Windowsプロジェクトとソリューションファイル
  • scripts - アプリケーションを実行するスクリプト
  • src - ソースコード
    • CommonInfrastructure - すべてのアプリケーションがRTI Connext DDSを使用してデータの送受信を開始するために使用するコード
    • Config - XML QoS設定ファイル
    • Generated - Idlから生成されたソースファイル
    • Idl - ネットワーク経由で送信されるデータ型の説明
    • その他のディレクトリ - 特定のアプリケーションのソースコード。RTI Connext DDSのパブリッシュとサブスクライブ コードは、FooInterface.hとFooInterface.cxxに含まれています

サンプルのビルド

すべてのプラットフォームで、まず、NDDSHOMEという環境変数を設定する必要があります。 この環境変数は、RTI Connext DDSインストール内のndds.5.xxディレクトリを指している必要があります。 環境変数の設定方法の詳細については、 RTIコアライブラリとユーティリティ入門ガイドを参照してください。

Windowsシステム

Windowsシステムでは、win32\AirTrafficExample-.slnファイルを開くことから開始します。

このコードは、アプリケーションへのインターフェイスを表すライブラリ、ソース、およびIDLファイルの組み合わせで構成されています。Visual Studioのソリューションファイルは、必要なコードと必要なライブラリとのリンクを自動的に生成するように設定されています。

 

Windowsシステムで航空管制サンプルをビルドする方法 [ビデオファイルのダウンロード]

Linuxシステム

Linuxシステムでアプリケーションをビルドするには、ディレクトリをExampleCodeディレクトリに変更し、次のコマンドを使用します。

gmake –f make/Makefile.<platform>

選択するプラットフォームは、プロセッサ、OS、およびコンパイラ バージョンの組み合わせになります。makeディレクトリのMakefilesの選択肢を確認して、使用するシステムにもっとも厳密に一致するものを見つけてください。

 

Linuxシステムで航空管制のサンプルをビルドする方法 [ビデオファイルのダウンロード]

その他の重要点

データモデルの考慮事項

DDSでデータをモデリングする際にもっとも重要な考慮事項のひとつは、「データ ストリームに含まれる、ひとつのエレメントまたは現実の世界のオブジェクトを表すものは何か?」です。車両追跡のケースでは、一般に各車両は固有のオブジェクトとして表されるべきと仮定できます。このサンプルでは、AirTrafficControl.idlでデータタイプをモデリングしています。 RTI Connext DDSは、IDL(Interface Definition Language: OMGによって定義されるインタフェース定義言語)を使用して、言語非依存型のデータタイプを定義します。IDLに関する詳細は、 RTI Connextユーザー マニュアルで参照できます。

DDSでは、これらの現実の世界に存在する固有のオブジェクトは インスタンスとしてモデリングされます。インスタンスは、//@キーの記号で示される、 キーと呼ばれる固有識別子のセットによって記述されます。

したがって、このサンプルでは、trackIdをキーフィールドとして使用します。

long trackId; //@key
              

各車両が固有のオブジェクトとして表されるべきというこの前提には、ひとつの弱点があります。同じ車両が複数のセンサによって追跡されているとしたら?

多くの場合、各センサからの更新は個別に管理することが推奨されます。  DDSでは、これは各車両が現実の世界の固有のオブジェクトではなく、車両とセンサの組み合わせが現実の世界のオブジェクトになることを意味します。  これをサポートするために、センサIDもまたキーフィールドになります:

long radarId; //@key
long trackId; //@key

緊急車両の位置を更新しているGPSなど、車両につき単一のセンサがあると仮定できる場合は、データの一要素として固有のセンサIDを配慮する必要はありません。このケースでは、インスタンスは車両です。

詳細設定:レーダーのスループットのためのXMLの設定

The Radar Generator uses XML to configure Quality of Service for high-throughput radar tracks

レーダー追跡または車両追跡システムを構築する重要なコンポーネントはパフォーマンスの調整であるため、コードそのものの詳細について述べる前に、まずこのパフォーマンスの調整について説明します。

ソースコードは、データの配信とリソースの特性を設定するのに使用する一連のXMLファイルをロードします。.xmlファイルはConfigディレクトリに格納されています。これらのファイルは、データの信頼性があるかどうかなど、データの通信特性を指定します。XML QoSプロファイルは互いに継承できます。

マルチキャスト

マルチキャストは、multicast_base_profile.xmlファイルで有効化されます。

このサンプルでは、これは「OneToManyMulticast.」と呼ばれるQoSプロファイルでカプセル化されています。この機能はデフォルトで無効に設定されています。これは高スループットのマルチキャストデータを送信中に一部のワイヤレス ネットワークで大量のトラフィックが発生するためです。ただし、ネットワークがこの機能をサポートしている場合、このセクションのコメントアウトを外して、一対多数のはるかに高いスループットを得ることができます。もうひとつのQoSプロファイルはこのプロファイルから継承します。

<qos_profile name="OneToManyMulticast">
   <datareader_qos>
     <!-- Uncomment this to enable user data over multicast.  This is
          commented out for systems that do not have multicast, or
          with switches that block some multicast traffic -->
     <!--<multicast>
       <value>
         <element>
           <!- - Must be a valid multicast address - ->
           <receive_address>239.255.5.1</receive_address>
         </element>
       </value>
     </multicast> -->
  </datareader_qos>
</qos_profile>

バッチング

小さなデータのバッチングは、遅延を犠牲にして高スループットを有効にすることができます。Radarのデフォルト プロファイル「LowLatencyRadar」はバッチングを使用しません。バッチングは「HighThroughputRadar」の設定で有効化されます。

<batch>
  <enable>true</enable>
  <!-- If the batch hits 1024 bytes, flush to the network -->
  <max_data_bytes>1024</max_data_bytes>
  <!-- You can decide on the maximum amount of additional latency
       you are willing to sacrifice for better throughput. -->
  <max_flush_delay>
    <sec>0</sec>
    <nanosec>200000000</nanosec>
  </max_flush_delay>
</batch>

すべてのアプリケーションに共通のDDSインフラストラクチャ

では、一度作成して、各DDSアプリケーションで使用するコードについて説明します。CommonInfrastructure/DDSCommunicator.h/.cxxのコードは、DDS通信を開始する基本オブジェクトを作成します。DDSCommunicatorクラスは、DDS DomainParticipantオブジェクトの作成と初期化をカプセル化します。

すべてのアプリケーションは、 他のRTI Connext DDSアプリケーションを検出し、また他のDDSエンティティを作成するために、少なくとも1つの DomainParticipant を必要とします。 通常、アプリケーションは DomainParticipantをひとつだけ含みます。

ソースコードでは、これはCommonInfrastructure/DDSCommunicator.cxxに含まれているDDSCommunicatorクラスで参照できます。

DomainParticipant* CreateParticipant(long domain,
        char *participantQosLibrary, char *participantQosProfile) {

  _participant = TheParticipantFactory->create_participant_with_profile(
          domain, participantQosLibrary, participantQosProfile,
    NULL, STATUS_MASK_NONE);
  ...
}

DomainParticipant's QoSは、1つまたは複数のXMLファイルからロードされます。ロードすべきプロファイルは、participantQosLibraryとparticipantQosProfileによって指定されます。DomainParticipant QoSの完全なリストは、 HTML APIドキュメントに記載されています。

ハンズオン:ツールを使用してアプリケーションを参照する

これらのアプリケーションが何を作成しているかを理解するために、RTI Analyzerツールを使用して以下を確認できます:

  • ネットワーク上でアプリケーションが送受信しているトピックとは何か
  • アプリケーションのデータ構造の様子

RTI Analyzerツールは、お使いのアプリケーションが使用しているドメインと同じドメインで通信するように設定する必要があります。このビデオでは、RTI Analyzerを使い始める方法とデータタイプを参照する方法について説明します。

 

RTI Analyzer ツールを使用して、航空管制のサンプル アプリケーションを参照する [ビデオ ファイルのダウンロード]

ボーナスハンズオン: コードでドメインを変更する

RadarGeneratorによって使用されているドメインは、RadarInterface.cxxに含まれるこのコード スニペットを変更することで変更できます。

if (NULL == CreateParticipant(0, qosFileNames, libName, profileName))

「0」を 0 〜 232の間 の数値に変更します。これでこのアプリケーションは異なるドメインにあります。アプリケーションを実行します。これでこのアプリケーションはほかのアプリケーションを検出したり、また検出したそれらと通信しなくなります。

ドメインの分離は、分散システムに通信すべきでないサブシステムがある場合に役立ちます。またこれは複数のデベロッパが同じプロジェクトに携わっており、それぞれのアプリケーションやテストが妨害し合うことを防止したい場合にも役立ちます。

完了したら、アプリケーションをドメイン0に戻し、ビルドし直します。

 

ドメインを変更して、アナライザで参照する [ビデオ ファイルのダウンロード]

レーダー ジェネレータ (C++)

このアプリケーションはネットワーク上でデータを送受信します。アプリケーションのDDSインタフェースを作成するコードは、RadarInterfaceクラスに含まれています。このクラスは、以下の3つのオブジェクトで構成されています:

  • DDSCommunicator
  • RadarWriter
  • FlightPlanReader

DDSCommunicatorオブジェクトは、 RadarWriterとFlightPlanReaderエンティティを作成するのに使用される必要なDDSエンティティを作成します。

RadarWriterクラスはレーダー データを送信するDDS DataWriterのラッパーです。FlightPlanReaderクラスは飛行計画データを受信するDDS DataReaderのラッパーです。

データの送信

アプリケーションは、PublishTrack()によって呼び出される追跡データをパブリッシュします。ネットワーク上で実際にデータを送信するRTI Connext DDSコールは、以下のとおりです:

_trackWriter->write(track, handle);

このコールは、 ネットワーク上で送信されるデータとそのデータのハンドルを受け入れます。このサンプルでは、NILハンドルを渡します。 ただし、場合によっては、 データの事前登録とハンドルの使用によりパフォーマンスを向上させることができます。

アプリケーションは、DeleteTrack()で呼び出される追跡中止メッセージをパブリッシュします。これは、以下を呼び出すことで行われます:

_trackWriter->dispose(track, handle);

レーダーのデータモデル - データ タイプ

The Radar Generator uses IDL to represent language-independent data types

レーダーはAirTrafficControl.idlファイルでモデリングされています。RTI Connext DDSは、IDL(Interface Definition Language: OMGによって定義されるインタフェース定義言語)を使用して、言語非依存型のデータタイプを定義します。IDLに関する詳細は、 RTI Connextユーザー マニュアルで参照できます。

レーダーのデータ タイプは、以下のとおりです:

struct Track {
  long radarId; //@key
  long trackId; //@key
  . . .
};

これは、わずか数フィールドを含む非常にシンプルなデータとしてモデリングされています。ここで注目すべきもっとも重要な点は、追跡IDとレーダーIDは、//@keyのタグでマークされていることです。これはこれらのIDが個々の追跡に固有の識別子を構成していることを示しています。飛行IDは、追跡の作成時に利用可能な場合とそうでない場合があるため、追跡に固有のIDの一部を構成していません。追跡に固有の識別子をキーフィールドとしてマークすることにより、これらは インスタンスとして固有であるということをミドルウェアに伝えています。

トピック内で現実の世界に存在する固有のオブジェクトを表していることをミドルウェアに伝えることで、固有のオブジェクトのそれぞれに対して個別のキャッシュを保持するなど、ミドルウェアでのデータのスマートな処理を実現できます。この詳細は、 レーダーのデータ配信の特性 (QoS)のセクションで取り上げます。

データの一意に識別可能な要素に関する詳細は、 このベスト プラクティス のドキュメントで参照できます。

またデータには、緯度、経度、高度があります。ベアリング、スピードなど、他のフィールドをオプションとして追加することができます。

レーダーのデータ モデル - トピック

レーダーデータは単一のトピックとして表すことができます。トピックの名前はインタフェースの一部であるため、トピック名はXMLまたはIDL内で定義することがベスト プラクティスです。

const string AIR_TRACK_TOPIC = "AirTrack";

レーダーのデータ配信の特性 (QoS):

デフォルトでは、レーダーデータは急速に送信されるため、信頼性が有効化されていない状態で送信される可能性があります。しかし、受信側のアプリケーションが各追跡の最新の更新情報を受信することは重要です。

これをサポートするために、このサンプルでは、1の履歴の深さと組み合わせて信頼性を有効にしています。上記で説明したように、各追跡は固有のインスタンスとしてモデリングされています。信頼性と1の履歴の深さを組み合わせた、インスタンスとしてのモデリング データが意味することは、以下のとおりです:

  • アプリケーションには、各レーダー追跡に対してキューに単一のスペースがあり、また
  • アプリケーションは、現在そのキューの各スペースに含まれるすべてを確実に配信します。 

これにより、送信される最後のデータ(最後の更新情報または中止メッセージ)が配信されることが確実になります。Reliability(信頼性)とHistory QoS(履歴QoS)は、XMLで有効化されています。これらの設定は、確実な配信を確保するために、DataWriterとDataReaderの両方で有効化されている必要があることに注意してください。

<reliability>
  <kind>RELIABLE_RELIABILITY_QOS</kind>
</reliability>
<history>
  <kind>KEEP_LAST_HISTORY_QOS</kind>
  <depth>1</depth>
</history>

そのほかに、レーダーデータは低遅延、高スループット データを得るように調整されています。上記のとおり、このサンプルでは、バッチングを有効化することで、遅延を犠牲にしてスループットをさらに向上させることができます。

飛行計画ジェネレータ (C++)

このアプリケーションはネットワーク経由で飛行計画データを送信します。またこのサンプルでは、3つのアプリケーションの中でもっともシンプルです。

アプリケーションのDDSインタフェースを作成するコードは、FlightPlanPublisherInterfaceクラスに含まれています。このクラスはデータの書き込みを直接管理します。またこのクラスは、DomainParticipantとネットワーク上で実際にデータを送信するFlightPlanDataWriterを作成するのに使用されるDDSCommunicatorを含みます。

飛行計画データ モデルの概要

飛行計画は、以下の特性を持つOccasionally Changing State Data(状況によって変化する状態のデータ)としてDDSでモデリングされています。

  • このデータは特定のオブジェクトの状態が変化したときのみ更新されます(このケースでは、条件に基づいてパブリッシュまたは更新される場合がある飛行計画)
  • そのオブジェクトの状態は常に変化しているというわけではありません
  • その他のアプリケーションは、起動前にパブリッシュされたとしても、各オブジェクトの現在の状態を知る必要があります

飛行計画データ モデル - データ タイプ

The Flight-Plan Generator uses IDL to represent language-independent data types

データタイプはAirTrafficControl.idlファイルでモデリングされています。このデータタイプは、Analyzerツールを使用して参照できます。FlightPlan(飛行計画)のデータタイプは、列挙、文字列、代替飛行場のシーケンスなどを含み、追跡データ タイプよりも複雑です。

struct FlightPlan
{
  // Up to seven characters that represent the unique flight ID
  FlightId flightId; //@key

  // flight rules (enumeration)
  FlightRulesKind flightRules;

  // type of flight (enumeration)
  FlightTypeKind flightType;

  ...
};

状態データは、現実の世界に存在する、あるエレメントまたはオブジェクトの状態を表します。このケースでは、特定のフライトに対する飛行計画です。DDSでは、現実の世界に存在するオブジェクトは インスタンスとしてモデリングされます。

インスタンスは、//@キーの記号で示される、 キーと呼ばれる固有識別子のセットによって記述されます。このケースでは、キーは固有の飛行識別子(航空会社IDと便名を含む最長7つの文字で構成される文字列)です。

飛行計画データモデル - トピック

飛行計画データは単一のトピックとして表すことができます。トピックの名前はインタフェースの一部であるため、トピック名はXMLまたはIDL内で定義することがベスト プラクティスです

const string AIRCRAFT_FLIGHT_PLAN_TOPIC = "FlightPlan";

飛行計画のデータ配信の特性 (QoS)

このデータは常に送信されているわけではないため、信頼性をもって送信される必要があります。Reliability QoS(信頼性QoS)はXMLファイルで設定されます。これらの設定は、確実な配信を確保するために、DataWriterとDataReaderの両方で有効化されている必要があることに注意してください。

<reliability>
  <kind>RELIABLE_RELIABILITY_QOS</kind>
</reliability>

状態データの送信のためにRTI Connext DDSを使用するメリットのひとつは、状態が変化すると同時にデータを送信できるだけでなく、後で接続された関連アプリケーションも起動直後に最新の状態データを確実に受信できる機能です。これは、飛行計画が取得可能になり次第または更新され次第、送信できることを意味します。関連アプリケーションがまだ起動していない場合は、起動直後に最新の飛行計画を受信します。後で接続されたアプリケーションへの送信を可能にするには、データは一時的にローカルで送信されるか、より高いレベルの耐久性をもって送信される必要があります。

<durability>
  <kind>TRANSIENT_LOCAL_DURABILITY_QOS</kind>
</durability>

あらゆる飛行計画の最新の更新情報のみを送信するために、このXMLは飛行計画インスタンス毎に1つのサイズ履歴を保持するように、DataWriterで履歴キャッシュを設定します。

 

<history>
  <kind>KEEP_LAST_HISTORY_QOS</kind>
  <depth>1</depth>
</history>

このデータは極めて高いスループットに対応するように調整する必要はありませんが、安定した信頼性を得るように調整します。詳細は、FlightPlanStateData XMLのプロファイルに記述されています。

航空管制GUI (C++)

GUIアプリケーションは、飛行計画ジェネレータから飛行計画を受信し、レーダー ジェネレータからレーダー追跡を受信します。このアプリケーションは、データを受信するのに2つのDDS DataReadersを使用します。 航空管制GUIは、モデル ビュー プレゼンター (MVP: Model View Presenter) 設計を使用して構築されています。モデルはネットワークから受信されます。ビューはデータを表示するGUIです。プレゼンターはモデルからのデータ取得を管理し、データをGUIが認識できるオブジェクトに変換し、モデルが変化したときにGUIに通知します。

追跡データの受信

このアプリケーションでは遅延を最小限に抑える必要はないため、プレゼンターは以下を呼び出して定期的に更新情報を要求します:

reader->GetCurrentTracks(&tracks);

GetCurrentTracks()コールは、RTI Connext DDS APIを呼び出すことで、現在TrackDataReaderのキューにあるすべての追跡データを取得します。

DDS_ReturnCode_t retcode = _reader->read(
        trackSeq, sampleInfos,
        DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE,
        DDS_ANY_VIEW_STATE, DDS_ALIVE_INSTANCE_STATE);

この呼び出しはTrackDataReaderのキューから「生きた」追跡を取得しますが、データを取り出す代わりにキューに残しておきます。

「生きた」追跡の処理後、アプリケーションは「生きていない」(削除された)追跡インスタンスを取得し、処理しながらそのインスタンスを排除します。

retcode = _reader->take(
        trackSeq, sampleInfos,
        DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE,
        DDS_ANY_VIEW_STATE,
        DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE |
        DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE);

飛行計画データの受信

GUIは追跡データの各 サンプル の更新情報を取得した後、その更新情報をその追跡に対応する飛行計画データと関連付ける必要があります。追跡データには、飛行計画インスタンスの固有識別子である飛行IDの文字列が含まれます。飛行IDを使用して、飛行計画インスタンスの最新の更新情報を取得することができます。

このためにアプリケーションは、以下を実行します:

  1. レーダー追跡データの一部として取得可能な飛行計画の固有ID(キー フィールド)を取得します
  2. 固有IDのセットのみでダミーの飛行計画オブエジェクトを作成します
  3. 飛行計画のDataReaderにlookup_instanceを呼び出し、固有IDからインスタンスのハンドルに対応付けます。
  4. インスタンスのハンドルがNilでない場合、read_instance()を呼び出し、その飛行計画のみに対してキューにある更新情報を取得します。QoS設定の履歴の深さ = 1であるため、飛行計画につき、キューには1つの更新情報しかないことに注意してください。
// Look up the particular instance
const DDS_InstanceHandle_t handle =
        _fpReader->lookup_instance(flightPlan);

// ... Check if the instance is null

// Reading just the data for the flight plan we are interested in
_fpReader->read_instance(flightSeq, infoSeq,
        DDS_LENGTH_UNLIMITED,
        handle);

次のステップ

本サンプルの応用

さらに実践を試してみたい場合、記録/再生ツールを使用して、実際の追跡データを記録して、後で再生することができます。これは以下を実行できるため、実際のシステムで役に立ちます:

  • 分散システムで発生していることを記録して、そのデータを事後処理し、異常を検索する。
  • 生きたデータを記録して再生し、現実の世界のシナリオと比べ検証する。
  • 最初に記録された速度よりも高速にデータを再生することで、システムの耐久度テストを行う。
 

Using the Record and Replay tools to record and replay air traffic control data [Download video file]

コミュニティに参加する

RTIコミュニティフォーラム に、質問を投稿してください。.

これらの RTIコミュニティGitHub でCase + Codeでのサンプルに貢献してみましょう。 指示を使用して、