Search code examples
c#data-distribution-service

Subscribing to the built-in topic "DCPSTopic" in DDS


I am trying to create the simplest C# application that will allow me to get the topics currently available in the selected DDS domain. But I can't seem to make it work.

// 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);

When running the code above, I get a "Retcode_NoData" exception in the last line (builtinReader1.read(...)) even though both publishers and subscribers are running and posting in the same domain (domain 0). Do you have any idea about what could be wrong with my code?

By the way. I use RTI Connext 5.0 implementation of DDS.

Regards John


Solution

  • With RTI Connext, the TopicBuiltinTopic does not behave as one might expect. Check out the documentation of the C# API DDS::TopicBuiltinTopicData Class Reference:

    Note: The DDS_TopicBuiltinTopicData built-in topic is meant to convey information about discovered Topics. This Topic's samples are not propagated in a separate packet on the wire. Instead, the data is sent as part of the information carried by other built-in topics (DDS::PublicationBuiltinTopicData and DDS::SubscriptionBuiltinTopicData). Therefore TopicBuiltinTopicData DataReaders will not receive any data.

    What it basically says: because of the way discovery is implemented in Connext, you will not see any data in any TopicBuiltinTopicData DataReaders. This is what you observe in your code snippet.

    Fortunately, it is still possible to get information about Topics on the bus. This has to happen via the PublicationBuiltinTopicData and SubscriptionBuiltinTopicData. If you look at the documentation of the C# API DDS::PublicationBuiltinTopicData Class Reference, you can see that the data contains the string fields topic_name and type_name. Additionally, you can get information about the structure of the type, but that is more advanced and implementation specific.


    Three remarks in case you plan to implement the reading of the Publication and Subscription builtin Topics. First, in stead of hardcoding the name of the built-in Topic, like you did with "DCPSTopic", it is better to refer to the corresponding TypeSupport attribute, as in:

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

    Then it is good to know that with Connext, built-in DataReaders will not contain any samples about Publications or Subscriptions that live in the same DomainParticipant as the built-in Subscriber. In other words, you can only see other Participant's Entities, but not your own.

    Finally, while playing around with you code, I noticed that the reading of the samples did not work unless I replaced the constructor invocations of the sequences as follows:

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

    in stead of

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

    and similar for the data-sequence. I do not know why that is, but it should not have any practical implications.