Skip to content

fix(retargeters): guard against invalid controller grip poses in Se3 retargeters#743

Open
hougantc-nvda wants to merge 2 commits into
mainfrom
hougantc/se3-controller-pose-validity
Open

fix(retargeters): guard against invalid controller grip poses in Se3 retargeters#743
hougantc-nvda wants to merge 2 commits into
mainfrom
hougantc/se3-controller-pose-validity

Conversation

@hougantc-nvda

@hougantc-nvda hougantc-nvda commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Description

A connected controller with pose tracking lost (e.g. resting on a table) produces a present ControllerInput group with grip_is_valid=False and a zero-norm grip orientation. Se3AbsRetargeter and Se3RelRetargeter fed that quaternion straight to Rotation.from_quat, raising ValueError: Found zero norm quaternions and killing the retargeting pipeline (in pipelined mode the async retarget worker dies permanently, forcing consumers into session teardown/restart loops).

This change guards the controller branch with GRIP_IS_VALID, mirroring the hand branch's joint_valid handling:

  • Abs: holds the last pose (same as the is_none path).
  • Rel: emits a zero delta and re-arms the first-frame baseline so the first valid frame after recovery does not jump.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Testing

Added test/python/test_se3_retargeter_pose_validity.py covering both retargeters: invalid grip pose no longer raises, Abs holds the last valid pose, Rel emits a zero delta and does not jump on the first valid frame after recovery.

Checklist

  • I have read and understood the contribution guidelines
  • I have run the linter and formatter with SKIP=check-copyright-year pre-commit run --all-files
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix/feature works (or explained why not)
  • I have signed off all my commits (git commit -s) per the DCO

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Prevented retargeting from failing when a controller reports an invalid grip pose.
    • Absolute end-effector retargeting now keeps the last known pose during invalid input and resumes normally once valid input returns.
    • Relative end-effector retargeting now outputs a zero delta on invalid input and re-baselines cleanly on the next valid frame.
  • Tests
    • Added coverage for invalid-grip handling and recovery behavior in both absolute and relative retargeting flows.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: cdb4960e-2930-453a-9406-0063e06e57e4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds a guard in both Se3AbsRetargeter._compute_fn and Se3RelRetargeter._compute_fn to check ControllerInputIndex.GRIP_IS_VALID. When invalid, the absolute retargeter emits the cached last pose and returns early; the relative retargeter re-arms its first-frame baseline, emits a zero delta, and returns early. A new test module validates these behaviors for both retargeters across invalid-grip and recovery scenarios.

Estimated code review effort: 2 (Simple) | ~12 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Controller
  participant Se3AbsRetargeter
  participant Se3RelRetargeter

  Controller->>Se3AbsRetargeter: ControllerInput (GRIP_IS_VALID=false)
  Se3AbsRetargeter->>Se3AbsRetargeter: write ee_pose from _last_pose
  Se3AbsRetargeter-->>Controller: return early

  Controller->>Se3RelRetargeter: ControllerInput (GRIP_IS_VALID=false)
  Se3RelRetargeter->>Se3RelRetargeter: set _first_frame=True, ee_delta=0
  Se3RelRetargeter-->>Controller: return early

  Controller->>Se3RelRetargeter: ControllerInput (GRIP_IS_VALID=true, next frame)
  Se3RelRetargeter->>Se3RelRetargeter: re-baseline from valid input
  Se3RelRetargeter-->>Controller: emit ee_delta (no jump)
Loading

Related issues: None referenced.

Related PRs: None referenced.

Suggested labels: bug, tests

Suggested reviewers: None identified from provided data.

🐇 A quaternion of zero, a grip gone astray,
No crash, no panic — we hold pose at bay.
Rebaseline gently when valid frames return,
No jumpy deltas, no lessons unlearned.
Hop along, retargeter, the fix is in play!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding invalid grip pose handling in Se3 retargeters.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hougantc/se3-controller-pose-validity

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/retargeters/se3_retargeter.py`:
- Around line 394-401: Reset the retargeter’s smoothing state when grip tracking
is invalid in se3_retargeter.py. In the invalid-grip early return inside the SE3
retargeter logic, do not only set _first_frame; also clear the cached smoothing
buffers (_smoothed_delta_pos and _smoothed_delta_rot, or their equivalents in
the class) so the next valid sample starts clean instead of blending with stale
motion. Use the existing invalid-input branch around the grip validity check to
locate the fix.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: cfc47aaf-1540-4bc1-b9fb-d7511ef6cb6f

📥 Commits

Reviewing files that changed from the base of the PR and between 5da61a9 and 1124d99.

📒 Files selected for processing (2)
  • src/core/retargeting_engine_tests/python/test_se3_retargeter_pose_validity.py
  • src/retargeters/se3_retargeter.py

Comment thread src/retargeters/se3_retargeter.py
hougantc-nvda added a commit that referenced this pull request Jul 7, 2026
Re-arming _first_frame alone drops only the rebaseline sample; the
smoothed-delta EMA buffers still hold pre-loss motion at full strength
(they never decay while the invalid branch returns early), so the second
valid frame after recovery blends stale motion into the output. Zero
both buffers in the invalid-grip branch, matching the reset handler's
convention for re-arming the first-frame baseline.

Addresses CodeRabbit review feedback on #743.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Hougant Chen <hougantc@nvidia.com>
hougantc-nvda and others added 2 commits July 7, 2026 16:59
…retargeters

A connected controller with pose tracking lost (e.g. resting on a table)
produces a present ControllerInput group with grip_is_valid=False and a
zero-norm grip orientation. Se3AbsRetargeter and Se3RelRetargeter fed
that quaternion straight to Rotation.from_quat, raising
'ValueError: Found zero norm quaternions' and killing the retargeting
pipeline (in pipelined mode the async retarget worker dies permanently,
forcing consumers into session teardown/restart loops).

Guard the controller branch with GRIP_IS_VALID, mirroring the hand
branch's joint_valid handling: Abs holds the last pose (same as the
is_none path); Rel emits a zero delta and re-arms the first-frame
baseline so the first valid frame after recovery does not jump.

Signed-off-by: Hougant Chen <hougantc@nvidia.com>
Re-arming _first_frame alone drops only the rebaseline sample; the
smoothed-delta EMA buffers still hold pre-loss motion at full strength
(they never decay while the invalid branch returns early), so the second
valid frame after recovery blends stale motion into the output. Zero
both buffers in the invalid-grip branch, matching the reset handler's
convention for re-arming the first-frame baseline.

Addresses CodeRabbit review feedback on #743.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Hougant Chen <hougantc@nvidia.com>
@hougantc-nvda hougantc-nvda force-pushed the hougantc/se3-controller-pose-validity branch from 60d4e7b to 86a8c62 Compare July 7, 2026 20:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants