Configuration System

Complete reference for JOSHUA's configuration-driven architecture. Learn how a single Protocol Buffers text file defines your entire robot system—hardware, sensors, AI models, communication, and operation mode—without requiring any code changes.

Overview

The entire JOSHUA system is driven by a single .pbtxt (Protocol Buffers text format) configuration file. This design philosophy eliminates the need for code changes when reconfiguring the robot: swapping hardware, changing operation modes, adding sensors, or switching AI models are all accomplished by editing the configuration file alone.

Why Protocol Buffers Text Format? Protocol Buffers provide schema validation, type safety, language-neutral serialization, and backward-compatible evolution. The text format (.pbtxt) is human-readable and version-control friendly, making it ideal for robot configuration management.

Key benefits of the configuration-driven approach:

The configuration file is parsed by the Node Generator (the central orchestrator), which validates the configuration, resolves hardware dependencies, detects port conflicts, and spawns the appropriate ROS2 nodes as child processes.

Configuration Schema Hierarchy

The root of every JOSHUA configuration is the Config proto message. It is a composite structure containing five major sub-messages, each governing a distinct aspect of the system:

// Root configuration message
message Config {
  General     general     = 1;   // Operation mode, robot identity
  Robot       robot       = 2;   // Actuators and sensors
  Ai          ai          = 3;   // AI models, data stores, training
  Calibration calibration = 4;   // Servo calibration data
  SimulationConfig simulation = 5; // MuJoCo simulation settings
}

The hierarchy is designed so each subsystem is self-contained. The Node Generator reads the top-level Config and delegates each sub-message to the corresponding subsystem:

Sub-message Proto File Responsibility
General config.proto Operation mode, robot type, name, and unique identifier
Robot config.proto All actuator and sensor definitions with their ROS2 nodes
Ai config.proto AI model registry, dataset configuration, and training pipelines
Calibration config.proto Servo motor calibration offsets and operational limits
SimulationConfig simulation.proto MuJoCo simulation mode, model paths, and mirror mappings

General Configuration

The General message defines the system-wide identity and operation mode for the robot. Every configuration file must include a general block.

message General {
  OperationMode mode       = 1;   // System operation mode
  string        robot_type = 2;   // e.g., "SO-ARM100", "LeKoch"
  string        name       = 3;   // Human-readable name
  string        id         = 4;   // Unique identifier
}

Operation Modes

The OperationMode enum determines the entire behavioral profile of the system. It controls which nodes are spawned, what hardware is initialized, and how data flows through the pipeline.

Enum Value Description Typical Use Case
MODE_TELEOPERATE Leader-follower manual control Demonstration recording, manual manipulation, Xbox controller input
MODE_INFERENCE Autonomous AI model execution Deploy trained SmolVLA or custom models for real-time robot control
MODE_TRAINING Model training pipeline RL training (PPO), imitation learning, evaluation runs
MODE_CALIBRATION Hardware calibration sequence Servo motor range detection, offset tuning, limit configuration
MODE_TEST Hardware and system testing Validate wiring, test individual actuators, verify sensor readings
MODE_DATA_STORE Dataset collection and management Record teleoperation episodes, organize training data, upload to HuggingFace
MODE_SIMULATION Physics simulation environment MuJoCo interactive simulation, digital twin mirroring, offscreen rendering

Example general configuration block:

general {
  mode: MODE_TELEOPERATE
  robot_type: "SO-ARM100"
  name: "leader_follower_teleop"
  id: "joshua-arm-001"
}

Robot Configuration

The Robot message defines all physical hardware in the system. It contains two repeated fields: one for actuators (actions) and one for sensors (perceptions). Each entry maps a piece of hardware to a ROS2 node with full communication configuration.

message Robot {
  repeated SingleAction     actions     = 1;  // Actuators (motors, servos)
  repeated SinglePerception perceptions = 2;  // Sensors (cameras, encoders, LiDAR)
}

