blanchon's picture
Mostly UI Update
18b0fa5

๐Ÿค– LeRobot Arena - Complete Robot Control System

A comprehensive WebSocket-based robot control platform featuring master-slave architecture, real-time 3D visualization, and seamless integration between physical robots and digital twins.

๐Ÿ›๏ธ Core Architecture

Master-Slave Pattern

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    Commands     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    Execution    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚    ๐ŸŽฎ MASTERS   โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚  ๐Ÿค– ROBOT CORE  โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚   ๐Ÿ”ง SLAVES     โ”‚
โ”‚                 โ”‚                 โ”‚                 โ”‚                 โ”‚                 โ”‚
โ”‚ โ€ข Remote Server โ”‚    WebSocket    โ”‚ โ€ข Robot Manager โ”‚   USB/Mock/WS   โ”‚ โ€ข Physical Bot  โ”‚
โ”‚ โ€ข Demo Scripts  โ”‚    HTTP API     โ”‚ โ€ข State Sync    โ”‚   Direct I/O    โ”‚ โ€ข 3D Simulation โ”‚
โ”‚ โ€ข Manual UI     โ”‚    Sequences    โ”‚ โ€ข Safety Logic  โ”‚   Commands      โ”‚ โ€ข Mock Testing  โ”‚
โ”‚ โ€ข AI Agents     โ”‚                 โ”‚ โ€ข Multi-Robot   โ”‚                 โ”‚ โ€ข Remote Proxy  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Key Principles:

  • ๐ŸŽฏ Single Source of Truth: Only one master per robot at a time
  • ๐Ÿ”’ Safety First: Manual control disabled when master active
  • ๐ŸŒ Multi-Modal: Same commands work across all slave types
  • ๐Ÿ”„ Real-Time Sync: Virtual and physical states synchronized
  • ๐Ÿ“ก Network Native: Built for remote operation from day one

๐Ÿš€ Quick Start Guide

1. Server Setup

# Install dependencies
cd src-python
uv sync

# Start the WebSocket server
python start_server.py
# Server runs on http://localhost:8080

2. Frontend Integration

# In your Svelte app
npm run dev
# Visit http://localhost:5173

3. Create & Control Robot

// Create robot in UI or via API
const robot = await robotManager.createRobot('my-robot', robotUrdfConfig);

// Option 1: Manual control (sliders in UI)
await robot.updateJointValue('Rotation', 45);

// Option 2: Demo sequences
await robotManager.connectDemoSequences('my-robot');

// Option 3: Remote server control
await robotManager.connectMaster('my-robot', {
  type: "remote-server",
  url: "ws://localhost:8080"
});

// Option 4: Direct API sequence trigger
curl -X POST http://localhost:8080/api/robots/my-robot/play-sequence/gentle-wave

๐ŸŽฎ Master Drivers (Command Sources)

MockSequenceMaster

Pre-programmed movement patterns for testing and demos

const config: MasterDriverConfig = {
    type: "mock-sequence",
    sequences: DEMO_SEQUENCES,
    autoStart: true,
    loopMode: true
};

await robotManager.connectMaster("robot-1", config);

Available Sequences:

  • ๐ŸŒŠ Gentle Wave Pattern (6s): Smooth greeting gesture with wrist movements
  • ๐Ÿ” Small Scanning Pattern (8s): Horizontal sweep for environment scanning
  • ๐Ÿ’ช Tiny Flex Pattern (8s): Articulation demonstration with elbow/jaw coordination

Features:

  • โœ… Safe movement ranges (ยฑ25ยฐ max)
  • โœ… Smooth interpolation between keyframes
  • โœ… Loop mode for continuous operation
  • โœ… Automatic master takeover

RemoteServerMaster

WebSocket connection to external control systems

const config: MasterDriverConfig = {
    type: "remote-server",
    url: "ws://localhost:8080",
    apiKey: "optional-auth-token"
};

await robotManager.connectMaster("robot-1", config);

Features:

  • โœ… Real-time bidirectional communication
  • โœ… Automatic reconnection with exponential backoff
  • โœ… Heartbeat monitoring (30s intervals)
  • โœ… Command acknowledgment
  • โœ… Status and error reporting

Message Format:

{
    "type": "command",
    "timestamp": "2024-01-01T12:00:00Z",
    "data": {
        "timestamp": 1704110400000,
        "joints": [{ "name": "Rotation", "value": 45, "speed": 100 }]
    }
}

