Getting Started with Connext DDS: From Defining your Data Type to Sending and Receiving Data

The following four steps are all you need to build an RTI Connext DDS “Hello World” example (See Figure 1). This document assumes you already have RTI Connext DDS installed and the NDDSHOME environment variable is set, and you are about to write your first RTI Connext DDS publisher and subscriber applications. 

The steps below are assuming C language coding under Linux using GCC compiler. 

                                     Figure 1: Example “Hello World” application flow

Step 1:  

Create a type definition (data structure) in a text file and save the text file with*.idl extension (e.g. HelloWorld.idl). This is the data structure that will allow sharing data/samples between a DDS publisher (using a DataWriter) and subscriber (using a DataReader) application.

struct HelloWorld {
     string<64>             prefix;
     long                   sampleId;
     sequence<octet, 8192>  payload;
};

More information on IDL

Step 2:

Generate RTI Connext DDS code by using rtiddsgen (interface compiler for IDL files).  This step shows how to generate example code and makefiles for Linux with the i86Linux2.6gcc4.4.5 architecture (e.g., makefile_HelloWorld_i86Linux2.6.gcc4.4.5 and Makefile.common).  See Chapter 3 of the RTI Core Libraries and Utilities User's Manual for more details on code generation (e.g., for Windows/VS projects). 

rtiddsgen  -language C  -example i86Linux2.6gcc4.4.5 HelloWorld.idl 

Other flags that might be helpful are -ppDisable (disable the c pre-processor) and -replace (force rtiddsgen to overwrite existing files with the same names).  The code that is generated by rtiddsgen falls into a few categories, including:

  1. DDS application source code:  Source for example publisher and subscriber applications, where a developer can populate the defined data structure with desired values to publish, and can receive and process the data via the example subscriber.

  2. DDS DataBus source code (typical user should not change it): This code is an interface to the RTI Connext DDS middleware. The middleware itself is responsible for auto-discovery of other DDS domain participants in the network, acts as a factory for the several DDS 'entities' (DomainParticipant, Publisher, Subscriber, Topic, DataReader and DataWriter), and also for maintaining the various states of internal MetaData, threads and databases.

  3. User QoS XML file: This QoS file allows developer to configure various QoS settings e.g., Reliability, Transport, Sample filtering (time/content based) etc.

Note: Make sure you have installed RTI Connext DDS libraries (default location e.g., ~/RTI/ndds.5.1.0/lib/) for the desired target architecture and GCC version (e.g., ~/RTI/ndds.5.1.0/lib/i86Linux2.6gcc4.4.5) for which you have generated the code. Otherwise there will be warnings related to the missing libraries in the Step 3. 

Step 3:

Compile the generated Connext DDS code using the rtiddsgen-generated makefile (for Windows VS, a project file is generated).

 make -f makefile_HelloWorld_i86Linux2.6.gcc4.4.5

Step 4: 

Execute the publisher and pubscriber applications. The publisher and subscriber application executables are under the “/obj/<architecture>” directory.  Open two console windows; on the first run an instance of the publisher application (./obj/i86Linux2.6.gcc4.4.5/HelloWorld_publisher), on the second run the subscriber application (./obj/i86Linux2.6.gcc4.4.5/HelloWorld_subscriber).

 

Note: You can run the publisher and subscriber instances on different PCs if they are connected to the same LAN. For WAN you need additional configuration.

Note: There are reasons (i.e., loading USER_QOS_PROFILES.xml  from compile directory) to use the syntax ./obj/<arch>/<application> when starting the instances.  For now, treat the compile directory as the working directory and avoid changing to the ./obj/<arch> directory before launching the application instances.

  DataWriter and DataReader overview diagram

        Figure 2: The logical view of DDS DataBus with publisher and subscriber application interaction.

 A few definitions associated with Figure 2:

  • The word 'entities' is a general term for Domain Participant, Publisher, Subscriber, DataWriter, DataReader and Topic.  Entities have an internal status that can be queried, can have their behavior altered through use of Quality of Service settings, and an application may attach a listener callback to them (these are the three requirements for being an "entity" in DDS).  In this document, entities are capitalized in order to differentiate them from other usages.  A "Publisher" is a DDS entity, a "publisher" is an application that uses a DataWriter to publish structured data.
  • Domain is a logical container in which DDS entities communicate - hence allowing separate “communication planes”. A domain is uniquely defined by a domain ID number, which provides a level of isolation between domains.  DDS permits multiple, uniquely identifiable domains even on the same network fabric, while also crossing network fabric boundaries. A single domain may span shared memory and Ethernet (and other connections), allowing an application to exchange data between both shared-memory connections and ethernet connections, at the same time, with no additional configuration.
  • A Participant (also called 'DomainParticipant'), defines the scope of an application within a single, global data space (a domain). It is a factory for creating other DDS entities in its domain.
  • Topic is a type-specific domain segment that allows publishers and subscribers to link with a common data type (data structure) by a Topic name. Where a Topic name is uniquely and unambiguously identified in a domain (e.g. “Example HelloWorld”).
  • Quality of Service (QoS) policies govern RTI Connext DDS application behaviour by specifying their reliability, durability, resource usage, fault tolerance etc. The DDS standard defines policies which may be applied to the various RTI Connext DDS entities, additionally there are other QoS policies available depending on the DDS implementation (RTI Connext DDS, RTI Connext Micro, etc).
  • A DataWriter (DW) is strongly typed, and publishes data on a Topic.  A DW can be configured to publish data synchronously, or asynchronously.  Data published asynchronously may be "batched" to limit network overhead, and may also be subject to flow-control.
  • A DataReader (DR) is strongly typed, and subscribes to data on a Topic; it receives data published on a Topic.  DataReaders may present data to the subscriber application via a listener callback, via a "waitset" (blocking wait, similar to a "select" call on a TCP socket), or via application polling.
  • A Publisher is the factory, container and manager for one or more heterogeneous (differently typed) DataWriters.
  • A Subscriber is the factory, container and manager for one or more heterogeneous (differently typed) DataReaders.
  • Listeners are used to notify the application of events (status changes).  For example, that there is new data available on a DataReader, or that a new DataWriter on a Topic has mismatched QoS settings and so will not be able to provide data.