Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 0 additions & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,6 @@ jobs:
test_rendering_lift_kuka_hetero.py,
test_rendering_lift_kuka_homo.py,
test_rendering_franka_cloth.py,
test_rendering_franka_soft.py,
test_rendering_franka_cable.py,
test_rendering_registered_tasks.py,
test_rendering_shadow_hand.py
Expand Down
5 changes: 5 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
- Keep related public symbols discoverable through consistent prefixes.
- Keep joint-wrench sensor coverage separate from articulation control-joint selection. Reuse cached
body bindings without changing the shared view's joint filters or creating a second view for sensing.
- Keep articulation ordering maps on articulation data; do not mirror maps or add cached ordering flags.
- Keep backend ownership on `SimulationContext`, using backend type and configuration rather than service
locators, resource keys, or separate renderer registries.
- Renderers consume geometry through `SceneDataProvider`. Keep Newton imports out of OVRTX renderers
and Fabric destination ownership and shadow remapping out of physics backends.
- For external wrenches, follow the asset API's `is_global` boolean and `_b`/`_w` buffer naming. Keep
frame conversion decisions in `WrenchComposer` and track pending contributions with plain booleans;
do not introduce frame enums, content bitmasks, or a classification layer.
Expand Down
17 changes: 13 additions & 4 deletions docs/source/api/lab/isaaclab.sim.schemas.rst
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,19 @@ Tendon
.. autofunction:: modify_fixed_tendon_properties
.. autofunction:: modify_spatial_tendon_properties

Tendon cfg classes are PhysX-only and live in
:mod:`isaaclab_physx.sim.schemas`
(:class:`~isaaclab_physx.sim.schemas.PhysxFixedTendonPropertiesCfg`,
:class:`~isaaclab_physx.sim.schemas.PhysxSpatialTendonPropertiesCfg`).
PhysX tendon schemas are configured through :mod:`isaaclab_physx.sim.schemas`.
Newton's MuJoCo solver also supports tendons;
:class:`~isaaclab_newton.sim.schemas.MujocoFixedTendonCfg` tunes fixed-tendon spring stiffness and damping.

Position limits specify a range of the accumulated tendon coordinate on both backends. Their force response
uses different parameters: PhysX uses force stiffness and shares tendon damping with the limit, while
MuJoCo uses separate ``solreflimit`` and ``solimplimit`` parameters. Newton already
`converts force gains for joint limits
<https://github.com/newton-physics/newton/blob/v1.6.0/newton/_src/solvers/mujoco/kernels.py#L2622-L2732>`_
using inverse inertia and impedance. The corresponding tendon conversion is not implemented, so Isaac Lab's
shared tendon limit-stiffness API still raises :class:`NotImplementedError`. This is an implementation gap;
MuJoCo supports stiffness/damping through its
`solver parameters <https://mujoco.readthedocs.io/en/stable/modeling.html#reference>`_.

Deformable Body
---------------
Expand Down
87 changes: 63 additions & 24 deletions docs/source/developer-tools/scene_data_providers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Scene Data Provider

:class:`~isaaclab.scene_data.SceneDataProvider` bridges physics simulation backends and the
visualizers/renderers that consume scene data. It exposes a single Warp-native read path for
body transforms regardless of which physics backend (PhysX or Newton) is active, so renderers
body transforms and visual geometry regardless of which physics backend is active, so renderers
and visualizers can stay backend-agnostic.

Overview
Expand Down Expand Up @@ -44,11 +44,14 @@ The system has three layers:
- :attr:`SceneDataBackend.transform_paths`: list of USD prim paths, one per transform.
- :attr:`SceneDataBackend.native_transform_formats`: formats published without conversion.
PhysX publishes either packed poses or Fabric matrices and refreshes only the requested representation.
- :attr:`SceneDataBackend.points`: flattened deformable nodal positions as
:class:`SceneDataFormat.Points` (optional; rigid-only backends return an empty buffer).
- :attr:`SceneDataBackend.point_count`: total number of geometry points.
- :attr:`SceneDataBackend.geometry_paths`: one USD prim path per deformable body instance.
- :attr:`SceneDataBackend.geometry_counts`: unpadded nodal count per geometry entity.
- :meth:`SceneDataBackend.get_geometry_batches`: native point arrays or interpolation inputs,
paired with exact visual prim paths and ranges compiled during backend construction. It returns
the requested native representation when available, otherwise the primary representations for
SDP to convert. The return type is always a list of batches, including native Fabric.
- :attr:`SceneDataBackend.geometry_timestamp`: logical update timestamp, advanced for same-step
writes and native pointer swaps. Cached outputs record the timestamp they contain, like asset
data buffers. This is not elapsed simulation time or a shared dirty flag that a reader clears.
- :attr:`SceneDataBackend.native_geometry_formats`: geometry formats available without conversion.

