Configuration

Every recording session in the Trossen SDK is driven by a single JSON configuration file.

What You Need

Before editing a config, complete Installation and Setup and have the following information available:

  • Arm controller IP addresses.

  • Camera serial numbers (for Stereolabs ZED or RealSense) or /dev/video* paths (for V4L2 USB cameras).

  • The mobile base serial port, if applicable.

Starting From an Example

Three reference configs ship with the SDK under examples/. Pick the one that matches your hardware. The rest of the docs assume you are working from one of these.

1 leader + 1 follower + 2 cameras. Config: examples/trossen_solo_ai/config.json


Schema Reference

A config is a JSON object with top-level keys, used by every example:

{
  "robot_name":  "my_robot",    // Identifier stored in dataset metadata
  "hardware":    { ... },       // Physical devices
  "producers":   [ ... ],       // Data streams (one per device channel)
  "teleop":      { ... },       // Leader/follower pairing
  "backend":     { ... },       // TrossenMCAP output settings
  "observers":   [ ... ],       // Optional live-stream consumers (e.g. ReRun viewer)
  "session":     { ... }        // Episode durations and limits
}

Hardware

The hardware block describes the physical devices connected to the PC. It contains arms and cameras (always required), plus an optional mobile_base.

hardware.arms is a map of arm ID to arm config. Each entry accepts:

Field

Type

Description

ip_address

string

IPv4 address of the arm controller

model

string

Arm model, currently only "wxai_v0"

end_effector

string

"wxai_v0_leader" or "wxai_v0_follower"

hardware.cameras is an array of camera configs. Each entry accepts:

Field

Type

Description

id

string

User-chosen label referenced by producers

serial_number

string

Camera serial (Stereolabs ZED or RealSense)

width / height

int

Frame resolution in pixels

fps

int

Capture frame rate

hardware.mobile_base (optional) accepts:

Field

Type

Description

reset_odometry

bool

Zero the odometry on startup

enable_torque

bool

Enable base motors on startup

Producers

producers is a JSON array. Each entry describes one data stream that the SDK will poll and record. Add one producer per arm, one per camera, and one per mobile base.

{
  "type":           "trossen_arm",      // Producer type (table below)
  "hardware_id":    "leader",           // Must match a key in hardware
  "stream_id":      "leader",           // Label used inside the MCAP file
  "poll_rate_hz":   30.0,
  "use_device_time": false,
  "encoding":       "bgr8"              // Cameras only
}

Supported producer types:

type

Description

trossen_arm

Trossen AI Kit arm

zed_camera

Stereolabs ZED (Jetson only; requires -DTROSSEN_ENABLE_ZED=ON)

realsense_camera

RealSense RGB

opencv_camera

V4L2 USB camera (any /dev/video*)

slate_base

SLATE mobile base

Tip

Set use_device_time: true for cameras so the timestamp attached to each image is the sensor capture time rather than the host-side poll time. For arms, false is usually fine because the host-side timestamp matches the joint-state read.

Teleop

"teleop": {
  "enabled": true,        // Set false to disable teleop
  "rate_hz": 1000.0,      // Teleop command rate
  "pairs": [              // One entry per leader/follower pair
    { "leader": "<arm_id>", "follower": "<arm_id>" }
  ]
}

leader and follower values must match keys in hardware.arms.

Backend

"backend": {
  "root":             "~/.trossen_sdk",   // Directory where episodes are written
  "dataset_id":       "my_dataset",       // Sub-directory for this dataset
  "compression":      "",                 // "" | "lz4" | "zstd"
  "chunk_size_bytes": 4194304             // MCAP chunk size (4 MB default)
}

Episodes land at <root>/<dataset_id>/episode_NNNNNN.mcap. Episode numbers are assigned automatically and resume from the highest existing index in the directory.

Observers

observers is an optional JSON array of live, non-durable consumers that receive records as they are produced. Each observer runs alongside the backend and is independent of the on-disk .mcap capture — leave the key out entirely if you do not need live streaming.

The only observer that ships with the SDK today is the ReRun viewer ("type": "rerun"). For background on what ReRun is and how to launch the viewer, see Visualize.

"observers": [
  {
    "type":      "rerun",                                // Observer type (table below)
    "id":        "live_viewer",                          // Logging label; defaults to type
    "enabled":   true,                                   // Set false to disable this observer
    "rerun_url": "rerun+http://127.0.0.1:9876/proxy",    // gRPC endpoint of a running ReRun viewer
    "app_id":    "trossen_solo_ai",                      // ReRun application id
    "spawn":     false,                                  // true = SDK launches the viewer itself (ignores rerun_url)
    "subscriptions": [
      { "record_id": "leader",      "throttle_hz": 30.0 },
      { "record_id": "follower",    "throttle_hz": 30.0 },
      { "record_id": "camera_main", "throttle_hz": 15.0 }
    ]
  }
]

