Skip to content

Updates URDF/MJCF importer to use the latest Isaac Sim importer - #5394

Merged
kellyguo11 merged 12 commits into
isaac-sim:developfrom
stevfeng:dev/stevfeng/update_importers
May 15, 2026
Merged

kellyguo11 merged 12 commits into
isaac-sim:developfrom
stevfeng:dev/stevfeng/update_importers

Conversation

@stevfeng

Copy link
Copy Markdown
Contributor

Description

Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context.
List any dependencies that are required for this change.

In Isaac Sim, we have added more capabilities to handle joint presets, fixed joints, and other properties to the importers, so we can simplify the isaac lab importer workflow.

Fixes # (issue)

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (existing functionality will not work without user modification)
  • Documentation update

Screenshots

Please attach before and after screenshots of the change if applicable.

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with ./isaaclab.sh --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the changelog and the corresponding version in the extension's config/extension.toml file
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

@github-actions github-actions Bot added the isaac-lab Related to Isaac Lab team label Apr 24, 2026

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Isaac Lab Review Bot

Summary

This PR refactors the URDF and MJCF converters to delegate the full conversion pipeline to Isaac Sim's native importers (URDFImporter/URDFImporterConfig and MJCFImporter/MJCFImporterConfig). The PR removes ~750 lines of duplicated IsaacLab-specific post-processing code (fix-base insertion, joint drives, link density, ArticulationRootAPI relocation) and replaces it with a thin translation layer. The urdf_utils.py module is reduced to a re-export shim forwarding to the canonical Isaac Sim implementation.

Architecture Impact

High impact, well-contained. The changes affect the asset conversion pipeline which runs offline before simulation. The public API (UrdfConverterCfg, MjcfConverterCfg, merge_fixed_joints) is preserved. However:

  • Downstream callers using UrdfConverterCfg.collision_from_visuals will see a type annotation change (was missing, now bool)
  • Tests validate the new pipeline produces equivalent USD output
  • No runtime simulation impact — converters only affect USD generation

Implementation Verdict

Minor fixes needed. The refactor is architecturally sound, but there are a few issues with config field types, missing type annotations, and a potential test fragility.

Test Coverage

Good coverage. The test file has been updated and covers:

  • Config change detection for lazy conversion
  • Drive type/gains application (scalar and per-joint dict)
  • fix_base creates FixedJoint
  • merge_fixed_joints XML-level and full pipeline
  • Deprecated NaturalFrequencyGainsCfg warning
  • collision_from_visuals, self_collision, link_density

Missing: No test for ros_package_paths resolution with package:// URIs. This is a new config field without coverage.

CI Status

No CI checks available yet.

Findings

🔴 Critical: urdf_converter_cfg.py:174 — ros_package_paths type mismatch with Isaac Sim API

The config declares ros_package_paths: list[dict[str, str]] = [] and the docstring says "Each entry is a dictionary with keys name and path". However, in urdf_converter.py:96, it's passed as:

ros_package_paths=list(cfg.ros_package_paths),

The URDFImporterConfig.ros_package_paths in Isaac Sim may expect a different structure (likely list[tuple[str, str]] or a flat dict). Without verifying the Isaac Sim API contract, this could cause silent failures or exceptions when users actually try to resolve package:// URIs. The test suite does not exercise this path.

🟡 Warning: mjcf_converter_cfg.py:91-92 — override_gain_prm and override_bias_prm should validate length

The docstrings specify these are "10 floats" but there's no validation. If a user passes a list of wrong length, the error will surface deep in the Isaac Sim importer with a confusing message. Consider adding a validate_config hook:

def validate_config(self):
    if self.override_gain_prm is not None and len(self.override_gain_prm) != 10:
        raise ValueError("override_gain_prm must have exactly 10 elements")

🟡 Warning: urdf_converter.py:88-89 — collision_type literal values may not match Isaac Sim enum

