Architecture¶
The canonical architecture document lives at the repository root
(ARCHITECTURE.md)
so it stays next to the source tree it describes. This page embeds it
directly so the same content is browsable as part of the docs site,
without a second copy to keep in sync.
FIGAROH Architecture¶
Source audit: 2026-09-28. This document describes the current source tree.
Future capabilities belong in the roadmap and
design decisions. The docs site embeds this file;
API details are generated from docstrings under docs/source/api/.
System boundaries¶
FIGAROH is a Python library for dynamic identification, geometric calibration
and experiment design. The installable package is src/figaroh/; robot-specific
scripts, datasets and models live in the separate
figaroh-examples repository.
The principal user entry points are subclasses of BaseIdentification,
BaseCalibration, BaseOptimalTrajectory and BaseOptimalCalibration.
RobotIdentificationSystem provides a smaller CSV/URDF identification wrapper.
The source currently imports several subpackages eagerly, so installing only a
single numerical dependency is not sufficient to import the package.
Robot-specific script + YAML + measurements + URDF
|
Workflow classes / integration wrapper
|
Regressors, solvers, robot model, result processing
|
Backend-aware operations + direct Pinocchio use
|
Identified/calibrated results
|
Verification / reports / archives / explicit export
Module responsibilities¶
| Module | Owns | Reference |
|---|---|---|
calibration/ |
Config, measured poses, kinematic residuals, fitting and validation | BaseCalibration |
identification/ |
Signal processing, dynamic regressors, identifiable parameters, optional physical projection/reconstruction | BaseIdentification |
optimal/ |
Excitation trajectories and calibration posture selection | trajectory workflow, configuration workflow |
backends/ |
Common dynamics operations and Pinocchio/MuJoCo implementations | DynamicsBackend |
tools/ |
Robot loading, QR/linear solvers, collisions, export, reports and archives | Robot, regressor, QR |
utils/ |
Config inheritance/migration, result handling and error types | config parser, results |
integration/ |
Convenience wrapper around the identification workflow | API |
measurements/, visualisation/ |
Measurement and viewer utilities | Generated API reference |
Generic algorithms stay in core; robot paths, data conventions and experiment recipes stay in examples. A change spanning both repos records the tested revision pair and expected core dependency in the examples PR.
Backend boundary¶
- PinocchioBackend exists and implements
dynamics/kinematics operations.
Robot.backendlazily wraps the robot's current Pinocchio model and data throughPinocchioBackend.from_model(). - MuJoCoBackend exists. Its analytical regressor delegates to a Pinocchio model loaded from the model path; its Coriolis matrix uses a finite-difference construction. A MuJoCo operation being available does not imply the complete identification/calibration workflow is portable.
- Regressor construction and several calibration helpers use a backend when provided. Direct Pinocchio model/frame/inertia operations remain, especially model mutation during calibration and visualization/collision integration.
- Genesis and IsaacSim implementations are absent. They are roadmap proposals.
RobotIdentificationSystem.from_mjcf()raisesNotImplementedError.from_urdf(backend=...)loads the usual Robot and stores the requested name; that name alone does not switch the robot's executing backend. Treat the convenience identification path as Pinocchio/URDF-based until selection is implemented and verified.
Backend and cross-backend tests live in
test_backends.py and
test_cross_backend.py.
Optional dependency skips are reported as missing coverage.
Identification data flow¶
- Load the robot and YAML configuration. A subclass supplies trajectory data; the convenience wrapper reads position, velocity, acceleration and torque CSVs.
- Process signals and build configurations, then construct the dynamic regressor and the nominal CAD reference torque.
- Eliminate zero columns, optionally decimate, and use QR to obtain an identifiable parameter basis. Solve and compute fitting metrics.
- Apply configured weighting, physical-consistency projection and reconstruction where enabled. These are distinct result stages.
- Evaluate validation data when available, generate verification/report output, and explicitly choose the result stage to export or archive.
Important contracts:
- Joint order, units and the provenance of torque measurements belong to the data boundary. The convenience CSV loader creates sample-index timestamps; it is not a universal timestamped log-ingestion API.
- Regressor rows are joint-major. Enabled friction, actuator-inertia and offset blocks must match parameter key order; see the identification regressions.
- Pinocchio's dynamic parameter order is
[m, mx, my, mz, Ixx, Ixy, Iyy, Ixz, Iyz, Izz]; FIGAROH's standard ordering differs. Use the conversion helpers inidentification/parameter.py. - Projection is default-off.
result["physical consistency"]records status, feasibility information, and, after projection,raw_parametersandprojected_parameters. Reconstruction has its ownresult["reconstruction"]. Callers must not equate a fitted base vector with a complete physical model. - Unified signal-processing settings feed the filter parameters; explicit filter
overrides take precedence.
qr_relative_toleranceis optional, preserving the default rank-selection behavior when unset.
Calibration and experiment design¶
Calibration fits geometric parameters through the workflow and helpers in
calibration/. Model edits still use Pinocchio types. A held-out measurement
comparison assesses fit quality; an exported-model FK consistency check assesses
whether a file represents the intended calibrated model. They answer different
questions and are reported separately.
Optimal trajectory generation uses the IPOPT wrapper in
tools/robotipopt.py. Calibration posture
selection lives in BaseOptimalCalibration. Both provide result saving;
a common report format across every optimal workflow remains roadmap work.
Use the figaroh-dev conda environment for development, including cyipopt.
Physical projection is opt-in at runtime, although picos is currently a
package dependency in pyproject.toml.
Export and reporting¶
tools/urdf_exporter.py maps parameter names
to update handlers. Joint placement/offset, mass, friction, armature and elasticity
handlers exist. Identified inertial parameters are written as complete per-link
sets (#60): inputs follow Pinocchio toDynamicParameters() order, with first
moments and inertia about the link-frame origin. The exporter writes the CoM
origin and the CoM-frame tensor, keeping an existing inertial rotation. A link
target or a moving joint (resolved to its child link) is accepted. Targets
with massive links attached by fixed joints (merged by Pinocchio), partial
sets and m <= 0 are refused; physically infeasible sets are refused unless
allow_infeasible=True. Tests check
reloaded-model RNEA parity against known feasible inputs; round-trip parity
shows file consistency, not hardware accuracy.
Metrology base/measurement-frame parameters are described for the caller instead
of automatically applied to robot geometry. PAL runtime correction YAML uses
geometric_calibration_export.py.
Calibration and identification HTML reports, two-run comparison, provenance and
run archives live in tools/; workflow verification methods attach verdicts to
results. Example CLIs explicitly verify numerical execution; library verification defaults
to prediction acceptance. Independent prediction
acceptance requires explicit per-output error limits and separate validation.
Physical/export and general acquisition-provenance certification remain separate;
missing required evidence is not a successful check. Use the reporting and verification guide
for user-facing behavior. Store metrics with the model/config/data provenance;
report whether validation is held-out, training-only, simulated or physical.
Configuration and extension rules¶
UnifiedConfigParser supports YAML inheritance. The workflow-specific config
adapters translate unified task config into internal dictionaries; the legacy
flat config was removed in 1.0 and raises an error naming the migration command. The
configuration reference owns the schema.
For a new interface, dependency, result schema or module boundary, add a decision
record first or in the same PR. Proposed ResidualTerm/LinearRegressorTerm,
full MJCF workflows and deployment/control layers are not current API contracts.
For a new backend, implement the supported operations, document unsupported ones,
and add numerical comparisons before claiming workflow parity.
The contribution workflow owns branch/release policy; the validation guide owns commands and evidence requirements. Keep numerical claims linked to tests or archived runs and update this overview when boundaries or result contracts change.