Skip to main content

Quick Start

Get up and running with Cerulion Core in just a few minutes. This guide will walk you through installation and your first publisher/subscriber example.

Prerequisites

Rust Toolchain

Rust 1.70+ and Cargo installed. Install via rustup if needed.

System Dependencies

For local transport: iceoryx2 dependencies. For network: Zenoh runtime.

Installation

1

Rust: Add Cerulion Core to your project

Add cerulion-core to your Cargo.toml:
[dependencies]
cerulion-core = "0.1.0"
Then run cargo build to compile Cerulion Core and its dependencies.
You should see successful compilation. The first build may take a few minutes to compile dependencies.
2

Python: Install dependencies

Install Zenoh Python bindings and required packages:
pip install zenoh-python
Python support is currently in development. For now, you can use Zenoh directly for network communication. Local zero-copy transport will be available in a future release.
3

C++: Install dependencies

Install Zenoh C++ bindings:
# Using vcpkg (recommended)
vcpkg install zenoh-cpp

# Or build from source
# See: https://github.com/eclipse-zenoh/zenoh-cpp
C++ support is currently in development. For now, you can use Zenoh directly for network communication. Local zero-copy transport will be available in a future release.

Your First Example

Let’s create a simple publisher and subscriber that communicate locally:
use cerulion_core::prelude::*;

// Define a simple message type
#[derive(Copy, Clone, Debug)]
#[repr(C)]
struct SensorData {
    temperature: f32,
    timestamp: u64,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a publisher
    let publisher = Publisher::<SensorData>::create("sensors/temperature")?;
    
    // Create a subscriber (auto-detects local transport)
    let subscriber = Subscriber::<SensorData>::create("sensors/temperature", None)?;
    
    // Send a message
    let data = SensorData {
        temperature: 23.5,
        timestamp: 1234567890,
    };
    publisher.send(data)?;
    
    // Receive the message
    if let Ok(Some(received)) = subscriber.receive() {
        println!("Received: temp={}°C, time={}", 
                 received.temperature, received.timestamp);
    }
    
    Ok(())
}
If you run this code, you should see: Received: temp=23.5°C, time=1234567890

Understanding the Example

Let’s break down what’s happening:
  1. Message Type: SensorData is a simple struct with Copy trait. This makes it compatible with Cerulion Core’s automatic serialization.
  2. Publisher: Publisher::create() creates a publisher for the topic "sensors/temperature". It automatically enables both local (iceoryx2) and network (Zenoh) transport.
  3. Subscriber: Subscriber::create() with None auto-detects transport. Since a local publisher exists, it uses the fast local path.
  4. Send/Receive: publisher.send() writes directly to shared memory (zero-copy). subscriber.receive() reads from the same memory location.
The #[repr(C)] attribute ensures the struct has a C-compatible memory layout, which is required for zero-copy serialization. This also enables future cross-language compatibility.

Network Communication

To force network transport (useful for cross-process or remote communication):
// Force network-only subscriber
let subscriber = Subscriber::<SensorData>::create(
    "sensors/temperature", 
    Some(true)  // Force network transport
)?;
Network transport has higher latency (1-10ms) compared to local transport (< 1μs). Use local transport when possible for best performance.

Verification

1

Check compilation

Ensure your code compiles without errors:
cargo build
2

Run the example

Execute your program:
cargo run
You should see the received message printed to the console.
3

Verify zero-copy

The message was sent and received without serialization. You can verify this by checking that the data matches exactly (no precision loss, no conversion overhead).

Next Steps

Now that you have a working example, explore more features:
For more complex examples, check out the examples/ directory in the Cerulion Core repository. You’ll find examples for joint states, multi-language communication, and MCAP logging.