Skip to main content

SDK overview

The Roboticks SDK is the only ROS2-specific code in the product. The platform itself is ROS-version-agnostic; the SDK is what gets your tests speaking the wire contract the platform parses.
The SDK is the boundary. Inside the SDK we know about rclpy, MCAP, Gazebo. Outside (in the platform, in the matrix, in evidence packs) we only know about the wire contract. Cross that line cleanly and everything else composes.

What ships

ComponentLanguageDistributionRepository
roboticksPythonPyPIgithub.com/roboticks-io/roboticks-sdk
roboticks_cppC++17ament_cmake packageSame repo, cpp/ directory
Both are versioned together — a 0.1.x Python release and a 0.1.x C++ release agree on the schema version and the registry contract.

What’s in the Python package

from roboticks import (
    confirms, tags, deadline, requires_sim, mcap_capture,
    attach_artifact, KIND_MCAP, KIND_LOGS, KIND_ATTACHMENTS,
)
from roboticks.assertions import (
    assert_topic_published, assert_service_response,
    assert_action_result, assert_param_equals, assert_tf_transform,
)
from roboticks.fault_injection import (
    drop_messages, delay_messages, kill_node, corrupt_topic,
)
from roboticks.launch_testing import (
    make_node_action, generate_test_description, spin_node,
)
ModulePurpose
roboticks.decorators@confirms, @tags, @deadline, @requires_sim
roboticks.assertionsrclpy-aware assert-and-wait helpers
roboticks.fault_injectiondrop / delay / kill / corrupt context managers
roboticks.mcap_captureper-test MCAP recording context manager
roboticks.artifactsattach_artifact() — per-test file uploads (mcap / logs / screenshots)
roboticks.launch_testingthin wrappers around the ROS2 launch_testing module
roboticks.pytest_pluginpytest11 entry-point plugin (loaded automatically)
roboticks.reportersJUnit-with-confirms writer; CLI stitcher entrypoint

attach_artifact()

Register an arbitrary file as a per-test artifact for upload alongside JUnit. Use it when a test produces a screenshot, a generated report, a coredump, an extra log, or any other file that should land next to the MCAP in the audit trail.
from roboticks import attach_artifact, capture_mcap, KIND_MCAP

def test_obstacle_detection(node):
    with capture_mcap(node) as mcap_path:
        # ... drive the test ...
        pass
    attach_artifact(mcap_path, kind=KIND_MCAP)
    attach_artifact("/tmp/before.png", kind="attachments")
    attach_artifact("/tmp/after.png",  kind="attachments")
    attach_artifact("/tmp/decision_log.jsonl", kind="logs")
The SDK only records the path — the actual upload happens later (in the cloud-runner agent for cloud runs, in rbtk for local runs). Each attachment becomes one roboticks.attach.{kind} property on the testcase (see the wire contract), and the platform lands files at:
test-runs/{run_id}/test-cases/{sha256(nodeid)[:16]}/{kind}/{filename}
kind is any single URL-safe path segment. Reserved values for the common cases:
ConstantValueUse for
KIND_MCAP"mcap"MCAP bag files
KIND_LOGS"logs"Log dumps, JSONL traces
KIND_ATTACHMENTS (default)"attachments"Screenshots, reports, anything else
Called outside a pytest context (e.g. from a helper or fixture not bound to a test function), pass test_func= explicitly; otherwise the plugin’s thread-local resolution finds the active test. Full module map: SDK modules.

What’s in the C++ package

find_package(roboticks_cpp REQUIRED)
target_link_libraries(my_tests roboticks_cpp::roboticks_cpp)
#include <roboticks_cpp/confirms.hpp>     // ROBOTICKS_CONFIRMS, ConfirmsRegistry
#include <roboticks_cpp/assertions.hpp>   // assert_topic_published, etc.
roboticks_cpp is a header-only INTERFACE library so it adds zero compile time outside the test target. The registry has a single inline definition; thread safety is guaranteed by an internal std::mutex. Full C++ surface: C++ reference.

Why the SDK is a separate repo

The product splits into three repos for a reason:
  • Public + OSS means every audit trail is reproducible without proprietary tooling — important to regulators.
  • Independent versioning lets the SDK move at the cadence of ROS2 distros (yearly), while the platform iterates weekly.
  • Wire contract as the API means we can rewrite the SDK in v2 without rewriting the platform.

ROS-version-agnostic

The Python package installs cleanly on a host without ROS2 — rclpy imports are guarded behind try-blocks and raise a clear error only when an assertion helper is actually called. You can pip install roboticks on macOS for local linting, on a CI image without ROS2 for non-ROS test suites, and on a ROS2 Humble/Iron/Rolling box for the real thing.
# Works on macOS without rclpy installed:
from roboticks import confirms

@confirms("REQ-100")
def test_pure_python_logic():
    assert 2 + 2 == 4

# Raises informative RuntimeError at call time, not import time:
from roboticks.assertions import assert_topic_published
ROS2 distroPythonStatus
Humble3.10, 3.11supported
Iron3.10, 3.11supported
Rolling3.10, 3.11, 3.12supported
(none)3.10–3.13decorators + plugin only

Releases and stability

  • 0.x = pre-1.0, expect minor breaking changes between minors.
  • 1.0 locks the wire contract and the decorator signatures.
  • Schema versions are independent of SDK versions; see Wire contract.

Install

pip install roboticks + ament_cmake setup.

Decorators

@confirms, @tags, @deadline, @requires_sim.

Assertions

rclpy-aware wait-and-assert helpers.

Wire contract

Authoritative schema reference.