diff --git a/source/isaaclab/changelog.d/fix-zero-wrench-fast-path.rst b/source/isaaclab/changelog.d/fix-zero-wrench-fast-path.rst new file mode 100644 index 000000000000..1521e8f9db31 --- /dev/null +++ b/source/isaaclab/changelog.d/fix-zero-wrench-fast-path.rst @@ -0,0 +1,12 @@ +Fixed +^^^^^ + +* Fixed a per-step performance regression in :func:`~isaaclab.envs.mdp.events.apply_external_force_torque` + when the event was configured with all-zero ``force_range`` and ``torque_range`` (a common default + for tasks that declare the event term but apply no disturbance). The event was unconditionally + sampling zero wrenches and routing them through the dual-buffer ``WrenchComposer`` introduced in + PR #5265, paying the full per-step compose-and-apply cost in + :meth:`~isaaclab.assets.Articulation.write_data_to_sim` for what is semantically a no-op. The + function now returns early when both ranges are exactly zero. This restores the H1, G1, and + Anymal-C ``Velocity-Rough`` throughput observed prior to PR #5265. Behaviour for non-zero ranges + is unchanged. diff --git a/source/isaaclab/isaaclab/envs/mdp/events.py b/source/isaaclab/isaaclab/envs/mdp/events.py index 9c1c885520a9..f6cfddc2a64e 100644 --- a/source/isaaclab/isaaclab/envs/mdp/events.py +++ b/source/isaaclab/isaaclab/envs/mdp/events.py @@ -1709,6 +1709,10 @@ def apply_external_force_torque( # resolve number of bodies num_bodies = len(asset_cfg.body_ids) if isinstance(asset_cfg.body_ids, list) else asset.num_bodies + # Skip force application if the wrench ranges are zero + if force_range[0] == 0.0 and force_range[1] == 0.0 and torque_range[0] == 0.0 and torque_range[1] == 0.0: + return + # sample random forces and torques size = (len(env_ids), num_bodies, 3) forces = math_utils.sample_uniform(*force_range, size, asset.device)