2. :class:`~isaaclab.scene_data.SceneDataProvider`: wraps a backend and offers format conversion
plus index re-mapping.
Expand All @@ -60,11 +63,12 @@ The system has three layers:
- :meth:`SceneDataProvider.create_mapping`: builds a remap array from the backend's prim
paths to a consumer's desired ordering. Used when a renderer or visualizer wants
transforms indexed by its own body list rather than by the physics view order.
- :meth:`SceneDataProvider.get_points`: copies backend deformable nodal positions into a
consumer buffer, optionally remapping entity slices via
:meth:`SceneDataProvider.create_geometry_mapping`.
- :meth:`SceneDataProvider.create_geometry_mapping`: maps backend deformable entities to
consumer particle offsets in a shadow Newton ``particle_q`` buffer.
- :meth:`SceneDataProvider.get_geometry_points`: read-only world-space point views keyed by
exact visual prim path. Native point ranges alias the producer; interpolation and destination
reordering are fused into one cached conversion. Consumers with fixed native storage pass
that array or ``FabricPoints`` as ``output`` and visual-path offsets as ``offsets``. These
calls return the supplied destination. Destination caches retain indexing metadata, not the
consumer's buffers, and expire with the destination.
- :meth:`SceneDataProvider.get_camera_transforms`: discovers per-camera, per-env world
transforms from the USD stage.
- :attr:`SceneDataProvider.usd_stage`: USD stage handle for stage-walking consumers.
Expand Down Expand Up @@ -96,17 +100,14 @@ the shared clone plan before initialization. Its rigid ``body_q`` binds to SDP's
``Transform`` array; no intermediate per-frame copy into a second state buffer is required.
OVRTX requests ``TransposedMatrix44d`` directly from SDP, including destination ordering and
static scale in the same conversion. It no longer reads Newton state for rigid transforms.
When the scene has PhysX or OVPhysX deformables, the shadow model also allocates
``particle_q`` render slots for soft/cloth meshes, syncs simulation nodal positions through
:meth:`SceneDataProvider.get_points` with ``allow_passthrough=False`` into a separate
sim-sized buffer, and remaps or copies those positions into the render-sized ``particle_q``
buffer each frame. Volume deformables with mismatched sim and visual vertex counts use a
barycentric sim-to-visual remap so Newton Warp and OVRTX render the paired visual mesh rather
than tet simulation topology. The shadow deformable registry exposes render-slot offsets and
``particles_per_body`` counts for OVRTX point bindings.

The deformable and cable geometry bridge remains separate from this rigid-transform path.
OVRTX still uses Newton geometry metadata for those features.
For deformables with different simulation and visual meshes, the producer compiles barycentric
indices and weights from the declared prototype once. SDP applies that interpolation directly into
the Newton representation's final ``particle_q`` slots. There is no intermediate simulation-sized
buffer and no consumer-owned remap. Native PhysX padded nodal arrays are borrowed without packing.

OVRTX receives the same exact visual-path publications through SDP. It neither imports Newton
managers nor requests a Newton model. Meshes, particle clouds, and cable curves use one point-binding
path.

PhysX owns its native Fabric refresh and publishes the resulting matrices through SDP without
fetching packed poses. ``isaaclab_physx.renderers.fabric.FabricBackend`` owns the shared native stage
Expand All @@ -124,7 +125,13 @@ bound once. Fabric's selection reuse API reports scene-wide structural changes;
array views without repeating path matching or scale capture. Otherwise GPU propagation
reuses the hierarchy topology. Clean requests never acquire writable Fabric arrays.
Renderers do not select a physics-specific synchronization path.
``FabricMatrix44`` contains only matrix storage, not bindings or native engine handles.
The same Fabric resource receives geometry through ``update_geometries(provider, frame)``.
PhysX publishes its native ``FabricPoints`` without a conversion or rewrite. Foreign mesh points
are interpolated directly into GPU Fabric storage. The current Kit Hydra path requires CPU Fabric
destinations for ``Points`` and ``BasisCurves``; SDP handles their device transfer without USD
attribute writes. Only destinations whose update interval has elapsed are transferred. World-space
point destinations reset their transform stack to avoid applying the environment or body pose twice.
``FabricMatrix44`` and ``FabricPoints`` contain only array storage, not bindings or native engine handles.

