thanhndv212/figaroh-plus/figaroh-setup-calibration
Claude Code and agent skill by thanhndv212/figaroh-plus
- community
Checking that the SKILL.md file is still in the repository.
Set up and run a FIGAROH geometric (kinematic) calibration task end to end — correcting joint offsets and frame transforms from measured end-effector poses. Use when the user wants to calibrate a robot, has mocap/laser-tracker measurements to fit, or asks which config keys and CSV columns a calibration needs. Covers both existing example robots and bringing your own data.
Install
npx vskill@latest install thanhndv212/figaroh-plus/figaroh-setup-calibrationSKILL.md
Set Up a Geometric Calibration Task
_Arguments: robot name (or "my robot"), and where the measurement data lives._
Paths.$FIGAROH_WSis the workspace root — the directory holding thefigarohandfigaroh-examplesrepos side by side. Set it once per shell:export FIGAROH_WS="$(cd /path/to/your/workspace && pwd)".
Prerequisite: figaroh-setup-env exits 0. Working directory for every command below: $FIGAROH_WS/figaroh-examples/examples/<robot>/.
What this task does
Fits geometric parameters (joint offsets, link frame transforms, and the base/tool metrology frames) so forward kinematics reproduces externally measured end-effector poses. Inputs: a URDF + a CSV of measured poses paired with joint configurations. Outputs: a parameter vector, a modified URDF, and a run archive.
Step 1 — Pick the path
| Situation | Do this | |
|---|---|---|
Robot already under examples/ with a calibration.py | Go to Step 2. Robots with calibration: ur10, tiago, talos (calibration_upperbody.py), talos_table_contact (run_calibration.py), tiago_pro (run_calibration.py). | |
| Robot exists but no calibration entry point | Copy examples/ur10/calibration.py and utils/ur10_tools.py's UR10Calibration as the reference; add a tasks.calibration block to its unified config. | |
| No folder for this robot yet | Stop — run `figaroh-setup-new-robot` first, then come back. |
Verify before assuming:
Step 2 — Assemble the three required inputs
a) URDF + meshes. URDF at examples/<robot>/urdf/<robot>.urdf; its package:// mesh references must resolve under figaroh-examples/models/. Loaded as:
../../models is only correct when CWD is examples/<robot>/.
b) Measurement CSV. This is the input people get wrong most often. Columns are derived from the config, not fixed — figaroh/src/figaroh/calibration/data_loader.py builds them like this:
- Marker columns, per marker
i(1-indexed), emitted **only for DOFs flagged
true in that marker's measurable_dof**, in the order x, y, z, phix, phiy, phiz:
- 6-DOF marker (
[true]*6) →x1,y1,z1,phix1,phiy1,phiz1(UR10) - position-only (
[true,true,true,false,false,false]) →x1,y1,z1(TIAGo) - two markers → repeat the block as
…2columns - Joint columns: one per active joint, named exactly as in the URDF /
model.names — e.g. shoulder_pan_joint,…,wrist_3_joint. Not q0..q5.
One row = one pose. Real header from examples/ur10/data/calibration.csv:
Positions in metres, orientations in radians (log-map / rotation-vector convention).
c) Config. config/<robot>_unified_config.yaml, unified format, with extends: pointing at ../../templates/manipulator_robot.yaml (fixed base) or humanoid_robot.yaml (mobile/floating base).
Step 3 — Fill in tasks.calibration
Key coupling to keep straight:
measurable_dof⇄ CSV columns ⇄reference_jointmust all agree. Changing
measurable_dof changes which columns are read.
base_pose/tool_poseare initial guesses for the metrology frames, in
[x,y,z,roll,pitch,yaw]. UR10's script deliberately sets calib_config["known_baseframe"] = False / known_tipframe = False so both are estimated; if your setup measures them independently, leave them known.
- `validation_data_file` must be genuinely independent data — a separate
acquisition, never a split of the training file. Leaving it empty falls back to the calibration data with a visible warning; that verdict is not an independent validation, so do not report it as one.
Step 4 — Run
Useful flags (UR10 exposes all of them; check --help per robot):
| Flag | Effect | |
|---|---|---|
--config, --urdf | Override the defaults instead of editing files | |
--validation-data <csv> | Override validation_data_file for one run | |
--no-plot | No matplotlib windows — required for headless/CI | |
--html-report / --no-html-report | Self-contained HTML diagnostic (on by default) | |
--geometric-calibration-yaml | PAL robot_state_publisher deploy YAML, full + >=2σ conservative | |
--archive / --no-archive | Timestamped run archive (on by default) | |
--asset-id, --operator | Provenance for the specific physical unit | |
--verbose / -v | INFO logging (default is WARNING) |
Step 5 — Read the outputs
<asset> comes from robot.instance.asset_id / --asset-id; with neither, runs land under <robot>-unspecified (e.g. ur10e-unspecified). Nothing is overwritten — every run is timestamped and archived separately. results/ and calibration_results_*.npz are gitignored, so running a task never dirties the tree.
Judge the fit by the printed block:
Then the URDF export consistency check re-runs FK on the exported URDF over 200 samples. Position RMSE there should be small relative to the calibration residual — if the export check is large, the export lost parameters, not the fit.
Metrology frame parameters are printed but NOT written into the URDF (base_*, pEE*, phiEE*). They describe your measurement setup and must be applied in the controller or pipeline. frame_settings_doc() explains the conventions.
Step 6 — Verify
Failure → cause → fix
| Symptom | Cause | Fix | |
|---|---|---|---|
KeyError: 'x1' / '<joint>' from pandas | CSV column names do not match what the config implies | Regenerate headers per Step 2b — check measurable_dof and use exact URDF joint names | |
"<name> does not exist in the file" warning, then a crash | Same, caught one step earlier | Same fix | |
| Residuals huge (metres) but solver converged | Wrong base_pose/tool_pose guess, or marker attached to a different joint than reference_joint says | Fix the guesses; confirm the marker's parent joint | |
| Residuals fine, FK export check huge | tool_frame not the frame the markers actually measure | Set tool_frame to the real measured link | |
| Config/URDF "file not found" | Ran from repo root | cd examples/<robot>/ | |
package:// mesh errors | Wrong CWD, so ../../models misses | Same | |
| Validation metrics suspiciously equal to training | validation_data_file empty → documented fallback | Supply an independent CSV, or stop calling it validation | |
| Plot window blocks | Interactive backend | --no-plot or MPLBACKEND=Agg |
Anything not in this table: Re-run with --verbose/-v for INFO logging and work from the traceback; each repo's AGENTS.md lists the known gotchas.
Related
figaroh-setup-optimal generates the measurement configurations you should collect before acquiring calibration data. figaroh-setup-identification is the dynamics counterpart. Library-side changes belong in figaroh/src/figaroh/calibration/.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/figaroh-setup-calibration/SKILL.md
Popularity
- Repository stars
- 61
- Repository forks
- 8
- 7-day trend score
- 21
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/thanhndv212/figaroh-plus/figaroh-setup-calibration)