Spaces:
Running
Running
| # ๐ค 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 | |
| ```bash | |
| # Install dependencies | |
| cd src-python | |
| uv sync | |
| # Start the WebSocket server | |
| python start_server.py | |
| # Server runs on http://localhost:8080 | |
| ``` | |
| ### 2. Frontend Integration | |
| ```bash | |
| # In your Svelte app | |
| npm run dev | |
| # Visit http://localhost:5173 | |
| ``` | |
| ### 3. Create & Control Robot | |
| ```javascript | |
| // 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** | |
| ```typescript | |
| 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** | |
| ```typescript | |
| 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:** | |
| ```json | |
| { | |
| "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** | |
| ```typescript | |
| 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** | |
| ```typescript | |
| 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** | |
| ```typescript | |
| 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 | |
| ```json | |
| { | |
| "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 | |
| ```json | |
| { | |
| "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 | |
| ```json | |
| { | |
| "type": "heartbeat", | |
| "timestamp": "2024-01-01T12:00:00Z" | |
| } | |
| ``` | |
| ### Slave โ Server Communication | |
| #### Status Update | |
| ```json | |
| { | |
| "type": "status_update", | |
| "timestamp": "2024-01-01T12:00:00Z", | |
| "data": { | |
| "isConnected": true, | |
| "lastConnected": "2024-01-01T11:58:00Z", | |
| "error": null | |
| } | |
| } | |
| ``` | |
| #### Joint State Feedback | |
| ```json | |
| { | |
| "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 | |
| ```json | |
| { | |
| "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 | |
| ```bash | |
| # 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 | |
| ```bash | |
| # 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 | |
| ```bash | |
| # 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 | |
| ```bash | |
| # 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 | |
| ```javascript | |
| // 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) | |
| ```typescript | |
| 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) | |
| ```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++) | |
| ```cpp | |
| #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 | |
| ```typescript | |
| // 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 | |
| ```bash | |
| # 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 | |
| ```python | |
| # 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 | |
| ```bash | |
| cd src-python && python start_server.py | |
| ``` | |
| ### Docker | |
| ```dockerfile | |
| 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) | |
| ```bash | |
| # Procfile | |
| web: cd src-python && python start_server.py | |
| ``` | |
| ### Raspberry Pi (Edge) | |
| ```bash | |
| # systemd service for autostart | |
| sudo systemctl enable lerobot-arena | |
| sudo systemctl start lerobot-arena | |
| ``` | |
| ## ๐งช Testing & Debugging | |
| ### Unit Tests | |
| ```bash | |
| cd src-python | |
| pytest tests/ -v | |
| ``` | |
| ### Integration Tests | |
| ```javascript | |
| // 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 | |
| ```bash | |
| # Enable verbose logging | |
| export LOG_LEVEL=DEBUG | |
| python start_server.py | |
| # Frontend debug | |
| export VITE_DEBUG=true | |
| npm run dev | |
| ``` | |
| ### Health Monitoring | |
| ```bash | |
| # 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 | |
| ```bash | |
| # 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._ | |