The UrdfConverterCfg.collision_type accepts "Bounding Sphere" and "Bounding Cube" (with spaces), and this string is passed directly to URDFImporterConfig(collision_type=...). If the Isaac Sim importer expects different casing (e.g., "BoundingSphere") or an enum, this will fail. The test test_collider_type_convex_decomposition uses collider_type (which doesn't exist in the config — should be collision_type), so the test isn't actually validating this.

🔴 Critical: test_urdf_converter.py:622 — Test uses non-existent config field collider_type

config.collider_type = "convex_decomposition"  # WRONG: field is `collision_type`

This line sets a non-existent attribute. The test passes because the default collision_type="Convex Hull" is used. The test name and docstring claim to verify "Convex Decomposition" but it's actually testing "Convex Hull". Additionally, the value should be "Convex Decomposition" (with capitals and space) per the Literal type.

🟡 Warning: urdf_converter_cfg.py:171 — merge_mesh added but not forwarded to importer

In urdf_converter.py:_convert_asset, the config field merge_mesh is correctly forwarded. However, looking at the diff, this was an existing field that's now properly wired up. Good.

🔵 Improvement: urdf_utils.py — Missing fallback for Isaac Sim versions without the import

The module unconditionally imports from isaacsim.asset.importer.urdf.impl.urdf_utils. If a user has an older Isaac Sim version where this module doesn't exist, they'll get an ImportError at module load time. Consider a try/except with a clear error message:

try:
    from isaacsim.asset.importer.urdf.impl.urdf_utils import merge_fixed_joints
except ImportError as e:
    raise ImportError(
        "merge_fixed_joints requires Isaac Sim 4.5+ with the updated URDF importer"
    ) from e

🔵 Improvement: urdf_converter.py:153 — Deprecation warning for NaturalFrequencyGainsCfg should use warnings.warn consistently

The method uses warnings.warn with stacklevel=2, which is correct for showing the user's call site. However, the warning is only triggered inside _convert_asset → _warn_unsupported_features, meaning stacklevel=2 points to _convert_asset, not the user's UrdfConverter(cfg) call. Should be stacklevel=4 to trace through _warn_unsupported_features → _convert_asset → AssetConverterBase.__init__ → user code.

🔵 Improvement: CHANGELOG.rst:4 — Date is in the future (2026-04-24)

The changelog date appears to be a placeholder. Should be updated to the actual release date.

@greptile-apps

greptile-apps Bot commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR refactors the URDF and MJCF converters to delegate the full conversion pipeline to the latest Isaac Sim importers (URDFImporter / MJCFImporter), removing ~300 lines of duplicated IsaacLab-side USD post-processing and adding new config fields that mirror the expanded URDFImporterConfig / MJCFImporterConfig options.

  • P1 — silent breakage of per-joint drive configs: JointDriveCfg.drive_type, target_type, gains.stiffness, and gains.damping all accept dict[str, ...] for per-joint regex overrides (a documented, previously-working feature). _unpack_joint_drive passes those dicts verbatim to URDFImporterConfig fields that expect scalar values, with no warning emitted — existing users relying on per-joint patterns will get type errors or silent no-ops.

Confidence Score: 4/5

Mostly safe to merge, but the per-joint JointDriveCfg dict handling is a silent regression for existing users of that feature.

The refactor is well-structured and the MJCF changes are clean. The one P1 finding — per-joint dict values for drive_type/target_type/stiffness/damping being forwarded to scalar-expecting importer fields without a warning — is a real regression for users of that documented API. The fix is low-effort.

source/isaaclab/isaaclab/sim/converters/urdf_converter.py — specifically _unpack_joint_drive and _warn_unsupported_features.

Important Files Changed

Filename Overview
source/isaaclab/isaaclab/sim/converters/urdf_converter.py Major refactor: multi-step pipeline replaced with a thin wrapper around URDFImporter.import_urdf(). Per-joint dict support for drive_type/target_type/stiffness/damping is silently broken — those values are forwarded verbatim to scalar-expecting importer fields with no warning.
source/isaaclab/isaaclab/sim/converters/urdf_converter_cfg.py New config fields added (ros_package_paths, robot_type, run_asset_transformer, run_multi_physics_conversion, debug_mode); collision_type Literal extended; deprecated fields annotated. Well-documented.
source/isaaclab/isaaclab/sim/converters/mjcf_converter.py New MJCFImporterConfig fields forwarded cleanly. Shutil import moved to top-level. Straightforward and clean.
source/isaaclab/isaaclab/sim/converters/mjcf_converter_cfg.py Well-documented addition of fix_base, link_density, robot_type, actuator gain override fields, and pipeline control flags mirroring the new MJCFImporterConfig options.
source/isaaclab/isaaclab/sim/converters/urdf_utils.py Replaced with a re-export shim. Top-level import will fail at load time if isaacsim is not present rather than deferring the error as other Isaac Sim imports do.
source/isaaclab/test/sim/test_urdf_converter.py Minor comment update only. No functional test changes.

Sequence Diagram

sequenceDiagram
    participant User
    participant UrdfConverter
    participant _unpack_joint_drive
    participant URDFImporterConfig
    participant URDFImporter

    User->>UrdfConverter: UrdfConverterCfg(fix_base, joint_drive, ...)
    UrdfConverter->>_unpack_joint_drive: JointDriveCfg
    _unpack_joint_drive-->>UrdfConverter: (drive_type, target_type, stiffness, damping)
    UrdfConverter->>URDFImporterConfig: urdf_path, usd_path, merge_fixed_joints, collision_*, fix_base, link_density, joint_drive_type, override_joint_stiffness, run_asset_transformer, debug_mode
    URDFImporterConfig-->>UrdfConverter: config
    UrdfConverter->>URDFImporter: import_urdf()
    URDFImporter-->>UrdfConverter: robot_name/robot_name.usda
Loading

Reviews (1): Last reviewed commit: "update urdf mjcf importer to use the lat..." | Re-trigger Greptile

Comment on lines -155 to +179
drive.GetDampingAttr().Set(0.0)

if isinstance(drive_cfg.target_type, str):
for _name, (prim, _is_rev, inst) in joints.items():
_apply(prim, inst, drive_cfg.target_type)
elif isinstance(drive_cfg.target_type, dict):
for pattern, target_type in drive_cfg.target_type.items():
matches = [n for n in joints if re.search(pattern, n)]
if not matches:
raise ValueError(
f"Joint name pattern '{pattern}' in target_type config matched no joints."
f" Available joints: {list(joints.keys())}"
)
for name in matches:
prim, _, inst = joints[name]
_apply(prim, inst, target_type)

@staticmethod
def _set_drive_gains_on_joints(joints: dict, drive_cfg: UrdfConverterCfg.JointDriveCfg):
"""Set stiffness and damping on joint drive APIs.

For revolute joints the user-facing values (Nm/rad) are converted to the USD
convention (Nm/deg) by multiplying by ``pi / 180``.

Args:
joints: Mapping of joint name → (prim, is_revolute, instance_name).
drive_cfg: The joint drive configuration.
Returns:
Tuple ``(drive_type, target_type, stiffness, damping)`` suitable for
:class:`~isaacsim.asset.importer.urdf.URDFImporterConfig`. Entries are ``None`` when
the user did not request an override.
"""
from pxr import UsdPhysics

gains = drive_cfg.gains
if not isinstance(gains, UrdfConverterCfg.JointDriveCfg.PDGainsCfg):
return

def _set_stiffness(prim, instance_name: str, is_revolute: bool, value: float):
drive = UsdPhysics.DriveAPI.Get(prim, instance_name)
usd_value = value * math.pi / 180.0 if is_revolute else value
stiffness_attr = drive.GetStiffnessAttr()
if not stiffness_attr:
stiffness_attr = drive.CreateStiffnessAttr()
stiffness_attr.Set(usd_value)

def _set_damping(prim, instance_name: str, is_revolute: bool, value: float):
drive = UsdPhysics.DriveAPI.Get(prim, instance_name)
usd_value = value * math.pi / 180.0 if is_revolute else value
damping_attr = drive.GetDampingAttr()
if not damping_attr:
damping_attr = drive.CreateDampingAttr()
damping_attr.Set(usd_value)

# --- stiffness ---
if isinstance(gains.stiffness, (float, int)):
for _name, (prim, is_rev, inst) in joints.items():
_set_stiffness(prim, inst, is_rev, gains.stiffness)
elif isinstance(gains.stiffness, dict):
for pattern, stiffness in gains.stiffness.items():
matches = [n for n in joints if re.search(pattern, n)]
if not matches:
raise ValueError(
f"Joint name pattern '{pattern}' in stiffness config matched no joints."
f" Available joints: {list(joints.keys())}"
)
for name in matches:
prim, is_rev, inst = joints[name]
_set_stiffness(prim, inst, is_rev, stiffness)

# --- damping ---
if gains.damping is None:
return
if isinstance(gains.damping, (float, int)):
for _name, (prim, is_rev, inst) in joints.items():
_set_damping(prim, inst, is_rev, gains.damping)
elif isinstance(gains.damping, dict):
for pattern, damping in gains.damping.items():
matches = [n for n in joints if re.search(pattern, n)]
if not matches:
raise ValueError(
f"Joint name pattern '{pattern}' in damping config matched no joints."
f" Available joints: {list(joints.keys())}"
)
for name in matches:
prim, is_rev, inst = joints[name]
_set_damping(prim, inst, is_rev, damping)
if joint_drive is None:
return None, None, None, None

gains = joint_drive.gains
if isinstance(gains, UrdfConverterCfg.JointDriveCfg.PDGainsCfg):
stiffness = gains.stiffness
damping = gains.damping
else:
# `NaturalFrequencyGainsCfg` is deprecated; leave gains unchanged.
stiffness = None
damping = None

return joint_drive.drive_type, joint_drive.target_type, stiffness, damping

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Per-joint dict configs silently passed to scalar-expecting importer fields

JointDriveCfg.drive_type, target_type, gains.stiffness, and gains.damping all accept dict[str, ...] for per-joint regex-pattern overrides. The old code explicitly handled this with re.search pattern matching. _unpack_joint_drive now extracts these values verbatim and forwards them to URDFImporterConfig(joint_drive_type=..., joint_target_type=..., override_joint_stiffness=..., override_joint_damping=...), which almost certainly expects scalar/string values — not dicts. Any user who relied on per-joint configs will either hit a runtime type error or have their settings silently ignored, with no warning emitted.

_warn_unsupported_features should detect dict-valued drive_type, target_type, stiffness, and damping and emit a deprecation warning, the same way it does for NaturalFrequencyGainsCfg.

:mod:`isaacsim.asset.importer.urdf.impl.urdf_utils`, so this module now simply re-exports
the canonical implementation to preserve the public import path
``isaaclab.sim.converters.urdf_utils``.
"""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Re-export shim has no fallback for missing upstream module

The entire urdf_utils.py module is now a single import from isaacsim.asset.importer.urdf.impl.urdf_utils. If that internal path changes or the isaacsim package is not installed (e.g., when the module is imported in a documentation/test environment without Isaac Sim), any import of isaaclab.sim.converters.urdf_utils will raise an ImportError at module load time rather than at conversion time. Consider wrapping the import in a try/except and raising a clearer error only when merge_fixed_joints is actually called, similar to how other Isaac Sim-specific imports are deferred inside methods across the codebase.

Comment on lines +113 to +121
run_asset_transformer: bool = True
"""Whether to run the asset transformer profile after conversion. Defaults to True.

When enabled, the importer restructures the intermediate USD into a layered,
payload-based package. Disable for a single flat USD output.
"""

run_multi_physics_conversion: bool = True
"""Whether to run the MJCF-to-PhysX physics conversion pass. Defaults to True."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 run_asset_transformer and run_multi_physics_conversion default to True — worth documenting the behavioral implications

Defaulting them to True preserves existing behaviour, which is correct. However, if a user accidentally sets run_multi_physics_conversion=False, the resulting USD will lack PhysX joint attributes and the articulation will be unusable in simulation. Consider adding a .. warning:: block to both docstrings noting that disabling these flags produces a non-simulated asset intended only for inspection/debugging.

Comment on lines +49 to +51
# ---------------------------------------------------------------
# Physics / articulation options
# ---------------------------------------------------------------

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: We can remove these dunders here as they are redundant and not done at other places in the code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed

Comment on lines +29 to +31
# ---------------------------------------------------------------
# Geometry / mesh options
# ---------------------------------------------------------------

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: We can remove these dunders here as they are redundant and not done at other places in the code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed

# Actuator gain overrides
# ---------------------------------------------------------------

override_gain_type: str | None = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this called override here and not apply? I suppose a one-to-one naming makes more sense unless justified.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm calling it override because it will apply this overrides the imported gains settings on the mujoco actuators, not just the empty ones. Would you prefer if i use "apply" instead?

"""

override_gain_prm: list[float] | None = None
"""MuJoCo actuator gain parameter array (10 floats) override. Defaults to ``None``.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain here what the 10 floats correspond to?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, I gave a more general explanation F = gain * control + bias, the param array doesn't need to be 10 elements I think

"""

override_bias_prm: list[float] | None = None
"""MuJoCo actuator bias parameter array (10 floats) override. Defaults to ``None``.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too. Could you explain what do the floats mean?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, I gave a more general explanation F = gain * control + bias, the param array doesn't need to be 10 elements I think

# ---------------------------------------------------------------

run_asset_transformer: bool = True
"""Whether to run the asset transformer profile after conversion. Defaults to True.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This too needs more information. We should avoid docstrings that just describe what the name says. Ideally, they should add more information on what the attribute/function is doing internally, so that the developer is more informed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I listed out the file structure that the asset transformer generates for extra clarity

payload-based package. Disable for a single flat USD output.
"""

run_multi_physics_conversion: bool = True

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this mean? Is it only for PhysX or also for Newton?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added explanation: yes, so this will convert mujoco: attributes to physx: attributes. I can imagine this will slowly fade away as newton bridges the gap between mujoco and physx.

@@ -102,11 +108,16 @@ class NaturalFrequencyGainsCfg:
"""The name of the root link. Defaults to None.

If None, the root link will be set by PhysX.

.. deprecated::
This option is no longer supported by the URDF importer 3.0. A warning is logged if set.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An explanation on why is needed. Otherwise it stays unclear.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure about the purpose of this config, so I kept the arg there purely for backwards compatibility

to :class:`~isaacsim.asset.importer.urdf.URDFImporterConfig`.
"""

robot_type: str = "Default"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this mean? Could you explain what other types are there? Otherwise, it is unclear.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added robot types

"""

run_asset_transformer: bool = True
"""Whether to run the asset transformer profile after conversion. Defaults to True.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same docstring note here as the mjcf importer

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I listed out the file structure that the asset transformer generates for extra clarity

payload-based package. Disable for a single flat USD output.
"""

run_multi_physics_conversion: bool = True

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same docstring note here as the mjcf importer

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree, explained further. this will convert urdf: tags to newton, mujoco, and physx

R: A 3x3 rotation matrix.
Historically, IsaacLab shipped its own copy of ``merge_fixed_joints`` for the URDF
pipeline. That logic has moved to the Isaac Sim URDF importer at
:mod:`isaacsim.asset.importer.urdf.impl.urdf_utils`, so this module now simply re-exports

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean one needs to have Isaac Sim installed? If so, then this isn't ideal IMO.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this module is still in develop, I suggest just removing it altogether and directly call isaacsim import where used in the codebase. Following that please update the changelog to say this module is deleted and check versioning accordingly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hopefully Isaac Sim is not a hard requirement, we are looking into shipping the importer as a separate isaac sim independent pip package. and yes sounds good, I will update the doc string

@Mayankm96 Mayankm96 changed the title update urdf mjcf importer to use the latest isaac sim importer Updates URDF/MJCF importer to use the latest Isaac Sim importer May 11, 2026

@isaaclab-review-bot isaaclab-review-bot Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

This PR represents a significant architectural improvement by delegating URDF/MJCF conversion logic to the Isaac Sim importer, reducing code duplication and maintenance burden. The refactoring is well-executed overall.

✅ Strengths

  1. Excellent Code Simplification: Removing ~400 lines of duplicated conversion logic from urdf_converter.py in favor of the upstream Isaac Sim implementation is the right architectural decision.

  2. Good Backwards Compatibility: The urdf_utils.py re-export shim preserves the public import path for merge_fixed_joints, preventing breaking changes for downstream users.

  3. Comprehensive Test Coverage: The 202 new lines of MJCF tests cover the new configuration options (self-collision, collision types, actuator gains, etc.).

  4. Clear Documentation: The changelog entries thoroughly document all added/changed configuration fields.

🔍 Findings

1. Potential Issue: Dictionary-based joint drive gains not supported

File: urdf_converter.py (lines 145-171)
Severity: Medium

The _unpack_joint_drive() method only extracts scalar stiffness and damping values. The previous implementation supported regex-based per-joint dictionaries (dict[str, float]) for fine-grained control. If the Isaac Sim importer does not support per-joint overrides via override_joint_stiffness/override_joint_damping, this represents a feature regression.

Recommendation: Verify whether the Isaac Sim importer accepts dictionary-based gains, or document this as a breaking change for users who relied on per-joint gain specifications.

2. Missing validation for JointDriveCfg dictionary types

File: urdf_converter.py (line 159-163)

if isinstance(gains, UrdfConverterCfg.JointDriveCfg.PDGainsCfg):
    stiffness = gains.stiffness
    damping = gains.damping

If gains.stiffness or gains.damping is a dict (for per-joint values), passing it directly to the importer may cause unexpected behavior. Consider adding type validation or conversion.

3. Type annotation missing for ros_package_paths

File: urdf_converter_cfg.py (line 174-178)

ros_package_paths: list[dict[str, str]] = []

The docstring states each entry should have keys name and path, but there is no TypedDict or validation to enforce this structure. Consider using a @dataclass or TypedDict for better type safety.

📋 Previous Concerns Status

  • ⏳ Per-joint dictionary gains not supported — not addressed (original inline comment still stands)
  • ⏳ Re-export shim fallback — not addressed (original inline comment still stands)
  • ⏳ Documentation for disabled flags — not addressed (original inline comment still stands)

🆕 Update (085e3f8): OVPhysX RigidObject Implementation

This is a substantial update adding a complete OVPhysX backend implementation for RigidObject, mirroring the PhysX API. Key additions:

New Files

  • rigid_object.py (1173 lines): Full OVPhysX-backed RigidObject implementation with pose/velocity writers, mass/COM/inertia setters, and wrench composers
  • rigid_object_data.py (1198 lines): Data container with lazy timestamped buffers and ProxyArray wrappers
  • test_rigid_object.py (1134 lines): Comprehensive test suite covering initialization, state setting, external forces, and material properties (some xfail due to missing RIGID_BODY_MATERIAL TensorType)

Architecture Observations

✅ Well-designed:

  • Device-lock mechanism at process level (_locked_device) correctly handles ovphysx<=0.3.7's C++ constraint
  • Lazy binding creation via _get_binding() avoids unnecessary allocations
  • CPU staging buffers for CPU-only bindings (mass/coms/inertia) handle device mismatch properly
  • Clear documentation of HACK notes for Carbonite dual-instance workarounds

⚠️ Potential concerns:

  1. Process-global PhysX instance reuse (ovphysx_manager.py lines 90-97, 158-178)
    The PhysX instance is now intentionally kept alive across SimulationContext instances. The _release_physx() method only calls physx.reset() rather than dropping the reference. This is documented well but users may be surprised if they expect fresh state between contexts.

  2. _configure_physx_scene_prim() device branching (lines 330-425)
    GPU-specific attributes are only applied when device == "gpu". Verify this doesn't cause issues when switching device modes within the same process (though the device lock should prevent this).

  3. _read_binding_into() assertion vs exception (rigid_object_data.py line 875)
    Uses assert for shape checking which is stripped in -O mode. Consider raise ValueError for production safety.

Minor Issues

  1. Changelog entries removed prematurely (lines removed from changelog.d/)
    The feature entries for heterogeneous Dexsuite and Newton extra were removed but the version bump is to 0.6.4. Verify these changes were already released in 0.6.3.

  2. Test device parametrization (test_rigid_object.py)
    Tests parametrize over ["cuda:0", "cpu"] but the autouse fixture _ovphysx_skip_other_device may skip half the tests based on session lock. This is documented but could be confusing for CI.

Overall Assessment

The new OVPhysX RigidObject implementation is well-architected and follows the established patterns from the Articulation implementation. The device-lock mechanism and Carbonite workarounds are properly documented. The main previous concerns about URDF converter remain unaddressed but the incremental changes are solid.

Recommendation: Merge after addressing or acknowledging the per-joint dictionary gains concern from the original review.


Update (a8aa860c): Reviewed 13 new commits (mostly merge commits from develop). Key upstream changes include:

  • Backend-agnostic task-space accessors for IK/OSC (#5400)
  • RSL-RL config updates for rsl_rl >= 5.0 (#5551)
  • New Scene Data Provider API (#5128)
  • Newton dependency simplification using newton[sim] (#5566)
  • Shadow-Hand-Over MAPPO Newton backend (#5437)

The upstream merges introduce no new issues related to the URDF/MJCF importer changes in this PR. Previous concerns about per-joint dictionary gains and documentation remain unaddressed but are not blocking.

✅ No new issues found in the incremental changes.


Update (a3a3d0a): Reviewed incremental changes.

Changes Summary

  • Documentation: Extensive improvements to URDF/MJCF importer docs (configuration parameter organization, notes about auto-deduplication)
  • LEAPP Install Fix: Changed pip install leapp → ./isaaclab.sh -p -m pip install leapp for proper Isaac Lab environment installation
  • Changelog Consolidation: Released entries from changelog.d/ merged into main CHANGELOGs; version bumps to isaaclab 5.2.0/5.3.0
  • Test Fix: Added sim._disable_app_control_on_stop_handle = True in MJCF converter test to prevent timeout

Previous Concerns Status

  1. urdf_utils.py re-export shim — ✅ Resolved (removed): The file was completely deleted rather than being a shim. Import path is now directly from isaacsim.asset.importer.urdf.impl.urdf_utils. This is a clean break from the old API. Tests updated to import from the new location.

  2. Per-joint dictionary gains — ⏳ Still unaddressed: The inline comment about dict-valued drive_type/target_type/gains being silently passed to scalar-expecting importer fields remains relevant.

  3. Documentation for disabled flags — ⏳ Still unaddressed: The inline comment about adding warnings for run_asset_transformer=False / run_multi_physics_conversion=False remains relevant.

✅ No new issues found in the incremental changes. The documentation improvements are excellent.


Update (f1addb0): Reviewed incremental changes.

Changes Summary

  • Changelog housekeeping: Added changelog fragment file stevfeng-fix-converter-usd-path.minor.rst containing the properly formatted changelog entries
  • Main CHANGELOG.rst cleanup: Removed pre-generated 5.3.0 entries from the main changelog (will be auto-generated from fragments during release)

This follows the correct scriv/towncrier changelog fragment pattern - entries are maintained in changelog.d/ and compiled into the main CHANGELOG during releases.

✅ No new issues. This is correct changelog management - no code changes, just documentation housekeeping.


Update (1a665c5): Reviewed incremental changes since f1addb0.

Changes Summary

  • Documentation RST fixes: Corrected section heading underlines in import_new_asset.rst (changed from """ to ~~~ for proper heading hierarchy)
  • CHANGELOG.rst formatting: Fixed orphan paragraph indentation, added proper bullet prefix and blank lines between versions
  • Changelog validation tooling: Added orphan paragraph detection to tools/changelog/cli.py to catch malformed fragments at CI time
  • Test fixtures: Added test case for the new orphan paragraph validation

