[isaacsim.robot_setup.sysid] System Identification Backend (Beta)#
Version: 2.2.3
Overview#
System Identification#
Beta: This extension is in beta. Its run contracts, exported run specifications, and APIs are not guaranteed to stay future compatible.
The isaacsim.robot_setup.sysid extension identifies robot simulation parameters from recorded motion. It provides the data contracts, telemetry ingestion, parameter models, optimizers, and simulator bridges used to reduce the difference between measured and simulated trajectories.
The extension is the headless backend for the interactive isaacsim.robot_setup.sysid.ui extension. Use the UI for guided identification in Isaac Sim, or use the Python API and command-line tools for repeatable and automated runs.
Headless integrations import run_sysid from isaacsim.robot_setup.sysid.execution and call
await run_sysid(spec, ...). The package root contains no dynamic exports; portable APIs are imported from
their owning modules without loading Kit. Isaac Sim stage, PhysX, and Fabric execution still requires a
bootstrapped Kit runtime. Newton execution can run in ordinary Python with the newton wheel dependencies
installed.
For a complete Kit-hosted lifecycle,
run_headless_sysid_job loads the stage and
telemetry, runs preflight and preparation, starts the timeline, and executes the solve without creating or
closing SimulationApp.
SysIdJobService serializes these jobs for automation clients that
reuse one headless Kit process through isaacsim.code_editor.python_server.
Local LeRobot-format telemetry#
PyArrow is not bundled while its third-party approval is pending. To use this optional loader, provide PyArrow 24.0.0 in the active environment. CSV, MCAP, and ROS bag ingestion do not require PyArrow.
The local dataset must contain meta/info.json and Parquet files under data/. Joint positions must use a
recognized signal such as observation.state or observation.qpos; SysID does not guess joint state from
unrelated numeric columns. The dataset’s own license and usage terms remain the user’s responsibility.
load_trajectoryloads CSV, ROS 2 bag, MCAP, or LeRobot telemetry into the common trajectory model.build_sysid_check_reportchecks telemetry quality and parameter identifiability before optimization.build_parameter_confidence_reportestimates how strongly the final data constrains each identified parameter.
Trajectory ingestion and quality checks#
Use TrajectoryLoadConfig with load_trajectory to select CSV, MCAP, ROS 2 bag, or local LeRobot
ingestion. CSV sources can use an explicit column map or the compact built-in layout. MCAP and ROS 2
bag sources require a JSON or YAML topic map. Topic-based loaders align optional channels to position
timestamps using bounded nearest-neighbor matching and record alignment diagnostics in trajectory
provenance.
When a topic map explicitly names a command channel, that channel must decode and align successfully. The loader reports an error instead of substituting measured positions. Position-only sources may omit command mapping and intentionally use positions as the command fallback.
Nearby phase-event and collection-manifest files can supply train and validation chunks when their timestamps overlap the loaded trajectory. Unrelated or stale event logs are ignored rather than rebased onto a recording. Preflight and telemetry-quality reports validate channel shapes, finiteness, strictly increasing timestamps, chunk coverage, excitation, and command alignment.
Analytical presolve and checks#
For fixed-base robots, the optional analytical presolve builds a compact USD-derived recursive Newton-Euler model and uses torque-domain least squares to seed supported parameters. Joint context must be ordered from base to tip, USD joint bodies must resolve unambiguously, the active regressor must be full rank and well conditioned, and unconstrained solutions must remain inside the configured parameter bounds. If any gate fails, the original seed is retained and the check report explains why.
Torque telemetry must declare torque_semantics explicitly as link_side or external.
Only link-side transmitted joint torque is used for inertial and friction seeding. External or
unspecified torque channels are excluded rather than guessed.
The pre-solve check report combines telemetry quality with per-parameter identifiability and
uses unknown when a stage or compatible analytical equation is unavailable. Unknown verdicts
do not produce an ok result. The run report records configuration, optimizer status, validation
metrics and artifacts, delay quantization, tuning assessment, and parameter sensitivity. The
reported sens. span is the parameter offset associated with a 10% modeled cost rise; it is not
a statistical confidence interval.
Both reports have versioned JSON schemas under resources/schemas/.
Recipes and validation artifacts#
Bundled recipes configure parameter families, solver settings, chunking, and compatible residual channels for common robot classes. Changing parameter-space flags clears an existing selection so stale parameter rows cannot survive a recipe change. Optional validation artifacts include position, velocity, effort, and angle-delta plots, RMSE summaries, and a trajectory animation or storyboard. Generated artifact paths are contained beneath the configured artifact directory.
Importing the package root does not require Kit or Carbonite. Kit-dependent services are imported only when their adapters are called, preserving use from standalone Python and wheel builds.
Getting started with a new robot#
Optimization and simulation#
ParameterSpacemaps bounded optimizer variables to physical robot parameters.create_optimizerprovides Levenberg-Marquardt, CMA-ES, Bayesian, and Adam gradient-descent backends.IsaacSimSysIdBridgeevaluates candidates in an Isaac Sim-hosted rollout.NewtonSysIdBridgeandNewtonDifferentiableSysIdBridgeprovide standalone Newton rollout paths.
Importing contracts and portable helpers does not bootstrap Kit, USD, or a simulator. Isaac Sim rollouts still require a bootstrapped Kit runtime.
Interactive workflow#
Enable isaacsim.robot_setup.sysid.ui, then open Tools > Robotics > Asset Editors > System Identification. The UI guides you through six stages:
Robot selects the articulation, physics engine, and actuator runtime.
Data loads telemetry and defines training and validation chunks.
Parameters selects the values and bounds to optimize.
Check evaluates data quality and identifiability before spending rollout time.
Solve configures and runs the optimizer.
Results compares parameter values, residuals, confidence ranges, and held-out validation metrics.
Start with a built-in recipe when possible. Recipes pre-fill the workflow for common robot classes while leaving every setting editable.
Headless quick start#
Synthesize a complete run specification from a robot, telemetry source, and recipe. The tools ship
with the extension under its tools/ directory and run through the Isaac Sim Python launcher
(python.sh on Linux, python.bat on Windows):
./python.sh tools/headless_sysid_solve.py --robot /World/Robot --telemetry data.csv --recipe drive_calibration_inair --stage robot.usd
The command synthesizes a complete run spec (saved next to the results for later editing), prints the
pre-solve check, and runs the solve. The UI follows a gated pipeline — Robot → Data →
Parameters → Check → Solve → Results: the Check stage validates telemetry quality and
per-parameter identifiability before any rollouts are spent, and the Run button requires a
fresh check. After a solve, the Results panel reports each identified value with a sensitivity
range and a verdict (well/weakly constrained) so you can tell which parameters to trust.
Quick-start parallel cloning is disabled unless --source-env identifies a cloneable environment
prim such as /World/envs/env_0.
Filesystem paths stored in a RunSpec are portable: relative stage, telemetry, mapping, manifest, and output paths resolve from the directory containing the RunSpec JSON file, independent of the shell’s working directory. Absolute paths and asset URLs are preserved by both the command-line tools and persistent job service.
Persistent headless jobs#
Launch one headless Kit process with isaacsim.code_editor.python_server and this backend enabled. Remote
clients submit a JSON-safe
SysIdServiceJobRequest through
submit_sysid_job, then use
get_sysid_job_status or
cancel_sysid_job. The singleton service runs one trial at
a time because the USD context, timeline, and active physics engine are process-wide. By default it stops
simulation and creates a clean empty stage after each terminal job.
The Python server is a trusted-code interface, not an authentication or sandbox boundary. Its process-wide
job service rejects all filesystem-backed requests until the host calls
get_sysid_job_service(allowed_roots=["C:/trusted/sysid"]) before the first submission. Every request,
run-spec, telemetry, stage, mapping, provenance, animation, and result path that addresses the local filesystem
must resolve beneath one of those roots; paths escaping through .., symlinks, or file:// URLs are rejected.
Keep the server bound to trusted clients and grant the Kit process only the filesystem permissions it needs.
The standalone tools/headless_sysid_solve.py command uses the same public headless job API while continuing
to own SimulationApp only at its outer process boundary.
Fast offline PhysX stepping#
Isaac Sim rollouts default to simulation.offline_stepping = true. In this mode the bridge advances PhysX
directly with SimulationManager.step() and does not render or pump a complete Kit frame for every physics
step. If the timeline is stopped, the bridge starts it long enough to initialize physics automatically. The
bridge then pauses timeline-driven updates before calling SimulationManager.step() so physics has exactly
one step owner. Set offline_stepping to false to use the timeline-driven path for interactive playback
and debugging.
Physics backend and actuator compatibility#
The rollout host, physics backend, and actuator implementation are independent run-spec axes.
simulation.engine selects isaac_sim or standalone newton; simulation.physics_backend
selects auto, physx, or newton; and simulation.actuator_runtime selects auto,
implicit_drive, newton_explicit, or mixed. Isaac Sim + Newton requires the optional
isaacsim.physics.newton extension and switches through SimulationManager, while standalone
Newton uses the Newton 1.5 dependency set declared by the newton package extra.
For standalone Newton, mixed is the recommended actuator mode. Existing USD Newton actuator prims own only their
target joints; the remaining joints continue to use implicit USD drives. Stateful parameters
such as PID integral gain and actuator_command_delay_seconds can promote only the selected joints into temporary
session-layer actuator prims by setting explicit_actuator_policy to promote_selected.
Promotion is non-destructive during a run. Accepted results are copied to the root layer only
when actuator writeback is requested; cancellation or cleanup discards the session edits.
Telemetry timing correction is a separate operation. telemetry.command_alignment_seconds
shifts the imported command series once to remove common recording/transport offset. The actuator
parameter is per-DOF plant behavior, is applied once inside the explicit actuator during rollout,
and is persisted as integer newton:delaySteps.
Supported mutable explicit actuator schemas include PD, PID, physics-step delay, maximum-effort and DC-motor clamping. Standalone Newton can execute already-authored neural controllers, but they are not mutable SysID parameter targets; the Isaac Sim compatibility adapter rejects them. Position clamping is also rejected because this extension does not yet expose a compatible optimization contract. A joint has exactly one control owner: explicit joints have their native drive gains disabled for the rollout, while all other joints retain their authored drive behavior.
Example run-spec fragment:
{
"simulation": {
"engine": "isaac_sim",
"physics_backend": "newton",
"actuator_runtime": "mixed",
"explicit_actuator_policy": "promote_selected"
},
"parameters": {
"space": {
"include_basic": true,
"include_command_delay": true
}
}
}
Newton MuJoCo CUDA graph capture#
Standalone Newton MuJoCo rollouts enable simulation.newton.cuda_graph_capture by default on CUDA devices.
The first rollout for a fixed trajectory and population shape runs uncaptured to compile kernels and allocate
solver storage. The bridge then captures that shape and reuses the graph for later optimizer evaluations.
Capture failures are reported and fall back to the uncaptured path; CPU execution is unchanged.
Each captured and uncaptured rollout starts by resetting MuJoCo’s rollout-local acceleration warm-start, actuator-activation, applied-force, and control buffers before restoring the requested initial joint state. This prevents solver history from a preceding candidate batch from changing the next rollout. Captured and uncaptured CUDA results should be compared with numerical tolerances rather than bitwise equality because GPU kernel execution can still introduce small floating-point differences.
Graph replay is intended for repeated, fixed-shape population evaluations. In a reference Franka run with
16 candidates and 800 steps, replay reduced median evaluation time from 13.59 seconds uncaptured to 0.515
seconds captured, a 26.4x speedup after warmup. Treat this result as workload- and hardware-specific rather
than a guaranteed ratio. Set simulation.newton.cuda_graph_capture to false when diagnosing an individual
rollout or when capture setup cannot be amortized.
Differentiable Newton bridge (contact-free)#
Setting simulation.newton.solver = "featherstone_diff" in the run spec selects a
differentiable Newton bridge that rolls trajectories with SolverFeatherstone recorded on a
Warp tape. Rollout costs then backpropagate to the parameters, and the gradient_descent
(Adam) optimizer backend — chosen automatically in auto mode — obtains the exact gradient of
all selected parameters from a single backward pass per iteration. This makes high-dimensional
identification (per-link mass via parameters.space.include_per_link_mass, per-link CoM
offsets, and log-Cholesky inertia) tractable where finite differences are not.
The bridge is contact-free by construction (no contact solve is executed): record trajectories
with the robot fixed-based or in the air, following the PACE identification protocol
(arXiv:2509.06342). Supported parameters are joint friction/stiffness/damping, link mass, CoM
offsets, and log-Cholesky inertia; joint_armature, actuator_command_delay_seconds, integral gains,
and joint-limit scales are rejected with a pointer to the MuJoCo Newton
bridge or the derivative-free backends. Each taped substep owns its Featherstone
factorization workspace, so the mass matrix is rebuilt at the current configuration without
overwriting values required by the reverse pass. Mapped-joint PD, feedforward, friction, and
maximum-effort limiting are evaluated together, and the reported torque is the torque applied
to the simulated plant.
Enable Extension#
The extension can be enabled (if not already) in one of the following ways:
Define the next entry as an application argument from a terminal.
APP_SCRIPT.(sh|bat) --enable isaacsim.robot_setup.sysid
Define the next entry under [dependencies] in an experience (.kit) file or an extension configuration (extension.toml) file.
[dependencies]
"isaacsim.robot_setup.sysid" = {}
Open the Window > Extensions menu in a running application instance and search for isaacsim.robot_setup.sysid.
Then, toggle the enable control button if it is not already active.