Shapes Demo Guide

The AstuteDDS Shapes Demo is a Qt6-based graphical application for testing DDS interoperability. It's the standard tool used by DDS vendors to demonstrate cross-vendor compatibility.

What is the Shapes Demo?

The Shapes Demo publishes and subscribes to geometric shapes (circles, squares, triangles) with different colors on a shared canvas. Each shape's position is updated in real-time over DDS, allowing multiple applications from different vendors to see the same shapes moving.

Building the Shapes Demo

Requirements

  • Qt6 (6.2 or later)
  • CMake 3.20 or later
  • C++20 compatible compiler
  • AstuteDDS library

Installing Qt6 on Ubuntu 22.04/24.04

sudo apt-get update
sudo apt-get install -y qt6-base-dev qt6-base-dev-tools libqt6widgets6

Build Steps

# Clone the repository
git clone https://github.com/Astute-Systems/astutedds-cxx.git
cd astutedds-cxx

# Create build directory
mkdir build && cd build

# Configure with examples enabled
cmake .. -DASTUTEDDS_BUILD_EXAMPLES=ON

# Build the shapes demo
cmake --build . --target shapes_demo

# Run the application
./examples/shapes_demo/shapes_demo

Running the Shapes Demo

Starting the Application

./build/examples/shapes_demo/shapes_demo

The application window displays:

  • Canvas: 240x270 coordinate space showing shapes
  • Shape Controls: Select shape type (Circle, Square, Triangle)
  • Color Selector: Choose from standard colors (RED, GREEN, BLUE, etc.)
  • Publish Button: Start publishing a shape
  • Subscribe Button: Subscribe to shapes from other applications
  • QoS Settings: Configure Quality of Service policies

Publishing Shapes

To publish a shape:

  1. Select Shape Type: Choose Circle, Square, or Triangle
  2. Choose Color: Select a color (e.g., BLUE)
  3. Set Size: Adjust shape size (10-100 pixels)
  4. Enable Auto-move: Check to animate the shape
  5. Click Publish: Shape appears and starts moving

Publish Options Window

Shapes Demo Publish Options

The publish options window allows you to configure:

  • Shape type: Circle, Square, or Triangle
  • Color: Select from standard DDS colors
  • Size: Shape size in pixels (10-100)
  • Auto-move: Enable automatic shape animation
  • QoS Settings: Reliability, Durability, History depth, Ownership

Publishing Live Window

Shapes Demo Publishing Live

Once published, you'll see:

  • Your shape moving on the canvas
  • Real-time position updates
  • Active publishers listed in the status area

Publishing Example Workflow

sequenceDiagram
    participant User
    participant ShapesDemo
    participant DDS

    User->>ShapesDemo: Select "Circle", "BLUE"
    User->>ShapesDemo: Click "Publish"
    ShapesDemo->>DDS: Create DataWriter<Circle>
    ShapesDemo->>DDS: write(x, y, color, size)

    loop Every 33ms
        ShapesDemo->>ShapesDemo: Update position
        ShapesDemo->>DDS: write(new x, new y, ...)
    end

Standard Colors

The Shapes Demo uses standard DDS colors:

  • RED
  • GREEN
  • BLUE
  • YELLOW
  • CYAN
  • MAGENTA
  • ORANGE
  • PURPLE

Subscribing to Shapes

To subscribe to shapes:

  1. Select Color: Choose which color to subscribe to (e.g., BLUE)
  2. Click Subscribe: Create a DataReader for that color
  3. View Shapes: Shapes published by any DDS application appear on the canvas

Subscribe Options Window

Shapes Demo Subscribe Options

The subscribe options window allows you to configure:

  • Color: Select which color to subscribe to
  • QoS Settings: Match publisher's QoS for successful communication
  • History: Control how many historical samples to receive

Subscription Example Workflow

sequenceDiagram
    participant User
    participant ShapesDemo
    participant DDS
    participant RemoteApp

    User->>ShapesDemo: Select "BLUE"
    User->>ShapesDemo: Click "Subscribe"
    ShapesDemo->>DDS: Create DataReader<Circle>

    RemoteApp->>DDS: write(Circle, BLUE, x, y)
    DDS->>ShapesDemo: DATA submessage
    ShapesDemo->>ShapesDemo: Draw shape at (x, y)

    loop Continuous updates
        RemoteApp->>DDS: write(new position)
        DDS->>ShapesDemo: DATA submessage
        ShapesDemo->>ShapesDemo: Update shape position
    end

Standard Topics

The Shapes Demo uses three standard DDS topics:

Topic Name Data Type Description
Circle ShapeType Circular shapes
Square ShapeType Square shapes
Triangle ShapeType Triangular shapes

ShapeType IDL Definition

All topics use the same data type:

module ShapesDemo {
    @mutable
    struct ShapeType {
        @key string<128> color;
        long x;
        long y;
        long shapesize;
    };
};

Generated C++ structure:

namespace ShapesDemo {
    struct ShapeType {
        std::string color;  // Key field
        int32_t x;
        int32_t y;
        int32_t shapesize;
    };
}

Coordinate System

The Shapes Demo uses a standard coordinate system:

  • X axis: 0 to 240 (left to right)
  • Y axis: 0 to 270 (top to bottom)
  • Origin: Top-left corner
  • Bounds: Shapes bounce off edges
(0,0) ----------------------- (240,0)
  |                              |
  |        Canvas Area           |
  |                              |
  |                              |
(0,270) --------------------- (240,270)

Testing Interoperability

The AstuteDDS Shapes Demo is compatible with shapes demos from other DDS vendors:

