Skips apply_external_force_torque when both ranges are zero#5688
Conversation
Documents the early-return added to apply_external_force_torque when force_range and torque_range are both zero, restoring H1/G1/Anymal-C Velocity-Rough throughput regressed by the WrenchComposer rework in isaac-sim#5265. Refs: isaac-sim/IsaacLab-Internal#906, isaac-sim/IsaacLab-Internal#911
There was a problem hiding this comment.
Review Summary
TL;DR: Clean performance fix — the early-return logic is correct and well-documented. The change restores throughput for zero-wrench configurations by avoiding unnecessary WrenchComposer overhead.
⚠️ Base Branch Note
This PR targets main but shows 2214 files changed due to develop divergence. The actual meaningful change is isolated to:
source/isaaclab/isaaclab/envs/mdp/events.py— 4 lines addedsource/isaaclab/changelog.d/fix-zero-wrench-fast-path.rst— changelog fragment
Please consider rebasing onto main or develop to clean up the diff.
Code Review
The Change (events.py):
# 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:
returnAnalysis:
-
Correctness ✅ — Applying a zero wrench is semantically equivalent to not applying one. The early-return correctly short-circuits when both
force_rangeandtorque_rangeare(0.0, 0.0). -
Edge cases ✅ — The comparison uses exact floating-point equality (
== 0.0), which is appropriate here since these are user-provided configuration values, not computed results subject to floating-point error. -
Backward compatibility ✅ — Non-zero ranges behave identically to before. The
WrenchComposerdual-buffer architecture (PR #5265) is untouched. -
Performance rationale ✅ — The PR description explains the regression: zero-wrench configs were paying full per-step compose-and-apply costs for a no-op. This fix restores throughput for H1, G1, and Anymal-C
Velocity-Roughtasks.
Minor Suggestions
-
Consider tuple comparison for readability:
if force_range == (0.0, 0.0) and torque_range == (0.0, 0.0): return
This is functionally equivalent but slightly more readable.
-
Changelog fragment looks good — correctly documents the fix with links to the relevant PRs (#5265) and describes the regression context.
Checklist
- Builds successfully (CI
labelerpassed) - Code logic is correct
- Changelog fragment included
- No breaking changes
- CI: Full test suite not yet run (only
labelercheck visible — base branch issue may be blocking)
Verdict: LGTM pending rebase to clean up the base branch diff.
Update (67e0b1d): ✅ The base branch issue has been resolved — the PR now correctly targets develop. The rebase introduced significant unrelated changes in the commit comparison (contact sensors, Newton actuators, Isaac Teleop MCAP support, etc.) but the actual functional change in this PR remains unchanged: the early-return optimization in apply_external_force_torque when both ranges are zero. No further action needed — this PR is ready for merge.
Description
Fast-path early-return in :func:
~isaaclab.envs.mdp.events.apply_external_force_torquewhen bothforce_rangeandtorque_rangeare exactly zero — a common configuration for tasks that declare the event term but apply no disturbance.Before this change, zero-wrench configurations were still sampled, written into the dual-buffer
WrenchComposerintroduced in #5265, and pushed through the per-step compose-and-apply path inArticulation.write_data_to_sim, paying the full per-step cost for what is semantically a no-op. Applying a zero wrench is equivalent to not applying one at all, so the function now returns immediately when both ranges are zero.This restores the H1, G1, and Anymal-C
Velocity-Roughthroughput observed prior to #5265, as recorded in the OmniPerf DB regression flagged inisaac-sim/IsaacLab-Internal#906.Scope limitation. This only addresses the zero-force case. Tasks that apply non-zero external forces (curriculum disturbances, push events, domain-randomized wrenches) still pay the per-step body-frame recompose cost under the new dual-buffer architecture. That broader optimization (compose caching / kernel fusion) is tracked separately in
isaac-sim/IsaacLab-Internal#911and is out of scope here.Correctness. The dual-buffer
WrenchComposerarchitecture from #5265 is untouched; this fix sits one layer above it in the event term. For any non-zeroforce_rangeortorque_range, the early-return predicate is false and behavior is unchanged.Fixes
isaac-sim/IsaacLab-Internal#906Follow-up:
isaac-sim/IsaacLab-Internal#911Type of change
Screenshots
N/A — performance fix, no user-visible behavior change.
Checklist
pre-commitchecks with./isaaclab.sh --formatsource/<pkg>/changelog.d/for every touched package (do not editCHANGELOG.rstor bumpextension.toml— CI handles that)CONTRIBUTORS.mdor my name already exists there