Previous Concerns Status

  1. Per-joint dictionary gains — ⏳ Still unaddressed (not modified in this update)
  2. Documentation for disabled flags — ⏳ Still unaddressed (not modified in this update)

✅ No new issues found. These are purely documentation and CI tooling improvements with no impact on the URDF/MJCF converter functionality.


Update (178634f): Reviewed incremental changes since 1a665c5.

Changes Summary

This update contains a collection of bug fixes and improvements unrelated to the URDF/MJCF importer changes:

  • AppLauncher CUDA fix: Deferred torch.cuda.set_device() call until after SimulationApp starts to prevent OpenBLAS/NumPy fork crashes during Kit startup
  • Math utility edge case fixes: create_rotation_matrix_from_view() now returns valid orthonormal frames when look-at direction is parallel to up axis (previously returned singular matrix); quat_from_matrix() now returns NaN for non-rotation inputs (singular, reflection, scale-error matrices)
  • Camera pose fixes: Camera.set_world_poses_from_view() and RayCasterCamera.set_world_poses_from_view() now handle degenerate cases (eye==target) with warnings instead of silently applying garbage poses
  • PVA sensor debug visualizer fixes: Both newton and physx backends now skip bodies with zero acceleration when drawing direction arrows (previously drew undefined directions)
  • LEAPP export script refactoring: Restructured as importable library with deferred runtime dependencies for testability
  • CI test improvements: Added LEAPP package debug output, unset HUB__ARGS__DETECT_ONLY flag
  • Import path fixes: Several files changed from from isaaclab.utils import configclass to direct import
  • Test cleanup: Removed unnecessary Isaac Sim launcher imports from pure-Python tests
  • Version bumps: isaaclab 5.2.1, isaaclab_newton 0.9.1, isaaclab_physx 0.7.1

Previous Concerns Status

  1. Per-joint dictionary gains — ⏳ Still unaddressed (not modified in this update)
  2. Documentation for disabled flags — ⏳ Still unaddressed (not modified in this update)

✅ No new issues found. These are solid bug fixes with comprehensive test coverage for the math edge cases.

@stevfeng
stevfeng force-pushed the dev/stevfeng/update_importers branch from c638330 to 0ba9b59 Compare May 12, 2026 00:41
@stevfeng
stevfeng force-pushed the dev/stevfeng/update_importers branch 3 times, most recently from 64447a7 to 17e01a9 Compare May 13, 2026 16:49
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label May 13, 2026
@stevfeng
stevfeng force-pushed the dev/stevfeng/update_importers branch from a8aa860 to a3a3d0a Compare May 14, 2026 16:22
@stevfeng
stevfeng force-pushed the dev/stevfeng/update_importers branch from 127f48d to d7d45ba Compare May 14, 2026 17:35
@kellyguo11 kellyguo11 moved this to In review in Isaac Lab May 15, 2026
@kellyguo11 kellyguo11 moved this from In review to Ready to merge in Isaac Lab May 15, 2026
@kellyguo11
kellyguo11 merged commit 94c0967 into isaac-sim:develop May 15, 2026
33 of 34 checks passed
@github-project-automation github-project-automation Bot moved this from Ready to merge to Done in Isaac Lab May 15, 2026
kellyguo11 pushed a commit that referenced this pull request Oct 10, 2026
…#8389)

# Description

Before the 3.0 release, the domain owners need to review the "Migrating
to 3.0" guide (`docs/source/migration/migrating_to_isaaclab_3-0.rst` and
`docs/source/migration/include/*`) one section at a time. This PR
assigns each section to likely reviewers and gives each one a concrete
check. Reviewers come from `.github/CODEOWNERS` and from `git log` on
the source the section describes, counting commits since 2025-10. Names
are plain handles with no mentions, so nobody is pinged yet.

While preparing the checklist, I compared every Sphinx cross-reference
and every `from X import Y` in the guide against the source tree. I
fixed the statements that were clearly stale. No other content was
rewritten.

**Doc fixes in this PR**

- Actuator limit aliases: the guide said they stay "through the 3.x
release line and will be removed in 3.1". `actuator_base_cfg.py` says
they are removed in 3.1, so the guide now says that.
- `RayCasterCfg.attach_yaw_only`: the guide called it deprecated, but it
was removed (isaaclab CHANGELOG 4.6.11).
- `isaaclab.utils.math.convert_quat`: the guide said it was removed. It
still exists and is still called by the HDF5 dataset handler and a
contrib task, so the guide now says it is no longer needed for Isaac Lab
data and is kept for external WXYZ data.
- Legacy `write_*_to_sim(data, env_ids)`: the guide said these were
removed. They are deprecated forwarders to the `_index` variants.
- MJCF importer: `fix_base` and `link_density` came out of the "Removed
Settings" list. They were added back to `MjcfConverterCfg` in #5394.
- MJCF `collision_type` example: replaced `"default"`, which the
`Literal` type does not accept, with values it does accept.
- Data Access and Math overview card:
`write_root_pose_to_sim_index(pose, env_ids)` became
`write_root_pose_to_sim_index(root_pose=pose, env_ids=env_ids)`, since
its arguments are keyword-only on every backend.
- XR teleop install: `pip install isaacteleop~=1.0 --extra-index-url
...` became `uv sync --extra teleop --extra isaacsim`. The `teleop`
extra pins `isaacteleop~=1.4.145`, and uv is the only supported install
method.

The `skills/user/migrate-2x-to-3x/` skill does not repeat any of these
claims, so it needs no change.

## Per-section review checklist

Format: `Section — reviewers — check`. "Verified" means the symbol or
path was found in `develop`. Each reviewer still needs to run the
snippets in a real environment.

**Isaac Lab 2.x → 3.0**

