DT-Robot is a browser-based digital twin control platform for multi-modal robotic systems. It simulates sensor telemetry, locomotion physics, communication links, and mission control in a unified heads-up display (HUD).
Use this guide to learn the layout, run your first simulation, and understand how inputs flow through the system to outputs.
- Open the Dashboard.
The main page shows the 3D simulation viewport, sensor tile grid, hardware toggles, and LIDAR radar.
- Pick a locomotion mode.
Use the mode strip below the header to switch between Ground, Legged, Aerial, Surface, or Submarine. Each mode changes the available sensor set and physics behavior.
- Toggle hardware links.
In the right column, turn on WiFi, Bluetooth, Ethernet, Cellular, LoRa, or WebRTC. Status LEDs in the header reflect live link health.
- Interact with the scene.
Place obstacles, waypoints, or targets. The robot will path around them in the 3D view.
- Run an I/O demonstration.
Open the I/O Demonstrator panel, choose a category, select an item, inject a waveform, and watch the input-to-output transfer function in real time.
The dashboard is a 12-column grid divided into a main workspace (left, 9 cols on XL) and a sidebar (right, 3 cols on XL).
Live robot model with camera orbit, zoom, and pan. Shows the current locomotion geometry and any placed scene objects.
Each tile displays a live value, sparkline history, unit, and threshold-based color alerts.
Polar radar plot of 36 distance samples updated every frame. Mean range shown below.
Latitude and longitude readout. Switches to DEAD-RECKON when submerged.
Enable/disable communication links. Each toggle affects header status LEDs and telemetry noise levels.
Start/stop/pause session recording. Export telemetry as JSON or capture the viewport as a .webm video.
The mode strip below the header lets you switch the robot's locomotion class. Each mode alters the 3D model, sensor availability, and physics constants.
Every sensor tile shows a current value, a 60-sample sparkline, and a unit. Threshold alerts change the tile border color:
Values are synthetic: they combine a base sinusoid with per-mode noise, link-quality attenuation, and injected scene perturbations. This gives realistic-looking telemetry without a physical robot.
Six independent comms links can be toggled on or off. Each link affects telemetry in a different way:
Below the 3D viewport, the Scene Controls panel lets you place objects into the simulation world. The robot will path around obstacles and navigate toward waypoints.
The I/O Demonstrator panel is an interactive teaching tool. It shows how a given input signal propagates through a system block to produce an output.
Every simulation tick emits a single TelemetryFrame object. This is the canonical wire shape: recorder exports, the I/O Demonstrator inputs, and any future Cloud sync all use it. Numeric fields are plain JS number (double precision) unless otherwise noted.
{
"t": 1718553600123, // epoch ms
"values": { /* see Sensor values */ },
"gps": { "lat": 37.7749, "lon": -122.4194 },
"lidar": [0.42, 0.51, /* 36 samples, 0..1 normalized */ ],
"detections": [
{ "id": 7, "x": 0.31, "y": 0.44, "w": 0.12, "h": 0.18,
"label": "person", "conf": 0.87 }
],
"links": {
"wifi": 0.92, // 0..1 signal quality
"bluetooth": true,
"ethernet": false,
"cellular": 0.65, // 0..1 signal
"lora": true,
"webrtc": true
},
"velocity": { "x": 0.4, "y": 0.0, "throttle": 0.7 }
}{
"depth": 0.0, // m ToF distance to nearest surface
"mic": -42.3, // dBFS microphone RMS level
"ir": 0.18, // m IR proximity range
"sonar": 1.24, // m ultrasonic range
"lidar": 2.30, // m mean of lidar[] array
"imu": 0.02, // g |accel| - 1.0 (motion magnitude)
"gps": 1.0, // bool fix valid (0 = dead-reckon)
"temp": 22.4, // °C
"humidity": 48.2, // %RH
"co2": 612, // ppm
"voc": 0.34, // 0..1 IAQ index
"pressure": 1013.2, // hPa
"battery": 0.78, // 0..1 state-of-charge
"speed": 0.95, // m/s
"heading": 174.0, // ° from North
"altitude": 12.4, // m AGL (aerial only)
"pitch": -3.1, // ° (aerial / surface / sub)
"roll": 1.7, // °
"yaw": 174.0, // °
"depthGauge": 4.2 // m below surface (submarine only)
}Inactive channels for a mode are still present in the object but hold 0 or the last known value. Tile rendering hides them based on mode.
// 36 entries, one per 10° bin, index 0 = forward, clockwise
// each value: 0..1 (1 = max range, ~5 m)
[0.42, 0.51, 0.60, 0.55, /* ... 36 total ... */]{
"id": 7, // stable track id
"x": 0.31, // 0..1 left edge (image-normalized)
"y": 0.44, // 0..1 top edge
"w": 0.12, // 0..1 width
"h": 0.18, // 0..1 height
"label": "person", // class string
"conf": 0.87 // 0..1 confidence
}{
"id": "evt_8f3a",
"t": 1718553600123, // epoch ms
"kind": "sensor", // "sensor"|"command"|"mode"|"system"
"severity": "warn", // "info"|"warn"|"alert"
"message": "CO2 above 1000 ppm"
}{
"type": "move", // "move"|"halt"|"home"|"arm"|"mode"
"payload": { "vx": 0.5, "vy": 0.0, "yaw": 0.1 },
"source": "keyboard" // "gamepad"|"keyboard"|"button"|"system"
}{
"sessionId": "rec_2026-06-16T14-03-22Z",
"startedAt": 1718553600123,
"endedAt": 1718553842901,
"mode": "aerial",
"frames": [ /* TelemetryFrame[] sampled at 10 Hz */ ],
"events": [ /* LogEvent[] */ ],
"commands": [ /* Command[] */ ]
}The canonical TypeScript definitions live in src/lib/robot/types.ts — keep that file as the source of truth when integrating with a real robot.
The Recorder panel in the right sidebar lets you capture sessions for later review or sharing.
Shortcuts are active on the /control page and in the 3D viewport when focused.
Need more help? Open the Dashboard and experiment — nothing you do here affects a real robot.