๐Ÿ”ง Slave Drivers (Execution Targets)

MockSlave

Perfect simulation for development and testing

const config: SlaveDriverConfig = {
    type: "mock-slave",
    simulateLatency: 50, // Realistic response delay
    simulateErrors: false, // Random connection issues
    responseDelay: 20 // Command execution time
};

await robotManager.connectSlave("robot-1", config);

Features:

  • โœ… Perfect command execution (real_value = virtual_value)
  • โœ… Configurable network latency simulation
  • โœ… Error injection for robustness testing
  • โœ… Instant connection without hardware
  • โœ… Real-time state feedback

USBSlave

Direct serial communication with physical robots

const config: SlaveDriverConfig = {
    type: "usb-slave",
    port: "/dev/ttyUSB0", // Auto-detect if undefined
    baudRate: 115200
};

await robotManager.connectSlave("robot-1", config);

Features:

  • โœ… Feetech servo protocol support
  • โœ… Position and speed control
  • โœ… Real servo position feedback
  • โœ… Calibration workflow for sync
  • โœ… Error handling and recovery

Calibration Process:

  1. Manually position robot to match digital twin
  2. Click "Calibrate" to sync virtual/real coordinates
  3. System calculates offset: real_pos = raw_pos + offset
  4. All future commands automatically compensated

WebSocketSlave

Remote robot control via WebSocket relay

const config: SlaveDriverConfig = {
    type: "websocket-slave",
    url: "ws://robot-proxy:8080",
    robotId: "remote-arm-1"
};

await robotManager.connectSlave("robot-1", config);

Use Cases:

  • ๐ŸŒ Control robots across internet
  • ๐Ÿข Enterprise robot fleet management
  • ๐Ÿ”’ Firewall-friendly robot access
  • ๐Ÿ“ก Proxy through edge devices

๐Ÿ“ก WebSocket Protocol Specification

Master โ†’ Server Communication

Send Joint Command

{
    "type": "command",
    "timestamp": "2024-01-01T12:00:00Z",
    "data": {
        "timestamp": 1704110400000,
        "joints": [
            { "name": "Rotation", "value": 45, "speed": 100 },
            { "name": "Pitch", "value": -30, "speed": 150 }
        ],
        "duration": 2000,
        "metadata": { "source": "manual_control" }
    }
}

Send Movement Sequence

{
    "type": "sequence",
    "timestamp": "2024-01-01T12:00:00Z",
    "data": {
        "id": "custom-dance",
        "name": "Custom Dance Sequence",
        "commands": [
            {
                "timestamp": 0,
                "joints": [{ "name": "Rotation", "value": -30 }],
                "duration": 1000
            },
            {
                "timestamp": 1000,
                "joints": [{ "name": "Rotation", "value": 30 }],
                "duration": 1000
            }
        ],
        "total_duration": 2000,
        "loop": false
    }
}

Heartbeat

{
    "type": "heartbeat",
    "timestamp": "2024-01-01T12:00:00Z"
}

Slave โ†’ Server Communication

Status Update

{
    "type": "status_update",
    "timestamp": "2024-01-01T12:00:00Z",
    "data": {
        "isConnected": true,
        "lastConnected": "2024-01-01T11:58:00Z",
        "error": null
    }
}

Joint State Feedback

{
    "type": "joint_states",
    "timestamp": "2024-01-01T12:00:00Z",
    "data": [
        {
            "name": "Rotation",
            "servo_id": 1,
            "type": "revolute",
            "virtual_value": 45.0,
            "real_value": 44.8,
            "limits": {
                "lower": -180,
                "upper": 180,
                "velocity": 200
            }
        }
    ]
}

Error Reporting

{
    "type": "error",
    "timestamp": "2024-01-01T12:00:00Z",
    "data": {
        "code": "SERVO_TIMEOUT",
        "message": "Servo 3 not responding",
        "joint": "Elbow",
        "severity": "warning"
    }
}

๐Ÿ› ๏ธ REST API Reference

Robot Management

Method Endpoint Description Example
GET / Server status & metrics curl http://localhost:8080/
GET /api/robots List all robots curl http://localhost:8080/api/robots
POST /api/robots Create new robot curl -X POST -H "Content-Type: application/json" -d '{"robot_type":"so-arm100","name":"My Robot"}' http://localhost:8080/api/robots
GET /api/robots/{id} Get robot details curl http://localhost:8080/api/robots/robot-123
GET /api/robots/{id}/status Get connection status curl http://localhost:8080/api/robots/robot-123/status
DELETE /api/robots/{id} Delete robot curl -X DELETE http://localhost:8080/api/robots/robot-123

