Free dynamics Identification and Geometrical cAlibration of RObot and Human
FIGAROH is a Python toolbox for geometric calibration and dynamic parameter identification of rigid multi-body systems described by a URDF. It handles serial manipulators and tree-structured systems such as humanoids and mobile manipulators, and covers the whole loop: design the experiment, fit the parameters, validate them on held-out data, and export an updated model.
Start with the documentation: step-by-step workflow guides, a quickstart and setup for AI coding agents.
Install
pip install figaroh
Optimal trajectory generation also needs cyipopt, which is not
pip-installable. Use the conda environment for that, or for development:
git clone https://github.com/thanhndv212/figaroh-plus.git
cd figaroh-plus
conda env create -f environment.yml
conda activate figaroh-dev
pip install -e .
Quickstart
FIGAROH's workflow classes are subclassed once per robot. The figaroh-examples repository ships those subclasses, configs and data for each supported robot. The fastest way to see a complete run is its UR10 identification reference, which takes a few seconds:
git clone https://github.com/thanhndv212/figaroh-examples.git
cd figaroh-examples/examples/ur10
python identification_reference.py
It fits the UR10 dynamic parameters on a simulated training log, checks the
prediction error on a separate held-out log, computes a physically consistent
estimate, exports an identified URDF, and archives the run with its config,
revisions and an HTML report under results/runs/.
To use your own robot, follow the Getting Started guide and the Configuration System page; the examples repository has a new-example guide and a scaffold script.
What it does
Geometric calibration (figaroh.calibration) estimates joint offsets and
frame transforms from end-effector measurements: motion capture, cameras,
laser trackers, or contact with a plane when there is no external metrology.
Identifiable parameters are found by QR decomposition, and the fit is a
Levenberg–Marquardt solve with outlier removal.
Dynamic identification (figaroh.identification) fits masses, inertias,
friction and actuator inertia from joint positions and measured effort. A run
goes through up to three stages:
fit: base parameters by least squares, with optional weighted least squares and decimation. Base-parameter selection is deterministic across platforms.reconstruction: a full standard-parameter set recovered from the base fit.physical_fit: a direct LMI fit constrained to physically consistent inertias.
identification.select_stage chooses which stage is reported, validated and
exported; a requested stage that fails is rejected rather than replaced.
problem.torque_fit_joints restricts the fit to the joints whose effort you
trust.
Optimal experiment design (figaroh.optimal) selects well-conditioned
calibration postures and generates exciting identification trajectories
(cubic splines optimised with IPOPT under joint, velocity, torque and collision
limits).
Reporting and verification. Every run can write a self-contained HTML
report (solve(html_report=True)) and a machine-readable verdict
(verify()). The verdict states its scope: an execution PASS means the
numerics are sound, while a prediction PASS needs separate validation data
and per-joint limits that you declare. generate_compare_page() diffs two
archived runs offline. See
Reporting & Verification.
Backends. Pinocchio is the default dynamics backend; MuJoCo is available
as an optional backend (pip install mujoco). See
Backends.
Outputs
Both tasks write the result back into a copy of your URDF
(figaroh.tools.urdf_exporter.export_urdf), but they change different
parts of it:
| Written to the URDF | Not written to the URDF | |
|---|---|---|
| Calibration | Joint placements: corrected joint offsets and frame transforms | Metrology frames (base_*, pEE*, phiEE*): the pose of the measurement system and the marker or tool. These are returned separately; frame_settings_doc() explains them |
| Identification | Link mass, centre of mass and inertia, joint friction (BaseIdentification.export_urdf) |
The base-parameter fit, which has no per-link values: export needs select_stage: reconstruction or physical_fit |
The exporter refuses inertias that are not physically consistent unless you
pass allow_infeasible=True. Identification exports only an accepted
estimate and reloads the written URDF with Pinocchio as a check.
Every run can also write:
- the estimated parameters as YAML, CSV or NPZ (
save_results()); - a self-contained HTML report (
export_html_report()); - a JSON verdict with the scope, per-stage status and each check
(
export_verification_report()).
What's new in 1.1
- Calibration noise per measurement component:
estimation.noise_stdtakes one value per component, orper_componentto estimate them, and a calibrator can give the sensor frame the noise is fixed in (#215). - The
map,map_cv,excitationandcv_subsetestimation methods work with calibrators that measure something other than a pose, such as a table contact (#210). estimation.structural_selection: orderedmakes the selected parameter names independent ofrandom_seed(#204).- Fixes found by the calibration studies, several of which change results:
joint_offseton unaligned joints (#205), joint elasticity beyond simple chains (#206), the eye-hand camera anchor on a moving chain (#217), the base-frame rename (#204), the optimal-trajectory base columns (#218) andDetmax(#90). Read "Upgrading from 1.0" in the changelog.
The full list, including fixes and behaviour changes, is in the CHANGELOG.
Supported platforms
| Tested | |
|---|---|
| Python | 3.10, 3.12 and 3.14 (3.11 and 3.13 are supported but not tested) |
| Pinocchio | 3.7 (with ndcurves 2.0.0.1) and 4.1 (with ndcurves 2.3.0) |
| OS | Linux (CI), macOS (maintainer). Windows is not tested. |
Install Pinocchio and ndcurves together so their native libraries match. Other
versions within pin>=3.7,<5 may work but have no CI profile; see the
version support decision.
Documentation
| Documentation site | Guides, tutorials, configuration reference, API reference |
| Tutorials | Calibration, identification and optimal design walkthroughs |
| ARCHITECTURE.md | Package layout and design |
| CHANGELOG.md | Changes by release |
| ROADMAP.md | Planned work |
| CONTRIBUTING.md | Branches, review, validation and release process |
Working with an AI coding agent? skills/ holds agent skills
that set up a calibration, identification, optimal-design or new-robot task
end to end. Start with figaroh-start, which
routes to the right one, and figaroh-setup-env,
whose doctor.sh checks your environment first.
Citation
If you use FIGAROH in your research, please cite:
@inproceedings{nguyen2023figaroh,
title={FIGAROH: a Python toolbox for dynamic identification and geometric calibration of robots and humans},
author={Nguyen, Dinh Vinh Thanh and Bonnet, Vincent and Maxime, Sabbah and Gautier, Maxime and Fernbach, Pierre and others},
booktitle={IEEE-RAS International Conference on Humanoid Robots},
pages={1--8},
year={2023},
address={Austin, TX, United States},
doi={10.1109/Humanoids57100.2023.10375232},
url={https://hal.science/hal-04234676v2}
}
Related work
@inproceedings{nguyen2024improving,
title={Improving Operational Accuracy of a Mobile Manipulator by Modeling Geometric and Non-Geometric Parameters},
author={Nguyen, Thanh D. V. and Bonnet, V. and Fernbach, P. and Flayols, T. and Lamiraux, F.},
booktitle={2024 IEEE-RAS 23rd International Conference on Humanoid Robots (Humanoids)},
pages={965--972},
year={2024},
address={Nancy, France},
doi={10.1109/Humanoids58906.2024.10769790}
}
@techreport{nguyen2025humanoid,
title={Humanoid Robot Whole-body Geometric Calibration with Embedded Sensors and a Single Plane},
author={Nguyen, Thanh D V and Bonnet, Vincent and Fernbach, Pierre and Daney, David and Lamiraux, Florent},
year={2025},
institution={HAL},
url={https://hal.science/hal-05169055}
}
License
Apache License 2.0; see LICENSE.
FIGAROH started at LAAS-CNRS (original GitLab repository); this repository is its maintained continuation.
Metadata
Release files for figaroh 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| figaroh-1.1.0.tar.gz | 5.2 MB | Without provenance | Details for figaroh-1.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| figaroh-1.1.0-py3-none-any.whl | Python 3 | none | any | Details for figaroh-1.1.0-py3-none-any.whl |
Total release size: 5.6 MB
Release files / figaroh-1.1.0.tar.gz
| Download URL | figaroh-1.1.0.tar.gz |
|---|---|
| Size | 5.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2d5695c171dc197ac6e1cbaabc4f781cdbc90a4643bbb235076493ff07680fe5
|
|
BLAKE2b-256 checksum How to use checksums |
a5a883633f608fa18c45d494070889fc085fd353489c85bb887c25d8738940b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.11
|
Release files / figaroh-1.1.0-py3-none-any.whl
| Download URL | figaroh-1.1.0-py3-none-any.whl |
|---|---|
| Size | 357.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5bfa182ed680e151643f369087b34e01bfd192e9cde9f05c6ea7c2c2b455f80d
|
|
BLAKE2b-256 checksum How to use checksums |
9b7326e32d8417846c6cc8687973959ef94463ff5ceb8aae644c0084aafc85bd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.11
|
Security for figaroh 1.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.