Skip to main content

Examples

Learn from complete working examples included in the SDK.

HelloWorld Module

The simplest module - publishes a message at regular intervals.

Source Code

config/HelloWorld.yaml:
name: HelloWorldModule
version: 1.0.0
description: "Simple hello world module"

module:
  tasks:
    - name: HelloWorldTask
      description: "Publishes hello messages"
      update_rate_hz: 1

      outputs:
        - name: message
          topic: "/hello/message"
          message_type: "roboticks.messages.common.StringMessage"
          qos: "RELIABLE"

      custom:
        greeting: "Hello World!"

  logging:
    level: "INFO"
src/HelloWorldTask.cpp:
#include "HelloWorldTask.hpp"
#include <roboticks/module/TaskFactory.hpp>

static roboticks::module::TaskRegistrar<HelloWorldTask> registrar("HelloWorldTask");

HelloWorldTask::HelloWorldTask(const std::string& config)
    : HelloWorldTaskIO(config)
{
    greeting_ = getConfig("custom.greeting", "Hello!");
    ROBOTICKS_INFO(*getLogger(), "HelloWorldTask created");
}

bool HelloWorldTask::onInitialize() {
    ROBOTICKS_INFO(*getLogger(), "Initializing...");
    return true;
}

bool HelloWorldTask::onStart() {
    ROBOTICKS_INFO(*getLogger(), "Starting...");
    return true;
}

void HelloWorldTask::onUpdate() {
    count_++;

    roboticks::messages::common::StringMessage msg(greeting_, count_);
    message_output_->publish(msg);

    ROBOTICKS_INFO(*getLogger(), "Published: {} (count: {})", greeting_, count_);
}

void HelloWorldTask::onStop() {
    ROBOTICKS_INFO(*getLogger(), "Stopped after {} messages", count_);
}

Running

cd modules/HelloWorldModule
mkdir build && cd build
cmake .. && make
./HelloWorldModule
Output:
[INFO] HelloWorldTask created
[INFO] Initializing...
[INFO] Starting...
[INFO] Published: Hello World! (count: 1)
[INFO] Published: Hello World! (count: 2)
...

ROS2 Bridge Module

Bridges Roboticks messaging with ROS2 topics.

Overview

This module subscribes to ROS2 topics and republishes them to Roboticks topics, enabling integration with ROS2 systems.

Configuration

name: Ros2BridgeModule
version: 1.0.0

module:
  tasks:
    - name: Ros2BridgeTask
      update_rate_hz: 100

      # ROS2 input topics
      inputs:
        - name: ros_cmd_vel
          topic: "/ros2/cmd_vel"
          message_type: "geometry_msgs.msg.Twist"

      # Roboticks output topics
      outputs:
        - name: roboticks_velocity
          topic: "/robot/velocity"
          message_type: "roboticks.messages.control.Velocity"
          qos: "RELIABLE"

      custom:
        ros_domain_id: 0

Use Cases

  • Simulation: Run ROS2 simulation (Gazebo, Isaac Sim) with Roboticks modules
  • Hardware abstraction: Bridge ROS2 drivers to Roboticks
  • Gradual migration: Integrate Roboticks into existing ROS2 systems

Sensor Processor Module

Processes sensor data and publishes results.

Configuration

name: SensorProcessorModule
version: 1.0.0

module:
  tasks:
    - name: SensorProcessorTask
      update_rate_hz: 30

      inputs:
        - name: lidar
          topic: "/sensors/lidar/points"
          message_type: "roboticks.messages.sensors.PointCloud"
          qos: "BEST_EFFORT"

        - name: imu
          topic: "/sensors/imu/data"
          message_type: "roboticks.messages.sensors.Imu"
          qos: "BEST_EFFORT"

      outputs:
        - name: obstacles
          topic: "/perception/obstacles"
          message_type: "roboticks.messages.perception.ObstacleList"
          qos: "RELIABLE"

      custom:
        min_obstacle_size: 0.1
        max_range: 50.0

Implementation Pattern

void SensorProcessorTask::onUpdate() {
    // Fuse sensor data
    if (lidar_input_->hasData() && imu_input_->hasData()) {
        const auto& lidar_data = lidar_input_->getData();
        const auto& imu_data = imu_input_->getData();

        // Transform point cloud using IMU orientation
        auto transformed = transformPointCloud(lidar_data, imu_data);

        // Detect obstacles
        auto obstacles = detectObstacles(transformed);

        // Publish results
        obstacles_output_->publish(obstacles);
    }
}

Docker Composition

Run multiple modules together using Docker Compose.

docker-compose.yaml

version: '3.8'

services:
  hello-world:
    build:
      context: .
      dockerfile: docker/roboticks/Dockerfile
      args:
        COMPOSITION: HelloWorldComposition
    volumes:
      - roboticks-logs:/var/roboticks/logs
    networks:
      - roboticks

  sensor-processor:
    build:
      context: .
      dockerfile: docker/roboticks/Dockerfile
      args:
        COMPOSITION: SensorProcessorComposition
    depends_on:
      - hello-world
    networks:
      - roboticks

networks:
  roboticks:
    driver: bridge

volumes:
  roboticks-logs:

Running

# Build and start
docker compose up -d --build

# View logs
docker compose logs -f

# Stop
docker compose down

CI/CD Testing Example

Test your modules using the Roboticks CLI:

test_my_module.py

from ci.cli_wrapper import CLI
from ci.helpers import wait_for, assert_session_success

def test_my_module():
    cli = CLI()

    # Upload module as capsule
    result = cli.capsule_push(
        "./build/MyModule.tar.gz",
        name="my-module",
        version="1.0.0"
    )
    capsule_id = result["id"]

    # Create test job on cloud runner
    job = cli.simulate_run(
        fleet_id=1,
        test_package_id=test_pkg_id
    )

    # Wait for completion
    wait_for(
        lambda: cli.simulate_get(job["id"])["status"] == "completed",
        timeout=300
    )

    # Verify results
    result = cli.simulate_get(job["id"])
    assert_session_success(result)

Running Tests

# Install test dependencies
pip install -r ci/requirements.txt

# Run tests
python ci/run_tests.py pr

More Examples

Find more examples in the roboticks-examples repository:
git clone https://github.com/roboticks-io/roboticks-examples.git
ExampleDescription
HelloWorldModuleBasic module structure
Ros2HelloWorldModuleROS2 integration
SensorFusionModuleMulti-sensor processing
ControllerModuleMotion control example

Next Steps