Fields common to every observer:

Field

Type

Description

type

string

Observer type. Required. Only "rerun" ships today.

id

string

Logging label for this instance. Defaults to type when omitted.

enabled

bool

When false, the observer is parsed and validated but not started. Defaults to true.

subscriptions

array

Per-stream subscriptions. At least one entry is required and record_id values must be unique within one observer.

Each subscription entry accepts:

Field

Type

Description

record_id

string

Exact match against a producer’s stream_id (joint-state / odometry) or camera channel (e.g. camera_main). Required.

throttle_hz

number

Maximum dispatch rate to this observer for this stream. Range [1e-3, 1e4]. Required.

fields

array of strings

Optional per-subscription field filter. Observer-specific semantics — for rerun on a JointStateRecord subscription, accepted values are "positions", "velocities", "efforts" (drop the channels you don’t want plotted). Omit the key entirely to forward all fields; "fields": [] is rejected.

ReRun-specific fields (used only when type is "rerun"):

Field

Type

Description

rerun_url

string

gRPC URL of an already-running ReRun viewer. Defaults to "rerun+http://127.0.0.1:9876/proxy".

app_id

string

ReRun application id passed to the recording stream. Defaults to "trossen_sdk".

spawn

bool

When true, the SDK launches a local ReRun viewer at session start instead of connecting to an already-running one, and rerun_url is ignored. Requires the rerun binary on PATH (see Visualize); if its version differs from the SDK’s, ReRun prints a one-time compatibility warning but still connects and renders. Defaults to false.

Note

ReRun support is a build-time option. Configure with -DTROSSEN_ENABLE_RERUN_OBSERVER=ON to compile the observer in. With the option off (default), any "type": "rerun" entry in your config fails to load with an “unknown observer type” error. See Visualize for the full setup walkthrough.

Session

"session": {
  "max_duration":   20.0,            // Seconds per episode
  "max_episodes":   50,              // Total episodes to record
  "backend_type":   "trossen_mcap",  // Selects the backend implementation
  "reset_duration": 5.0              // Pause between episodes (see table)
}

reset_duration behavior:

Value

Behavior

Positive number (e.g. 5.0)

Countdown for that many seconds, then start the next episode

0

No pause; start the next episode immediately

Omitted / null

Wait indefinitely until the operator presses right arrow


Configuring Your Robot

The example configs work out of the box on the reference hardware. For your own robot you will typically need to change:

  • Arm IP addresses. One per arm. Must match the controllers on your network.

  • Camera serial numbers. One per camera. Must match the physical cameras plugged in.

  • Dataset ID. Pick a short, unique label so episodes from different runs don’t mix.

Everything else can stay at the example defaults for a first recording. See Finding Device Identifiers below for how to look up each value.

The solo config has 2 arms and 2 cameras. Replace the placeholders in examples/trossen_solo_ai/config.json:

"hardware": {
  "arms": {
    "leader":   { "ip_address": "<LEADER_IP>",   ... },
    "follower": { "ip_address": "<FOLLOWER_IP>", ... }
  },
  "cameras": [
    { "id": "camera_main",  "serial_number": "<MAIN_SERIAL>",  ... },
    { "id": "camera_wrist", "serial_number": "<WRIST_SERIAL>", ... }
  ]
},
"backend": {
  "dataset_id": "<YOUR_DATASET>",
  ...
}

Finding Device Identifiers

RealSense Serial Numbers

With the RealSense SDK installed, launch the official viewer:

realsense-viewer

Each connected camera appears in the left panel. Hover over a camera’s name to see its serial number, or expand the Info section in the camera’s settings to copy it. Plug in every camera, open its live stream in the viewer, and match the feed to the serial by its field of view.


CLI Overrides

Any JSON key can be overridden at runtime using dot-notation with --set KEY=VALUE. This is the fastest way to tweak one value without editing JSON:

./build/examples/trossen_solo_ai \
    --set hardware.arms.leader.ip_address=192.168.1.2 \
    --set session.max_duration=30 \
    --set backend.dataset_id=trial_01

Flags can be repeated. Overrides are applied after the JSON file is loaded and before the config is validated, so you can inspect the merged result without running hardware by appending --dump-config.

What’s Next

With a working config, continue to Record to record your first dataset.