Skip to content

fix(retargeting): derive locomotion hip-height dt from graph_time#477

Open
nvddr wants to merge 2 commits intomainfrom
fix/locomotion-dt-from-graph-time
Open

fix(retargeting): derive locomotion hip-height dt from graph_time#477
nvddr wants to merge 2 commits intomainfrom
fix/locomotion-dt-from-graph-time

Conversation

@nvddr
Copy link
Copy Markdown
Contributor

@nvddr nvddr commented May 7, 2026

Summary

  • LocomotionRootCmdRetargeter integrated hip height with a hardcoded config.dt=1/60, so deployments at 90/120 Hz integrated 1.5x/2x too slowly relative to the operator's intent.
  • Read dt from ComputeContext.graph_time.real_time_ns each step. First frame after init/reset uses the configured nominal fallback_dt (1/60 by default), since no prior timestamp exists.
  • Renames the config field dtfallback_dt to make the role explicit. No callers in this repo passed dt= as a kwarg, but downstream consumers should be aware.
  • Adds test_locomotion_retargeter.py with a rate-invariance test (60/90/120 Hz produce the same hip-height delta over the same wall-clock duration), a stick-zero no-drift test, and a reset-clears-prev-timestamp test.
  • Updates the doc reference in docs/source/references/retargeting/index.rst to mention fallback_dt.

Why this matters

This is a correctness bug visible in any non-60 Hz deployment. CloudXR commonly runs at 90 Hz; locomotion stick → hip-height behavior was wrong in those sessions.

Test plan

  • CTest: ctest -R retargeting_test_locomotion_retargeter
  • Existing retargeting_test_retargeter_reset continues to pass
  • Manual: drive the retargeter from an OpenXR controller at 90 Hz; verify hip-height response matches a 60 Hz reference for the same hold duration

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Improvements

    • Locomotion retargeter now computes hip-height integration using actual elapsed time instead of a fixed value, providing more accurate behavior across different control rates.
    • Reset behavior improved to properly reinitialize timing state.
  • Documentation

    • Updated configuration parameter documentation for clarity on timestep derivation.

The hip-height integration in LocomotionRootCmdRetargeter used a hardcoded
config.dt=1/60 regardless of the actual control rate, so any deployment
running at 90/120 Hz integrated 1.5x/2x too slowly. Read dt from
ComputeContext.graph_time.real_time_ns instead, with a fallback_dt for the
first frame after init/reset. Add a rate-invariance test that drives the
retargeter at 60/90/120 Hz with the same stick value over the same wall
duration and asserts the hip delta matches across rates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 7, 2026 20:37
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR refactors the locomotion retargeter to compute integration timesteps dynamically from the simulation graph clock rather than using a fixed configured value. The key change replaces the dt configuration field with fallback_dt, which serves as a default only for the first frame or after resets. The implementation tracks the previous real-time timestamp and derives dt as the delta between successive frames, enabling rate-invariant hip-height integration. A comprehensive test suite validates the behavior across different control rates, zero-input conditions, and reset scenarios.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: deriving the locomotion hip-height integration timestep from graph_time instead of using a fixed config value.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/locomotion-dt-from-graph-time

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes locomotion hip-height integration so it uses actual elapsed wall-clock time from ComputeContext.graph_time.real_time_ns, making behavior invariant to control loop rate (e.g., 60/90/120 Hz) and clarifying configuration intent by renaming dt to fallback_dt.

Changes:

  • Derive per-step dt from ComputeContext.graph_time.real_time_ns with a first-frame/reset fallback to fallback_dt.
  • Rename config field dtfallback_dt and reset stored timestamp on reset events.
  • Add locomotion retargeter tests covering rate invariance, zero-input no drift, and reset timestamp clearing; update docs to reference fallback_dt.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/retargeters/locomotion_retargeter.py Switch hip-height integration timestep to be derived from graph_time.real_time_ns; rename config to fallback_dt; clear timestamp on reset.
src/core/retargeting_engine_tests/python/test_locomotion_retargeter.py Add tests validating rate-invariant integration, zero-input stability, and reset behavior.
docs/source/references/retargeting/index.rst Update retargeter config documentation to mention fallback_dt and graph_time-derived steady-state dt.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/core/retargeting_engine_tests/python/test_locomotion_retargeter.py Outdated
Comment thread src/core/retargeting_engine_tests/python/test_locomotion_retargeter.py Outdated
Two assertions in test_locomotion_retargeter.py compared the float32
hip-height output against a Python float with exact equality / 1e-9
tolerance. CI on Ubuntu (Python 3.10–3.13) round-tripped the values
slightly off (0.7200000286 ≠ 0.72), failing both tests.

Switch both checks to math.isclose with float32-friendly absolute
tolerances (1e-6 for the zero-input case, 1e-5 for the post-reset
fallback-dt case). The rate-invariance test already passed; only the
overly tight equality checks needed to relax.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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/core/retargeting_engine_tests/python/test_locomotion_retargeter.py`:
- Around line 153-155: The assertion uses abs_tol=1e-9 which is too tight for
float32 outputs; update the test so the comparison between h_after_reset (from
outputs["root_command"][0], float32) and expected (computed from
LocomotionRootCmdRetargeterConfig) uses a looser absolute tolerance such as 1e-6
(matching the existing rate-invariance test) to avoid spurious failures due to
float32 rounding.
🪄 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: 360721fb-b6d3-41c0-9f54-a919365ced4a

📥 Commits

Reviewing files that changed from the base of the PR and between 260f766 and 15472a7.

📒 Files selected for processing (3)
  • docs/source/references/retargeting/index.rst
  • src/core/retargeting_engine_tests/python/test_locomotion_retargeter.py
  • src/retargeters/locomotion_retargeter.py

Comment thread src/core/retargeting_engine_tests/python/test_locomotion_retargeter.py Outdated
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