[release/3.0.0-beta2] Fix LEAPP projected gravity export#6079
Conversation
The current LEAPP export emits projected_gravity as an input instead of root_quat_w. With Warp-backed observation terms, LEAPP can no longer automatically trace projected gravity back to root_quat_w, so this backport handles that mapping manually until LEAPP has Warp support. Changes: - Export mdp.projected_gravity through root_quat_w for LEAPP graphs. - Keep the policy observation as projected gravity by computing it inside the exported graph. - Add regression coverage and changelog fragments. (cherry picked from commit 74f9e8e)
There was a problem hiding this comment.
🤖 Isaac Lab Review Bot — PR #6079
Title: [release/3.0.0-beta2] Fix LEAPP projected gravity export
Verdict: ✅ Looks Good (minor suggestions below)
Summary
Clean cherry-pick of #6007 that fixes the LEAPP export so mdp.projected_gravity exposes root_quat_w as the graph input boundary and computes projected gravity analytically inside the exported graph. The fix is necessary because the Warp-backed observation terms prevent LEAPP from automatically tracing back through the quaternion-to-gravity projection.
🔵 Suggestion: Inline quaternion math duplicates math_utils.quat_apply_inverse
File: source/isaaclab/isaaclab/utils/leapp/export_annotator.py (lines 469–476)
The rotation logic in _wrap_projected_gravity:
quat_xyz = root_quat_w[..., :3]
quat_w = root_quat_w[..., 3:4]
t = torch.cross(quat_xyz, gravity_w, dim=-1) * 2.0
return gravity_w - quat_w * t + torch.cross(quat_xyz, t, dim=-1)is functionally identical to isaaclab.utils.math.quat_apply_inverse(root_quat_w, gravity_w). The inline version works correctly, but referencing the canonical utility would reduce duplication and make the quaternion convention dependency explicit.
Likely reason it's inlined: The export path may need torch-traceable ops without the reshape in quat_apply_inverse (which reshapes to (-1, 4) and views back). If traceability is the motivation, a brief comment explaining this would help future maintainers.
🔵 Suggestion: First positional arg (env) is silently consumed
File: source/isaaclab/isaaclab/utils/leapp/export_annotator.py (line 464)
def wrapped(*args, **kwargs):The original mdp.projected_gravity(env, asset_cfg=...) passes env as args[0], but the wrapper never uses env. This is intentional (the wrapper bypasses the real env and uses proxy_env from the closure), and the test confirms it works. However, adding a brief inline comment like # args[0] is env, unused — we use proxy_env from closure would clarify this for future readers.
🔵 Suggestion: Consider adding @staticmethod consistency note
File: source/isaaclab/isaaclab/utils/leapp/export_annotator.py
_wrap_projected_gravity is correctly a @staticmethod (it doesn't use self), consistent with _wrap_with_proxy. Good.
✅ Architecture/Design
- The backport is a clean cherry-pick from
74f9e8ec(develop #6007). - The dispatch in
_patch_observation_managercorrectly intercepts"projected_gravity"by function name, matching the pattern used for"last_action"and"generated_commands". - Noise is correctly nullified for all patched terms (line 299), which is appropriate for export (noise should not be traced into the deployment graph).
✅ Correctness
- The quaternion math is correct: uses xyzw convention matching Isaac Lab's standard, and implements
quat_apply_inverse(q, [0,0,-1])identically to the canonical utility. - The test validates numerical equivalence against
math_utils.quat_apply_inversewith a non-trivial rotation (90° about X axis), confirming the formula is sound.
✅ Test Coverage
- New test file (
test_leapp_proxy.py) provides two focused regression tests:- Direct data proxy read preserves
projected_gravity_bas its own VECTOR3D input - Observation term export lowers through
root_quat_wwith BODY_ROTATION semantics
- Direct data proxy read preserves
- Both tests verify LEAPP annotation side effects (input name, kind, connection metadata).
- The PR description shows manual red/green verification.
⚠️ CI Note
- "Check for Broken Links" is failing — this appears pre-existing and unrelated to this PR's changes (no URLs were added/modified in source code).
Overall: This is a well-structured, minimal backport with good test coverage. The fix correctly bridges the gap between Warp-backed observation terms and LEAPP's tracing expectations.
Greptile SummaryThis backport fixes the LEAPP export of
Confidence Score: 5/5Safe to merge — the change is self-contained and the core rotation math matches Isaac Lab's existing quat_apply_inverse reference implementation exactly. The inverse quaternion rotation is correct and consistent with Isaac Lab's XYZW convention (confirmed by comparing with quat_apply_inverse in math.py). The proxy chain correctly routes through _DataProxy to trigger the LEAPP BODY_ROTATION annotation, and the cache/dedup mechanism is unaffected. Two regression tests cover both the direct-proxy path and the patched-observation path, including a numerical correctness check against the reference implementation. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[_patch_observation_manager] --> B{func.__name__?}
B -- last_action --> C[_wrap_last_action]
B -- generated_commands --> D[_wrap_generated_commands]
B -- projected_gravity --> E[_wrap_projected_gravity NEW]
B -- other --> F[_wrap_with_proxy]
E --> G[wrapped closure captures proxy_env]
G --> H[resolve asset_name from asset_cfg, default robot]
H --> I[proxy_env.scene.asset_name.data.root_quat_w.torch]
I --> J[LEAPP annotate BODY_ROTATION input]
J --> K[compute gravity_w = 0 0 -1 broadcast]
K --> L[t = 2 x cross qxyz gravity_w]
L --> M[return gravity_w minus qw x t plus cross qxyz t]
M --> N[projected_gravity_b in body frame]
Reviews (1): Last reviewed commit: "Fix LEAPP projected gravity export (#600..." | Re-trigger Greptile |
5f9fa3a
into
isaac-sim:release/3.0.0-beta2
Summary
Backports #6007 to
release/3.0.0-beta2.This fixes LEAPP export for
mdp.projected_gravityso the exported graph takesroot_quat_was the input and computes projected gravity inside the graph, instead of exporting projected gravity directly as an input.Changes
mdp.projected_gravitythroughroot_quat_wfor LEAPP graphs.Testing
uv run --with pytest --with leapp python -m pytest source/isaaclab_rl/test/export/test_leapp_proxy.py -q-> failed as expected intest_projected_gravity_observation_exports_root_quat_w_input.uv run --with pytest --with leapp python -m pytest source/isaaclab_rl/test/export/test_leapp_proxy.py -q->2 passed, 37 warnings.uv run --with ruff --with leapp ruff check source/isaaclab/isaaclab/utils/leapp/export_annotator.py source/isaaclab/isaaclab/utils/leapp/proxy.py source/isaaclab_rl/test/export/test_leapp_proxy.py-> passed../isaaclab.sh -f-> passed.