SingleAction

Each SingleAction entry defines one actuator group (e.g., one robot arm) with its ROS2 node configuration, action type, and hardware-specific driver settings.

message SingleAction {
  Node        node        = 1;   // ROS2 node configuration
  ActionType  action_type = 2;   // Type of actuator
  oneof actuator_config {
    STS3215Config    sts3215_config    = 3;  // Waveshare STS3215 servo bus
    MockMotorConfig  mock_motor_config = 4;  // Virtual motor for testing
    SpikeMotorConfig spike_motor_config = 5; // LEGO SPIKE Pybricks motor
  }
}

ActionType Enum

Enum Value Description Hardware
ACTION_LEADER Leader arm in teleoperation pair STS3215 servo bus
ACTION_FOLLOWER Follower arm that mirrors leader STS3215 servo bus
ACTION_SINGLE Standalone actuator Any supported motor
ACTION_MOCK Virtual actuator for testing MockMotorConfig
ACTION_SPIKE LEGO SPIKE hub motor SpikeMotorConfig via BLE

Actuator Configurations

STS3215Config — Configuration for Waveshare STS3215 serial bus servos commonly used in the SO-ARM100 and similar arm designs:

message STS3215Config {
  Comm          comm          = 1;  // Serial port configuration
  repeated int32 motor_ids    = 2;  // Bus IDs [1, 2, 3, 4, 5, 6]
  int32         position_min  = 3;  // Minimum position value
  int32         position_max  = 4;  // Maximum position value
  int32         velocity      = 5;  // Default velocity
  int32         acceleration  = 6;  // Default acceleration
}

MockMotorConfig — Virtual motor driver for testing without physical hardware:

message MockMotorConfig {
  int32         num_motors   = 1;  // Number of simulated motors
  int32         position_min = 2;  // Simulated range minimum
  int32         position_max = 3;  // Simulated range maximum
}

SpikeMotorConfig — Configuration for LEGO SPIKE motors controlled via Pybricks over BLE:

message SpikeMotorConfig {
  Comm           comm        = 1;  // BLE connection configuration
  repeated string port_names = 2;  // Hub port identifiers ["A", "B", "C"]
}

SinglePerception

Each SinglePerception entry defines one sensor with its ROS2 node, perception type, and device-specific configuration.

message SinglePerception {
  Node            node            = 1;  // ROS2 node configuration
  PerceptionType  perception_type = 2;  // Type of sensor
  oneof device_config {
    CameraConfig   camera_config  = 3;  // Camera (OpenCV)
    EncoderConfig  encoder_config = 4;  // Rotary encoder
    LidarConfig    lidar_config   = 5;  // LiDAR sensor
  }
}

PerceptionType Enum

Enum Value Description Device Config
PERCEPTION_CAMERA RGB camera via OpenCV CameraConfig
PERCEPTION_ENCODER Rotary position encoder EncoderConfig
PERCEPTION_LIDAR 2D/3D LiDAR scanner LidarConfig

Device Configurations

CameraConfig — OpenCV-based camera configuration with full control over capture parameters:

message CameraConfig {
  int32  device_id   = 1;   // /dev/video index (e.g., 0, 2, 4)
  int32  width       = 2;   // Capture width in pixels (e.g., 640)
  int32  height      = 3;   // Capture height in pixels (e.g., 480)
  int32  fps         = 4;   // Frames per second (e.g., 30)
  string pixel_format = 5;  // OpenCV pixel format (e.g., "MJPG")
  int32  brightness  = 6;   // OpenCV CAP_PROP_BRIGHTNESS
  int32  contrast    = 7;   // OpenCV CAP_PROP_CONTRAST
  int32  saturation  = 8;   // OpenCV CAP_PROP_SATURATION
  int32  exposure    = 9;   // OpenCV CAP_PROP_EXPOSURE
}

EncoderConfig — Rotary encoder for joint position feedback:

