Skip to main content

Quickstart

Get TraceHouse™ tracing your robot in minutes — the SDK way.

TraceHouse tracing has two halves:

  • The agent (the "carrier") — robot-agent, the on-robot binary that receives spans from the SDK over a local socket and forwards them to TraceHouse. It also keeps collecting logs, metrics, TF, and MCAP on its own.
  • The RobotOps Trace SDK — small libraries you add to your robot as normal dependencies (no forks, no framework rebuilds). They produce deterministic, in-process traces and hand them to the agent.

:::info Prerequisites

  • Ubuntu 24.04 Noble (ROS 2 Jazzy) — or Ubuntu 22.04 Jammy (ROS 2 Humble, arm64 / Jetson). See system requirements
  • ROS 2 installed and sourced
  • sudo access on the robot's onboard computer (not needed inside most containers, which run as root)
  • A TraceHouse account and API key — sign up at robotops.com :::

1. Install​

Run the installer on your robot:

curl -fsSL https://tracehouse.robotops.com/install.sh | bash

The script adds the apt.robotops.com repository and installs, for your detected ROS distro:

  • robot-agent — the carrier (binary at /usr/bin/robot-agent)
  • The Trace SDK — ros-<distro>-robotops-trace-cpp (the C++ core) plus the rclcpp and BehaviorTree.CPP integrations and the shared semantic conventions
  • Env-default auto-init — a sourceable env file at /etc/robotops/trace.env that you apply to your ROS launch environment to turn tracing on (step 3). It is not a global preload.

Pass ROBOTOPS_SKIP_SDK=1 to install the agent only, or ROBOTOPS_SKIP_AUTOINIT=1 to install the SDK without writing the auto-init env file.

:::caution The legacy passive path is deprecated Earlier versions installed rmw_robotops (the passive content-hash RMW shim) and told you to set RMW_IMPLEMENTATION=rmw_robotops. That path is deprecated and is no longer installed — tracing now comes from the SDK below. See Related Libraries. :::

What's in this script?

The installer performs these steps — no surprises:

# Add the RobotOps GPG key
curl -fsSL https://apt.robotops.com/robotops-public-key.asc \
| sudo gpg --dearmor -o /usr/share/keyrings/robotops-archive-keyring.gpg

# Add the apt repository (suite = your Ubuntu codename, e.g. noble)
echo "deb [signed-by=/usr/share/keyrings/robotops-archive-keyring.gpg] https://apt.robotops.com noble main" \
| sudo tee /etc/apt/sources.list.d/robotops.list

sudo apt update

# The carrier (Jazzy — amd64 + arm64; Jetson/Humble arm64: robot-agent-humble)
sudo apt install -y robot-agent-jazzy

# The Trace SDK + integrations (per distro)
sudo apt install -y ros-jazzy-robotops-trace-cpp \
ros-jazzy-robotops-trace-rclcpp \
ros-jazzy-robotops-trace-bt-cpp \
ros-jazzy-robotops-trace-semconv

You can also run these steps manually if you prefer not to pipe scripts.

Pick the integrations you use​

The SDK core is framework-agnostic; the integrations are à-la-carte apt packages. Install only the ones matching your stack:

PackageCovers
ros-<distro>-robotops-trace-cppSDK core (required) — RAII span guard, ROBOTOPS_TRACE(), OTLP exporter
ros-<distro>-robotops-trace-rclcpprclcpp executor callbacks + rclcpp_action goal-UUID stitching
ros-<distro>-robotops-trace-bt-cppBehaviorTree.CPP tick callbacks (covers Nav2 + MoveIt Pro)
ros-<distro>-robotops-trace-semconvShared robotics semantic conventions

ros2_control and MoveIt integrations are available as additional packages; see Instrumentation.

Python (rclpy)​

The Python SDK ships to PyPI:

pip install robotops-trace robotops-trace-rclpy

:::note PyPI lane: coming soon robotops-trace / robotops-trace-rclpy on PyPI are not published yet (the PyPI org is being set up). The apt (dev channel) lane for the C++ SDK above is live today. If you run rclpy nodes, instrument your C++ / rclcpp nodes now and track the PyPI lane on this page. ROS-coupled fleets can also get robotops_trace_rclpy as an ament_python deb via apt once published. :::

2. Configure the agent (carrier)​

The agent is configured entirely through environment variables — point it at TraceHouse:

VariableRequired?Value
ROBOTOPS_API_KEYYesYour key (sk_…) from the dashboard
ROBOT_OPS_AGENT_BACKEND_URLRecommendedhttps://backend.robotops.com (the production endpoint)