Sequence Control

Method Endpoint Description Example
GET /api/sequences List demo sequences curl http://localhost:8080/api/sequences
POST /api/robots/{id}/play-sequence/{seq_id} Play sequence curl -X POST http://localhost:8080/api/robots/robot-123/play-sequence/gentle-wave
POST /api/robots/{id}/stop-sequence Stop sequences curl -X POST http://localhost:8080/api/robots/robot-123/stop-sequence

WebSocket Endpoints

Endpoint Purpose Client Type Example
/ws/master/{robot_id} Send commands Control sources ws://localhost:8080/ws/master/robot-123
/ws/slave/{robot_id} Receive commands Execution targets ws://localhost:8080/ws/slave/robot-123

๐ŸŽฏ Usage Scenarios

1. ๐Ÿงช Development & Testing

# Create robot with mock slave for safe testing
robot = await robotManager.createRobot('test-bot', urdfConfig);
await robotManager.connectMockSlave('test-bot', 50);
await robotManager.connectDemoSequences('test-bot');

Perfect for:

  • Algorithm development without hardware risk
  • UI/UX testing with realistic feedback
  • Automated testing pipelines
  • Demo presentations

2. ๐Ÿฆพ Physical Robot Control

# Connect real hardware
robot = await robotManager.createRobot('real-bot', urdfConfig);
await robotManager.connectUSBSlave('real-bot', '/dev/ttyUSB0');

# Manual control via UI sliders
# OR automated via demo sequences
await robotManager.connectDemoSequences('real-bot');

Calibration Workflow:

  1. Connect USB slave to robot
  2. Manually position to match 3D model rest pose
  3. Click "Calibrate" to sync coordinate systems
  4. Robot now mirrors 3D model movements precisely

3. ๐ŸŒ Remote Operation

# Master controls slave over internet
# Master side:
await robotManager.connectMaster('local-avatar', {
  type: "remote-server",
  url: "wss://robot-farm.com:8080"
});

# Slave side (at robot location):
await robotManager.connectSlave('physical-robot', {
  type: "websocket-slave",
  url: "wss://robot-farm.com:8080",
  robotId: "local-avatar"
});

Use Cases:

  • Telepresence robotics
  • Remote maintenance and inspection
  • Distributed manufacturing
  • Educational robot sharing

4. ๐Ÿค– Multi-Robot Coordination

# One master controlling multiple robots
await robotManager.connectMaster('fleet-commander', masterConfig);

// Multiple slaves executing same commands
for (const robot of robotFleet) {
  await robotManager.connectSlave(robot.id, slaveConfig);
}

Applications:

  • Synchronized dance performances
  • Assembly line coordination
  • Swarm robotics research
  • Entertainment shows

5. ๐Ÿง  AI Agent Integration

// AI agent as master driver
class AIAgentMaster implements MasterDriver {
  async generateNextCommand(): Promise<RobotCommand> {
    const sensorData = await this.readEnvironment();
    const decision = await this.aiModel.predict(sensorData);
    return this.convertToRobotCommand(decision);
  }
}

await robot.setMaster(new AIAgentMaster(config));

๐Ÿ”ง Integration Guide

Frontend Integration (Svelte)

import { robotManager } from "$lib/robot/RobotManager.svelte";
import { robotUrdfConfigMap } from "$lib/configs/robotUrdfConfig";

// Create robot
const robot = await robotManager.createRobot("my-robot", robotUrdfConfigMap["so-arm100"]);

// Add visualization
await robotManager.connectMockSlave("my-robot");

// Add control
await robotManager.connectDemoSequences("my-robot", true);

// Monitor state
robot.joints.forEach((joint) => {
    console.log(`${joint.name}: virtual=${joint.virtualValue}ยฐ real=${joint.realValue}ยฐ`);
});

Backend Integration (Python)

import asyncio
import websockets
import json

async def robot_controller():
    uri = "ws://localhost:8080/ws/master/my-robot"
    async with websockets.connect(uri) as websocket:
        # Send command
        command = {
            "type": "command",
            "timestamp": "2024-01-01T12:00:00Z",
            "data": {
                "timestamp": 1704110400000,
                "joints": [{"name": "Rotation", "value": 45}]
            }
        }
        await websocket.send(json.dumps(command))

        # Listen for responses
        async for message in websocket:
            data = json.loads(message)
            if data["type"] == "joint_states":
                print(f"Robot position: {data['data']}")

