Skip to content

Commit fba12ee

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into esekkin/camera-refactor
2 parents 38a65b7 + f16c3b1 commit fba12ee

6 files changed

Lines changed: 98 additions & 2 deletions

File tree

source/isaaclab/docs/CHANGELOG.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ Removed
3434
now managed internally by the renderer backend and are not part of the public API.
3535

3636

37+
4.5.28 (2026-04-10)
38+
~~~~~~~~~~~~~~~~~~~
39+
40+
Added
41+
^^^^^
42+
43+
* Added :meth:`~isaaclab.physics.PhysicsManager.wait_for_playing` hook and
44+
integrated it into :meth:`~isaaclab.sim.SimulationContext.step` so the
45+
training loop blocks while the Kit GUI timeline is paused.
46+
47+
3748
4.5.27 (2026-04-08)
3849
~~~~~~~~~~~~~~~~~~~
3950

source/isaaclab/isaaclab/physics/physics_manager.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,11 @@ def stop(cls) -> None:
324324
"""Stop physics simulation. Default is no-op."""
325325
pass
326326

327+
@classmethod
328+
def wait_for_playing(cls) -> None:
329+
"""Block until the timeline is playing. Default is no-op."""
330+
pass
331+
327332
@classmethod
328333
def get_backend(cls) -> str:
329334
"""Get the tensor backend being used ("numpy" or "torch")."""

source/isaaclab/isaaclab/sim/simulation_context.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,9 +654,15 @@ def reset(self, soft: bool = False) -> None:
654654
def step(self, render: bool = True) -> None:
655655
"""Step physics and optionally render.
656656
657+
If the timeline is paused (e.g. via the GUI), this method blocks and keeps
658+
the visualizer responsive until the timeline is resumed or stopped.
659+
657660
Args:
658661
render: Whether to render the scene after stepping. Defaults to True.
659662
"""
663+
# Block while the GUI timeline is paused so the entire training loop freezes.
664+
# See: https://github.com/isaac-sim/IsaacLab/issues/4279
665+
self.physics_manager.wait_for_playing()
660666
self._physics_step_count += 1
661667
self.physics_manager.step()
662668
if render and self.is_rendering:

source/isaaclab_physx/config/extension.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22

33
# Note: Semantic Versioning is used: https://semver.org/
4-
version = "0.5.13"
4+
version = "0.5.14"
55

66
# Description
77
title = "PhysX simulation interfaces for IsaacLab core package"

source/isaaclab_physx/docs/CHANGELOG.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
Changelog
22
---------
33

4+
0.5.14 (2026-04-06)
5+
~~~~~~~~~~~~~~~~~~~
6+
7+
Fixed
8+
^^^^^
9+
10+
* Fixed the simulation training loop not pausing when the Kit GUI timeline is
11+
paused. :meth:`~isaaclab_physx.physics.PhysxManager.wait_for_playing` now
12+
blocks and keeps the GUI responsive until the timeline is resumed or stopped.
13+
* Fixed articulation visualization freezing after pausing and unpausing the
14+
simulation through the headed GUI in Isaac Sim 5.1+. Articulation meshes now
15+
remain visually updated after resuming.
16+
17+
418
0.5.13 (2026-03-25)
519
~~~~~~~~~~~~~~~~~~~
620

source/isaaclab_physx/isaaclab_physx/physics/physx_manager.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import omni.physx
2929
import omni.timeline
3030
import omni.usd
31-
from pxr import Sdf
31+
from pxr import Sdf, UsdUtils
3232

3333
import isaaclab.sim as sim_utils
3434
from isaaclab.physics import CallbackHandle, PhysicsEvent, PhysicsManager
@@ -290,6 +290,30 @@ def stop(cls) -> None:
290290
# Pump events so timeline callbacks fire synchronously
291291
omni.kit.app.get_app().update()
292292

293+
@classmethod
294+
def wait_for_playing(cls) -> None:
295+
"""Block until the timeline is playing, keeping the GUI responsive.
296+
297+
After resume, forces a fabric re-sync so articulation meshes unfreeze.
298+
See: https://github.com/isaac-sim/IsaacLab/issues/4279
299+
"""
300+
if cls._timeline.is_playing():
301+
return
302+
app = omni.kit.app.get_app()
303+
while not cls._timeline.is_playing():
304+
app.update()
305+
if cls._timeline.is_stopped():
306+
break
307+
# Force fabric to re-sync articulation transforms after resume.
308+
# detach/attach resets the FabricManager, then we immediately push
309+
# current poses so the first render after resume shows correct state.
310+
if not cls._timeline.is_stopped():
311+
cls._re_sync_fabric()
312+
if cls._view is not None:
313+
cls._view.update_articulations_kinematic()
314+
if cls._update_fabric is not None:
315+
cls._update_fabric(0.0, 0.0)
316+
293317
@classmethod
294318
def close(cls) -> None:
295319
"""Clean up physics resources."""
@@ -585,6 +609,42 @@ def _load_fabric(cls) -> None:
585609
sim.set_setting("/isaaclab/fabric_enabled", use_fabric) # type: ignore[union-attr]
586610
sim.set_setting("/physics/visualizationDisplaySimulationOutput", False) # type: ignore[union-attr]
587611

612+
@classmethod
613+
def _re_sync_fabric(cls) -> None:
614+
"""Force the PhysX fabric extension to re-synchronize after a pause/resume transition.
615+
616+
Starting with PhysX fabric 107.3.21 (Isaac Sim 5.1), the FabricManager skips writing
617+
initial articulation poses to fabric on subsequent resumes, causing articulation meshes
618+
to freeze visually while physics continues to run.
619+
620+
The workaround detaches and re-attaches the USD stage on the fabric interface, forcing
621+
the FabricManager to fully reinitialize and write transforms into fabric so that Hydra
622+
picks them up.
623+
"""
624+
if cls._fabric is None:
625+
return
626+
sim = PhysicsManager._sim
627+
if sim is None:
628+
return
629+
stage = sim.stage
630+
if stage is None:
631+
return
632+
stage_id = UsdUtils.StageCache.Get().GetId(stage).ToLongInt()
633+
if stage_id <= 0:
634+
return
635+
try:
636+
cls._fabric.detach_stage()
637+
except Exception:
638+
logger.warning("Failed to detach fabric stage during re-sync. Articulation visuals may be stale.")
639+
return
640+
try:
641+
cls._fabric.attach_stage(stage_id)
642+
except Exception:
643+
logger.error(
644+
"Could not re-attach fabric stage. Articulation visuals will be broken until next reset.",
645+
exc_info=True,
646+
)
647+
588648
@classmethod
589649
def _warmup_and_create_views(cls) -> None:
590650
"""Warm-start physics and create simulation views."""

0 commit comments

Comments
 (0)