Spaces:
Sleeping
title: RMScript Web Demo
emoji: π€
colorFrom: purple
colorTo: blue
sdk: docker
app_port: 7860
pinned: false
RMScript Web Demo
Web-based IDE for writing, verifying, and executing rmscript code on Reachy Mini.
Architecture
Components
Frontend (
frontend/): Pure HTML/CSS/JavaScript web IDEindex.html: UI layout with embedded CSS stylingapp.js: Application logic, compilation API calls, robot communication- Auto-detects environment (file:// for local, web server for production)
Backend (
backend/): FastAPI server (Python 3.11)app.py: REST API for rmscript compilation and validation- Serves frontend files via static file mounting
- Runs on port 8001 (local) or port 7860 (HuggingFace Spaces)
Robot Daemon: Reachy Mini daemon (expected on localhost:8000)
- REST API:
/api/move/goto(with duration support) - WebSocket API:
/api/move/ws/set_target(streaming, no duration) - State API:
/api/state/*(robot current state)
- REST API:
Communication Flow
Script Verification/Compilation:
- Frontend β Backend (
/api/verifyor/api/compile) - Backend compiles rmscript using the rmscript package
- Returns IR (Intermediate Representation) + errors/warnings
- Frontend β Backend (
Script Execution (Local):
- Frontend β Robot Daemon (
POST /api/move/goto) - Each IR action sent with duration and interpolation mode
- Proper timing with minimum-jerk interpolation
- Frontend β Robot Daemon (
Script Execution (HuggingFace Spaces):
- Frontend β Robot Daemon (WebSocket
/api/move/ws/set_target) - Fallback due to HTTPS β HTTP localhost blocking
- No duration control - moves are instant
- Frontend β Robot Daemon (WebSocket
Quick Start
On HuggingFace Spaces
Just open the Space - the web IDE will load automatically.
Requirements:
- Reachy Mini daemon running on
localhost:8000on your local machine - Modern web browser with WebSocket support
Local Development
- Install rmscript package:
cd rmscript
uv sync
- Start backend server:
cd backend
uv sync
uv run python app.py
Make sure your Reachy Mini daemon is running on
localhost:8000Open
frontend/index.htmlin your web browser
Features
- Code Editor: Write rmscript with syntax examples
- Verify Button: Check script validity without executing
- Execute Button: Compile and run script on connected robot
- Live Compilation: See IR (Intermediate Representation) of your script
- Example Scripts: Load pre-written examples (basic, complex, repeat)
- Real-time Logging: Console shows compilation errors, warnings, and execution progress
Usage
- Write rmscript in the editor (or load an example)
- Click "Verify" to check syntax and semantics
- Review any errors/warnings in the console
- Click "Execute" to run on the robot (robot must be connected)
- Watch execution progress in the Execution Info panel
Current Limitations
- Sound and picture actions are not yet implemented in execution
- Movement timing on HuggingFace Spaces: Due to browser security (HTTPS cannot fetch
http://localhost), the Space version cannot use the robot's/gotoendpoint which supports duration control.- On Spaces: Robot moves to each target as fast as possible (instant), but script execution pauses for the specified duration before the next move
- Locally: Robot moves smoothly with proper duration and minimum-jerk interpolation
- Recommendation: For demos requiring accurate movement timing, run locally
Deployment to HuggingFace Spaces
To deploy this demo to HuggingFace Spaces:
Prepare the repository structure:
Copy the
rmscriptandreachy_minidirectories (without.gitand binary files):cd rmscript_space_demo # Option 1: Using rsync (recommended - cleaner) rsync -av --exclude='.git' --exclude='.venv' --exclude='__pycache__' \ --exclude='*.pyc' ../rmscript/ ./rmscript/ rsync -av --exclude='.git' --exclude='.venv' --exclude='__pycache__' \ --exclude='*.pyc' ../reachy_mini/ ./reachy_mini/ # Option 2: Using cp then cleanup cp -r ../rmscript ./rmscript cp -r ../reachy_mini ./reachy_mini rm -rf ./rmscript/.git ./reachy_mini/.git rm -rf ./rmscript/.venv ./reachy_mini/.venv # Remove binary files that HuggingFace Spaces rejects rm -rf ./reachy_mini/src/reachy_mini/assets/*.wav rm -rf ./reachy_mini/src/reachy_mini/daemon/app/dashboard/static/fonts/*.ttf rm -rf ./reachy_mini/docs ./reachy_mini/examples rm -rf ./reachy_mini/src/reachy_mini/descriptions/reachy_mini/mjcf rm -rf ./rmscript/examples ./rmscript/testsYour structure should be:
rmscript_space_demo/ βββ Dockerfile βββ README.md βββ .dockerignore βββ backend/ βββ frontend/ βββ rmscript/ β copied source (no .git, no binaries) βββ reachy_mini/ β copied source (no .git, no binaries)
Create a new Space:
- Go to https://huggingface.co/new-space
- Select "Docker" as the SDK
- Push this directory to your Space repository
The Space will:
- Build the Docker container
- Install rmscript and dependencies
- Serve the web IDE on port 7860
Note: The Space connects to your local robot daemon on localhost:8000. Make sure it's running when using the demo.
Development
File Structure
rmscript_space_demo/
βββ Dockerfile # Docker build config for HuggingFace Spaces
βββ .dockerignore # Excludes .git, .venv, __pycache__, etc.
βββ README.md # This file (includes HF Space metadata in YAML)
βββ backend/
β βββ app.py # FastAPI server (compilation + static file serving)
β βββ pyproject.toml # Python dependencies
βββ frontend/
βββ index.html # Web IDE UI (with embedded CSS)
βββ app.js # Frontend logic (compilation + execution)
Key Implementation Details
Matrix to Euler Conversion (frontend/app.js:328-355):
- Converts 4x4 pose matrices (from rmscript IR) to euler angles (roll, pitch, yaw)
- Uses XYZ euler convention to match
scipy.spatial.transform.Rotation.as_euler("xyz") - Required because WebSocket API expects
{x, y, z, roll, pitch, yaw}format
Environment Detection (frontend/app.js:9-11):
- Detects
file://protocol β useshttp://localhost:8001for backend - Detects web server β uses relative URLs (same origin)
- Script loading path adapts similarly for
app.jsimports
Execution Strategy (frontend/app.js:357-427):
- Tries
POST /api/move/gotowith duration (works locally) - Catches fetch failures β falls back to WebSocket (for Spaces)
- Logs warnings when fallback is used
Modifying the Demo
Frontend Changes:
- Edit
frontend/app.jsfor logic changes - Edit
frontend/index.htmlfor UI/styling changes - Test by opening
index.htmldirectly in browser (local mode)
Backend Changes:
- Edit
backend/app.pyfor API changes - Run locally:
cd backend && uv run python app.py - Test API at
http://localhost:8001/docs(FastAPI Swagger UI)
Deployment:
- Changes auto-deploy when pushed to HuggingFace Space repo
- Build logs visible in Space's "Build" tab
- Runtime logs visible in Space's "Logs" tab
Technical Notes
Browser Security & Mixed Content
The Problem:
- HuggingFace Spaces serve content over HTTPS
- Robot daemon runs on
http://localhost:8000(HTTP, not HTTPS) - Modern browsers block HTTPS β HTTP requests (mixed content policy)
- This blocks
fetch()to the robot's REST API
Current Solution:
- WebSocket connections are allowed (less strict security)
- Use WebSocket
/ws/set_targetas fallback - Limitation: No duration control via WebSocket
Why We Can't Fix This:
- Robot daemon is on user's local machine
- Space backend runs on HuggingFace servers (can't reach localhost)
- Can't proxy through Space backend
- Can't get robot's current state for client-side interpolation
Alternative Approaches (Not Implemented):
- Client-side interpolation: Would need current robot state (blocked by same security issue)
- Local HTTPS proxy: Too complex for end users
- Run robot daemon on HTTPS: Requires SSL certificates for localhost
Deployment Gotchas
Binary Files:
- HuggingFace Spaces reject binary files (WAV, TTF, PNG, etc.)
- Must remove from
reachy_mini/andrmscript/copies before pushing - Already removed: docs/, examples/, assets/, fonts/
OpenGL Dependencies:
- OpenCV (cv2) requires system libraries:
libgl1,libglib2.0-0, etc. - Must install in Dockerfile (see lines 8-15)
- Package name changed from
libgl1-mesa-glxβlibgl1in newer Debian
Git Submodules:
- Don't copy
.gitdirectories fromrmscript/andreachy_mini/ - Use
rsync --exclude='.git'or remove after copying - Otherwise Space treats them as submodules (causes issues)
Future Improvements
Potential Enhancements
Sound & Picture Support:
- Currently IR supports these actions but execution skips them
- Would need to implement in
frontend/app.js:executeScript()
Syntax Highlighting:
- Add CodeMirror or Monaco Editor for better editing experience
- Custom rmscript syntax highlighting rules
Save/Load Scripts:
- localStorage for saving scripts in browser
- Or integrate with HuggingFace Datasets for cloud storage
Real-time Error Highlighting:
- Show errors inline in editor (like VS Code)
- Currently only shows in console panel
Movement Visualization:
- 3D preview of robot movements before execution
- Using Three.js or similar
Execution Controls:
- Pause/resume execution
- Step through script line-by-line
- Stop/cancel running script
Known Issues
- Spaces timing limitation: Cannot be fixed without changing browser security or deployment architecture
- Cached IR bug: Fixed - now always compiles fresh editor content
- Euler angle conversion: Works but could add gimbal lock handling improvements
Development History & Fixes
Issues Fixed During Development:
Robot not executing moves (2025-11-26):
- Problem: Robot daemon connected but moves didn't execute
- Cause: Frontend was extracting translation but hardcoding euler angles to 0
- Fix: Implemented
matrixToEulerXYZ()to properly extract rotation from 4x4 matrices - Location:
frontend/app.js:328-355
Modified scripts not executing (2025-11-26):
- Problem: Editing script in editor didn't affect execution - same old script ran
- Cause:
executeScript()was using cached IR instead of compiling fresh - Fix: Always compile editor content before execution
- Location:
frontend/app.js:285-290
Local development broken after Space changes (2025-11-26):
- Problem: Opening
index.htmllocally didn't loadapp.js - Cause: Changed script path to
/static/app.jsfor Space deployment - Fix: Auto-detect environment and load appropriate path
- Location:
frontend/index.html:320-329
- Problem: Opening
Binary files rejected during Space deployment (2025-11-26):
- Problem: HuggingFace push rejected due to WAV/TTF/PNG files
- Cause: HuggingFace Spaces don't allow binary files without LFS
- Fix: Remove docs, examples, assets from copied dependencies
- Commands: See deployment section step 1
Docker build failing on Spaces (2025-11-26):
- Problem:
libgl1-mesa-glxpackage not found during build - Cause: Package renamed in newer Debian (Trixie)
- Fix: Changed to
libgl1in Dockerfile - Location:
Dockerfile:10
- Problem:
Duration not respected in execution (2025-11-26):
- Problem: All moves happened instantly regardless of specified duration
- Cause: Using WebSocket
/ws/set_targetwhich doesn't support duration - Fix: Switch to REST API
POST /api/move/gotowith duration parameter - Location:
frontend/app.js:394-405
Fetch failures on HuggingFace Spaces (2025-11-26):
- Problem: "Failed to fetch" errors when executing on Space
- Cause: Browser mixed content policy blocks HTTPS β HTTP localhost
- Fix: Fallback to WebSocket when fetch fails (timing limitation accepted)
- Location:
frontend/app.js:407-426
Troubleshooting
Backend won't start locally:
# Make sure rmscript is installed
cd ../rmscript && uv sync
cd ../rmscript_space_demo/backend
# Install backend deps
uv sync
uv run python app.py
Robot not connecting:
- Check robot daemon is running:
curl http://localhost:8000/api/health - Check WebSocket connection in browser console
- Try reloading the page
Space build fails:
- Check build logs in Space's "Build" tab
- Common issues: binary files not removed, missing system dependencies
- Dockerfile may need updating for new Debian versions
Compilation errors:
- Check rmscript syntax in examples
- Use "Verify" button before "Execute"
- Check console for detailed error messages
Credits
Built with:
- rmscript - Kid-friendly robot programming language
- reachy_mini - Reachy Mini SDK
- FastAPI - Backend framework
- HuggingFace Spaces - Deployment platform