asyncio.run(robot_controller())

Hardware Integration (Arduino/C++)

#include <WiFi.h>
#include <WebSocketsClient.h>
#include <ArduinoJson.h>

WebSocketsClient webSocket;

void onWebSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
    if (type == WStype_TEXT) {
        DynamicJsonDocument doc(1024);
        deserializeJson(doc, payload);

        if (doc["type"] == "execute_command") {
            JsonArray joints = doc["data"]["joints"];
            for (JsonObject joint : joints) {
                String name = joint["name"];
                float value = joint["value"];
                moveServo(name, value);
            }
        }
    }
}

void setup() {
    webSocket.begin("192.168.1.100", 8080, "/ws/slave/arduino-bot");
    webSocket.onEvent(onWebSocketEvent);
}

๐Ÿ›ก๏ธ Security & Production

Authentication

// API key authentication (planned)
const master = new RemoteServerMaster(
    {
        type: "remote-server",
        url: "wss://secure-robot-farm.com:8080",
        apiKey: "your-secret-api-key"
    },
    robotId
);

TLS/SSL

# Production deployment with SSL
uvicorn main:app --host 0.0.0.0 --port 443 --ssl-keyfile key.pem --ssl-certfile cert.pem

Rate Limiting & Safety

# Built-in protections
- Command rate limiting (100 commands/second max)
- Joint velocity limits from URDF
- Emergency stop on connection loss
- Position bounds checking
- Servo temperature monitoring

๐Ÿš€ Deployment Options

Development

cd src-python && python start_server.py

Docker

FROM python:3.12-slim
COPY src-python/ /app/
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 8080
CMD ["python", "start_server.py"]

Cloud (Railway/Heroku)

# Procfile
web: cd src-python && python start_server.py

Raspberry Pi (Edge)

# systemd service for autostart
sudo systemctl enable lerobot-arena
sudo systemctl start lerobot-arena

๐Ÿงช Testing & Debugging

Unit Tests

cd src-python
pytest tests/ -v

Integration Tests

// Frontend testing
import { expect, test } from "@playwright/test";

test("robot creation and control", async ({ page }) => {
    await page.goto("/");
    await page.click('[data-testid="create-robot"]');
    await page.click('[data-testid="connect-demo-sequences"]');
    await expect(page.locator('[data-testid="robot-status"]')).toContainText("Master + Slaves");
});

Debug Mode

# Enable verbose logging
export LOG_LEVEL=DEBUG
python start_server.py

# Frontend debug
export VITE_DEBUG=true
npm run dev

Health Monitoring

# Check server health
curl http://localhost:8080/

# Monitor WebSocket connections
curl http://localhost:8080/api/robots

๐Ÿ”ฎ Roadmap

v2.0 - Enhanced Control

  • Script Player Master: Execute Python/JS scripts
  • Simulation Slave: Physics-based simulation
  • Force Control: Torque and compliance modes
  • Vision Integration: Camera feeds and computer vision

v2.1 - Enterprise Features

  • Authentication: JWT tokens and user management
  • Multi-tenancy: Isolated robot fleets per organization
  • Monitoring: Prometheus metrics and Grafana dashboards
  • Recording: Command sequences and replay

v2.2 - Advanced Robotics

  • Path Planning: Trajectory optimization
  • Collision Detection: Safety in shared workspaces
  • AI Integration: Reinforcement learning environments
  • ROS Bridge: Integration with ROS2 ecosystem

๐Ÿค Contributing

Development Setup

# Frontend
npm install
npm run dev

# Backend
cd src-python
uv sync
python start_server.py

# Tests
npm run test
cd src-python && pytest

Code Style

  • TypeScript: ESLint + Prettier
  • Python: Black + isort + mypy
  • Commits: Conventional commits format

Pull Request Process

  1. Fork repository
  2. Create feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. Update documentation
  6. Submit PR with clear description

๐Ÿ“„ License

MIT License - Feel free to use in commercial and personal projects.


Built with โค๏ธ for the robotics community

LeRobot Arena bridges the gap between digital twins and physical robots, making robotics accessible to developers, researchers, and enthusiasts worldwide.