DDS Overview

The Data Distribution Service (DDS) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group (OMG). It provides a publish-subscribe pattern for real-time, scalable, and high-performance data exchange.

What is DDS?

DDS enables applications to communicate by publishing and subscribing to data samples identified by topics. It provides:

  • Decoupling: Publishers and subscribers don't need to know about each other
  • QoS Control: Fine-grained control over reliability, durability, latency, and resource usage
  • Discovery: Automatic discovery of participants, topics, and endpoints
  • Type Safety: Strongly-typed data model with type propagation
  • Scalability: From small embedded systems to large distributed systems

DDS Architecture

graph TB subgraph "Domain Participant" P1[Publisher] S1[Subscriber] T1[Topic: Temperature] T2[Topic: Pressure] P1 --> DW1["DataWriter Temperature"] P1 --> DW2["DataWriter Pressure"] S1 --> DR1["DataReader Temperature"] S1 --> DR2["DataReader Pressure"] DW1 -.publishes.-> T1 DR1 -.subscribes.-> T1 DW2 -.publishes.-> T2 DR2 -.subscribes.-> T2 end

Key Components

Domain Participant

The entry point for DDS applications. Represents a participant in a DDS domain (isolated communication space).

auto participant = astutedds::dcps::DomainParticipantFactory::create_participant(
    domain_id,
    PARTICIPANT_QOS_DEFAULT
);

Topic

Named data channel typed by a specific data structure. Topics are the foundation of DDS communication.

auto topic = participant->create_topic<SensorData>(
    "SensorTopic",
    TOPIC_QOS_DEFAULT
);

Publisher and DataWriter

Publishers create DataWriters that publish samples on topics.

auto publisher = participant->create_publisher();
auto writer = publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);

SensorData data;
data.temperature = 25.5;
writer->write(data);

Subscriber and DataReader

Subscribers create DataReaders that receive samples from topics.

auto subscriber = participant->create_subscriber();
auto reader = subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);

std::vector<SensorData> samples;
reader->take(samples);

Communication Flow

Simple Publish-Subscribe

sequenceDiagram participant Publisher participant DDS participant Subscriber Publisher->>DDS: Create DataWriter Subscriber->>DDS: Create DataReader Note over DDS: Discovery Protocol Note over DDS: (SPDP/SEDP) DDS-->>Publisher: Reader discovered DDS-->>Subscriber: Writer discovered Publisher->>DDS: write(sample) DDS->>Subscriber: DATA submessage Subscriber-->>DDS: ACKNACK (if RELIABLE) Note over Subscriber: Process sample

Discovery Process

DDS uses automatic discovery to match publishers and subscribers:

sequenceDiagram participant App1 as Application 1 participant App2 as Application 2 Note over App1,App2: SPDP: Simple Participant Discovery Protocol App1->>App2: SPDP: Participant announcement App2->>App1: SPDP: Participant announcement Note over App1,App2: SEDP: Simple Endpoint Discovery Protocol App1->>App2: SEDP: DataWriter metadata App2->>App1: SEDP: DataReader metadata Note over App1,App2: Endpoints matched! Note over App1,App2: Ready for data exchange

Reliable Data Exchange

When using RELIABLE reliability QoS:

sequenceDiagram participant Writer participant Reader Writer->>Reader: DATA (seq=1) Writer->>Reader: DATA (seq=2) Note over Reader: seq=2 lost Writer->>Reader: HEARTBEAT (seq=1-3) Reader->>Writer: ACKNACK (missing: 2) Writer->>Reader: DATA (seq=2) [repair] Reader->>Writer: ACKNACK (all received) Note over Writer,Reader: All data delivered

Best-Effort Data Exchange

When using BEST_EFFORT reliability QoS:

sequenceDiagram participant Writer participant Reader Writer->>Reader: DATA (seq=1) Writer->>Reader: DATA (seq=2) Note over Reader: seq=2 lost Writer->>Reader: DATA (seq=3) Note over Reader: Process seq=1, 3 Note over Reader: Skip seq=2 (no repair)

Quality of Service (QoS)

QoS policies control the behavior of DDS entities. Key policies include:

Reliability

  • BEST_EFFORT: Fast, no retransmission (good for real-time sensor data)
  • RELIABLE: Guaranteed delivery with retransmission (good for commands)

Durability

  • VOLATILE: No historical data (only live data)
  • TRANSIENT_LOCAL: Late joiners get historical data
  • TRANSIENT: Historical data survives process restart
  • PERSISTENT: Historical data persists in database

History

  • KEEP_LAST(n): Keep only last n samples
  • KEEP_ALL: Keep all samples (subject to resource limits)

Example QoS Configuration

auto qos = astutedds::dcps::DataWriterQosBuilder()
    .reliability(astutedds::dcps::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS)
    .durability(astutedds::dcps::DurabilityQosPolicyKind::TRANSIENT_LOCAL_DURABILITY_QOS)
    .history(astutedds::dcps::HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS, 10)
    .build();

auto writer = publisher->create_datawriter(topic, qos);

RTPS Wire Protocol

DDS uses the RTPS (Real-Time Publish-Subscribe) protocol for network communication:

graph LR A[Application] --> B[DDS API] B --> C[RTPS Protocol] C --> D[UDP/IP Transport] D --> E[Network]

RTPS provides:

  • Discovery: Automatic participant and endpoint discovery
  • Reliability: HEARTBEAT/ACKNACK protocol for guaranteed delivery
  • Efficiency: Compact binary encoding (CDR/XCDR)
  • Interoperability: Standard wire format for cross-vendor communication

Type System (X-Types)

AstuteDDS supports DDS X-Types 1.3 for dynamic type handling:

graph TB IDL[IDL Definition] --> Compiler[IDL Compiler] Compiler --> TypeObject[TypeObject] Compiler --> CppCode[C++ Code] TypeObject --> TypeRegistry[Type Registry] CppCode --> App[Application] TypeRegistry --> DynamicData[Dynamic Data] App --> DynamicData TypeRegistry -.type discovery.-> RemoteApp[Remote Application]

Features:

  • TypeObject: Runtime type representation
  • Type Discovery: Automatic type propagation
  • Assignability: Type compatibility checking
  • Dynamic Data: Runtime data manipulation without code generation

Data Representation

DDS uses CDR (Common Data Representation) for serialization:

  • XCDR1: Traditional CDR with alignment rules
  • XCDR2: Enhanced CDR with delimiters and optional members
graph LR A[Struct Data] --> B{Encoding} B -->|XCDR1| C[Aligned Binary] B -->|XCDR2| D[Delimited Binary] C --> E[Network Transmission] D --> E E --> F{Decoding} F --> G[Struct Data]

Use Cases

DDS is used in:

  • Military & Defense: Command and control, sensor fusion
  • Aerospace: Flight control, avionics
  • Industrial IoT: Factory automation, SCADA
  • Automotive: ADAS, autonomous vehicles
  • Medical: Real-time patient monitoring
  • Financial: High-frequency trading

Next Steps