Skip to content

Commit 3ec09f7

Browse files
Merge pull request #3079 from aftersomemath:sysid-pr
PiperOrigin-RevId: 868229512 Change-Id: I790bc08fc8b0745583a2f92d9ee2c5a19ba558ea
2 parents 3c107b3 + a1f2b87 commit 3ec09f7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+11554
-0
lines changed

python/build_requirements.txt

Lines changed: 687 additions & 0 deletions
Large diffs are not rendered by default.

python/mujoco/sysid/README.md

Lines changed: 637 additions & 0 deletions
Large diffs are not rendered by default.

python/mujoco/sysid/__init__.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Copyright 2026 DeepMind Technologies Limited
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
# ==============================================================================
15+
"""Practical system identification for MuJoCo."""
16+
17+
from mujoco.sysid._src import model_modifier
18+
from mujoco.sysid._src import parameter
19+
from mujoco.sysid._src import plotting
20+
from mujoco.sysid._src import signal_modifier
21+
from mujoco.sysid._src.io import save_results
22+
from mujoco.sysid._src.model_modifier import apply_body_inertia
23+
from mujoco.sysid._src.model_modifier import apply_dgain
24+
from mujoco.sysid._src.model_modifier import apply_param_modifiers
25+
from mujoco.sysid._src.model_modifier import apply_param_modifiers_spec
26+
from mujoco.sysid._src.model_modifier import apply_pdgain
27+
from mujoco.sysid._src.model_modifier import apply_pgain
28+
from mujoco.sysid._src.model_modifier import body_inertia_param
29+
from mujoco.sysid._src.model_modifier import remove_visuals
30+
from mujoco.sysid._src.optimize import calculate_intervals
31+
from mujoco.sysid._src.optimize import optimize
32+
from mujoco.sysid._src.parameter import InertiaType
33+
from mujoco.sysid._src.parameter import Parameter
34+
from mujoco.sysid._src.parameter import ParameterDict
35+
from mujoco.sysid._src.plotting import plot_sensor_comparison
36+
from mujoco.sysid._src.plotting import render_rollout
37+
from mujoco.sysid._src.residual import build_residual_fn
38+
from mujoco.sysid._src.residual import BuildModelFn
39+
from mujoco.sysid._src.residual import construct_ts_from_defaults
40+
from mujoco.sysid._src.residual import CustomRolloutFn
41+
from mujoco.sysid._src.residual import model_residual
42+
from mujoco.sysid._src.residual import ModifyResidualFn
43+
from mujoco.sysid._src.residual import residual
44+
from mujoco.sysid._src.signal_modifier import apply_bias
45+
from mujoco.sysid._src.signal_modifier import apply_delay
46+
from mujoco.sysid._src.signal_modifier import apply_delayed_ts_window
47+
from mujoco.sysid._src.signal_modifier import apply_gain
48+
from mujoco.sysid._src.signal_modifier import apply_resample_and_delay
49+
from mujoco.sysid._src.signal_modifier import get_sensor_indices
50+
from mujoco.sysid._src.signal_modifier import normalize_residual
51+
from mujoco.sysid._src.signal_modifier import weighted_diff
52+
from mujoco.sysid._src.signal_transform import SignalTransform
53+
from mujoco.sysid._src.timeseries import SignalType
54+
from mujoco.sysid._src.timeseries import TimeSeries
55+
from mujoco.sysid._src.trajectory import create_initial_state
56+
from mujoco.sysid._src.trajectory import ModelSequences
57+
from mujoco.sysid._src.trajectory import sysid_rollout
58+
from mujoco.sysid._src.trajectory import SystemTrajectory
59+
from mujoco.sysid.report.defaults import default_report
60+
from mujoco.sysid.report.defaults import default_report_matplotlib
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2026 DeepMind Technologies Limited
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
# ==============================================================================
15+

python/mujoco/sysid/_src/io.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Copyright 2026 DeepMind Technologies Limited
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
# ==============================================================================
15+
16+
"""I/O utilities for saving system identification results."""
17+
18+
from collections.abc import Sequence
19+
import os
20+
import pathlib
21+
import pickle
22+
23+
from absl import logging
24+
from mujoco.sysid._src import parameter
25+
from mujoco.sysid._src.optimize import calculate_intervals
26+
from mujoco.sysid._src.trajectory import ModelSequences
27+
import scipy.optimize as scipy_optimize
28+
29+
30+
def save_results(
31+
experiment_results_folder: str | os.PathLike[str],
32+
models_sequences: Sequence[ModelSequences],
33+
initial_params: parameter.ParameterDict,
34+
opt_params: parameter.ParameterDict,
35+
opt_result: scipy_optimize.OptimizeResult,
36+
residual_fn,
37+
):
38+
"""Save optimization results and confidence intervals to disk."""
39+
experiment_results_folder = pathlib.Path(experiment_results_folder)
40+
if not experiment_results_folder.exists():
41+
experiment_results_folder.mkdir(parents=True, exist_ok=True)
42+
logging.info(
43+
"Experiment results will be saved to %s", experiment_results_folder
44+
)
45+
46+
initial_params.save_to_disk(experiment_results_folder / "params_x_0.yaml")
47+
opt_params.save_to_disk(experiment_results_folder / "params_x_hat.yaml")
48+
49+
with open(
50+
os.path.join(experiment_results_folder, "results.pkl"), "wb"
51+
) as handle:
52+
pickle.dump(opt_result, handle, protocol=pickle.HIGHEST_PROTOCOL)
53+
54+
# TODO(b/0): these intervals should be part of the params object.
55+
residuals_star, _, _ = residual_fn(
56+
opt_result.x, opt_params, return_pred_all=True
57+
)
58+
covariance, intervals = calculate_intervals(residuals_star, opt_result.jac)
59+
with open(
60+
os.path.join(experiment_results_folder, "confidence.pkl"), "wb"
61+
) as handle:
62+
pickle.dump(
63+
{"cov": covariance, "intervals": intervals},
64+
handle,
65+
protocol=pickle.HIGHEST_PROTOCOL,
66+
)
67+
68+
# Dump identified models to disk.
69+
for model_sequences in models_sequences:
70+
model_sequences.spec.to_file(
71+
(experiment_results_folder / f"{model_sequences.name}.xml").as_posix()
72+
)
73+
74+
# Log nominal compared to initial.
75+
x0 = initial_params.as_vector()
76+
x_nominal = initial_params.as_nominal_vector()
77+
logging.info(
78+
"Initial Parameters\n%s",
79+
initial_params.compare_parameters(
80+
x0, opt_result.x, measured_params=x_nominal
81+
),
82+
)

0 commit comments

Comments
 (0)