message EncoderConfig {
  Comm   comm             = 1;  // Communication interface
  int32  resolution       = 2;  // Ticks per revolution
  bool   inverted         = 3;  // Reverse counting direction
}

LidarConfig — LiDAR sensor for distance measurement and mapping:

message LidarConfig {
  Comm   comm             = 1;  // Communication interface
  float  angle_min        = 2;  // Minimum scan angle (radians)
  float  angle_max        = 3;  // Maximum scan angle (radians)
  float  range_min        = 4;  // Minimum detection range (meters)
  float  range_max        = 5;  // Maximum detection range (meters)
}

AI Configuration

The Ai message configures the complete AI pipeline: model selection, dataset management, and training infrastructure.

message Ai {
  repeated SingleModel models     = 1;  // AI models to load
  DataStore            data_store = 2;  // Dataset configuration
  Training             training   = 3;  // Training pipeline settings
}

SingleModel

Each SingleModel entry registers an AI model with the system. Models are loaded into the model registry and can be instantiated on demand.

message SingleModel {
  ModelType model_type                   = 1;  // Model architecture
  string    pretrained_model_name_or_path = 2;  // HuggingFace model ID or local path
  Node      node                         = 3;  // ROS2 node for inference I/O
}

ModelType Enum

Enum Value Description Use Case
RANDOM_NOISE Random action generator Testing and baseline comparison; outputs uniform random joint positions
SMOLVLA Vision-Language-Action model Multi-camera visual input + natural language task instruction to joint actions

Example model configuration for SmolVLA inference:

models {
  model_type: SMOLVLA
  pretrained_model_name_or_path: "lerobot/smolvla_base"
  node {
    node_name: "smolvla_inference"
    node_id: 1
    node_type: PYTHON
    publishers {
      data_type: JOINT_STATE
      topic_name: "/ai/actions"
      publish_rate_hz: 10.0
    }
    subscriptions {
      data_type: IMAGE
      topic_name: "/camera/top/image_raw"
    }
    subscriptions {
      data_type: IMAGE
      topic_name: "/camera/wrist/image_raw"
    }
  }
}

DataStore

The DataStore message configures how demonstration data and training datasets are managed.

message DataStore {
  DataFormat     format       = 1;  // Serialization format
  StorageBackend storage      = 2;  // Storage location
  string         dataset_name = 3;  // Dataset identifier
  string         local_path   = 4;  // Local filesystem path
  string         remote_url   = 5;  // Cloud storage URL
}

DataFormat Enum

Enum Value Description
FORMAT_HUGGINGFACE HuggingFace Datasets format with Arrow backend (recommended)
FORMAT_CSV Comma-separated values for simple tabular data
FORMAT_JSONL JSON Lines for structured, schema-flexible records
FORMAT_PARQUET Apache Parquet columnar format for efficient large-scale storage

StorageBackend Enum

Enum Value Description
STORAGE_LOCAL Local filesystem storage
STORAGE_CLOUD Cloud storage (HuggingFace Hub, S3, GCS)

Training

The Training message configures the full training pipeline, including environment selection, training method, and simulator backend.

message Training {
  TrainingEnvironment environment        = 1;  // Sim or real
  TrainingMethod      method             = 2;  // RL, imitation, or evaluation
  SimulatorBackend    simulator_backend  = 3;  // MJX or Isaac Sim
  RLConfig            rl_config          = 4;  // Reinforcement learning parameters
  ImitationConfig     imitation_config   = 5;  // Imitation learning parameters
  EvalConfig          eval_config        = 6;  // Evaluation parameters
}

TrainingEnvironment Enum

Enum Value Description
ENV_SIMULATION Train in simulated physics environment (MuJoCo)
ENV_REAL Train on physical robot hardware

TrainingMethod Enum

Enum Value Description
METHOD_RL Reinforcement learning (PPO via JAX/Flax on MJX)
METHOD_IMITATION Imitation learning from demonstration datasets
METHOD_EVAL Evaluation of a trained model against benchmarks

