From ebf86180bbbd4037fe12d5c52570ec964451cac6 Mon Sep 17 00:00:00 2001 From: nvsekkin Date: Tue, 19 May 2026 13:03:39 -0700 Subject: [PATCH 1/3] Remove stale xfail decorator --- .../changelog.d/esekkin-pr-a-newton-xfail.rst | 6 ++++++ source/isaaclab_tasks/test/test_environments_newton.py | 8 -------- 2 files changed, 6 insertions(+), 8 deletions(-) create mode 100644 source/isaaclab_tasks/changelog.d/esekkin-pr-a-newton-xfail.rst diff --git a/source/isaaclab_tasks/changelog.d/esekkin-pr-a-newton-xfail.rst b/source/isaaclab_tasks/changelog.d/esekkin-pr-a-newton-xfail.rst new file mode 100644 index 000000000000..46deff6be8a0 --- /dev/null +++ b/source/isaaclab_tasks/changelog.d/esekkin-pr-a-newton-xfail.rst @@ -0,0 +1,6 @@ +Fixed +^^^^^ + +* Removed the stale file-level ``@pytest.mark.xfail`` decorator on + ``test_environments_newton`` (the cited Hydra deep-nesting issue was already + resolved by PR #5029 and follow-ups #5130 / #5177). \ No newline at end of file diff --git a/source/isaaclab_tasks/test/test_environments_newton.py b/source/isaaclab_tasks/test/test_environments_newton.py index 23456946a689..1915d8a649b3 100644 --- a/source/isaaclab_tasks/test/test_environments_newton.py +++ b/source/isaaclab_tasks/test/test_environments_newton.py @@ -36,14 +36,6 @@ ), ) @pytest.mark.newton_ci -@pytest.mark.xfail( - reason=( - "TODO: Nested PresetCfg resolution for named presets (e.g. 'newton_mjwarp') is not yet supported. " - "The logic in parse_cfg.apply_named_preset should be unified with the deep-nesting " - "fixes in https://github.com/isaac-sim/IsaacLab/pull/5029 (isaaclab_tasks.utils.hydra)." - ), - strict=False, -) def test_environments_newton(task_name, num_envs, device): # run environments with MJWarp physics preset _run_environments(task_name, device, num_envs, physics_preset_name="newton_mjwarp", create_stage_in_memory=False) From 8165d66e6ba8584e1cdd6c9530bd38e398b9df92 Mon Sep 17 00:00:00 2001 From: nvsekkin Date: Tue, 19 May 2026 13:48:57 -0700 Subject: [PATCH 2/3] Add newline --- source/isaaclab_tasks/changelog.d/esekkin-pr-a-newton-xfail.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/isaaclab_tasks/changelog.d/esekkin-pr-a-newton-xfail.rst b/source/isaaclab_tasks/changelog.d/esekkin-pr-a-newton-xfail.rst index 46deff6be8a0..42736dca455b 100644 --- a/source/isaaclab_tasks/changelog.d/esekkin-pr-a-newton-xfail.rst +++ b/source/isaaclab_tasks/changelog.d/esekkin-pr-a-newton-xfail.rst @@ -3,4 +3,4 @@ Fixed * Removed the stale file-level ``@pytest.mark.xfail`` decorator on ``test_environments_newton`` (the cited Hydra deep-nesting issue was already - resolved by PR #5029 and follow-ups #5130 / #5177). \ No newline at end of file + resolved by PR #5029 and follow-ups #5130 / #5177). From d3e33ae38b435d107b6fc32686da2a5438cf8b51 Mon Sep 17 00:00:00 2001 From: nvsekkin Date: Wed, 20 May 2026 15:20:27 -0700 Subject: [PATCH 3/3] Fire interval event handlers earlier --- .../esekkin-force-interval-events.skip | 5 ++ source/isaaclab_tasks/test/env_test_utils.py | 47 ++++++++++++++++++- .../isaaclab_tasks/test/test_environments.py | 8 +++- 3 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 source/isaaclab_tasks/changelog.d/esekkin-force-interval-events.skip diff --git a/source/isaaclab_tasks/changelog.d/esekkin-force-interval-events.skip b/source/isaaclab_tasks/changelog.d/esekkin-force-interval-events.skip new file mode 100644 index 000000000000..eed9e7244538 --- /dev/null +++ b/source/isaaclab_tasks/changelog.d/esekkin-force-interval-events.skip @@ -0,0 +1,5 @@ +Test-only change. + +* Reduced the default ``num_steps`` from 100 to 20 in ``_run_environments``. +* Tuned ``test_environments`` to pass ``force_interval_events=True`` so ``EventManager`` interval handlers + (e.g. locomotion ``push_robot``) run on step 1 instead of never firing within the legacy step budget. diff --git a/source/isaaclab_tasks/test/env_test_utils.py b/source/isaaclab_tasks/test/env_test_utils.py index cde4db9a3693..525e3e8770b0 100644 --- a/source/isaaclab_tasks/test/env_test_utils.py +++ b/source/isaaclab_tasks/test/env_test_utils.py @@ -217,15 +217,49 @@ def setup_environment( ] +def _force_interval_events_to_fire_immediately(env_cfg) -> None: + """Rewrite every interval-mode event term so it fires on the first ``step()``. + + The :class:`isaaclab.managers.EventManager` samples ``time_left`` from + ``interval_range_s`` at reset, then fires the term once ``time_left < 1e-6`` + after subtracting ``dt`` each step. Setting both bounds of the range to + ``1e-6`` guarantees the sampled ``time_left`` lands at the trigger threshold + on the first step, regardless of ``is_global_time``. + + Mutates ``env_cfg.events`` in place. No-op if ``env_cfg.events`` is ``None`` + or has no interval-mode terms. + + Args: + env_cfg: A parsed env config. + """ + events_cfg = getattr(env_cfg, "events", None) + if events_cfg is None: + return + for term_name in dir(events_cfg): + if term_name.startswith("_"): + continue + try: + term = getattr(events_cfg, term_name, None) + except AttributeError: + continue + if ( + term is not None + and getattr(term, "mode", None) == "interval" + and getattr(term, "interval_range_s", None) is not None + ): + term.interval_range_s = (1e-6, 1e-6) + + def _run_environments( task_name, device, num_envs, - num_steps=100, + num_steps=20, multi_agent=False, create_stage_in_memory=False, disable_clone_in_fabric=False, physics_preset_name: str | None = None, + force_interval_events: bool = False, ): """Run all environments and check environments return valid signals. @@ -239,6 +273,8 @@ def _run_environments( disable_clone_in_fabric: Whether to disable fabric cloning. physics_preset_name: Name of the physics preset to apply (e.g., 'newton_mjwarp'). If None, uses the environment's default physics. + force_interval_events: If True, rewrite interval-mode event terms so they + fire on the first ``step()``. """ # skip test if stage in memory is not supported @@ -300,6 +336,7 @@ def _run_environments( create_stage_in_memory=create_stage_in_memory, disable_clone_in_fabric=disable_clone_in_fabric, physics_preset_name=physics_preset_name, + force_interval_events=force_interval_events, ) print(f""">>> Closing environment: {task_name}""") print("-" * 80) @@ -309,11 +346,12 @@ def _check_random_actions( task_name: str, device: str, num_envs: int, - num_steps: int = 100, + num_steps: int = 20, multi_agent: bool = False, create_stage_in_memory: bool = False, disable_clone_in_fabric: bool = False, physics_preset_name: str | None = None, + force_interval_events: bool = False, ): """Run random actions and check environments return valid signals. @@ -327,6 +365,8 @@ def _check_random_actions( disable_clone_in_fabric: Whether to disable fabric cloning. physics_preset_name: Name of the physics preset to apply (e.g., 'newton_mjwarp'). If None, uses the environment's default physics. + force_interval_events: If True, rewrite interval-mode event terms so they + fire on the first ``step()``. """ # create a new context stage, if stage in memory is not enabled if not create_stage_in_memory: @@ -355,6 +395,9 @@ def _check_random_actions( if disable_clone_in_fabric: env_cfg.scene.clone_in_fabric = False + if force_interval_events: + _force_interval_events_to_fire_immediately(env_cfg) + # filter based off multi agents mode and create env if multi_agent: if not hasattr(env_cfg, "possible_agents"): diff --git a/source/isaaclab_tasks/test/test_environments.py b/source/isaaclab_tasks/test/test_environments.py index 6f9da001b514..a56a030a0e15 100644 --- a/source/isaaclab_tasks/test/test_environments.py +++ b/source/isaaclab_tasks/test/test_environments.py @@ -37,4 +37,10 @@ @pytest.mark.isaacsim_ci def test_environments(task_name, num_envs, device): # run environments without stage in memory - _run_environments(task_name, device, num_envs, create_stage_in_memory=False) + _run_environments( + task_name, + device, + num_envs, + force_interval_events=True, + create_stage_in_memory=False, + )