--- title: Reachy Mini Remote Control App emoji: 🎤 colorFrom: red colorTo: blue sdk: static pinned: false short_description: Remote control Reachy Mini ! hf_oauth: true hf_oauth_expiration_minutes: 480 hf_oauth_scopes: - contribute-repos - manage-repos - write-repos tags: - reachy_mini - reachy_mini_python_app --- # Reachy Mini Remote Control App A standalone app that connects Reachy Mini robot to a remote server for WebSocket-based control. The robot acts as a WebSocket **client** connecting to a remote server (e.g., Hugging Face Space), enabling remote control, video streaming, and bidirectional audio. ## 🚀 Quick Start - Multi-User Central Server This app now supports a **centralized multi-user server** where multiple users can securely connect their own robots without needing to clone spaces. ### How It Works 1. **Central Server**: One HuggingFace Space hosts all users 2. **Secure Authentication**: Each user authenticates with their HuggingFace account 3. **Automatic Matching**: Your robot connects to the server with your HF token 4. **Isolated Sessions**: Each user can only see and control their own robot ### Setup Instructions #### Step 1: Get Your HuggingFace Token 1. Go to https://huggingface.co/settings/tokens 2. Create a new token with `read` permissions 3. Copy the token (starts with `hf_`) #### Step 2: Configure Your Robot ```bash # Set your HuggingFace token (REQUIRED for authentication) export HF_TOKEN=hf_your_token_here # Optional: Set the central server URI (if different from default) # export WEBSOCKET_URI=wss://YOUR-CENTRAL-SERVER.hf.space ``` #### Step 3: Start the Remote Control App ```bash # Using the default profile python -m reachy_mini_remote_control_app # Or with a specific profile python -m reachy_mini_remote_control_app --profile default ``` #### Step 4: Open the Control Interface 1. Open the control interface in your browser: https://huggingfacem4-reachy-mini-remote-control.hf.space 2. Click "Sign in with Hugging Face" and authorize with the same account you used for the token 3. Once authenticated, you'll see your robot listed as connected 4. Start controlling your robot through the web interface! > **Note:** The Space may be asleep if unused for 48+ hours. Open it in your browser first and wait for it to fully load (~30 seconds) before your robot tries to connect. ### Legacy Setup (Private Space Cloning) If you prefer the old approach of cloning your own space: 1. Clone the `remote_control_space` to your own HuggingFace Space 2. Get your custom URI: `wss://your-username-reachy-mini-remote-control.hf.space` 3. Configure the URI in your robot's profile config 4. Set your HF token: `export HF_TOKEN=hf_your_token_here` **Note**: The multi-user central server approach is recommended as it's simpler and doesn't require space cloning. ## Features - **WebSocket Client Architecture**: Robot connects to remote server (works behind NAT/firewalls) - **Profile-Based Configuration**: Easily switch between different remote servers - **Bidirectional Streaming**: Video (robot → server) and Audio (robot ↔ server) - **Movement Control**: Receive movement commands from remote server - **Connection Monitoring**: Track latency, frames, and connection health - **Optional REST API**: Query status and manage profiles via HTTP endpoints ## Architecture ``` Remote Server Robot (this app) Reachy Mini Daemon (Hugging Face Space) WebSocket Server ←────── WebSocket Clients ←────── ReachyMini SDK - /robot - robot_control.py (Zenoh protocol) - /video_stream - video_stream.py - /audio_stream - audio_stream.py ``` The app connects TO a remote server as a client, not the other way around. This simplifies network setup since the robot only needs outbound connections. ## Installation ### From Source ```bash cd reachy_mini_remote_control_app pip install -e . ``` ### Requirements - Python >= 3.10 - Reachy Mini daemon running (`reachy-mini-daemon`) - Remote server running (e.g., [reachy_mini_remote_control/app.py](../reachy_mini_remote_control/app.py)) ## Usage ### 1. Start the Remote Server First, start the remote server that the robot will connect to: ```bash cd ../reachy_mini_remote_control python app.py # Server starts on ws://localhost:8000 ``` ### 2. Start the Reachy Mini Daemon ```bash reachy-mini-daemon --mockup-sim ``` ### 3. Start the Remote Control App ```bash reachy-mini-remote-control-app --profile default ``` The app will: - Connect to the remote server at `ws://localhost:8000` - Stream video and audio - Receive and execute movement commands ### Command Line Options ```bash reachy-mini-remote-control-app [OPTIONS] Options: --profile PROFILE Profile to use (default: from .env) --websocket-uri URI WebSocket URI to connect to (overrides profile) --robot-name NAME Robot name (default: reachy_mini) --log-level LEVEL Logging level (DEBUG, INFO, WARNING, ERROR) --no-rest-api Disable REST API for status endpoints ``` ## Configuration ### Profiles Profiles are stored in `src/reachy_mini_remote_control_app/profiles/`. Each profile is a directory with a `config.txt` file. **Default Profile** (`profiles/default/config.txt`): ``` WEBSOCKET_URI=wss://huggingfacem4-reachy-mini-remote-control.hf.space VIDEO_JPEG_QUALITY=80 VIDEO_WITH_TIMESTAMP=false VIDEO_FPS=25 AUDIO_WITH_TIMESTAMP=false AUDIO_BATCH_SIZE=4096 ENABLE_METRICS_LOGGING=true METRICS_LOG_INTERVAL_SEC=5 ``` **Example Remote Profile** (`profiles/example_remote/config.txt`): ``` WEBSOCKET_URI=wss://YOUR-SPACE.hf.space VIDEO_JPEG_QUALITY=75 VIDEO_WITH_TIMESTAMP=true VIDEO_FPS=25 AUDIO_WITH_TIMESTAMP=true AUDIO_BATCH_SIZE=4096 ENABLE_METRICS_LOGGING=true METRICS_LOG_INTERVAL_SEC=10 ``` ### Connecting to Private Spaces If you're using a private Hugging Face Space, you need to authenticate with a Hugging Face token: 1. **Create a Hugging Face Access Token**: - Go to https://huggingface.co/settings/tokens - Create a new token with `read` permissions - Copy the token 2. **Configure the Token**: **Option A: Via Profile Configuration** (Recommended) Add the token to your profile's `config.txt`: ``` WEBSOCKET_URI=wss://your-username-reachy-mini-remote-control.hf.space HF_TOKEN=hf_your_token_here ``` **Option B: Via Environment Variable** Add to your `.env` file: ``` HF_TOKEN=hf_your_token_here ``` 3. **Run the app** - it will automatically use the token for authentication when connecting to the private space. ### Environment Variables Create a `.env` file (copy from `.env.example`): ```bash REMOTE_CONTROL_PROFILE=default ROBOT_NAME=reachy_mini LOG_LEVEL=INFO VIDEO_JPEG_QUALITY=80 LATENCY_WARNING_MS=200 ENABLE_REST_API=true REST_API_HOST=0.0.0.0 REST_API_PORT=7860 # Optional: HF_TOKEN for private Hugging Face Spaces # HF_TOKEN=hf_your_token_here ``` ## REST API (Optional) If `ENABLE_REST_API=true`, the app provides HTTP endpoints: ### Get Status ```bash curl http://localhost:7860/status ``` Response: ```json { "robot_connected": true, "control": { "connected": true, "commands_received": 42, "last_command_type": "movement", "last_activity": 1705123456.78 }, "video": { "connected": true, "frames_sent": 1234, "frames_dropped": 5, "fps": 24.8, "latency_ms": 45.2, "latency_avg_ms": 42.1, "latency_min_ms": 38.5, "latency_max_ms": 52.3, "last_activity": 1705123456.78 }, "audio": { "connected": true, "chunks_sent": 567, "chunks_received": 234, "latency_avg_ms": 38.5, "last_activity": 1705123456.78 } } ``` ### List Profiles ```bash curl http://localhost:7860/profiles ``` Response: ```json { "profiles": ["default", "example_remote"], "current": "default" } ``` ### Switch Profile ```bash curl -X POST http://localhost:7860/profile/example_remote ``` **Note**: Requires app restart to take effect. ### Health Check ```bash curl http://localhost:7860/health ``` ## Integration with Reachy Mini Dashboard This app integrates with the Reachy Mini dashboard as a `ReachyMiniApp`: 1. Install the app: `pip install -e reachy_mini_remote_control_app` 2. The app will appear in the dashboard 3. Start from the dashboard UI 4. The dashboard provides the `ReachyMini` instance and `stop_event` ## HuggingFace OAuth This Space uses OAuth for seamless authentication. The metadata above enables OAuth with: - `hf_oauth: true` - Enables OAuth flow - `hf_oauth_expiration_minutes: 480` - Tokens valid for 8 hours - `hf_oauth_scopes: openid, profile` - Access to user info ### How OAuth Works 1. **User clicks "Sign in with Hugging Face"** in the web interface 2. **HuggingFace OAuth flow** - User authorizes the app 3. **Access token returned** - Stored securely in session storage 4. **Space cloning** - User can duplicate the remote control server to their account 5. **Private URI generated** - Custom WebSocket URI for their private space The OAuth implementation uses the `@huggingface/hub` JavaScript library for client-side authentication. See [hf-auth.js](hf-auth.js) for implementation details. ### For Robot Users The robot doesn't need OAuth - it just connects to the WebSocket URI. OAuth is only used in the web interface for space management. ## Deployment to Production ### Hugging Face Space Setup 1. Deploy the remote server ([reachy_mini_remote_control/app.py](../reachy_mini_remote_control/app.py)) to Hugging Face Space 2. Note the Space URL: `wss://YOUR-SPACE.hf.space` 3. Create a new profile: ```bash mkdir -p src/reachy_mini_remote_control_app/profiles/production ``` Edit `profiles/production/config.txt`: ``` WEBSOCKET_URI=wss://YOUR-SPACE.hf.space VIDEO_JPEG_QUALITY=75 VIDEO_WITH_TIMESTAMP=true VIDEO_FPS=25 AUDIO_WITH_TIMESTAMP=true AUDIO_BATCH_SIZE=4096 ENABLE_METRICS_LOGGING=true METRICS_LOG_INTERVAL_SEC=10 ``` 4. Set environment variable: ```bash export REMOTE_CONTROL_PROFILE=production ``` 5. Run the app: ```bash reachy-mini-remote-control-app --profile production ``` ### Network Requirements - **Robot side**: Only **outbound** connections needed (no port forwarding required) - **Server side**: WebSocket server must be publicly accessible - **Protocol**: Use WSS (WebSocket Secure) for production ### Security Considerations - Use WSS (not WS) for encrypted connections - Consider implementing authentication tokens - Monitor connection logs for suspicious activity - Rate limiting on the server side ## Troubleshooting ### Robot fails to connect to daemon ``` Failed to connect to robot: Connection timeout ``` **Solution**: Make sure the daemon is running: ```bash reachy-mini-daemon --mockup-sim ``` ### WebSocket connections fail with HTTP 429 ``` [Robot Control] Connection failed: server rejected WebSocket connection: HTTP 429 ``` The control Space is asleep. HF Spaces sleep after 48 hours of inactivity. **Solution**: Open https://huggingfacem4-reachy-mini-remote-control.hf.space in your browser and wait for it to fully load (~30 seconds), then restart the robot app. ### WebSocket connection fails ``` [Robot Control] Connection failed: Cannot connect to host ``` **Solutions**: 1. Verify the remote server is running and accessible 2. Check the `WEBSOCKET_URI` in your profile 3. Test connectivity: `curl http://YOUR-SERVER:8000/health` (if server has health endpoint) 4. Check firewall rules ### No video/audio streaming **Solutions**: 1. Ensure media is started: check daemon logs 2. Verify WebSocket connections are established: check `/status` endpoint 3. Check frame/audio publisher threads are running (look for log messages) ### High latency Check the `/status` endpoint for latency metrics: ```bash curl http://localhost:7860/status | jq '.video.latency_avg_ms' ``` **Solutions**: - Reduce `VIDEO_JPEG_QUALITY` in profile (e.g., from 80 to 60) - Lower `VIDEO_FPS` (e.g., from 25 to 15) - Use a server geographically closer to the robot - Check network bandwidth ## Development ### Running Tests ```bash pytest tests/ ``` ### Code Structure - `config.py` - Configuration management and profile loading - `monitoring/` - Metrics tracking and connection monitoring - `websocket_clients/` - WebSocket client implementations - `robot_control.py` - Receive movement commands - `video_stream.py` - Send video frames - `audio_stream.py` - Bidirectional audio - `app.py` - Optional REST API for status - `main.py` - Entry point and ReachyMiniApp implementation ## License Same as Reachy Mini SDK. ## Support For issues and questions: - GitHub Issues: [pollen-robotics/reachy_mini](https://github.com/pollen-robotics/reachy_mini/issues) - Email: contact@pollen-robotics.com