SimulatorBackend Enum

Enum Value Description
BACKEND_MJX MuJoCo-XLA: GPU-accelerated parallel simulation (2048+ environments)
BACKEND_ISAAC NVIDIA Isaac Sim: industrial-grade simulation with USD assets

Training Sub-configurations

message RLConfig {
  string algorithm          = 1;  // e.g., "PPO"
  int32  num_envs           = 2;  // Parallel environments (e.g., 2048)
  int32  total_timesteps    = 3;  // Total training steps
  float  learning_rate      = 4;  // Optimizer learning rate
  float  gamma              = 5;  // Discount factor
  float  clip_range         = 6;  // PPO clipping parameter
  int32  batch_size         = 7;  // Mini-batch size
  string reward_function    = 8;  // Reward function identifier
}

message ImitationConfig {
  string dataset_name       = 1;  // Dataset to train on
  int32  num_epochs         = 2;  // Training epochs
  float  learning_rate      = 3;  // Optimizer learning rate
  int32  batch_size         = 4;  // Batch size
  string loss_function      = 5;  // e.g., "mse", "l1"
}

message EvalConfig {
  string model_checkpoint   = 1;  // Path to model weights
  int32  num_episodes       = 2;  // Episodes to evaluate
  repeated string metrics   = 3;  // e.g., ["success_rate", "avg_return"]
}

ROS2 Node Configuration

Every hardware device, AI model, and system component in JOSHUA is backed by a ROS2 node. The Node proto provides a unified configuration for node identity, process type, communication quality, and topic mappings.

message Node {
  string              node_name     = 1;  // ROS2 node name
  int32               node_id       = 2;  // Unique numeric identifier
  NodeType            node_type     = 3;  // Process backend
  QoSSettings         qos           = 4;  // Quality of Service profile
  repeated Publisher   publishers   = 5;  // Outgoing topics
  repeated Subscription subscriptions = 6; // Incoming topics
}

NodeType Enum

Enum Value Description
CPP C++ node (performance-critical: motor drivers, sensor I/O)
PYTHON Python node (AI inference, data processing, prototyping)

QoS Settings

Quality of Service settings control the reliability and performance characteristics of ROS2 communication.

message QoSSettings {
  Reliability reliability = 1;  // RELIABLE or BEST_EFFORT
  Durability  durability  = 2;  // VOLATILE or TRANSIENT_LOCAL
  History     history     = 3;  // KEEP_LAST or KEEP_ALL
  int32       depth       = 4;  // Queue depth (e.g., 10)
  Liveliness  liveliness  = 5;  // AUTOMATIC or MANUAL_BY_TOPIC
}
Setting Options Default Notes
reliability RELIABLE, BEST_EFFORT RELIABLE Use BEST_EFFORT for high-frequency sensor data
durability VOLATILE, TRANSIENT_LOCAL VOLATILE TRANSIENT_LOCAL caches last message for late subscribers
history KEEP_LAST, KEEP_ALL KEEP_LAST KEEP_ALL requires careful memory management
depth Positive integer 10 Queue depth for KEEP_LAST history policy
liveliness AUTOMATIC, MANUAL_BY_TOPIC AUTOMATIC Controls node liveness detection

Publisher and Subscription

Publishers and subscriptions define the topic interface for each node. JOSHUA supports all 91 standard ROS2 message types.

message Publisher {
  DataType data_type       = 1;  // One of 91 ROS2 message types
  string   topic_name      = 2;  // Topic path (e.g., "/arm/joint_states")
  float    publish_rate_hz = 3;  // Publishing frequency in Hz
}

message Subscription {
  DataType data_type       = 1;  // Expected message type
  string   topic_name      = 2;  // Topic to subscribe to
}

DataType Enum (Selected Types)

