Skip to content

Latest commit

 

History

History
96 lines (74 loc) · 3.96 KB

File metadata and controls

96 lines (74 loc) · 3.96 KB

System Identification Toolbox

Open In Colab

Given a MuJoCo model and recorded sensor data, find parameters that make simulation match reality. By default, the library uses nonlinear least-squares with box constraints to minimize the difference between measured and simulated (predicted) outputs. Residuals can be modified by static or optimized parameters, such as weights and time-delays.

The optimizer uses Gauss-Newton with finite-difference Jacobians. Each parameter perturbation requires an independent simulation rollout. All of them execute in a single batched call to mujoco.rollout, parallelized across threads.

Pipeline

You provide:

  • One or more ModelSequences each bundling a single MjSpec with one or more sequences of measured data. All will be optimized jointly.
  • A ParameterDict defining differentiable Parameters with bounds.
  • Callbacks to apply Parameters to an MjSpec (individually or jointly)
  • (optional) Functions (build_model, custom_rollout, modify_residual) that override the default residual function behavior.

The framework:

  • Composes user code into a residual function (build_residual_fn).
  • Optimizes parameters via batched parallel rollouts (optimize).
  • Saves results and generates an HTML report (save_results, default_report).

What Can You Identify?

You can optimize any parameter that differentiably modifies the final residuals. Common use cases include:

Physics parameters settable on MjSpec. Most parameters in MjSpec can be easily set directly by user-provided callbacks:

Target Approach
Contact sliding friction spec.pair("cp").friction[0] = p.value[0]
Joint damping spec.joint("j1").damping = p.value[0]

Convenience functions are provided for common system identification parameterizations that cannot be trivially applied to an MjSpec:

Target Approach
Body mass body_inertia_param(..., InertiaType.Mass)
Body mass + center of mass body_inertia_param(..., InertiaType.MassIpos)
Full inertia (10-D) body_inertia_param(..., InertiaType.Pseudo)
Actuator P/D gains apply_pdgain(spec, "act1", p.value)

Full inertia uses the pseudo-inertia Cholesky parameterization (Rucker & Wensing 2022), guaranteeing physical consistency without singularities.

Measurement parameters such as sensor delays, gains, and biases are properties of the measurement system, not the physics model. The library provides utilities for applying these corrections to the residual after rollout. They are functionally complete but their API is not yet final.

Example

import mujoco
from mujoco import sysid

# 1. Load model and define parameters.
spec = mujoco.MjSpec.from_file("robot.xml")
model = spec.compile()

def set_link1_mass(spec, p):
    spec.body("link1").mass = p.value[0]

params = sysid.ParameterDict()
params.add(sysid.Parameter(
    "link1_mass", nominal=2.0, min_value=0.5, max_value=5.0,
    modifier=set_link1_mass))

# 2. Load and package measured data.
# arrays assumed to be in MuJoCo order, otherwise pass names argument
control = sysid.TimeSeries.from_control_names(times, ctrl_array, model)
measureddata = sysid.TimeSeries.from_names(times, measurement_array, model)
initial_state = sysid.create_initial_state(model, qpos_0, qvel_0)
ms = sysid.ModelSequences("robot", spec, "traj_1", initial_state, control, measureddata)

# 3. Build residual, optimize, save.
residual_fn = sysid.build_residual_fn(models_sequences=[ms])
opt_params, opt_result = sysid.optimize(initial_params=params, residual_fn=residual_fn)
sysid.save_results("results/", [ms], params, opt_params, opt_result, residual_fn)

default_report generates an interactive HTML report with videos, measurement comparisons, parameter tables, and confidence intervals.