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
```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._