The DataType enum maps to all 91 standard ROS2 message types. Below is a representative subset organized by category:

Category DataType Values
Sensor IMAGE, COMPRESSED_IMAGE, CAMERA_INFO, IMU, LASER_SCAN, POINT_CLOUD2, RANGE, TEMPERATURE, FLUID_PRESSURE, ILLUMINANCE, MAGNETIC_FIELD, RELATIVE_HUMIDITY, NAV_SAT_FIX, JOY, BATTERY_STATE
Joint / Actuator JOINT_STATE, JOINT_TRAJECTORY, MULTI_DOF_JOINT_STATE
Geometry TWIST, TWIST_STAMPED, POSE, POSE_STAMPED, POSE_ARRAY, WRENCH, WRENCH_STAMPED, TRANSFORM, TRANSFORM_STAMPED, VECTOR3, QUATERNION, ACCEL, ACCEL_STAMPED
Navigation ODOMETRY, PATH, OCCUPANCY_GRID, MAP_META_DATA, GRID_CELLS
Standard BOOL, INT32, INT64, FLOAT32, FLOAT64, STRING, BYTE_MULTI_ARRAY, FLOAT32_MULTI_ARRAY, FLOAT64_MULTI_ARRAY, INT32_MULTI_ARRAY
Diagnostic DIAGNOSTIC_STATUS, DIAGNOSTIC_ARRAY, LOG
Visualization MARKER, MARKER_ARRAY, IMAGE_MARKER
TF / Clock TF_MESSAGE, CLOCK, TIME, DURATION, HEADER
Tip: Choosing QoS for Sensor Data For high-frequency camera or LiDAR data, use BEST_EFFORT reliability with KEEP_LAST history and a depth of 1. This avoids buffering stale frames and minimizes latency. For joint commands, use RELIABLE to ensure no commands are dropped.

Communication Configuration

The Comm message (defined in comm.proto) configures the physical communication interface between the host and hardware devices.

// comm.proto
message Comm {
  oneof interface {
    Serial serial = 1;   // Wired serial (USB/UART)
    BLE    ble    = 2;   // Bluetooth Low Energy
  }
}

message Serial {
  string port     = 1;   // Device path (e.g., "/dev/ttyACM0")
  int32  baudrate = 2;   // Baud rate (e.g., 1000000)
}

message BLE {
  string device_name = 1;   // BLE device name to connect to
  string service_uuid = 2;  // BLE service UUID
}
Interface Key Parameters Typical Use
Serial port, baudrate STS3215 servo bus at 1 Mbps, Arduino sensors, LiDAR over UART
BLE device_name, service_uuid LEGO SPIKE hub via Pybricks BLE, wireless sensor modules

Example serial communication for an STS3215 servo bus:

comm {
  serial {
    port: "/dev/ttyACM0"
    baudrate: 1000000
  }
}

Example BLE communication for a SPIKE hub:

comm {
  ble {
    device_name: "Pybricks Hub"
    service_uuid: "c5f50001-8280-46da-89f4-6d8051e4aeef"
  }
}

Simulation Configuration

The SimulationConfig message (defined in simulation.proto) controls the MuJoCo physics simulation engine. It supports four distinct operational modes and provides configuration for model loading and digital twin topic mapping.

message SimulationConfig {
  SimulationMode mode       = 1;  // Simulation operational mode
  string         model_path = 2;  // Path to MJCF XML model file
  repeated MirrorTopicMapping mirror_topic_mappings = 3;  // Digital twin mappings
}

message MirrorTopicMapping {
  string ros_topic       = 1;  // ROS2 topic to subscribe to
  string mujoco_actuator = 2;  // MuJoCo actuator name to drive
}

SimulationMode Enum