- [ ] Installation — StafaH, kellyguo11, myurasov-nv — On a fresh
checkout, run `uv sync --extra isaacsim` and the `isaaclab train ...
physics=isaacsim_physx` command. Confirm that the `isaacsim` / `ovphysx`
extras and the `installation-method-uv` reference still match
`pyproject.toml`. Verified: `isaaclab.sh` / `isaaclab.bat` are gone.
- [ ] Multi-Backend Architecture and Presets (overview, Multi-Backend
Architecture, New `isaaclab_physx` / `isaaclab_newton` Extensions,
Backend-Neutral Imports, Newton Backend Implementations) —
AntoineRichard, ooctipus, StafaH — Run the import snippets under the
PhysX, Newton and OVPhysX presets. Confirm the factory still resolves
backend classes by module path. Confirm that `SurfaceGripper` is only in
`isaaclab_physx`, and that the list of Newton-backed classes is complete
(deformables and other sensors). Verified: all referenced classes exist.
- [ ] Schema Configuration Class Refactor — vidurv-nvidia, ooctipus,
mmichelis — For every row of the deprecated-class → fragment table,
construct the deprecated class and compare its warning with the listed
replacement set. Confirm that the three `warnings.filterwarnings`
regexes still match the emitted messages (they match `schemas_cfg.py`
today). Check the removal versions: classes go in 3.2, the `max_effort`
/ `max_velocity` field aliases in 4.0. The gravcomp note recommends
`MujocoRigidBodyPropertiesCfg`, which is itself deprecated; decide
whether it should point at `MujocoRigidBodyCfg`. Verified: all fragment
classes and `apply_*` writers exist.
- [ ] Multi-Backend Support: PresetCfg Pattern — ooctipus, StafaH,
AntoineRichard — Run `--task Isaac-Open-Drawer-Franka-Direct
physics=newton_mjwarp` and the default launch. Check that the Reach
"After" snippet still matches the Reach task source, and that the
`MJWarpSolverCfg` parameter table matches the cfg fields. The first
`MyPhysicsCfg` snippet uses `PhysxCfg` / `NewtonCfg` without importing
them; decide whether to add the imports. Verified:
`isaaclab.physics.PhysxAutoCfg` and `isaaclab_tasks.utils.PresetCfg`
exist.
- [ ] Isaac Sim API Compatibility — kellyguo11, ooctipus, hujc7 —
Compare the module rename table with the Isaac Sim 6.1 deprecation list.
Run the `enable_extension(...)` + `XformPrim` snippet inside Kit.
Verified: every listed `isaaclab.sim.utils.{stage,prims,queries}`
function exists, `PhysxManager` / `NewtonManager` are exported,
`source/isaaclab/test/deps/isaacsim` is gone, and no `apps/*.kit`
contains `extsDeprecated`.
- [ ] PhysX Tensors API Module Path — AntoineRichard, ooctipus,
kellyguo11 — Confirm on Isaac Sim 6.1 that `omni.physics.tensors.api`
exposes the view types. Verified: `source/` no longer imports
`omni.physics.tensors.impl`.
- [ ] Renaming of `XformPrimView` to `FrameView` — ooctipus,
AntoineRichard, StafaH — Confirm that the deprecated `XformPrimView`
alias is still exported and warns, and that the `FrameView` factory
dispatches to `FabricFrameView` (PhysX) and `NewtonSiteFrameView`
(Newton). Verified: all five new classes exist.
- [ ] Actuator effort and joint-limit names — ooctipus, StafaH,
AntoineRichard — Run an explicit-actuator task and confirm the behaviour
change (the solver keeps `joint_effort_limit`). Confirm that the
`resolve_joint_parameter(...)` call in the snippet matches its
signature. Verified: every read and write target in the
removed-group-property table exists, with dynamic friction only on PhysX
and OVPhysX. Fixed: removal version.
- [ ] Actuator API Moves to `ActuatorCollection` — ooctipus, StafaH,
AntoineRichard (LEAPP exception: frlai) — Run the before/after example.
Confirm the `set_*_index` / `_mask` setters are keyword-only and that
the LEAPP exception still holds. Verified: `target_command`,
`computed_effort` and `applied_effort` exist, and
`ArticulationData.gear_ratio` is gone.
- [ ] RigidObjectCollection API Renaming — AntoineRichard, ooctipus —
The rename table and the "After" example point at
`write_body_state_to_sim` and similar methods, which are themselves
deprecated forwarders in 3.0. Decide whether to point at the `_index` /
`_mask` variants instead. Confirm that every listed `object_*` property
still forwards.
- [ ] Deformable Object API Changes + Migration of Deformables
(`include/deformables.rst`) — mmichelis, ooctipus, AntoineRichard — Run
`examples/deformables.py` on PhysX and Newton, and the volume
before/after snippet. Confirm the removed-property table against
`PhysxDeformableBodyPropertiesCfg`. Verified: every listed material and
props cfg is exported from `isaaclab_physx.sim` / `isaaclab_newton.sim`,
and `linear_damping` / `settling_damping` exist.
- [ ] IMU Sensor Renamed to PVA; New Lightweight IMU Sensor —
AntoineRichard, ooctipus, StafaH — Check the gravity claims: PVA
acceleration excludes gravity and IMU always includes it. Confirm that
`ImuData` only exposes `ang_vel_b` / `lin_acc_b`. Verified:
`pva_orientation` / `pva_projected_gravity` exist and `gravity_bias` is
gone.
- [ ] Sensor Pose Properties Deprecation — ooctipus, AntoineRichard —
Confirm that `ContactSensorData.pose_w` / `pos_w` / `quat_w` emit a
deprecation warning on every backend, and run the `FrameTransformer`
replacement snippet.
- [ ] Contact force property names — ooctipus, AntoineRichard,
yufengsjtu — Check every row of the backend table on PhysX, OVPhysX and
Newton: the warn paths and the `NotImplementedError` for
`net_friction_forces_w*` on PhysX. Verified: every listed property
exists on the base and backend data classes.
- [ ] Articulation Joint Wrench Data Moved to `JointWrenchSensor` —
ooctipus, AntoineRichard, StafaH — Run both scene snippets. Confirm the
body-ordering claim: PhysX includes the root link, Newton reports child
bodies only. Verified: `body_incoming_joint_wrench_b` is gone, and
`mdp.body_incoming_wrench`, `body_names` and `find_bodies` exist.
- [ ] Ray Caster Warp Backend — ooctipus, AntoineRichard, pascal-roth —
Run the `RayCasterCfg(ray_alignment="yaw")` snippet. Verified:
`env_mask` is the first kernel argument and `RayCaster.meshes` is keyed
by `(prim_path, device)`. Fixed: `attach_yaw_only` is removed, not
deprecated.
- [ ] Quaternion Format / Quaternion Finder Tool / Runtime Quaternion
Access Detector / Quaternion Utility API Changes / Quaternion Migration
Checklist — AntoineRichard, StafaH — Run
`scripts/tools/find_quaternions.py` with every documented flag
(`--path`, `--base`, `--check-identity`, `--likely-wxyz`, `--all-quats`,
`--fix`, `--fix-identity-only`, `--dry-run`, `--force`) and check the
sample output format. Verified: `WARN_ON_TORCH_QUATF_ACCESS` exists in
`proxy_array.py`. Fixed: `convert_quat` still exists.
- [ ] ProxyArray Backend for Asset and Sensor Data / ProxyArray Interop
— AntoineRichard, StafaH, ooctipus — Confirm that the affected-classes
table should also list the Newton and OVPhysX sensors. Run the `torch.*`
bridge and confirm its one-time `DeprecationWarning`. Verified: the
`wp.to_torch` shim, `__torch_function__` and `__cuda_array_interface__`
all exist.
- [ ] Write Method Index/Mask Split — AntoineRichard — Confirm that
every listed `_index` / `_mask` writer exists on Articulation,
RigidObject and RigidObjectCollection for every backend. Fixed: the
legacy writers are deprecated forwarders, not removed, and the Data
Access and Math overview card now uses keyword arguments.
- [ ] Timestamped buffers — ooctipus, AntoineRichard — Run the
`TimestampedBuffer(wp.zeros(...))` snippet. Verified:
`TimestampedBufferWarp` is gone.
- [ ] Reinforcement Learning CLI Entrypoints / Unified Checkpoint and
Iteration Arguments — StafaH, ooctipus, kellyguo11 (RLinf rows:
mingxueg-nv) — Run `isaaclab train` and `isaaclab play` for each of
`rsl_rl`, `rl_games`, `skrl`, `sb3` and `rlinf`, plus the
`torch.distributed.run` command. Check the `--checkpoint
latest|best|pretrained` support matrix and the RLinf `--model_path` /
`--checkpoint` semantics. Verified:
`scripts/reinforcement_learning/train.py` exists.
- [ ] Visualizer CLI and Headless Behavior — matthewtrepte, StafaH,
kellyguo11 — Confirm that `--headless` is rejected, then check
`HEADLESS=1` with `--viz kit` (plus `--enable_cameras`) and with `--viz
newton_gl`, and run `--video viz:kit`.
- [ ] Viewport Camera Configuration (`ViewerCfg` deprecated) —
matthewtrepte, ooctipus — Confirm the `viewer.*` shim and the
`ViewportCameraController` warning. Run the
`KitVisualizerCfg(origin_type="asset", origin_track_path=...)` snippet.
Check the custom-visualizer `initialize(..., cameras=, stage=)`
paragraph against `base_visualizer.py`. Verified:
`resolve_camera_sources` and `get_visualized_env_ids` exist.
- [ ] Streaming Camera View (`tiled_cam_*` fields removed) —
matthewtrepte, ooctipus, pbarejko — Run the
`NewtonGLVisualizerCfg(streaming_*)` snippet with a scene-declared
camera. Confirm that the removed helpers are gone. Verified:
`resolve_streaming_envs` and `Camera.set_world_poses_from_view` exist.
- [ ] Newton Visualizer Type Split — matthewtrepte, StafaH — Confirm
that `NewtonVisualizerCfg` warns, that `--viz newton` aliases to
`newton_gl`, and that `visualizer:newton` / `viz:newton_gl` work as
video sources.
- [ ] Video Recording (`gym.wrappers.RecordVideo` replaced) —
matthewtrepte, ooctipus — Run the `VideoRecorderCfg(source="viz", ...)`
snippet. Confirm `eye` / `lookat` were removed and `recording_hooks` is
gone. Verified: `SimulationContext.add_render_callback` exists.
- [ ] URDF Importer — kellyguo11, stevfeng, ooctipus — With the Isaac
Sim 6.1 importer, run `convert_urdf.py` with the documented flags and
the Python before/after snippet. Confirm that the deprecated settings
warn and that the output path is
`{usd_dir}/{robot_name}/{robot_name}.usda`. Verified: the CLI flags
exist.
- [ ] MJCF Importer — kellyguo11, stevfeng — Run `convert_mjcf.py` with
the documented flags and the Python snippet. The Python before/after
example still drops `fix_base`, which is now supported again; decide
whether to keep it. Fixed: `fix_base` / `link_density` are no longer
listed as removed, and `collision_type` examples are valid values.
- [ ] Benchmark Workflows — AntoineRichard, StafaH, ooctipus — Run the
runtime, training, play and startup commands and `--benchmark_formatter
schema,omniperf`. The guide says the "transitional runtime, startup,
training, and play scripts were removed", but
`scripts/benchmarks/{runtime,startup,training,play}.py` still exist as
supported launchers; clarify which scripts are meant. The PhysX
micro-benchmarks now live under
`source/isaaclab_physx/benchmark/{assets,sensors}/`. Verified:
`isaaclab.test.benchmark` is gone and the formatter names match
`BenchmarkFormatter`.
- [ ] XR Teleoperation: Isaac Capture Integration — rwiltz,
hougantc-nvda, kellyguo11 — Run the pipeline-builder snippet against the
pinned `isaacteleop~=1.4`. Confirm that the deprecated
`isaaclab.devices.openxr` classes warn and that the import-mapping table
is still accurate. Fixed: install command.
- [ ] Section overview cards (Assets, Actuators, and Sensors / Data
Access and Math / Reinforcement Learning / Visualizers, Cameras, and
Recording / Tools and Integrations) — ooctipus (Assets), AntoineRichard
(Data Access), StafaH (Reinforcement Learning), matthewtrepte
(Visualizers), kellyguo11 (Tools) — Check each 2.x/3.0 card against the
detailed subsections below it, and run the 3.0 card snippets.
- [ ] Getting Help — AntoineRichard, kellyguo11 — Check the links. The
CHANGELOG link points at `main`.

**Isaac Gym / IsaacGymEnvs (`include/from_isaacgymenvs.rst`,
`include/comparing_simulation_isaacgym.rst`)**

- [ ] Migration from Isaac Gym and IsaacGymEnvs — StafaH, kellyguo11,
ooctipus — Compare the snippets with
`source/isaaclab_tasks/isaaclab_tasks/core/cartpole`, then run the
training and inference commands. Verified: the referenced classes and
the `CARTPOLE_CFG` import exist.
- [ ] Comparing Simulations Between Isaac Gym and Isaac Lab —
kellyguo11, StafaH — Re-run the OmniPVD recording workflow with
`isaaclab benchmark runtime` and the current kit args.

**Cross-cutting**

- [ ] Agent skills sync — StafaH, AntoineRichard — After the reviews
above land, update `skills/user/migrate-2x-to-3x/` and
`skills/user/migrate-from-isaac-gym/` to match, since the guide is their
source of truth.

## Validation

- Clean docs build (`uv run --extra dev make -C docs current-docs`,
which runs `sphinx-build -W --keep-going`): succeeded with 0 warnings,
and the changed passages render. Sphinx does not run in nitpicky mode,
so unresolved `py:` cross-references would not fail this build. The
symbol check below covers them.
- `pre-commit run --files
docs/source/migration/migrating_to_isaaclab_3-0.rst`: all hooks passed.
- Static symbol check: a throwaway script, not committed, resolved every
`:class:` / `:func:` / `:meth:` / `:attr:` / `:mod:` target and every
`from X import Y` in the four migration files against `source/`. The
only unresolved targets were intentional 2.x "before" snippets. I also
used targeted greps for the CLI flags, file paths and deprecation
messages listed above. I did not run any snippet in a simulator.
- Docs-only change outside `source/<pkg>/`, so no changelog fragment is
needed.

## Type of change

- Documentation update

## Release backport

- [x] <!-- backport-active-release --> Backport this pull request to the
active release branch after it merges into `develop`

## Checklist

- [x] I have read and understood the [contribution
guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html)
- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`uv run isaaclab --format`
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have validated the changed behavior with focused coverage and
applied the [test-audit
criteria](https://github.com/isaac-sim/IsaacLab/blob/develop/skills/developer/test-audit/SKILL.md)
to any test changes
- [ ] I have added a changelog fragment under
`source/<pkg>/changelog.d/` for every touched package (do **not** edit
`CHANGELOG.rst` or bump package versions — CI handles that)
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
isaaclab-bot Bot pushed a commit that referenced this pull request Oct 10, 2026
…#8389)

# Description

Before the 3.0 release, the domain owners need to review the "Migrating
to 3.0" guide (`docs/source/migration/migrating_to_isaaclab_3-0.rst` and
`docs/source/migration/include/*`) one section at a time. This PR
assigns each section to likely reviewers and gives each one a concrete
check. Reviewers come from `.github/CODEOWNERS` and from `git log` on
the source the section describes, counting commits since 2025-10. Names
are plain handles with no mentions, so nobody is pinged yet.

While preparing the checklist, I compared every Sphinx cross-reference
and every `from X import Y` in the guide against the source tree. I
fixed the statements that were clearly stale. No other content was
rewritten.

**Doc fixes in this PR**

- Actuator limit aliases: the guide said they stay "through the 3.x
release line and will be removed in 3.1". `actuator_base_cfg.py` says
they are removed in 3.1, so the guide now says that.
- `RayCasterCfg.attach_yaw_only`: the guide called it deprecated, but it
was removed (isaaclab CHANGELOG 4.6.11).
- `isaaclab.utils.math.convert_quat`: the guide said it was removed. It
still exists and is still called by the HDF5 dataset handler and a
contrib task, so the guide now says it is no longer needed for Isaac Lab
data and is kept for external WXYZ data.
- Legacy `write_*_to_sim(data, env_ids)`: the guide said these were
removed. They are deprecated forwarders to the `_index` variants.
- MJCF importer: `fix_base` and `link_density` came out of the "Removed
Settings" list. They were added back to `MjcfConverterCfg` in #5394.
- MJCF `collision_type` example: replaced `"default"`, which the
`Literal` type does not accept, with values it does accept.
- Data Access and Math overview card:
`write_root_pose_to_sim_index(pose, env_ids)` became
`write_root_pose_to_sim_index(root_pose=pose, env_ids=env_ids)`, since
its arguments are keyword-only on every backend.
- XR teleop install: `pip install isaacteleop~=1.0 --extra-index-url
...` became `uv sync --extra teleop --extra isaacsim`. The `teleop`
extra pins `isaacteleop~=1.4.145`, and uv is the only supported install
method.

The `skills/user/migrate-2x-to-3x/` skill does not repeat any of these
claims, so it needs no change.

## Per-section review checklist

Format: `Section — reviewers — check`. "Verified" means the symbol or
path was found in `develop`. Each reviewer still needs to run the
snippets in a real environment.

**Isaac Lab 2.x → 3.0**