Newton backend
--------------
Expand All @@ -142,6 +149,38 @@ Externally replayed CUDA graphs do not call Python write hooks. After writes hav
Newton conservatively republishes transforms when read so an unannounced replay cannot leave
rendering stale. Those reads do not benefit from clean-publication caching.

Geometry publication
--------------------

Newton deformable and MPM positions are direct views of native ``particle_q`` ranges. Cable
publications borrow native body poses and capsule parameters; SDP derives curve endpoints once
per update timestamp. Both camera renderers and viewers consume the same cached result.

``ClonePlan`` remains a generic replication and routing description. Asset construction authors
prototype geometry; native import combines those prototypes with the plan and records native
ranges. Consumers bind to those completed resources, never rediscovering the completed stage.

.. code-block:: python

# Default: read-only native or converted views, cached by producer timestamp.
points_by_path = provider.get_geometry_points()

# A consumer with fixed native storage receives the conversion directly.
provider.get_geometry_points(output=state.particle_q, offsets=visual_path_offsets)

# A Fabric consumer supplies native storage and its exact visual-path row indices.
provider.get_geometry_points(output=fabric_points, offsets=visual_path_rows)

The internal flat-node queries and physics-owned geometry sync methods were removed. Rendering
consumers use ``get_geometry_points``; physics managers no longer run geometry writers from ``pre_render``.

As in articulation and rigid-object data, the current timestamp and a cached buffer's timestamp
serve different purposes: one identifies current state; the other identifies the state in that buffer.
Asset data advances ``_sim_timestamp`` with time and invalidates dependent buffers on same-step writes.
SDP instead advances ``geometry_timestamp`` on those writes, so independently updated consumers all see
the change. The output's cache owns its freshness check; a downstream upload or BVH may need its own
invalidation, but should not repeat the conversion's cache bookkeeping.

Data requirements
------------------

Expand Down Expand Up @@ -173,7 +212,7 @@ consumer construction time, before the shared clone plan is built:
- Yes
- No
* - OVRTX renderer
- Yes
- No
- Yes

See Also
Expand Down
14 changes: 12 additions & 2 deletions docs/source/how-to/cloning.rst
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,21 @@ fields listed below are that table's columns:
- Optional per-env world positions [m], shape ``[num_envs, 3]``.
* - ``global_paths``
- Unique prim paths for scene assets shared by every env and therefore not replicated.
* - ``cfg_rows``
- Asset configuration identities mapped to the rows they own.
* - ``context_rows``
- Clone-context types mapped to the rows they consume.

The plan does not own a stage. Simulation-owned contexts supply their own runtime
when they consume it.
The plan describes replication and routing, not asset geometry or native state. Asset
construction authors the prototypes. Each backend imports its declared roots and records
the geometry-to-native mappings needed by its consumers; consumers bind after native
initialization. Clone contexts apply the plan but do not own native runtime resources.

Deformable imports read prototype meshes and expand their paths through the plan without
copying vertex arrays per environment. Newton cable imports retain ordered native segment
bindings. MPM spawners author render points under the asset before cloning, then bind the
importer's particle ranges. None requires geometry-specific fields on ``ClonePlan`` or
discovery of the completed replicated scene.

When every env is a copy of env_0:

Expand Down
16 changes: 8 additions & 8 deletions docs/source/refs/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -713,10 +713,10 @@ Please make sure that you add tests for your changes.
./isaaclab.sh --test # or "./isaaclab.sh -t"

# Run all tests in a particular file
uv run python -m pytest source/isaaclab/test/deps/test_torch.py
uv run python -m pytest source/isaaclab/test/utils/test_circular_buffer.py

# Run a particular test
uv run python -m pytest source/isaaclab/test/deps/test_torch.py::test_array_slicing
uv run python -m pytest source/isaaclab/test/utils/test_circular_buffer.py::test_reset