Enum Value Description Use Case
INTERACTIVE GUI window with direct mouse/keyboard interaction Manual testing, environment exploration, debugging physics
PASSIVE Read-only visualization, replays pre-recorded trajectories Reviewing recorded episodes, trajectory validation
MIRROR Digital twin: subscribes to ROS2 topics and mirrors real robot Real-time visualization of physical robot state, remote monitoring
OFFSCREEN Headless rendering without GUI window Data generation, automated testing, CI/CD pipeline validation

Example simulation configuration for a digital twin setup:

simulation {
  mode: MIRROR
  model_path: "models/so_arm100/scene.xml"
  mirror_topic_mappings {
    ros_topic: "/follower/joint_states"
    mujoco_actuator: "joint_1"
  }
  mirror_topic_mappings {
    ros_topic: "/follower/joint_states"
    mujoco_actuator: "joint_2"
  }
  mirror_topic_mappings {
    ros_topic: "/follower/joint_states"
    mujoco_actuator: "joint_3"
  }
  mirror_topic_mappings {
    ros_topic: "/follower/joint_states"
    mujoco_actuator: "joint_4"
  }
  mirror_topic_mappings {
    ros_topic: "/follower/joint_states"
    mujoco_actuator: "joint_5"
  }
  mirror_topic_mappings {
    ros_topic: "/follower/joint_states"
    mujoco_actuator: "gripper"
  }
}

Example Configuration

Below is a complete .pbtxt configuration for a teleoperation setup with leader and follower SO-ARM100 arms, a top-mounted camera, and data recording.

# JOSHUA Configuration: Leader-Follower Teleoperation with SO-ARM100
# File: configs/teleop_so_arm100.pbtxt

general {
  mode: MODE_TELEOPERATE
  robot_type: "SO-ARM100"
  name: "leader_follower_teleop"
  id: "joshua-teleop-001"
}

robot {
  # Leader arm (input device)
  actions {
    node {
      node_name: "leader_arm"
      node_id: 1
      node_type: CPP
      qos {
        reliability: RELIABLE
        durability: VOLATILE
        history: KEEP_LAST
        depth: 10
        liveliness: AUTOMATIC
      }
      publishers {
        data_type: JOINT_STATE
        topic_name: "/leader/joint_states"
        publish_rate_hz: 50.0
      }
    }
    action_type: ACTION_LEADER
    sts3215_config {
      comm {
        serial {
          port: "/dev/ttyACM0"
          baudrate: 1000000
        }
      }
      motor_ids: [1, 2, 3, 4, 5, 6]
      position_min: 0
      position_max: 4095
      velocity: 0
      acceleration: 0
    }
  }

  # Follower arm (actuated output)
  actions {
    node {
      node_name: "follower_arm"
      node_id: 2
      node_type: CPP
      qos {
        reliability: RELIABLE
        durability: VOLATILE
        history: KEEP_LAST
        depth: 10
        liveliness: AUTOMATIC
      }
      publishers {
        data_type: JOINT_STATE
        topic_name: "/follower/joint_states"
        publish_rate_hz: 50.0
      }
      subscriptions {
        data_type: JOINT_STATE
        topic_name: "/leader/joint_states"
      }
    }
    action_type: ACTION_FOLLOWER
    sts3215_config {
      comm {
        serial {
          port: "/dev/ttyACM1"
          baudrate: 1000000
        }
      }
      motor_ids: [1, 2, 3, 4, 5, 6]
      position_min: 0
      position_max: 4095
      velocity: 1000
      acceleration: 200
    }
  }

  # Top-mounted camera
  perceptions {
    node {
      node_name: "camera_top"
      node_id: 3
      node_type: CPP
      qos {
        reliability: BEST_EFFORT
        durability: VOLATILE
        history: KEEP_LAST
        depth: 1
        liveliness: AUTOMATIC
      }
      publishers {
        data_type: IMAGE
        topic_name: "/camera/top/image_raw"
        publish_rate_hz: 30.0
      }
    }
    perception_type: PERCEPTION_CAMERA
    camera_config {
      device_id: 0
      width: 640
      height: 480
      fps: 30
      pixel_format: "MJPG"
      brightness: 128
      contrast: 128
      saturation: 128
      exposure: -6
    }
  }
}

