Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.roboticks.io/llms.txt

Use this file to discover all available pages before exploring further.

ROS2 Examples

These examples demonstrate how to integrate ROS2 applications with Roboticks. All code is available in the roboticks-examples repository.

Hello World Example

A simple ROS2 node that publishes messages, managed by Roboticks. This is the perfect starting point for understanding the integration.

What It Does

  • Publishes “Hello from Roboticks!” messages at a configurable rate
  • Accepts input to dynamically update the message
  • Records all messages to a rosbag for later analysis
  • Demonstrates automatic restart on crash

Project Structure

Ros2HelloWorldModule/
├── ros2_ws/                    # Standard ROS2 workspace
│   └── src/
│       └── roboticks_hello_world/
│           ├── src/
│           │   └── hello_world_node.cpp
│           ├── launch/
│           │   └── hello_world.launch.py
│           ├── package.xml
│           └── CMakeLists.txt
├── src/                        # Roboticks module wrapper
│   ├── Ros2HelloWorldModule.cpp
│   └── Ros2HelloWorldModule.hpp
├── config/
│   └── Ros2HelloWorldModule.yaml
└── CMakeLists.txt

The ROS2 Node

A standard ROS2 node - nothing Roboticks-specific:
// hello_world_node.cpp
#include <rclcpp/rclcpp.hpp>
#include <std_msgs/msg/string.hpp>

class HelloWorldNode : public rclcpp::Node {
public:
    HelloWorldNode() : Node("roboticks_hello_world") {
        // Declare parameters
        this->declare_parameter<std::string>("message", "Hello from Roboticks!");
        this->declare_parameter<double>("rate_hz", 1.0);

        // Get parameters
        message_ = this->get_parameter("message").as_string();
        double rate_hz = this->get_parameter("rate_hz").as_double();

        // Create publisher
        publisher_ = this->create_publisher<std_msgs::msg::String>(
            "/roboticks/hello_world/output", 10);

        // Create timer
        timer_ = this->create_wall_timer(
            std::chrono::duration<double>(1.0 / rate_hz),
            [this]() { this->publish(); });
    }

private:
    void publish() {
        auto msg = std_msgs::msg::String();
        msg.data = message_;
        publisher_->publish(msg);
        RCLCPP_INFO(this->get_logger(), "Publishing: %s", msg.data.c_str());
    }

    std::string message_;
    rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
    rclcpp::TimerBase::SharedPtr timer_;
};

int main(int argc, char* argv[]) {
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<HelloWorldNode>());
    rclcpp::shutdown();
    return 0;
}

Module Configuration

The Roboticks module configuration tells the system how to manage your node:
# Ros2HelloWorldModule.yaml
name: Ros2HelloWorldModule
version: 1.0.0
description: "ROS2 HelloWorld node managed by Roboticks"

update_rate_hz: 10

custom:
  ros2:
    # Package and executable to launch
    package: "roboticks_hello_world"
    executable: "hello_world_node"

    # Node parameters
    message: "Hello from Roboticks!"
    rate_hz: 1.0

    # Topics
    output_topic: "/roboticks/hello_world/output"
    input_topic: "/roboticks/hello_world/input"

    # Process management
    auto_restart: true
    restart_delay_ms: 1000

  # Automatic rosbag recording
  rosbag:
    enabled: true
    output_dir: "/var/roboticks/ros2/bags/hello_world"
    topics: "/roboticks/hello_world/output, /roboticks/hello_world/status"

ROS2 Interface

TopicTypeDescription
/roboticks/hello_world/outputstd_msgs/StringPublished messages
/roboticks/hello_world/inputstd_msgs/StringUpdate the message dynamically
/roboticks/hello_world/statusstd_msgs/StringNode status (JSON)
ServiceTypeDescription
/roboticks/hello_world/enablestd_srvs/SetBoolEnable/disable publishing

Running the Example

Build the ROS2 package:
# Source ROS2
source /opt/ros/humble/setup.bash

# Build
cd examples/Ros2HelloWorldModule
./build_ros2_package.sh

# Source the workspace
source ros2_ws/install/setup.bash
Test standalone:
# Run directly
ros2 run roboticks_hello_world hello_world_node

# With parameters
ros2 run roboticks_hello_world hello_world_node --ros-args \
    -p message:="Custom message" \
    -p rate_hz:=2.0
Run with Roboticks:
# Start a session with the composition
roboticks session start --composition Ros2HelloWorldComposition --mode prod

Interacting with the Running Node

While the session is running, you can interact with the node via ROS2:
# Monitor output
ros2 topic echo /roboticks/hello_world/output

# Update message dynamically
ros2 topic pub --once /roboticks/hello_world/input \
    std_msgs/String "data: 'New message!'"

# Enable/disable publishing
ros2 service call /roboticks/hello_world/enable \
    std_srvs/srv/SetBool "{data: false}"

Composition Example

The composition bundles multiple modules together:
# Ros2HelloWorldComposition.yaml
name: Ros2HelloWorldComposition
version: 1.0.0
description: "ROS2 HelloWorld with Roboticks bridge"

modes:
  - name: prod
    description: "Production mode - bridge + HelloWorld"
    processes:
      - Ros2BridgeModule
      - Ros2HelloWorldModule

  - name: bridge_only
    description: "ROS2 bridge only"
    processes:
      - Ros2BridgeModule

processes:
  - name: Ros2BridgeModule
    type: module
    binary: "Ros2BridgeModule/Ros2BridgeModule"
    config: "Ros2BridgeModule/config/Ros2BridgeModule.yaml"
    restart_policy: on_failure
    initialization_order: 1
    description: "ROS2 to Roboticks bridge"

  - name: Ros2HelloWorldModule
    type: module
    binary: "Ros2HelloWorldModule/Ros2HelloWorldModule"
    config: "Ros2HelloWorldModule/config/Ros2HelloWorldModule.yaml"
    restart_policy: on_failure
    initialization_order: 2
    description: "ROS2 HelloWorld node"

What Gets Recorded

During a session, Roboticks automatically captures:
DataLocationAccess
Module logsCloudDashboard → Sessions → Logs
ROS2 node logsCloudDashboard → Sessions → Logs
Rosbag filesCloudDashboard → Sessions → Artifacts
Node statusCloudReal-time in dashboard

Best Practices

Use a consistent namespace for all your topics:
/my_robot/sensors/lidar
/my_robot/sensors/camera
/my_robot/control/cmd_vel
This makes rosbag recording and debugging easier.
Make your nodes configurable via ROS2 parameters:
this->declare_parameter<double>("rate_hz", 1.0);
double rate = this->get_parameter("rate_hz").as_double();
Roboticks can then set these parameters at launch time.
Add a status topic that publishes node health:
status_pub_ = this->create_publisher<std_msgs::msg::String>(
    "/my_robot/status", 10);
This helps with monitoring in the dashboard.
Your node should clean up properly on SIGTERM:
rclcpp::on_shutdown([this]() {
    RCLCPP_INFO(this->get_logger(), "Shutting down gracefully");
    // Cleanup code here
});

More Examples

Check the roboticks-examples repository for more examples:
  • Ros2BridgeModule - Bidirectional bridge between ROS2 and Roboticks
  • HelloWorldModule - Non-ROS2 example showing basic module concepts
  • Custom compositions - Examples of multi-module setups

Next Steps

SDK Reference

Learn about building custom modules

CLI Commands

Deploy and manage sessions via CLI