.. tab-item:: isaaclab.sh / isaaclab.bat

Expand All @@ -726,10 +726,10 @@ Please make sure that you add tests for your changes.
./isaaclab.sh --test # or "./isaaclab.sh -t"

# Run all tests in a particular file
./isaaclab.sh -p -m pytest source/isaaclab/test/deps/test_torch.py
./isaaclab.sh -p -m pytest source/isaaclab/test/utils/test_circular_buffer.py

# Run a particular test
./isaaclab.sh -p -m pytest source/isaaclab/test/deps/test_torch.py::test_array_slicing
./isaaclab.sh -p -m pytest source/isaaclab/test/utils/test_circular_buffer.py::test_reset

.. tab-item:: :icon:`fa-brands fa-windows` Windows
:sync: windows
Expand All @@ -744,10 +744,10 @@ Please make sure that you add tests for your changes.
isaaclab.bat --test # or "isaaclab.bat -t"

# Run all tests in a particular file
uv run python -m pytest source/isaaclab/test/deps/test_torch.py
uv run python -m pytest source/isaaclab/test/utils/test_circular_buffer.py

# Run a particular test
uv run python -m pytest source/isaaclab/test/deps/test_torch.py::test_array_slicing
uv run python -m pytest source/isaaclab/test/utils/test_circular_buffer.py::test_reset


.. tab-item:: isaaclab.sh / isaaclab.bat
Expand All @@ -758,10 +758,10 @@ Please make sure that you add tests for your changes.
isaaclab.bat --test # or "isaaclab.bat -t"

# Run all tests in a particular file
isaaclab.bat -p -m pytest source/isaaclab/test/deps/test_torch.py
isaaclab.bat -p -m pytest source/isaaclab/test/utils/test_circular_buffer.py

# Run a particular test
isaaclab.bat -p -m pytest source/isaaclab/test/deps/test_torch.py::test_array_slicing
isaaclab.bat -p -m pytest source/isaaclab/test/utils/test_circular_buffer.py::test_reset

All of these commands exit with a nonzero code when tests fail, so a test
failure fails the invoking shell or CI step as well.
Expand Down
14 changes: 0 additions & 14 deletions source/isaaclab/changelog.d/controller-fixes.rst

This file was deleted.

10 changes: 10 additions & 0 deletions source/isaaclab/changelog.d/core-cleanup-backend-routing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Fixed
^^^^^

* Fixed :class:`~isaaclab.envs.mdp.events.randomize_joint_parameters` choosing the friction write path by the
physics manager name. It now randomizes dynamic friction whenever the asset exposes it, which also covers
OVPhysX explicitly, and its invalid-operation error names the right term.
* Fixed :class:`~isaaclab.envs.mdp.events.randomize_rigid_body_com` choosing the center of mass layout by the
physics manager name; it passes poses to every backend.
* Fixed :func:`~isaaclab.envs.mdp.events.randomize_rigid_body_scale` detecting articulations by class name
instead of :class:`~isaaclab.assets.BaseArticulation`.

This file was deleted.

14 changes: 14 additions & 0 deletions source/isaaclab/changelog.d/core-cleanup-envs-managers-fixes.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Fixed
^^^^^

* Fixed :class:`~isaaclab.envs.mdp.events.randomize_fixed_tendon_parameters` raising ``NotImplementedError``
for limit stiffness, rest length, and offset on the PhysX and OVPhysX backends. The term
no longer checks the physics backend; it calls the asset setters, and a backend that does not support a
property raises ``NotImplementedError`` itself.
* Fixed :class:`~isaaclab.envs.mdp.events.randomize_fixed_tendon_parameters` passing tensors with an extra
dimension to the fixed tendon setters when all tendons are selected.
* Fixed :class:`~isaaclab.envs.mdp.curriculums.modify_env_param` failing on addresses that index into a
dictionary value, such as ``"params.ranges[1].high"``.
* Fixed :class:`~isaaclab.managers.EventManager` not calling :meth:`~isaaclab.managers.ManagerTermBase.reset`
on class-based event terms when the manager is created while the simulation is playing. Class-based
``"prestartup"`` terms are now also reset with the manager.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Test coverage for fixed tendon position limits.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading
Loading