ai {
  data_store {
    format: FORMAT_HUGGINGFACE
    storage: STORAGE_LOCAL
    dataset_name: "so_arm100_teleop_demos"
    local_path: "/data/datasets/so_arm100_teleop"
  }
}
Configuration Validation The Node Generator validates the configuration at startup. Common checks include: unique node IDs, no serial port conflicts, matching publisher/subscriber data types across topics, and valid enum values. If validation fails, the system prints a detailed error message and exits before initializing any hardware.

Configuration Presets Reference

JOSHUA ships with over 25 pre-built configuration presets covering common robot setups, training scenarios, and simulation environments. Presets are stored in the configs/ directory and can be used directly or as templates for custom configurations.

Preset Name Mode Description
teleop_so_arm100.pbtxt Teleoperate Leader-follower SO-ARM100 teleoperation with dual serial ports
teleop_so_arm100_camera.pbtxt Teleoperate Teleoperation with top and wrist cameras for data recording
teleop_xbox_controller.pbtxt Teleoperate Xbox controller input to single arm via gamepad mapping
teleop_keyboard.pbtxt Teleoperate Keyboard-based joint control for simple testing
teleop_dual_arm.pbtxt Teleoperate Dual leader-follower arms (bimanual manipulation)
inference_smolvla.pbtxt Inference SmolVLA model inference with dual camera input
inference_smolvla_jetson.pbtxt Inference SmolVLA optimized for NVIDIA Jetson Orin Nano deployment
inference_random_noise.pbtxt Inference Random action baseline for testing inference pipeline
training_rl_mjx.pbtxt Training PPO reinforcement learning on MuJoCo-XLA (2048 envs)
training_rl_isaac.pbtxt Training RL training using NVIDIA Isaac Sim backend
training_imitation.pbtxt Training Imitation learning from HuggingFace demonstration dataset
training_eval.pbtxt Training Model evaluation with success rate and return metrics
calibrate_so_arm100.pbtxt Calibration SO-ARM100 servo motor calibration with GUI output
calibrate_spike.pbtxt Calibration LEGO SPIKE motor calibration via BLE
test_single_motor.pbtxt Test Individual STS3215 servo test with oscillation pattern
test_camera.pbtxt Test Camera feed validation with OpenCV display
test_mock_hardware.pbtxt Test Full pipeline test with mock motors (no hardware required)
test_lidar.pbtxt Test LiDAR sensor validation and scan visualization
test_spike_ble.pbtxt Test LEGO SPIKE BLE connection and motor test
data_store_record.pbtxt Data Store Record teleoperation episodes to local HuggingFace dataset
data_store_upload.pbtxt Data Store Upload local dataset to HuggingFace Hub
data_store_replay.pbtxt Data Store Replay recorded episodes on physical robot
sim_interactive.pbtxt Simulation Interactive MuJoCo GUI with mouse/keyboard control
sim_passive.pbtxt Simulation Passive trajectory replay visualization
sim_mirror.pbtxt Simulation Digital twin mirroring real robot via ROS2 topics
sim_offscreen.pbtxt Simulation Headless rendering for CI/CD and data generation
sim_lekoch.pbtxt Simulation LeKoch mobile robot simulation in MuJoCo
Tip: Creating Custom Configurations The easiest way to create a new configuration is to copy the closest preset and modify it. All presets are located in the configs/ directory of the repository. Use joshua --config configs/your_custom.pbtxt to launch with your configuration.

To run a preset configuration:

# Run with a preset configuration
joshua --config configs/teleop_so_arm100.pbtxt

# Run with verbose logging for debugging
joshua --config configs/test_mock_hardware.pbtxt --log-level DEBUG

# Validate a configuration without launching
joshua --config configs/your_custom.pbtxt --validate-only