Interoperability Test Steps

  1. Start AstuteDDS Shapes Demo:
./build/examples/shapes_demo/shapes_demo
  1. Start another vendor's Shapes Demo (e.g., eProsima Fast DDS):
./ShapesDemo  # from Fast DDS installation
  1. Publish from AstuteDDS:
  2. Select "Circle" and "BLUE"
  3. Click "Publish"
  4. Enable "Auto-move"

  5. Subscribe from other vendor:

  6. Select "BLUE"
  7. Click "Subscribe"
  8. The blue circle should appear and move

  9. Verify bidirectional communication:

  10. Publish from the other vendor's demo
  11. Subscribe in AstuteDDS
  12. Shapes should appear in both applications

Expected Behavior

sequenceDiagram
    participant AstuteDDS
    participant Network
    participant FastDDS

    Note over AstuteDDS,FastDDS: Discovery Phase
    AstuteDDS->>Network: SPDP announcement
    FastDDS->>Network: SPDP announcement
    Network->>AstuteDDS: FastDDS participant discovered
    Network->>FastDDS: AstuteDDS participant discovered

    Note over AstuteDDS,FastDDS: Data Exchange
    AstuteDDS->>Network: DATA(Circle, BLUE, x, y)
    Network->>FastDDS: Receive DATA
    FastDDS->>FastDDS: Draw circle

    FastDDS->>Network: DATA(Square, RED, x, y)
    Network->>AstuteDDS: Receive DATA
    AstuteDDS->>AstuteDDS: Draw square

Quality of Service (QoS) Configuration

The Shapes Demo supports various QoS configurations:

Default QoS Settings

// Default configuration used by Shapes Demo
auto qos = astutedds::dcps::DataWriterQosBuilder()
    .reliability(astutedds::dcps::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS)
    .durability(astutedds::dcps::DurabilityQosPolicyKind::VOLATILE_DURABILITY_QOS)
    .history(astutedds::dcps::HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS, 10)
    .build();

Reliability Options

RELIABLE (default):

  • Guarantees delivery of all samples
  • Uses HEARTBEAT/ACKNACK protocol
  • Good for shape position updates

BEST_EFFORT:

  • No delivery guarantees
  • Lower latency
  • Suitable for high-frequency sensor data

Durability Options

VOLATILE (default):

  • No historical data
  • Late joiners only see new updates

TRANSIENT_LOCAL:

  • Late joiners receive last sample per instance
  • Useful for state synchronization

History Settings

KEEP_LAST(10) (default):

  • Maintains last 10 samples per shape
  • Prevents unbounded memory growth

KEEP_ALL:

  • Keeps all samples (up to resource limits)
  • Higher memory usage

Common Use Cases

Use Case 1: Basic Connectivity Test

Goal: Verify DDS connectivity between two applications.

  1. Start AstuteDDS Shapes Demo
  2. Publish a BLUE Circle
  3. Subscribe to BLUE in the same application
  4. You should see the circle (loopback test)

Use Case 2: Cross-Vendor Interoperability

Goal: Test interoperability with another DDS implementation.

  1. Start AstuteDDS Shapes Demo
  2. Start Fast DDS Shapes Demo
  3. Publish RED Square in AstuteDDS
  4. Subscribe to RED in Fast DDS
  5. Verify shape appears in both applications

Use Case 3: QoS Compatibility Testing

Goal: Test QoS policy matching.

  1. Configure RELIABLE in AstuteDDS
  2. Configure BEST_EFFORT in Fast DDS
  3. Attempt to communicate
  4. Observe that endpoints don't match (incompatible QoS)

Use Case 4: Multiple Instances

Goal: Test multiple instances with different keys.

  1. Publish BLUE Circle
  2. Publish GREEN Circle
  3. Publish RED Circle
  4. All circles should appear simultaneously
  5. Each is a separate instance (different key = color)

Troubleshooting

Shapes Not Appearing

Problem: Published shapes don't appear in subscribing application.

Solutions:

  1. Check network connectivity (ping test)
  2. Verify same DDS domain ID (default: 0)
  3. Check firewall settings (allow UDP multicast)
  4. Ensure QoS policies are compatible
  5. Verify topic names match exactly

Discovery Issues

Problem: Applications don't discover each other.

Solutions:

  1. Check multicast support on network
  2. Verify UDP ports are open (7400, 7401, etc.)
  3. Check participant announcements in logs
  4. Try running on localhost first

Performance Problems

Problem: Shapes are choppy or slow.

Solutions:

  1. Reduce publish rate
  2. Use BEST_EFFORT reliability for smoother motion
  3. Increase history depth
  4. Check CPU and network utilization

Advanced Topics

Custom Shape Behaviors

Modify the shapes demo source to:

  • Add custom shape types
  • Implement collision detection
  • Create pattern generators
  • Add physics simulation

Programmatic Control

Create automated test scripts:

// Example: Automated shapes test
#include "ShapeType_TypeSupport.hpp"

int main() {
    auto participant = create_participant(0);
    auto topic = participant->create_topic<ShapesDemo::ShapeType>("Circle");
    auto writer = create_datawriter(participant, topic);

    ShapesDemo::ShapeType shape;
    shape.color = "BLUE";
    shape.shapesize = 30;

    // Publish shapes in a pattern
    for (int i = 0; i < 100; ++i) {
        shape.x = 120 + 100 * std::cos(i * 0.1);
        shape.y = 135 + 100 * std::sin(i * 0.1);
        writer->write(shape);
        std::this_thread::sleep_for(std::chrono::milliseconds(33));
    }

    return 0;
}

Next Steps

Resources