Compact guidance for OpenCode sessions working in this repo. Read before editing. Every line here is something an agent would likely get wrong without it.
FIGAROH — Python toolbox for robot/human dynamics identification and geometric
calibration, URDF-based, built on Pinocchio. Published to PyPI as figaroh (0.4.3).
Forked from the LAAS gitlab repo. Examples and robot models live in a separate
repo (figaroh-examples) and are excluded from this package's sdist.
- Core dev install:
pip install -e .(src layout, hatchling backend). Required before anyimport figarohworks. - Need IPOPT? Use conda:
conda env create -f environment.ymlthenconda activate figaroh-dev. This is the only supported way to getcyipopt(Python 3.12, conda-forge), whichfigaroh.optimal/tools/robotipopt.pyrequire for trajectory optimization.cyipoptis not pip-installable in practice — that is the whole reason the conda env exists. requires-python >= 3.8, but the dev/conda env pins 3.12.
- Tests:
pytestfrom repo root. There is no pytest config (no[tool.pytest], nopytest.ini/setup.cfg/tox.ini) — defaults apply and discovery picks uptests/.- Single file:
pytest tests/unit/test_solver.py - Single test:
pytest tests/unit/test_solver.py::TestLinearSolver::test_name - Shared fixtures in
tests/conftest.py:temp_urdf,sample_robot_data,regressor_params. - Tests import submodules directly, e.g.
from figaroh.tools.solver import LinearSolver. Tests needing Pinocchio/meshcat/robot models (collisions, ipopt, visualization) will fail or skip without those deps + model files.
- Single file:
- Lint/format:
pre-commit run --all-files— this is the real quality gate. - Docs:
cd docs && make html(Sphinx).
- CI (
.github/workflows/docs.yml) only builds docs on push/PR tomain. There is no test or lint CI workflow — do not assume CI will catch type/test errors. - Pre-commit hooks:
flake8(ignores E501 line length),clang-format --style=Google,trailing-whitespace,check-yaml,check-ast,check-merge-conflict,check-added-large-files(100 MB, excludesmodels/). pre-commitci.autoupdate_branchisdevel→develis the dev branch,mainis the release branch. PRs targetmain.
ARCHITECTURE.md is partly aspirational and out of date. Verify against the actual tree:
- The "Pinocchio backend" does not exist as a backend module.
src/figaroh/backends/contains onlybase.py(abstractDynamicsBackend) andmujoco.py.backends/__init__.pytries to importpinocchio.py,genesis.py,isaacsim.py— those files do not exist, so the imports silently fail andget_backend("pinocchio")raisesValueError: ... not available. Ignore ARCHITECTURE.md's "✅ Implemented (Default)" claim for PinocchioBackend. - Pinocchio is used directly, imported as
import pinocchio as pinthroughouttools/,calibration/,identification/(e.g.pin.computeJointTorqueRegressor,RobotWrapper). It is not routed through the backend abstraction. - Real
tools/filenames (ARCHITECTURE.md gets some wrong):qrdecomposition.py(notqr_decomposer.py),robotcollisions.py,robotipopt.py,robotvisualization.py,randomdata.py,load_robot.py,regressor.py,robot.py,solver.py. tools/__init__.pyeagerly importsrobot, randomdata, regressor, qrdecomposition, robotvisualization, robotcollisions, robotipopt— but notsolverorload_robot. Import those by full path (figaroh.tools.solver).figaroh/__init__.pyeagerly imports all subpackages, soimport figarohpulls Pinocchio immediately.
- Workflow (
calibration/,identification/,optimal/) —Base*abstract classes; users subclass and implementcost_functionetc. - Tools (
tools/) —RegressorBuilder,LinearSolver(10+ methods: lstsq, qr, svd, ridge, lasso, elastic_net, tikhonov, constrained, robust, weighted),QRDecomposer,CollisionManager,RobotIPOPTSolver. - Backends (
backends/) — abstractDynamicsBackend; only MuJoCo implemented. Treat as WIP.
- Inertial parameter ordering differs between Pinocchio
(
[m, mx, my, mz, Ixx, Ixy, Iyy, Ixz, Iyz, Izz]) and the "standard" format used by solvers. Usereorder_inertial_parametersinidentification/parameter.py— do not hand-roll the permutation. - Physical consistency (SDP projection) is optional and default-off. Enable via
identification.physical_consistency.enabled: true. Needspicos+ an SDP solver (e.g.cvxopt). - Config: YAML with template inheritance via
utils.UnifiedConfigParser; legacy formats are auto-detected. - Logging: library uses the NullHandler pattern — do not add
printor root logging in library code. .github/skills/andROADMAP_PRIVATE.mdare gitignored — local-only, not shipped. Do not treat them as committed repo content.
Docs here live in several places that don't auto-sync: README.md,
CHANGELOG.md, ARCHITECTURE.md, ROADMAP.md, docs/decisions/ (design
rationale, not built into the site), docs/source/ (the built MkDocs site).
A change in one often leaves another stale — a renamed/merged decision doc
breaks links elsewhere; a shipped feature leaves ROADMAP.md's status
marker wrong. Before git push:
- Grep for stale references to anything renamed/moved/merged this session:
grep -rln "<old-name>" docs/ CHANGELOG.md README.md ARCHITECTURE.md ROADMAP.md. - Add a
CHANGELOG.md[Unreleased]entry — this project logs doc-only reorganizations too (git log --grep "^docs"for precedent), not just code. - If a
ROADMAP.md-tracked item's status changed, fix its marker rather than leaving it stale. See thefigaroh-devopsskill's "Pre-Push Documentation Sync" section for the full checklist; its "Release Procedure" is the separate, heavier version-bump case.