- [ ] Installation — StafaH, kellyguo11, myurasov-nv — On a fresh
checkout, run `uv sync --extra isaacsim` and the `isaaclab train ...
physics=isaacsim_physx` command. Confirm that the `isaacsim` / `ovphysx`
extras and the `installation-method-uv` reference still match
`pyproject.toml`. Verified: `isaaclab.sh` / `isaaclab.bat` are gone.
- [ ] Multi-Backend Architecture and Presets (overview, Multi-Backend
Architecture, New `isaaclab_physx` / `isaaclab_newton` Extensions,
Backend-Neutral Imports, Newton Backend Implementations) —
AntoineRichard, ooctipus, StafaH — Run the import snippets under the
PhysX, Newton and OVPhysX presets. Confirm the factory still resolves
backend classes by module path. Confirm that `SurfaceGripper` is only in
`isaaclab_physx`, and that the list of Newton-backed classes is complete
(deformables and other sensors). Verified: all referenced classes exist.
- [ ] Schema Configuration Class Refactor — vidurv-nvidia, ooctipus,
mmichelis — For every row of the deprecated-class → fragment table,
construct the deprecated class and compare its warning with the listed
replacement set. Confirm that the three `warnings.filterwarnings`
regexes still match the emitted messages (they match `schemas_cfg.py`
today). Check the removal versions: classes go in 3.2, the `max_effort`
/ `max_velocity` field aliases in 4.0. The gravcomp note recommends
`MujocoRigidBodyPropertiesCfg`, which is itself deprecated; decide
whether it should point at `MujocoRigidBodyCfg`. Verified: all fragment
classes and `apply_*` writers exist.
- [ ] Multi-Backend Support: PresetCfg Pattern — ooctipus, StafaH,
AntoineRichard — Run `--task Isaac-Open-Drawer-Franka-Direct
physics=newton_mjwarp` and the default launch. Check that the Reach
"After" snippet still matches the Reach task source, and that the
`MJWarpSolverCfg` parameter table matches the cfg fields. The first
`MyPhysicsCfg` snippet uses `PhysxCfg` / `NewtonCfg` without importing
them; decide whether to add the imports. Verified:
`isaaclab.physics.PhysxAutoCfg` and `isaaclab_tasks.utils.PresetCfg`
exist.
- [ ] Isaac Sim API Compatibility — kellyguo11, ooctipus, hujc7 —
Compare the module rename table with the Isaac Sim 6.1 deprecation list.
Run the `enable_extension(...)` + `XformPrim` snippet inside Kit.
Verified: every listed `isaaclab.sim.utils.{stage,prims,queries}`
function exists, `PhysxManager` / `NewtonManager` are exported,
`source/isaaclab/test/deps/isaacsim` is gone, and no `apps/*.kit`
contains `extsDeprecated`.
- [ ] PhysX Tensors API Module Path — AntoineRichard, ooctipus,
kellyguo11 — Confirm on Isaac Sim 6.1 that `omni.physics.tensors.api`
exposes the view types. Verified: `source/` no longer imports
`omni.physics.tensors.impl`.
- [ ] Renaming of `XformPrimView` to `FrameView` — ooctipus,
AntoineRichard, StafaH — Confirm that the deprecated `XformPrimView`
alias is still exported and warns, and that the `FrameView` factory
dispatches to `FabricFrameView` (PhysX) and `NewtonSiteFrameView`
(Newton). Verified: all five new classes exist.
- [ ] Actuator effort and joint-limit names — ooctipus, StafaH,
AntoineRichard — Run an explicit-actuator task and confirm the behaviour
change (the solver keeps `joint_effort_limit`). Confirm that the
`resolve_joint_parameter(...)` call in the snippet matches its
signature. Verified: every read and write target in the
removed-group-property table exists, with dynamic friction only on PhysX
and OVPhysX. Fixed: removal version.
- [ ] Actuator API Moves to `ActuatorCollection` — ooctipus, StafaH,
AntoineRichard (LEAPP exception: frlai) — Run the before/after example.
Confirm the `set_*_index` / `_mask` setters are keyword-only and that
the LEAPP exception still holds. Verified: `target_command`,
`computed_effort` and `applied_effort` exist, and
`ArticulationData.gear_ratio` is gone.
- [ ] RigidObjectCollection API Renaming — AntoineRichard, ooctipus —
The rename table and the "After" example point at
`write_body_state_to_sim` and similar methods, which are themselves
deprecated forwarders in 3.0. Decide whether to point at the `_index` /
`_mask` variants instead. Confirm that every listed `object_*` property
still forwards.
- [ ] Deformable Object API Changes + Migration of Deformables
(`include/deformables.rst`) — mmichelis, ooctipus, AntoineRichard — Run
`examples/deformables.py` on PhysX and Newton, and the volume
before/after snippet. Confirm the removed-property table against
`PhysxDeformableBodyPropertiesCfg`. Verified: every listed material and
props cfg is exported from `isaaclab_physx.sim` / `isaaclab_newton.sim`,
and `linear_damping` / `settling_damping` exist.
- [ ] IMU Sensor Renamed to PVA; New Lightweight IMU Sensor —
AntoineRichard, ooctipus, StafaH — Check the gravity claims: PVA
acceleration excludes gravity and IMU always includes it. Confirm that
`ImuData` only exposes `ang_vel_b` / `lin_acc_b`. Verified:
`pva_orientation` / `pva_projected_gravity` exist and `gravity_bias` is
gone.
- [ ] Sensor Pose Properties Deprecation — ooctipus, AntoineRichard —
Confirm that `ContactSensorData.pose_w` / `pos_w` / `quat_w` emit a
deprecation warning on every backend, and run the `FrameTransformer`
replacement snippet.
- [ ] Contact force property names — ooctipus, AntoineRichard,
yufengsjtu — Check every row of the backend table on PhysX, OVPhysX and
Newton: the warn paths and the `NotImplementedError` for
`net_friction_forces_w*` on PhysX. Verified: every listed property
exists on the base and backend data classes.
- [ ] Articulation Joint Wrench Data Moved to `JointWrenchSensor` —
ooctipus, AntoineRichard, StafaH — Run both scene snippets. Confirm the
body-ordering claim: PhysX includes the root link, Newton reports child
bodies only. Verified: `body_incoming_joint_wrench_b` is gone, and
`mdp.body_incoming_wrench`, `body_names` and `find_bodies` exist.
- [ ] Ray Caster Warp Backend — ooctipus, AntoineRichard, pascal-roth —
Run the `RayCasterCfg(ray_alignment="yaw")` snippet. Verified:
`env_mask` is the first kernel argument and `RayCaster.meshes` is keyed
by `(prim_path, device)`. Fixed: `attach_yaw_only` is removed, not
deprecated.
- [ ] Quaternion Format / Quaternion Finder Tool / Runtime Quaternion
Access Detector / Quaternion Utility API Changes / Quaternion Migration
Checklist — AntoineRichard, StafaH — Run
`scripts/tools/find_quaternions.py` with every documented flag
(`--path`, `--base`, `--check-identity`, `--likely-wxyz`, `--all-quats`,
`--fix`, `--fix-identity-only`, `--dry-run`, `--force`) and check the
sample output format. Verified: `WARN_ON_TORCH_QUATF_ACCESS` exists in
`proxy_array.py`. Fixed: `convert_quat` still exists.
- [ ] ProxyArray Backend for Asset and Sensor Data / ProxyArray Interop
— AntoineRichard, StafaH, ooctipus — Confirm that the affected-classes
table should also list the Newton and OVPhysX sensors. Run the `torch.*`
bridge and confirm its one-time `DeprecationWarning`. Verified: the
`wp.to_torch` shim, `__torch_function__` and `__cuda_array_interface__`
all exist.
- [ ] Write Method Index/Mask Split — AntoineRichard — Confirm that
every listed `_index` / `_mask` writer exists on Articulation,
RigidObject and RigidObjectCollection for every backend. Fixed: the
legacy writers are deprecated forwarders, not removed, and the Data
Access and Math overview card now uses keyword arguments.
- [ ] Timestamped buffers — ooctipus, AntoineRichard — Run the
`TimestampedBuffer(wp.zeros(...))` snippet. Verified:
`TimestampedBufferWarp` is gone.
- [ ] Reinforcement Learning CLI Entrypoints / Unified Checkpoint and
Iteration Arguments — StafaH, ooctipus, kellyguo11 (RLinf rows:
mingxueg-nv) — Run `isaaclab train` and `isaaclab play` for each of
`rsl_rl`, `rl_games`, `skrl`, `sb3` and `rlinf`, plus the
`torch.distributed.run` command. Check the `--checkpoint
latest|best|pretrained` support matrix and the RLinf `--model_path` /
`--checkpoint` semantics. Verified:
`scripts/reinforcement_learning/train.py` exists.
- [ ] Visualizer CLI and Headless Behavior — matthewtrepte, StafaH,
kellyguo11 — Confirm that `--headless` is rejected, then check
`HEADLESS=1` with `--viz kit` (plus `--enable_cameras`) and with `--viz
newton_gl`, and run `--video viz:kit`.
- [ ] Viewport Camera Configuration (`ViewerCfg` deprecated) —
matthewtrepte, ooctipus — Confirm the `viewer.*` shim and the
`ViewportCameraController` warning. Run the
`KitVisualizerCfg(origin_type="asset", origin_track_path=...)` snippet.
Check the custom-visualizer `initialize(..., cameras=, stage=)`
paragraph against `base_visualizer.py`. Verified:
`resolve_camera_sources` and `get_visualized_env_ids` exist.
- [ ] Streaming Camera View (`tiled_cam_*` fields removed) —
matthewtrepte, ooctipus, pbarejko — Run the
`NewtonGLVisualizerCfg(streaming_*)` snippet with a scene-declared
camera. Confirm that the removed helpers are gone. Verified:
`resolve_streaming_envs` and `Camera.set_world_poses_from_view` exist.
- [ ] Newton Visualizer Type Split — matthewtrepte, StafaH — Confirm
that `NewtonVisualizerCfg` warns, that `--viz newton` aliases to
`newton_gl`, and that `visualizer:newton` / `viz:newton_gl` work as
video sources.
- [ ] Video Recording (`gym.wrappers.RecordVideo` replaced) —
matthewtrepte, ooctipus — Run the `VideoRecorderCfg(source="viz", ...)`
snippet. Confirm `eye` / `lookat` were removed and `recording_hooks` is
gone. Verified: `SimulationContext.add_render_callback` exists.
- [ ] URDF Importer — kellyguo11, stevfeng, ooctipus — With the Isaac
Sim 6.1 importer, run `convert_urdf.py` with the documented flags and
the Python before/after snippet. Confirm that the deprecated settings
warn and that the output path is
`{usd_dir}/{robot_name}/{robot_name}.usda`. Verified: the CLI flags
exist.
- [ ] MJCF Importer — kellyguo11, stevfeng — Run `convert_mjcf.py` with
the documented flags and the Python snippet. The Python before/after
example still drops `fix_base`, which is now supported again; decide
whether to keep it. Fixed: `fix_base` / `link_density` are no longer
listed as removed, and `collision_type` examples are valid values.
- [ ] Benchmark Workflows — AntoineRichard, StafaH, ooctipus — Run the
runtime, training, play and startup commands and `--benchmark_formatter
schema,omniperf`. The guide says the "transitional runtime, startup,
training, and play scripts were removed", but
`scripts/benchmarks/{runtime,startup,training,play}.py` still exist as
supported launchers; clarify which scripts are meant. The PhysX
micro-benchmarks now live under
`source/isaaclab_physx/benchmark/{assets,sensors}/`. Verified:
`isaaclab.test.benchmark` is gone and the formatter names match
`BenchmarkFormatter`.
- [ ] XR Teleoperation: Isaac Capture Integration — rwiltz,
hougantc-nvda, kellyguo11 — Run the pipeline-builder snippet against the
pinned `isaacteleop~=1.4`. Confirm that the deprecated
`isaaclab.devices.openxr` classes warn and that the import-mapping table
is still accurate. Fixed: install command.
- [ ] Section overview cards (Assets, Actuators, and Sensors / Data
Access and Math / Reinforcement Learning / Visualizers, Cameras, and
Recording / Tools and Integrations) — ooctipus (Assets), AntoineRichard
(Data Access), StafaH (Reinforcement Learning), matthewtrepte
(Visualizers), kellyguo11 (Tools) — Check each 2.x/3.0 card against the
detailed subsections below it, and run the 3.0 card snippets.
- [ ] Getting Help — AntoineRichard, kellyguo11 — Check the links. The
CHANGELOG link points at `main`.

**Isaac Gym / IsaacGymEnvs (`include/from_isaacgymenvs.rst`,
`include/comparing_simulation_isaacgym.rst`)**

- [ ] Migration from Isaac Gym and IsaacGymEnvs — StafaH, kellyguo11,
ooctipus — Compare the snippets with
`source/isaaclab_tasks/isaaclab_tasks/core/cartpole`, then run the
training and inference commands. Verified: the referenced classes and
the `CARTPOLE_CFG` import exist.
- [ ] Comparing Simulations Between Isaac Gym and Isaac Lab —
kellyguo11, StafaH — Re-run the OmniPVD recording workflow with
`isaaclab benchmark runtime` and the current kit args.

**Cross-cutting**

- [ ] Agent skills sync — StafaH, AntoineRichard — After the reviews
above land, update `skills/user/migrate-2x-to-3x/` and
`skills/user/migrate-from-isaac-gym/` to match, since the guide is their
source of truth.

## Validation

- Clean docs build (`uv run --extra dev make -C docs current-docs`,
which runs `sphinx-build -W --keep-going`): succeeded with 0 warnings,
and the changed passages render. Sphinx does not run in nitpicky mode,
so unresolved `py:` cross-references would not fail this build. The
symbol check below covers them.
- `pre-commit run --files
docs/source/migration/migrating_to_isaaclab_3-0.rst`: all hooks passed.
- Static symbol check: a throwaway script, not committed, resolved every
`:class:` / `:func:` / `:meth:` / `:attr:` / `:mod:` target and every
`from X import Y` in the four migration files against `source/`. The
only unresolved targets were intentional 2.x "before" snippets. I also
used targeted greps for the CLI flags, file paths and deprecation
messages listed above. I did not run any snippet in a simulator.
- Docs-only change outside `source/<pkg>/`, so no changelog fragment is
needed.

## Type of change

- Documentation update

## Release backport

- [x] <!-- backport-active-release --> Backport this pull request to the
active release branch after it merges into `develop`

## Checklist

