Skip to content

Commit f16c3b1

Browse files
garylvovclaudeAntoineRichard
authored
Fixes Pausing and Unpausing in KIT GUI (#5178)
# Description Previously, when pausing the Kit GUI, the viz markers would keep moving regardless of pause state, and articulations would remain paused even when the simulation was unpaused (played). This fixes the kit gui visualization to respect the pause state (targeting ``develop``). Fixes #4279 (when this issue was reported, on ``main``, the viz markers would be paused correctly, but the articulations would remain paused after unpausing, hotfix for ``main`` here for reference: https://gist.github.com/garylvov/9919d936d0393d548d51d7deaf473402) <!-- As a practice, it is recommended to open an issue to have discussions on the proposed pull request. This makes it easier for the community to keep track of what is being developed or added, and if a given feature is demanded by more than one party. --> ## Type of change <!-- As you go through the list, delete the ones that are not applicable. --> - Bug fix (non-breaking change which fixes an issue) ## Screenshots Tested with ``python scripts/reinforcement_learning/rsl_rl/train.py --task Isaac-Velocity-Flat-Anymal-D-v0 --num_envs 4 --viz kit`` Before fix, on ``develop`` ![pause_unpause_broken](https://github.com/user-attachments/assets/8b923fef-d528-48ea-811e-fc623fb62baa) After fix, on ``develop`` ![pause_unpause_develop_fixed](https://github.com/user-attachments/assets/044735a9-49c7-4279-a874-405ce15c5c30) ## 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 `./isaaclab.sh --format` - [X] I have made corresponding changes to the documentation - [X] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [X] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [X] I have added my name to the `CONTRIBUTORS.md` or my name already exists there <!-- --------- Signed-off-by: garylvov <67614381+garylvov@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Antoine RICHARD <antoiner@nvidia.com>
1 parent df77fe7 commit f16c3b1

7 files changed

Lines changed: 99 additions & 3 deletions

File tree

source/isaaclab/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 = "4.5.27"
4+
version = "4.5.28"
55

66
# Description
77
title = "Isaac Lab framework for Robot Learning"

source/isaaclab/docs/CHANGELOG.rst

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

4+
4.5.28 (2026-04-10)
5+
~~~~~~~~~~~~~~~~~~~
6+
7+
Added
8+
^^^^^
9+
10+
* Added :meth:`~isaaclab.physics.PhysicsManager.wait_for_playing` hook and
11+
integrated it into :meth:`~isaaclab.sim.SimulationContext.step` so the
12+
training loop blocks while the Kit GUI timeline is paused.
13+
14+
415
4.5.27 (2026-04-08)
516
~~~~~~~~~~~~~~~~~~~
617

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)