:::note Why set ROBOT_OPS_AGENT_BACKEND_URL explicitly? The agent's built-in default still points at the legacy api.robotops.com host. Setting the backend URL pins you to the canonical production endpoint, backend.robotops.com. It's a normal override — point it anywhere for self-hosted or local development (e.g. http://localhost:50051). :::

3. Turn it on — env-default auto-init​

Auto-init is the Datadog -javaagent model: set it once in the launch environment and every node auto-instruments with zero per-node code.

  • C++: LD_PRELOAD a constructor lib (librobotops_trace_autoinit.so) — it runs RobotOps::init() on load.
  • Python: set ROBOTOPS_TRACE_AUTOINIT=1 — an installed .pth / sitecustomize hook calls robotops.init() on interpreter start.

The installer writes both into /etc/robotops/trace.env:

# /etc/robotops/trace.env (written by install.sh)
export LD_PRELOAD=/opt/ros/${ROS_DISTRO}/lib/librobotops_trace_autoinit.so${LD_PRELOAD:+:$LD_PRELOAD}
export ROBOTOPS_TRACE_AUTOINIT=1
export ROBOTOPS_OTLP_ENDPOINT=unix:///run/robotops/trace.sock

Apply that env file to your ROS launch environment — not globally — by picking the model that matches your deployment:

:::tip Scope it to your ROS nodes, not the whole machine Auto-init belongs in the environment of the nodes you want traced. The installer deliberately does not add a global /etc/profile.d preload by default (that would LD_PRELOAD the tracer into every process — ssh, cron, system daemons). If you really want preload-everything, re-run the installer with ROBOTOPS_GLOBAL_AUTOINIT=1. :::

For nodes launched by their own systemd units, point each unit at the env file:

[Service]
EnvironmentFile=/etc/robotops/trace.env

Then run the agent (the carrier) with its key:

sudo systemctl edit robot-agent
[Service]
Environment=ROBOTOPS_API_KEY=sk_your_api_key_here
Environment=ROBOT_OPS_AGENT_BACKEND_URL=https://backend.robotops.com
sudo systemctl enable --now robot-agent

:::tip Nodes outside the auto-init env A node launched outside that environment still works — call RobotOps::init() (C++) or robotops.init() (Python) explicitly at startup. This is the override path; everything downstream behaves identically. :::

4. Transport — plug-and-play​

The SDK exports spans to the agent as OTLP/HTTP + protobuf over a Unix domain socket by default:

  • Default socket: unix:///run/robotops/trace.sock. The agent's systemd RuntimeDirectory creates, owns, and cleans it; the SDK default matches, so the same-host case needs no configuration.

  • Plug-and-play: default permissions let the robot's node processes connect out of the box. For locked-down fleets, opt into 0660 + a robotops group (the deb postinst creates it).

  • Override: ROBOTOPS_OTLP_ENDPOINT accepts unix:///path and http://host:port.

  • Containerized split (agent in a separate container, no shared FS) — the one case that isn't automatic. Point the SDK at the agent over TCP loopback:

    export ROBOTOPS_OTLP_ENDPOINT=http://agent:4318

5. Annotate (optional)​

Auto-init gives you spans for every framework callback for free. To add first-party depth inside your own code, drop in one line:

// C++ — RAII span for this scope
void MyNode::plan() {
ROBOTOPS_TRACE("plan_grasp");
// ... your code ...
}
# Python — decorate a function
@robotops.trace
def plan_grasp(self):
...

These nest automatically under the surrounding callback span. See Instrumentation for more.

6. Verify​

Bring up your nodes and the agent. Traces appear in your TraceHouse dashboard within a few seconds — as waterfalls with span attributes and events.

sudo systemctl status robot-agent # is the carrier running?
sudo journalctl -u robot-agent -f # follow live logs
ls -l /run/robotops/trace.sock # the SDK→agent socket exists

What you get​

With the SDK installed and auto-init on, TraceHouse shows:

  • Deterministic intra-process traces — exact parent/child causality within a process, not statistical sampling.
  • Auto-spans per callback — every rclcpp / rclpy executor callback (and BehaviorTree.CPP tick) becomes a span, tagged with robot.callback.type.
  • Deterministic action-hop stitching — action client and server spans are joined by robot.action.goal_id (the goal UUID), so a NavigateToPose shows up as one trace across the process boundary.
  • Best-effort topic/service stitching — pub/sub and service hops are correlated via DDS content keys (ros.publisher_gid, ros.source_timestamp).
  • Black-box spans for uninstrumented code — frameworks you haven't added an integration for still appear as opaque spans (a gap, never a failure or a crash).

All of it is described by the shared robotics semantic conventions (robot.* concept keys + ros.* mapping keys), so traces are queryable with the same vocabulary across frameworks.


Manual install​

If you prefer to install without piping the script, run each step individually:

# 1. Add the GPG key
curl -fsSL https://apt.robotops.com/robotops-public-key.asc \
| sudo gpg --dearmor -o /usr/share/keyrings/robotops-archive-keyring.gpg

# 2. Add the repository
echo "deb [signed-by=/usr/share/keyrings/robotops-archive-keyring.gpg] https://apt.robotops.com noble main" \
| sudo tee /etc/apt/sources.list.d/robotops.list

# 3. Install the carrier + the SDK (Jazzy; Jetson/Humble: swap jazzy→humble)
sudo apt update
sudo apt install robot-agent-jazzy \
ros-jazzy-robotops-trace-cpp \
ros-jazzy-robotops-trace-rclcpp \
ros-jazzy-robotops-trace-bt-cpp \
ros-jazzy-robotops-trace-semconv

# 4. Turn on auto-init (set wherever your nodes launch)
export LD_PRELOAD=/opt/ros/jazzy/lib/librobotops_trace_autoinit.so
export ROBOTOPS_TRACE_AUTOINIT=1

Then configure and run the agent using one of the models in step 3.

Installing via rosdep / ament​

If your team manages dependencies declaratively, declare the SDK packages as run dependencies in your package.xml instead of apt install-ing them directly. Add the apt repository (step 1 of the manual install), then:

<exec_depend>robotops_trace_cpp</exec_depend>
<exec_depend>robotops_trace_rclcpp</exec_depend>
<exec_depend>robotops_trace_bt_cpp</exec_depend>
<exec_depend>robotops_trace_semconv</exec_depend>

rosdep install --from-paths src --ignore-src -y then resolves them from apt.robotops.com. You keep stock upstream MoveIt / Nav2 / BehaviorTree.CPP / ros2_control — the SDK adds tracing as a normal dependency, never a fork or rebuild.

The robot-agent daemon itself is infrastructure, not a ROS node — install it via the script or apt, never as an ament dependency.

What's next​