1

選択した DDS ドメインで現在利用可能なトピックを取得できる最も単純な C# アプリケーションを作成しようとしています。しかし、私はそれを機能させることができないようです。

// Create the DDS Domain participant on domain ID 0
DDS.DomainParticipant participant =                          
             DDS.DomainParticipantFactory.get_instance().create_participant(
                    0,
                    DDS.DomainParticipantFactory.PARTICIPANT_QOS_DEFAULT,
                    null, /* Listener */
                    DDS.StatusMask.STATUS_MASK_NONE);
DDS.Subscriber sub = participant.get_builtin_subscriber();
DDS.DataReader reader1 = sub.lookup_datareader("DCPSTopic");
DDS.TopicBuiltinTopicDataDataReader builtinReader1 =  
                       (DDS.TopicBuiltinTopicDataDataReader)reader1;
DDS.TopicBuiltinTopicDataSeq topicSeq = new DDS.TopicBuiltinTopicDataSeq(10) ;
DDS.SampleInfoSeq infoSeq = new DDS.SampleInfoSeq(10);
builtinReader1.read(topicSeq, 
                    infoSeq, 
                    10, 
                    DDS.SampleStateKind.ANY_SAMPLE_STATE, 
                    DDS.ViewStateKind.ANY_VIEW_STATE,
                    DDS.InstanceStateKind.ANY_INSTANCE_STATE);

上記のコードを実行すると、パブリッシャーとサブスクライバーの両方が同じドメイン (ドメイン 0) で実行および投稿しているにもかかわらず、最後の行 (builtinReader1.read(...)) で "Retcode_NoData" 例外が発生します。私のコードの何が問題なのか、何か考えはありますか?

ところで。DDS の RTI Connext 5.0 実装を使用しています。

よろしくジョン

4

2 に答える 2

1

レーニアは正しい。Connext DDS は、トピックを に直接伝播しませんTopicBuiltinTopicData。むしろ、 and で間接的にPublicationBuitinTopicData行いSubscriptionBuiltinTopicDataます。これは、DDS 仕様で許可されています。

DDS ドメイン内の DomainParticipants、DataWriters、および DataReaders の存在を検出するというタイトルのこの HOWTO には、組み込みトピックの使用方法に関する情報があります。HOWTO には、動作するサンプル コードが含まれています。これは C# ではなく Java ですが、マッピングは簡単です。この例では、一度に 1 つのサンプルを読み取るため、シーケンス構文を扱う必要はありません。

使用する必要がある理由:

DDS.SampleInfoSeq infoSeq = new DDS.SampleInfoSeq();

それ以外の:

DDS.SampleInfoSeq infoSeq = new DDS.SampleInfoSeq(10);

渡されたシーケンスが「空」(つまり、割り当てられた/最大長がゼロ) であるか、割り当てられた長さを持っているかによって、2 つの異なる動作を持つ読み取り/取得 API です。

シーケンスが空の場合 (デフォルトのコンストラクターで得られるもの)、読み取り/取得はゼロコピー API として動作します。これは、シーケンス内の実際の要素が、ミドルウェア内に既に格納されている要素から「借用」されることを意味します。このため、渡す必要があるシーケンスは「空の」シーケンスである必要があります。これにより、ミドルウェアは、内容を内部要素への参照に置き換えてもよいことを認識できます。要素にアクセスした後、操作を呼び出すミドルウェアに「貸与された要素」を返す必要がありますDataReader::return_loan

シーケンスが空でない場合。次に、DDS は要素が事前に割り当てられていると想定し、渡された要素にデータをコピーしようとします。あなたが示したコードの問題は、

DDS.SampleInfoSeq infoSeq = new DDS.SampleInfoSeq(10);

シーケンス自体だけを割り当てます。しかし、要素ではありません。したがって、読み取り/取得呼び出しは、コピーを作成しようとすると失敗します。この非ゼロコピー API を使用する場合は、呼び出しの後に各要素の割り当て/割り当てを行う必要があります。つまり、次のようになります。

for (int i=0; i< 10; i++ ) {
    infoSeq.set_at(i, new DDS.SampleInfo());
}

同じことがデータシーケンスにも当てはまります。これを行う場合、DataReader::return_loan操作を使用する必要はありません。ただし、余分なコピーが存在するため、効率が低下します。

DDS シーケンスの使用方法の詳細については、Howto use OMG DDS Sequences in C++というタイトルのこの HOWTO を参照してください。C++ の例で書かれていますが、原則はすべての言語に適用されます。

よろしく、ジェラルド

于 2013-03-11T14:16:42.830 に答える
1

RTI Connext では、TopicBuiltinTopic期待どおりに動作しません。C# API DDS::TopicBuiltinTopicData Class Referenceのドキュメントを確認してください。

注:DDS_TopicBuiltinTopicData組み込みのトピックは、検出されたトピックに関する情報を伝えるためのものです。このトピックのサンプルは、ネットワーク上で別のパケットで伝播されません。代わりに、データは他の組み込みトピック (DDS::PublicationBuiltinTopicDataおよび DDS::SubscriptionBuiltinTopicData) によって運ばれる情報の一部として送信されます。したがってTopicBuiltinTopicData 、DataReaders はデータを受け取りません。

基本的には、Connext でディスカバリーが実装されているため、どのTopicBuiltinTopicDataDataReader にもデータが表示されません。これは、コード スニペットで確認できることです。

幸いなことに、バスのトピックに関する情報を取得することは引き続き可能です。これは、PublicationBuiltinTopicData および SubscriptionBuiltinTopicData を介して発生する必要があります。C# API DDS::PublicationBuiltinTopicData Class Referenceのドキュメントを見ると、データに文字列フィールドtopic_nametype_name. さらに、型の構造に関する情報を取得できますが、これはより高度で実装固有のものです。


Publication および Subscription 組み込みトピックの読み取りを実装する予定がある場合の 3 つの注意事項。まず、組み込みトピックの名前をハードコーディングする代わりに、次のよう"DCPSTopic"に対応する TypeSupport 属性を参照することをお勧めします。

reader = sub.lookup_datareader(
             DDS.PublicationBuiltinTopicDataTypeSupport.PUBLICATION_TOPIC_NAME);

次に、Connext を使用すると、組み込みの DataReader には、組み込みのサブスクライバーと同じ DomainParticipant に存在するパブリケーションまたはサブスクリプションに関するサンプルが含まれないことを知っておくとよいでしょう。つまり、他の参加者のエンティティのみを表示でき、自分のエンティティは表示できません。

最後に、コードをいじっていると、次のようにシーケンスのコンストラクター呼び出しを置き換えない限り、サンプルの読み取りが機能しないことに気付きました。

DDS.SampleInfoSeq infoSeq = new DDS.SampleInfoSeq();

それ以外の

DDS.SampleInfoSeq infoSeq = new DDS.SampleInfoSeq(10);

data-sequence についても同様です。その理由はわかりませんが、実際的な意味はありません。

于 2013-03-08T15:51:32.380 に答える