- [x] I have read and understood the [contribution
guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html)
- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`uv run isaaclab --format`
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have validated the changed behavior with focused coverage and
applied the [test-audit
criteria](https://github.com/isaac-sim/IsaacLab/blob/develop/skills/developer/test-audit/SKILL.md)
to any test changes
- [ ] I have added a changelog fragment under
`source/<pkg>/changelog.d/` for every touched package (do **not** edit
`CHANGELOG.rst` or bump package versions — CI handles that)
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

(cherry picked from commit fa014dc)
jnskkmhr added a commit to jnskkmhr/IsaacLab that referenced this pull request Oct 11, 2026
* Update the cartpole OVRTX goldens for OVRTX 0.5.1 (isaac-sim#8443)

# Description

Updates the four cartpole OVRTX goldens
(`cartpole/{newton,ovphysx}-ovrtx_renderer-{rgb,rgba}.png`) to the CI
runner's OVRTX 0.5.1 renders. Since isaac-sim#8350,
`rendering-correctness-kitless (legacy)` fails on them deterministically
(about 1.95% different pixels against the 1.5% threshold; repeated runs
are byte-identical).

## Type of change

- Bug fix (non-breaking change which fixes an issue)

## Release backport

- [x] <!-- backport-active-release --> Backport this pull request to the
active release branch after it merges into `develop`

## Checklist

Docker and GPU tests run on demand. Push the commits you want tested,
then
comment `run-ci` on the pull request.

- [x] I have read and understood the [contribution
guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html)
- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`uv run isaaclab --format`
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have validated the changed behavior with focused coverage and
applied the [test-audit
criteria](https://github.com/isaac-sim/IsaacLab/blob/develop/skills/developer/test-audit/SKILL.md)
to any test changes
- [x] I have added a changelog fragment under
`source/<pkg>/changelog.d/` for every touched package (do **not** edit
`CHANGELOG.rst` or bump package versions — CI handles that)
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

* Deprecate legacy deformable cfgs and add OvPhysX fragment support (isaac-sim#8348)

# Description

Deformable fragment slots now create bodies on OvPhysX. PhysX and
OvPhysX use the same OmniPhysics USD authoring for the simulation API,
rest state, and bind pose. The legacy deformable cfgs and
`define_deformable_body_properties` /
`modify_deformable_body_properties` remain functional but warn in 3.1
ahead of removal in 3.2.

The affected tutorials, example, and fragment-path tests use the slots.
An empty slot creates a body with backend defaults; fragments are needed
only for properties being set. The Franka soft and cloth presets retain
`deformable_props` during the deprecation period so downstream overrides
keep working. The spawner continues to reject configurations that set
more than one deformable slot.

The legacy OmniPhysics writer and both PhysX managers share one
authoring function. No new precedence or adapter path is added.

## Validation

- Deprecation tests: 96 passed; deformable fragment tests: 10 passed;
backend-split tests: 4 passed.
- PhysX mesh spawning: 2 passed; OVPhysX deformables: 20 passed and 1
skipped, with both volume and surface fragment-slot cases passing when
the tetrahedralization extra is installed; Newton deformables: 8 passed.
- Repository formatting, changelog gate, and a clean Sphinx build with
warnings treated as errors passed.
- Franka training and tutorial scripts were not run end to end.

---------

Co-authored-by: Octi Zhang <zhengyuz@nvidia.com>

* [Docs] DOC-007: Migration guide: per-section review owners and checks (isaac-sim#8389)

# Description

Before the 3.0 release, the domain owners need to review the "Migrating
to 3.0" guide (`docs/source/migration/migrating_to_isaaclab_3-0.rst` and
`docs/source/migration/include/*`) one section at a time. This PR
assigns each section to likely reviewers and gives each one a concrete
check. Reviewers come from `.github/CODEOWNERS` and from `git log` on
the source the section describes, counting commits since 2025-10. Names
are plain handles with no mentions, so nobody is pinged yet.

While preparing the checklist, I compared every Sphinx cross-reference
and every `from X import Y` in the guide against the source tree. I
fixed the statements that were clearly stale. No other content was
rewritten.

**Doc fixes in this PR**

- Actuator limit aliases: the guide said they stay "through the 3.x
release line and will be removed in 3.1". `actuator_base_cfg.py` says
they are removed in 3.1, so the guide now says that.
- `RayCasterCfg.attach_yaw_only`: the guide called it deprecated, but it
was removed (isaaclab CHANGELOG 4.6.11).
- `isaaclab.utils.math.convert_quat`: the guide said it was removed. It
still exists and is still called by the HDF5 dataset handler and a
contrib task, so the guide now says it is no longer needed for Isaac Lab
data and is kept for external WXYZ data.
- Legacy `write_*_to_sim(data, env_ids)`: the guide said these were
removed. They are deprecated forwarders to the `_index` variants.
- MJCF importer: `fix_base` and `link_density` came out of the "Removed
Settings" list. They were added back to `MjcfConverterCfg` in isaac-sim#5394.
- MJCF `collision_type` example: replaced `"default"`, which the
`Literal` type does not accept, with values it does accept.
- Data Access and Math overview card:
`write_root_pose_to_sim_index(pose, env_ids)` became
`write_root_pose_to_sim_index(root_pose=pose, env_ids=env_ids)`, since
its arguments are keyword-only on every backend.
- XR teleop install: `pip install isaacteleop~=1.0 --extra-index-url
...` became `uv sync --extra teleop --extra isaacsim`. The `teleop`
extra pins `isaacteleop~=1.4.145`, and uv is the only supported install
method.

The `skills/user/migrate-2x-to-3x/` skill does not repeat any of these
claims, so it needs no change.

## Per-section review checklist

Format: `Section — reviewers — check`. "Verified" means the symbol or
path was found in `develop`. Each reviewer still needs to run the
snippets in a real environment.

**Isaac Lab 2.x → 3.0**

- [ ] Installation — StafaH, kellyguo11, myurasov-nv — On a fresh
checkout, run `uv sync --extra isaacsim` and the `isaaclab train ...
physics=isaacsim_physx` command. Confirm that the `isaacsim` / `ovphysx`
extras and the `installation-method-uv` reference still match
`pyproject.toml`. Verified: `isaaclab.sh` / `isaaclab.bat` are gone.
- [ ] Multi-Backend Architecture and Presets (overview, Multi-Backend
Architecture, New `isaaclab_physx` / `isaaclab_newton` Extensions,
Backend-Neutral Imports, Newton Backend Implementations) —
AntoineRichard, ooctipus, StafaH — Run the import snippets under the
PhysX, Newton and OVPhysX presets. Confirm the factory still resolves
backend classes by module path. Confirm that `SurfaceGripper` is only in
`isaaclab_physx`, and that the list of Newton-backed classes is complete
(deformables and other sensors). Verified: all referenced classes exist.
- [ ] Schema Configuration Class Refactor — vidurv-nvidia, ooctipus,
mmichelis — For every row of the deprecated-class → fragment table,
construct the deprecated class and compare its warning with the listed
replacement set. Confirm that the three `warnings.filterwarnings`
regexes still match the emitted messages (they match `schemas_cfg.py`
today). Check the removal versions: classes go in 3.2, the `max_effort`
/ `max_velocity` field aliases in 4.0. The gravcomp note recommends
`MujocoRigidBodyPropertiesCfg`, which is itself deprecated; decide
whether it should point at `MujocoRigidBodyCfg`. Verified: all fragment
classes and `apply_*` writers exist.
- [ ] Multi-Backend Support: PresetCfg Pattern — ooctipus, StafaH,
AntoineRichard — Run `--task Isaac-Open-Drawer-Franka-Direct
physics=newton_mjwarp` and the default launch. Check that the Reach
"After" snippet still matches the Reach task source, and that the
`MJWarpSolverCfg` parameter table matches the cfg fields. The first
`MyPhysicsCfg` snippet uses `PhysxCfg` / `NewtonCfg` without importing
them; decide whether to add the imports. Verified:
`isaaclab.physics.PhysxAutoCfg` and `isaaclab_tasks.utils.PresetCfg`
exist.
- [ ] Isaac Sim API Compatibility — kellyguo11, ooctipus, hujc7 —
Compare the module rename table with the Isaac Sim 6.1 deprecation list.
Run the `enable_extension(...)` + `XformPrim` snippet inside Kit.
Verified: every listed `isaaclab.sim.utils.{stage,prims,queries}`
function exists, `PhysxManager` / `NewtonManager` are exported,
`source/isaaclab/test/deps/isaacsim` is gone, and no `apps/*.kit`
contains `extsDeprecated`.
- [ ] PhysX Tensors API Module Path — AntoineRichard, ooctipus,
kellyguo11 — Confirm on Isaac Sim 6.1 that `omni.physics.tensors.api`
exposes the view types. Verified: `source/` no longer imports
`omni.physics.tensors.impl`.
- [ ] Renaming of `XformPrimView` to `FrameView` — ooctipus,
AntoineRichard, StafaH — Confirm that the deprecated `XformPrimView`
alias is still exported and warns, and that the `FrameView` factory
dispatches to `FabricFrameView` (PhysX) and `NewtonSiteFrameView`
(Newton). Verified: all five new classes exist.
- [ ] Actuator effort and joint-limit names — ooctipus, StafaH,
AntoineRichard — Run an explicit-actuator task and confirm the behaviour
change (the solver keeps `joint_effort_limit`). Confirm that the
`resolve_joint_parameter(...)` call in the snippet matches its
signature. Verified: every read and write target in the
removed-group-property table exists, with dynamic friction only on PhysX
and OVPhysX. Fixed: removal version.
- [ ] Actuator API Moves to `ActuatorCollection` — ooctipus, StafaH,
AntoineRichard (LEAPP exception: frlai) — Run the before/after example.
Confirm the `set_*_index` / `_mask` setters are keyword-only and that
the LEAPP exception still holds. Verified: `target_command`,
`computed_effort` and `applied_effort` exist, and
`ArticulationData.gear_ratio` is gone.
- [ ] RigidObjectCollection API Renaming — AntoineRichard, ooctipus —
The rename table and the "After" example point at
`write_body_state_to_sim` and similar methods, which are themselves
deprecated forwarders in 3.0. Decide whether to point at the `_index` /
`_mask` variants instead. Confirm that every listed `object_*` property
still forwards.
- [ ] Deformable Object API Changes + Migration of Deformables
(`include/deformables.rst`) — mmichelis, ooctipus, AntoineRichard — Run
`examples/deformables.py` on PhysX and Newton, and the volume
before/after snippet. Confirm the removed-property table against
`PhysxDeformableBodyPropertiesCfg`. Verified: every listed material and
props cfg is exported from `isaaclab_physx.sim` / `isaaclab_newton.sim`,
and `linear_damping` / `settling_damping` exist.
- [ ] IMU Sensor Renamed to PVA; New Lightweight IMU Sensor —
AntoineRichard, ooctipus, StafaH — Check the gravity claims: PVA
acceleration excludes gravity and IMU always includes it. Confirm that
`ImuData` only exposes `ang_vel_b` / `lin_acc_b`. Verified:
`pva_orientation` / `pva_projected_gravity` exist and `gravity_bias` is
gone.
- [ ] Sensor Pose Properties Deprecation — ooctipus, AntoineRichard —
Confirm that `ContactSensorData.pose_w` / `pos_w` / `quat_w` emit a
deprecation warning on every backend, and run the `FrameTransformer`
replacement snippet.
- [ ] Contact force property names — ooctipus, AntoineRichard,
yufengsjtu — Check every row of the backend table on PhysX, OVPhysX and
Newton: the warn paths and the `NotImplementedError` for
`net_friction_forces_w*` on PhysX. Verified: every listed property
exists on the base and backend data classes.
- [ ] Articulation Joint Wrench Data Moved to `JointWrenchSensor` —
ooctipus, AntoineRichard, StafaH — Run both scene snippets. Confirm the
body-ordering claim: PhysX includes the root link, Newton reports child
bodies only. Verified: `body_incoming_joint_wrench_b` is gone, and
`mdp.body_incoming_wrench`, `body_names` and `find_bodies` exist.
- [ ] Ray Caster Warp Backend — ooctipus, AntoineRichard, pascal-roth —
Run the `RayCasterCfg(ray_alignment="yaw")` snippet. Verified:
`env_mask` is the first kernel argument and `RayCaster.meshes` is keyed
by `(prim_path, device)`. Fixed: `attach_yaw_only` is removed, not
deprecated.
- [ ] Quaternion Format / Quaternion Finder Tool / Runtime Quaternion
Access Detector / Quaternion Utility API Changes / Quaternion Migration
Checklist — AntoineRichard, StafaH — Run
`scripts/tools/find_quaternions.py` with every documented flag
(`--path`, `--base`, `--check-identity`, `--likely-wxyz`, `--all-quats`,
`--fix`, `--fix-identity-only`, `--dry-run`, `--force`) and check the
sample output format. Verified: `WARN_ON_TORCH_QUATF_ACCESS` exists in
`proxy_array.py`. Fixed: `convert_quat` still exists.
- [ ] ProxyArray Backend for Asset and Sensor Data / ProxyArray Interop
— AntoineRichard, StafaH, ooctipus — Confirm that the affected-classes
table should also list the Newton and OVPhysX sensors. Run the `torch.*`
bridge and confirm its one-time `DeprecationWarning`. Verified: the
`wp.to_torch` shim, `__torch_function__` and `__cuda_array_interface__`
all exist.
- [ ] Write Method Index/Mask Split — AntoineRichard — Confirm that
every listed `_index` / `_mask` writer exists on Articulation,
RigidObject and RigidObjectCollection for every backend. Fixed: the
legacy writers are deprecated forwarders, not removed, and the Data
Access and Math overview card now uses keyword arguments.
- [ ] Timestamped buffers — ooctipus, AntoineRichard — Run the
`TimestampedBuffer(wp.zeros(...))` snippet. Verified:
`TimestampedBufferWarp` is gone.
- [ ] Reinforcement Learning CLI Entrypoints / Unified Checkpoint and
Iteration Arguments — StafaH, ooctipus, kellyguo11 (RLinf rows:
mingxueg-nv) — Run `isaaclab train` and `isaaclab play` for each of
`rsl_rl`, `rl_games`, `skrl`, `sb3` and `rlinf`, plus the
`torch.distributed.run` command. Check the `--checkpoint
latest|best|pretrained` support matrix and the RLinf `--model_path` /
`--checkpoint` semantics. Verified:
`scripts/reinforcement_learning/train.py` exists.
- [ ] Visualizer CLI and Headless Behavior — matthewtrepte, StafaH,
kellyguo11 — Confirm that `--headless` is rejected, then check
`HEADLESS=1` with `--viz kit` (plus `--enable_cameras`) and with `--viz
newton_gl`, and run `--video viz:kit`.
- [ ] Viewport Camera Configuration (`ViewerCfg` deprecated) —
matthewtrepte, ooctipus — Confirm the `viewer.*` shim and the
`ViewportCameraController` warning. Run the
`KitVisualizerCfg(origin_type="asset", origin_track_path=...)` snippet.
Check the custom-visualizer `initialize(..., cameras=, stage=)`
paragraph against `base_visualizer.py`. Verified:
`resolve_camera_sources` and `get_visualized_env_ids` exist.
- [ ] Streaming Camera View (`tiled_cam_*` fields removed) —
matthewtrepte, ooctipus, pbarejko — Run the
`NewtonGLVisualizerCfg(streaming_*)` snippet with a scene-declared
camera. Confirm that the removed helpers are gone. Verified:
`resolve_streaming_envs` and `Camera.set_world_poses_from_view` exist.
- [ ] Newton Visualizer Type Split — matthewtrepte, StafaH — Confirm
that `NewtonVisualizerCfg` warns, that `--viz newton` aliases to
`newton_gl`, and that `visualizer:newton` / `viz:newton_gl` work as
video sources.
- [ ] Video Recording (`gym.wrappers.RecordVideo` replaced) —
matthewtrepte, ooctipus — Run the `VideoRecorderCfg(source="viz", ...)`
snippet. Confirm `eye` / `lookat` were removed and `recording_hooks` is
gone. Verified: `SimulationContext.add_render_callback` exists.
- [ ] URDF Importer — kellyguo11, stevfeng, ooctipus — With the Isaac
Sim 6.1 importer, run `convert_urdf.py` with the documented flags and
the Python before/after snippet. Confirm that the deprecated settings
warn and that the output path is
`{usd_dir}/{robot_name}/{robot_name}.usda`. Verified: the CLI flags
exist.
- [ ] MJCF Importer — kellyguo11, stevfeng — Run `convert_mjcf.py` with
the documented flags and the Python snippet. The Python before/after
example still drops `fix_base`, which is now supported again; decide
whether to keep it. Fixed: `fix_base` / `link_density` are no longer
listed as removed, and `collision_type` examples are valid values.
- [ ] Benchmark Workflows — AntoineRichard, StafaH, ooctipus — Run the
runtime, training, play and startup commands and `--benchmark_formatter
schema,omniperf`. The guide says the "transitional runtime, startup,
training, and play scripts were removed", but
`scripts/benchmarks/{runtime,startup,training,play}.py` still exist as
supported launchers; clarify which scripts are meant. The PhysX
micro-benchmarks now live under
`source/isaaclab_physx/benchmark/{assets,sensors}/`. Verified:
`isaaclab.test.benchmark` is gone and the formatter names match
`BenchmarkFormatter`.
- [ ] XR Teleoperation: Isaac Capture Integration — rwiltz,
hougantc-nvda, kellyguo11 — Run the pipeline-builder snippet against the
pinned `isaacteleop~=1.4`. Confirm that the deprecated
`isaaclab.devices.openxr` classes warn and that the import-mapping table
is still accurate. Fixed: install command.
- [ ] Section overview cards (Assets, Actuators, and Sensors / Data
Access and Math / Reinforcement Learning / Visualizers, Cameras, and
Recording / Tools and Integrations) — ooctipus (Assets), AntoineRichard
(Data Access), StafaH (Reinforcement Learning), matthewtrepte
(Visualizers), kellyguo11 (Tools) — Check each 2.x/3.0 card against the
detailed subsections below it, and run the 3.0 card snippets.
- [ ] Getting Help — AntoineRichard, kellyguo11 — Check the links. The
CHANGELOG link points at `main`.

**Isaac Gym / IsaacGymEnvs (`include/from_isaacgymenvs.rst`,
`include/comparing_simulation_isaacgym.rst`)**

- [ ] Migration from Isaac Gym and IsaacGymEnvs — StafaH, kellyguo11,
ooctipus — Compare the snippets with
`source/isaaclab_tasks/isaaclab_tasks/core/cartpole`, then run the
training and inference commands. Verified: the referenced classes and
the `CARTPOLE_CFG` import exist.
- [ ] Comparing Simulations Between Isaac Gym and Isaac Lab —
kellyguo11, StafaH — Re-run the OmniPVD recording workflow with
`isaaclab benchmark runtime` and the current kit args.

**Cross-cutting**

- [ ] Agent skills sync — StafaH, AntoineRichard — After the reviews
above land, update `skills/user/migrate-2x-to-3x/` and
`skills/user/migrate-from-isaac-gym/` to match, since the guide is their
source of truth.

## Validation

- Clean docs build (`uv run --extra dev make -C docs current-docs`,
which runs `sphinx-build -W --keep-going`): succeeded with 0 warnings,
and the changed passages render. Sphinx does not run in nitpicky mode,
so unresolved `py:` cross-references would not fail this build. The
symbol check below covers them.
- `pre-commit run --files
docs/source/migration/migrating_to_isaaclab_3-0.rst`: all hooks passed.
- Static symbol check: a throwaway script, not committed, resolved every
`:class:` / `:func:` / `:meth:` / `:attr:` / `:mod:` target and every
`from X import Y` in the four migration files against `source/`. The
only unresolved targets were intentional 2.x "before" snippets. I also
used targeted greps for the CLI flags, file paths and deprecation
messages listed above. I did not run any snippet in a simulator.
- Docs-only change outside `source/<pkg>/`, so no changelog fragment is
needed.

## Type of change

- Documentation update

## Release backport

- [x] <!-- backport-active-release --> Backport this pull request to the
active release branch after it merges into `develop`

## Checklist

- [x] I have read and understood the [contribution
guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html)
- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`uv run isaaclab --format`
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have validated the changed behavior with focused coverage and
applied the [test-audit
criteria](https://github.com/isaac-sim/IsaacLab/blob/develop/skills/developer/test-audit/SKILL.md)
to any test changes
- [ ] I have added a changelog fragment under
`source/<pkg>/changelog.d/` for every touched package (do **not** edit
`CHANGELOG.rst` or bump package versions — CI handles that)
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

* [6Aiii] Use native Newton RTX with a borrowed scene stage (isaac-sim#8303)

# Description

Newton RTX now uses native `ViewerRTX(ovstage=...)` with a
simulation-owned scene stage instead of rebuilding viewer USD from the
Newton model. Authored lighting, materials, and clone placements reach
the viewer directly; Newton retains its window, perspective camera, and
debug markers. OVStage and OVRTX share private copy batching that omits
children already supplied by their parent.

GL and RTX share camera selection and model-reset code. Contact
rendering uses the sensor interface directly; selected PhysX
environments retain the correct body-pose ordering. Marker inputs
normalize directly to the simulation device, including host arrays and
partial prototype-index updates. Window defaults merge per field without
sharing mutable state. Newton and Kit use shared `WindowCfg(size=...)`;
Newton windows use a wall-clock `fps` limit (30 by default) instead of
skipping simulation frames. Scene-camera images stay on the GPU for
display, and window resizing scales fixed-resolution images without
resizing sensors. Backend construction stays inside the visualizer,
using the simulation owner passed to `initialize(sim, cameras=...)`.

This is **PR6Aiii**. Shared `ImageViewCfg`, window/recorder frame
caching, and removal of duplicate CPU composition are split into
**PR6Aiv (isaac-sim#8432)**. Follows merged isaac-sim#8103, isaac-sim#8319, and isaac-sim#8381; incorporates
isaac-sim#8221 without isaac-sim#8232.

**Migration:** Use Camera View instead of Open/Hide. Remove RTX
`rtx_environment`, `world_spacing`, and GL model options; author lights
and placement in the scene. Use GL for dragging and model overlays.
Custom visualizers must adopt `initialize(sim, cameras=...)`. Move
`window_width`/`window_height` to `window=WindowCfg(size=(width,
height))`, replace Newton `update_frequency` with `window.fps`, and use
`render_tiled_rgba_array()` for GPU images. Runtime material
randomization is not yet propagated to the borrowed stage.

## Validation

The review cleanup passed 121 tests on GPU0, including the full marker
suite and native RTX motion/pause/marker integration; the two lighting
cases below remain skipped. The extended existing tests reproduced the
window aliasing, partial-default inheritance, and marker-device bugs
before their fixes. The RTX media configuration now constructs
successfully. Formatting/lint and changelog checks passed; full CI is
being rerun.

Startup to the first rendered image, in seconds: **baseline → combined
implementation**, measured at preserved revision `00adda3a9` against
`a3acc244d` before this split. These measurements include the
shared-view follow-up and are not a new measurement of the isolated
PR6Aiii branch. Every case includes the **Newton RTX viewer** at
640×480; RGB adds one 64×64 OVRTX sensor per environment. Timings
include process launch, physics, scene, and viewer setup.

| Task / physics | Sensor cameras | 1,024 environments | 4,096
environments |
|---|---|---:|---:|
| ANYmal rough / Newton MJWarp | None | 55.8 → **28.4** | 251.8 →
**29.3** |
| ANYmal rough / Newton MJWarp | RGB | 60.1 → **32.5** | 258.7 →
**44.1** |
| ANYmal rough / OVPhysX | None | 64.7 → **38.8** | 294.1 → **70.7** |
| ANYmal rough / OVPhysX | RGB | 74.7 → **38.4** | 302.3 → **92.6** |
| Kuka–Allegro lift / Newton MJWarp | None | 46.1 → **17.3** | RAM limit
→ **28.9** |
| Kuka–Allegro lift / Newton MJWarp | RGB | 45.2 → **21.9** | RAM limit
→ **42.1** |
| Kuka–Allegro lift / OVPhysX | None | 102.1 → **71.6** | RAM limit →
**121.9** |
| Kuka–Allegro lift / OVPhysX | RGB | 101.4 → **78.3** | RAM limit →
**141.5** |

Single runs with warmed caches and identical dependencies on an RTX
5090, GPU0 only. All 16 PR cases passed image validation and three
rollout steps. Four 4,096-environment Kuka baselines exceeded available
host RAM; these have no valid timing and need a repeat after memory is
freed. The other 12 baselines passed. [Benchmark
setup](isaac-sim#8303 (comment)).

## Temporary test skip and follow-up

The two lighting/lifetime cases using an OVRTX sensor are temporarily
skipped because the sensor and native viewer create separate OVRTX
renderers; the second can stall when the first has loaded a scene but
never rendered. The two Warp-sensor cases remain enabled and passed on
GPU0 (2 passed, 2 skipped in 18 seconds). This skips affected coverage;
it does not fix the runtime stall.

Re-enable those cases after [Newton
isaac-sim#4627](newton-physics/newton#4627) merges and
Isaac Lab adopts its shared-renderer API. The test body and its
ownership, lighting, and sensor-buffer assertions remain intact.

The shared-renderer integration will also address stale deformable
geometry, pose-offset inference on hard reset, and unnecessary
perspective-scene construction for sensor-only windows. These are
confirmed limitations of the current separate-stage path, not fixed by
this cleanup.

GL sensor navigation still reads input one frame late. Fixing that
requires an input-update phase before image composition in Newton; the
current code does not add a second input pump.

## Type of change

- New feature
- Breaking change
- Bug fix
- Documentation update

## Release backport

- [ ] <!-- backport-active-release --> Backport this pull request to the
active release branch after it merges into `develop`

## Checklist

- [x] Read the contribution guidelines
- [x] Ran formatting/lint and changelog checks
- [x] Updated documentation and migration guidance
- [x] Validated the split with existing focused tests
- [x] Added package changelog fragments
- [x] Contributor already listed
- [x] Clean local documentation build
- [ ] Pass GPU CI

* [Tests] Serialize flaky Kit lifecycle tests in CI (isaac-sim#8447)

# Description

Two independent Kit lifecycle operations deadlocked in the same CI run
for isaac-sim#8443:

- the Spot LEAPP export wrote and validated its artifacts, cleared
`SimulationContext`, and then timed out in native Kit shutdown;
- the Galbot suction RMPFlow case timed out while synchronously enabling
`isaacsim.robot.surface_gripper` during the PhysX reset callback.

Both files were running alongside several independent Kit processes
through the package scheduler. Keep their behavioral coverage, but run
each file alone and run the LEAPP cases serially. This avoids concurrent
native extension loading and shutdown without skipping tests or
increasing their timeout.

Failed jobs:

-
https://github.com/isaac-sim/IsaacLab/actions/runs/38010614299/job/114089646270
-
https://github.com/isaac-sim/IsaacLab/actions/runs/38010614299/job/114089646003

This branch is rebased onto isaac-sim#8443 after it merged.

## Validation

- [Final `Docker + Tests`
workflow](https://github.com/isaac-sim/IsaacLab/actions/runs/38016776634):
passed
- [`isaaclab_tasks
[3/3]`](https://github.com/isaac-sim/IsaacLab/actions/runs/38016776634/job/114109605708):
passed, including all four RMPFlow cases
-
[`isaaclab_rl`](https://github.com/isaac-sim/IsaacLab/actions/runs/38016776634/job/114109605911):
passed; LEAPP export flow had 17 passed and 1 unavailable-checkpoint
skip, including the Spot case
- [`rendering-correctness-kitless
(legacy)`](https://github.com/isaac-sim/IsaacLab/actions/runs/38016776634/job/114109605883):
passed with the merged isaac-sim#8443 goldens
- All PR checks passed: 49 successful and 11 intentionally skipped
- `PYTHONPATH=tools:source/isaaclab uv run pytest --noconftest
tools/test_file_scheduler.py -q` (9 passed)
- `ISAACLAB_CHANGELOG_BASE_REF=upstream/develop uv run isaaclab -f`
- `uv run python tools/changelog/cli.py check upstream/develop
--include-worktree`

### CI timing impact

Both measurements used the `Docker + Tests` workflow on `cuda:0`, the
same 18-case LEAPP suite (17 passed, 1 unavailable-checkpoint skip), its
declared mix of default PhysX, Newton MJWarp, Isaac Sim PhysX, and
OvPhysX presets, and the same restored Warp cache key (387 MB restored,
578 MB final). The runners differed, so the comparison is directional
rather than a hardware-normalized benchmark.

| | Parallel baseline | Serial candidate |
| --- | ---: | ---: |
| Revision | isaac-sim#8443 `976de17` | isaac-sim#8447 `fc66fed` |
| Runner | `g6e.4xlarge` | `g7.4xlarge` |
| Full `isaaclab_rl` job | 13m 52s | 19m 20s |
| LEAPP file wall time | 388.63s | 1051.96s |

The candidate adds about five and a half minutes to the full RL job
while keeping it far below the workflow budget. (`d6372b0`, the next
isaac-sim#8443 revision, changed only changelog-fragment text.)

## Type of change

- Bug fix (CI / test infrastructure)

## Release backport

- [x] <!-- backport-active-release --> Backport this pull request to the
active release branch after it merges into `develop`

## Screenshots

Not applicable.

## Checklist

- [x] I have read and understood the [contribution
guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html)
- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`uv run isaaclab --format`
- [x] Documentation changes are not required for this CI-only change
- [x] My changes generate no new warnings
- [x] I have validated the changed behavior with focused coverage and
applied the [test-audit
criteria](https://github.com/isaac-sim/IsaacLab/blob/develop/skills/developer/test-audit/SKILL.md)
- [x] No source package is touched, so no package changelog fragment is
required
- [x] My name already exists in `CONTRIBUTORS.md`

* Add mesh_collision_props slot to all rigid-object spawners (isaac-sim#8349)

# Description

Adds the `mesh_collision_props` fragment slot to every rigid-object
spawner: the USD, URDF and MJCF file spawners, the shape spawners and
the mesh spawners. Several deprecation messages already pointed users at
"the spawner's `mesh_collision_props` slot", but only `MeshFileCfg` had
it. This makes that guidance true and migrates the last in-repo users of
the deprecated mesh-collision cfgs.

**The slot**
- Lives on `RigidObjectSpawnerCfg`. It accepts a `{pattern: fragments}`
mapping, a bare fragment, or a list.
- Applies only to matched prims that already carry
`UsdPhysics.CollisionAPI`. It never creates a collider, and a pattern
that matches none logs a warning.
- Default target:
- File spawners use `"(/.*)?"`, meaning every collider under the spawn
prim. That matches the reach of the legacy nested
`mesh_collision_property`, so migrating authors identical USD.
- Shape and mesh spawners target their geometry prim. On mesh spawners
the slot overrides the built-in default approximation.
- Legacy `MeshCollisionBaseCfg` / `*PropertiesCfg` values are still
accepted in the slot. They are routed through the deprecated writer and
warn as before.
- Setting it together with any deformable setting raises `ValueError`,
on the mesh spawners and on the USD/URDF/MJCF file spawners.
- `MeshFileCfg` keeps its existing narrower override, which takes a bare
fragment or a list but not the `{pattern: fragments}` mapping. It
anchors at each converted mesh prim, which is a single collider, so a
mapping would add nothing.

**Deprecation guidance and docs**
- The Newton mesh/SDF collision warnings now say which fragments go in
`collision_props` and which in `mesh_collision_props`.
- The `NewtonSDFCollisionCfg` docstring said it authors an approximation
token. It doesn't, and neither did the legacy class: Newton enables SDF
from `NewtonSDFCollisionAPI` itself.
- The schema-fragments concept page and the migration guide are updated.

**nist Factory** (`factory_assets_cfg.py`): the robot, socket and plug
presets move to `collision_props` + `mesh_collision_props` fragments,
with all-`None` fragments dropped. The PhysX presets are unchanged.

**Implementation:** The spawner selects existing colliders with the
public prim matcher and calls the existing single-prim mesh-collision
writer. Coverage is folded into the existing file, shape, mesh, and
deformable suites; the two standalone test files and duplicate changelog
entry were removed.

## Verification

- **Parity on the real assets** (franka_mimic, bolt_m16, nut_m16;
schemas, every attribute and relationship): legacy and migrated are
identical. All 7 negative controls are flagged.
- **Through the gym entry point:** `IsaacContrib-Factory-Franka` cfgs
for the default, physx, isaacsim_physx and newton_mjwarp presets were
spawned and compared against develop. All 12 are identical, and the
branch emits no legacy deprecation warnings.
- **Newton runtime:** the Factory task steps 20 times on newton_mjwarp
with finite rewards.
- **Sphere collider:** the legacy path also applies
`PhysicsMeshCollisionAPI` to the franka force-sensor Sphere collider.
The slot reproduces this so that migration stays USD-identical. Newton
models built with and without it are identical, so it is inert.
- **After rebasing:** 116 kitless routing, Factory parity,
schema-fragment parity, and deprecation checks passed. The repository
formatting and changelog hooks passed. Kit integration checks are
pending CI.

## Type of change

- New feature (non-breaking change which adds functionality)

## Checklist

- [x] I have read and understood the contribution guidelines
- [x] I have run the `pre-commit` checks
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] I have added a changelog fragment under
`source/<pkg>/changelog.d/` for every touched package
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

---------

Co-authored-by: Octi Zhang <zhengyuz@nvidia.com>

* Fix convert_instanceable mesh path and migrate schema docs to fragments (isaac-sim#8353)

# Description

The schema-fragment migration left `convert_instanceable.py` passing the
removed `collision_approximation` argument to `MeshConverterCfg`, so
converting a mesh raised `TypeError`. The script now passes a
`UsdPhysicsMeshCollisionCfg` fragment, or `None` when collisions are
disabled.

`MujocoJointCfg(actuatorgravcomp=True)` also overwrote an explicitly
authored body `mjc:gravcomp=0.0`. It now supplies `1.0` only when that
attribute has no authored value. The existing joint-drive test covers
both `0.0` and a nonzero authored value.

The affected guides and Newton asset skill now use the fragment API,
with the legacy schema page labeled as deprecated. The Cartpole example
edits its existing Newton articulation fragment instead of adding a
duplicate. Deprecated PhysX schema docstrings now agree with their 3.2
removal warnings.

# Validation

- Repository formatter and pre-commit checks passed (`uv run isaaclab
-f`).
- Skill validation passed (`tools/skills/cli.py check`).
- A Kitless USD probe passed for unset, `0.0`, and `0.5` body gravcomp;
converter configuration and the Cartpole example instantiated
successfully.
- The integration test could not run locally because Isaac Sim/Kit is
unavailable in this environment. Sphinx is also unavailable locally; the
documentation build remains for CI.

---------

Co-authored-by: Octi Zhang <zhengyuz@nvidia.com>

* [CI][Auto Version Bump] Compile changelog fragments (schedule)

Bumped packages:
- isaaclab: 35.2.0 → 36.0.0
- isaaclab_experimental: 0.2.6 → 0.2.7
- isaaclab_mimic: 2.1.2 → 2.1.3
- isaaclab_newton: 9.1.5 → 9.2.0
- isaaclab_ov: 4.1.3 → 5.0.0
- isaaclab_physx: 7.4.4 → 7.5.0
- isaaclab_rl: 4.0.1 → 5.0.0
- isaaclab_tasks: 25.0.1 → 25.0.2
- isaaclab_tasks_experimental: 1.0.0 → 1.0.1
- isaaclab_teleop: 0.10.2 → 0.10.3
- isaaclab_visualizers: 2.0.2 → 3.0.0

* Fix unintended stacking cubes in Agibot place scenes (isaac-sim#8454)

# Description

Agibot Toy2Box and upright mug place tasks reused the stacking
`ObjectTableSceneCfg`. When that shared scene gained three default
stacking cubes, both place tasks also began spawning and resetting those
unrelated rigid bodies.

Introduce a dedicated `AgibotPlaceSceneCfg` with the robot, end-effector
sensor, task-supplied table, ground plane, and lighting. Toy2Box now
contains only the toy truck and box; upright mug contains only the mug.
Their existing table geometry and poses are preserved. Both Agibot Mimic
variants inherit the corrected scene.

Audited all five registered Galbot tasks: they are stacking tasks that
explicitly configure and use all three cubes, so they require no change.

The regression checks assert the place tasks' configured rigid objects.
Both cases fail on the original code because of `cube_1`, `cube_2`, and
`cube_3`, and pass with the dedicated scene. This removes the unintended
cubes involved in the reported reset issue; it does not claim to fix a
general PhysX collision defect.

## Validation

- `uv run --no-sync python -m pytest
source/isaaclab_tasks/test/contrib/test_agibot_place_env_cfg.py -q`: 5
passed. The two added cases failed on the original implementation for
the expected extra cubes.
- Instantiated and validated both registered Agibot tasks, all five
registered Galbot tasks, and both Agibot Mimic configs after resolving
presets.
- `uv run --no-sync isaaclab -f`: passed all repository formatting and
lint hooks.
- `uv run --no-sync python tools/changelog/cli.py check develop
--include-worktree`: passed.
- `git diff --cached --check`: passed.

Full Kit simulation was not completed: first launch requested acceptance
of the NVIDIA Omniverse EULA. The requested QA branch currently pins
Isaac Sim 6.1.0.0, whereas the report names 6.2 rc9; its Kit asset root
points at 6.2. The full teleop extra also failed while compiling `imgui`
2.0.0 on Python 3.12. Configuration validation used the local
`isaaclab_teleop` package without the optional XR/UI dependencies.

## Type of change

- Bug fix (non-breaking change which fixes an issue)

## Release backport

- [x] <!-- backport-active-release --> Backport this pull request to the
active release branch after it merges into `develop`

## Checklist

- [x] I have read and understood the contribution guidelines.
- [x] I have run the pre-commit checks with `uv run isaaclab --format`
(using `--no-sync` to preserve the validated environment).
- [x] I have validated the changed behavior with focused coverage and
applied the test-audit criteria.
- [x] I have added a changelog fragment for the touched package.
- [x] My name already exists in `CONTRIBUTORS.md`.
- [ ] Full Isaac Sim 6.2 rc9 visual/reset reproduction.

---------

Co-authored-by: Ege Sekkin <72572910+nvsekkin@users.noreply.github.com>
Co-authored-by: vidurv-nvidia <vidurv@nvidia.com>
Co-authored-by: Octi Zhang <zhengyuz@nvidia.com>
Co-authored-by: Antoine RICHARD <antoiner@nvidia.com>
Co-authored-by: Kelly Guo <kellyg@nvidia.com>
Co-authored-by: isaaclab-bot[bot] <282401363+isaaclab-bot[bot]@users.noreply.github.com>
Co-authored-by: Rebecca Zhang <168459200+rebeccazhang0707@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation isaac-lab Related to Isaac Lab team

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants