Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

DDS Transport Layer

MiniROS uses a simplified Data Distribution Service (DDS) implementation to maintain compatibility with ROS2’s communication patterns while keeping the implementation minimal and focused on core functionality.

Overview

DDS is the middleware standard that ROS2 uses for communication. Our implementation provides:

  • Domain-based isolation: Different robots can operate in separate domains
  • Quality of Service (QoS): Reliability and durability policies
  • Multicast discovery: Automatic node and topic discovery
  • Type-safe messaging: Compile-time message type checking

Architecture

┌─────────────────────────────────────┐
│         Application Layer           │
├─────────────────────────────────────┤
│    DDS Publishers & Subscribers     │
├─────────────────────────────────────┤
│       Domain Participant            │
├─────────────────────────────────────┤
│     Multicast UDP Transport         │
├─────────────────────────────────────┤
│        Network Interface            │
└─────────────────────────────────────┘

Usage

Basic Setup

#![allow(unused)]
fn main() {
use mini_ros::dds_transport::{DdsTransport, QosPolicy};
use mini_ros::message::StringMsg;

// Create DDS transport with domain ID
let transport = DdsTransport::new(0).await?;

// Create publisher
let publisher = transport.create_publisher::<StringMsg>("chatter").await?;

// Create subscriber
let subscriber = transport.create_subscriber::<StringMsg>("chatter").await?;
}

Quality of Service (QoS)

#![allow(unused)]
fn main() {
use mini_ros::dds_transport::{QosPolicy, ReliabilityKind, DurabilityKind, HistoryKind};

let qos = QosPolicy {
    reliability: ReliabilityKind::Reliable,
    durability: DurabilityKind::TransientLocal,
    history: HistoryKind::KeepLast,
    depth: 10,
};

let publisher = transport.create_publisher_with_qos::<StringMsg>("topic", qos).await?;
}

Publishing Messages

#![allow(unused)]
fn main() {
let message = StringMsg {
    data: "Hello, DDS World!".to_string(),
};

publisher.publish(&message).await?;
}

Subscribing to Messages

#![allow(unused)]
fn main() {
// Callback-based subscription
subscriber.on_message(|msg: StringMsg| {
    println!("Received: {}", msg.data);
})?;

// Polling-based subscription
if let Some(message) = subscriber.try_recv::<StringMsg>() {
    println!("Received: {}", message.data);
}
}

Domain Management

Domain Isolation

Different domains operate independently:

#![allow(unused)]
fn main() {
// Robot 1 in domain 0
let transport1 = DdsTransport::new(0).await?;

// Robot 2 in domain 1 (isolated from domain 0)
let transport2 = DdsTransport::new(1).await?;
}

Port Assignment

Domains use different multicast ports:

  • Domain 0: Port 7400
  • Domain 1: Port 7401
  • Domain N: Port 7400 + N

QoS Policies

Reliability

  • BestEffort: Fast, may lose messages
  • Reliable: Guaranteed delivery (default)

Durability

  • Volatile: Messages not stored (default)
  • TransientLocal: Store messages for late-joining subscribers

History

  • KeepLast: Keep only latest N messages (default)
  • KeepAll: Keep all messages

Message Format

DDS messages include metadata:

#![allow(unused)]
fn main() {
struct DdsMessage {
    topic: String,           // Topic name
    sequence_number: u64,    // Message sequence
    timestamp: u64,          // Nanosecond timestamp
    data: Vec<u8>,          // Serialized payload
}
}

Network Configuration

Multicast Address

  • Default: 239.255.0.1
  • Configurable per domain
  • IPv4 multicast for local network discovery

Firewall Considerations

Ensure multicast traffic is allowed:

# Linux: Allow multicast
sudo iptables -A INPUT -m pkttype --pkt-type multicast -j ACCEPT

# macOS: Multicast generally works by default
# Windows: May require firewall configuration

Performance Characteristics

Benchmarks

MetricValue
Latency< 1ms (local network)
Throughput> 100MB/s
Max Message Size64KB
Discovery Time< 100ms

Optimization Tips

  1. Use appropriate QoS: BestEffort for high-frequency data
  2. Batch small messages: Combine when possible
  3. Tune history depth: Balance memory vs. reliability
  4. Monitor network usage: Avoid multicast flooding

Comparison with Full DDS

FeatureMiniROS DDSFull DDS (e.g., CycloneDX)
Standards ComplianceSimplifiedFull RTPS/DDS
Memory UsageLowHigher
Feature SetCore featuresComplete
InteroperabilityLimitedFull ROS2
Learning CurveSimpleComplex

Migration from TCP/UDP

If migrating from the legacy TCP/UDP transport:

#![allow(unused)]
fn main() {
// Old TCP/UDP transport
use mini_ros::transport::UdpTransport;

// New DDS transport
use mini_ros::dds_transport::DdsTransport;

// API is similar, but with QoS support
let transport = DdsTransport::new(domain_id).await?;
}

Troubleshooting

Common Issues

  1. Port conflicts: Use different domain IDs
  2. Multicast not working: Check network configuration
  3. Messages not received: Verify topic names and types
  4. High latency: Check network congestion

Debug Tools

#![allow(unused)]
fn main() {
// Enable detailed logging
tracing_subscriber::fmt::init();

// Check domain participant
println!("Domain ID: {}", transport.domain_id());

// Monitor message sequence numbers
publisher.publish(&message).await?;
}

Future Enhancements

  • Full RTPS protocol support
  • Dynamic discovery improvements
  • Security policies
  • Performance monitoring
  • ROS2 bridge compatibility