| name | xlerobot-onboard |
| description | Set up XLeRobot from scratch — clones lerobot + XLeRobot, grafts the robot classes into the lerobot tree, installs deps, then walks through motor configuration to first teleop. Use when the user types /xlerobot-onboard, asks to "set up" or "install" XLeRobot, or wants to onboard a new XLeRobot kit. |
XLeRobot Onboard
Take a developer with an XLeRobot kit and a laptop, get them to "first teleop episode" without hitting the install footguns that have broken past hackathon teams.
The deterministic install is handled by the xlerobot-install script in this repo (or, when called outside the repo, fetched from https://raw.githubusercontent.com/ScavieFae/xlerobot-onboard/main/xlerobot-install). Your job is the orchestration around it: env setup, error recovery, and the post-install hardware steps that need a human.
Workflow
Step 1 — Pre-flight
Detect and report:
python3 --version — need ≥ 3.12. Older = bail with a fix-recipe (Step 2).
which uv — if present, prefer uv for venv + pip (faster). If not, fall back to python3 -m venv + pip.
uname — Mac vs Linux. On Mac, surface brew install libusb upfront if the user hasn't installed it.
echo $VIRTUAL_ENV — if a venv is already active, use it. Otherwise ask where to create one (default: ./xle-onboard/.venv).
Step 2 — Venv
If no venv is active, create one inside the user's chosen working directory:
- With uv:
uv venv --python 3.12 .venv && source .venv/bin/activate
- Without uv:
python3.12 -m venv .venv && source .venv/bin/activate (Python 3.12 must already be installed — point at pyenv / Homebrew / conda if not).
Step 3 — Install
Run ./xlerobot-install --use-uv (or omit --use-uv if uv isn't available) from the repo root. Default install location is ./lerobot-xlerobot/. The script:
- Pre-checks Python ≥ 3.12.
- Clones huggingface/lerobot
v0.5.1 and Vector-Wangel/XLeRobot at a pinned SHA.
- Copies the xlerobot robot folder + IK solver into the lerobot tree.
- Runs
pip install -e ".[feetech]" against the modified tree.
- Verifies the imports actually resolve.
If the user is running this skill outside the cloned repo, fetch the script first:
curl -sSL https://raw.githubusercontent.com/ScavieFae/xlerobot-onboard/main/xlerobot-install -o xlerobot-install
chmod +x xlerobot-install
Step 4 — Recover
If the script fails, classify the error and propose the fix. Don't apply it without asking.
| Symptom | Cause | Fix |
|---|
Python <X.Y> is too old | lerobot v0.5.1 needs ≥ 3.12 | uv venv --python 3.12 .venv && source .venv/bin/activate, retry |
libusb-1.0 not found (Mac) | feetech needs libusb at link time | brew install libusb |
Could not build wheels for hidapi | system deps missing | Mac: brew install hidapi · Linux: sudo apt install libhidapi-dev |
| Verify imports fail after install succeeds | egg-info stale from a prior install attempt | cd lerobot && pip install -e ".[feetech]" --force-reinstall --no-deps |
git clone … XLeRobot fails or hangs | network / GitHub rate limit | retry; or pre-clone manually then re-run with the dirs already populated |
If the failure isn't here, dump the error verbatim and ask the user how they want to proceed. Don't guess.
Step 5 — Motor IDs (user action — pause)
Tell the user:
- XLeRobot has 17 Feetech sts3215 motors across 2 buses.
- Bus 1 (8 motors): left arm 1–6, head pan/tilt 7–8.
- Bus 2 (9 motors): right arm 1–6, base wheels 7–9.
- All Feetech motors ship with default ID 1. Each one must be programmed to its target ID before assembly, one at a time through the daisy chain.
- Easiest tool: https://bambot.org/feetech.js (browser, any OS).
- This is the #1 hidden footgun — see XLeRobot issue #85, where users replaced motors / cables / boards over multiple days before realizing the IDs were never written.
Ask: "Have you already programmed the motor IDs?" Wait for confirmation before continuing.
Step 6 — USB ports
Run python -m lerobot.find_port. It's interactive — asks the user to unplug then replug each cable. Walk them through it. Output: two /dev/tty… (Mac) or /dev/ttyACM… (Linux) paths.
Order matters. Port 1 = bus with arm-1 + head. Port 2 = bus with arm-2 + base. If the user got them backwards, swap before calibrating.
Save the two ports for Step 7.
Step 7 — Calibrate
Default (manual): lerobot-calibrate --robot.type=xlerobot --robot.port1=<port1> --robot.port2=<port2>. The user moves each joint through its full range, then to mid-position. Output saved under ~/.cache/huggingface/lerobot/calibration/.
If the autocalibrator (lerobot PR #3282 by Isaac Sin) is merged or available, prefer lerobot-auto-calibrate-feetech — drives joints to mechanical limits via stall detection, no manual sweeping required. Check PR status before recommending.
Footgun: if any joint reads way past its expected range — classic case is wrist_roll wrapping to a negative magnitude > 2047 — power-cycle the Waveshare board (unplug the barrel jack, position the joint to mid-range, plug back in). Don't rotate the joint by hand to "fix" the reading.
Step 8 — First teleop
python lerobot/examples/xlerobot/5_xlerobot_teleop_xbox.py (Xbox controller) or 4_xlerobot_teleop_keyboard.py (keyboard).
If the follower tracks the leader (or controller) — done. Acknowledge the user and stop. The next steps (recording episodes, training a policy) are out of scope for this skill.
Anti-patterns
- Don't pip-install dependencies the user didn't ask for. The script handles that.
- Don't try to script motor-ID programming or calibration. Both need physical access.
- Don't speculate on hardware failures. If a motor reports an error, the user has eyes on the robot — surface the error verbatim and ask.
- Don't keep going after a step fails. Stop, report, ask.
End state
User has:
lerobot/ cloned and extended with xlerobot.
- A working venv with feetech extras.
- Verified imports.
- Programmed motor IDs (their action).
- Discovered USB ports.
- Calibrated arms.
- A successful teleop session.
That's "ready for record/train." Stop here.