Skip to content

fix: foot-IK idle leg buzz (wrong leg orientation targets)#86

Merged
blugart-dev merged 1 commit into
mainfrom
fix/foot-ik-leg-orientation
Jun 23, 2026
Merged

fix: foot-IK idle leg buzz (wrong leg orientation targets)#86
blugart-dev merged 1 commit into
mainfrom
fix/foot-ik-leg-orientation

Conversation

@blugart-dev

Copy link
Copy Markdown
Owner

What

Fixes the idle leg vibration in foot IK — a latent 0.3.0 quality bug surfaced while validating the (now-parked) 0.4.0 stumble work. Substrate hardening; lands on main before 0.4.0 resumes.

Root cause (data-backed)

The two-bone IK solver built each leg segment's orientation target from scratch with an assumed local-axis convention (_basis_looking_alongBasis(s, -d, f)). That convention sits ~130° off the real Mixamo bone bases. The velocity spring then perpetually tried to twist the legs to those joint-unreachable orientations → sustained idle buzz.

Measured headlessly on the real ybot asset at rest (target error = angle between the IK target basis and the actual bone; ang vel = idle angular velocity):

Bone target error before → after idle ang. vel before → after
UpperLeg 130° → 0.6° 1.1 → 0.17 rad/s
LowerLeg 33° → 1.0° 1.8 → 0.52 rad/s
Foot 11° → 2.4° 1.7 → 1.17 rad/s

(The investigation also confirmed the velocity-spring core is sound — it tracks consistent targets calmly and is the same formula Jolt's own DriveToPoseUsingKinematics uses. It was faithfully chasing garbage targets, not malfunctioning.)

The fix

Express each leg segment's orientation as a swing of its animation basis onto the new IK bone direction — the same delta-from-animation approach the foot already used for slope correction (and why the foot's error was smallest). When the IK direction equals the animation direction (no adjustment needed), the swing is identity, so the target equals the animation pose → zero error.

  • Convention-agnostic: no longer assumes a Mixamo local axis, so non-Mixamo rigs benefit too (aligns with the role-based generality work).
  • Positions unchanged — knee, foot target, and pelvis drop are untouched; only segment orientations are corrected. Foot planting / pelvis / leg-length behavior is identical.
  • Removes _basis_looking_along; adds a degeneracy-hardened _swing helper.

Validation

  • Headless measurement above (target error 130° → <2.5°; leg buzz ~collapsed).
  • GUT 113/113 — all existing foot-IK tests (planting, pelvis-never-lifts, leg lengths, role-mapped non-Mixamo) still pass.
  • Visual in-editor confirmation pending (idle legs should be calm).

Note

The remaining ~1 rad/s residual on the foot is the spring's steady-state floor — addressed by the separate spring-hardening PR (settle deadband + solver-cooperative velocity), the second half of the substrate hardening.

🤖 Generated with Claude Code

The two-bone IK solver built each leg segment's orientation target from
scratch via _basis_looking_along (Basis(s, -d, f)), assuming a local-axis
convention that sat ~130deg off the real Mixamo bone bases. The velocity
spring then perpetually tried to twist the legs to those joint-unreachable
orientations, causing a sustained idle leg vibration.

Measured on the ybot asset at rest, before -> after this change:
  UpperLeg target error 130deg -> 0.6deg,  ang vel 1.1 -> 0.17 rad/s
  LowerLeg target error  33deg -> 1.0deg,  ang vel 1.8 -> 0.52 rad/s
  Foot     target error  11deg -> 2.4deg,  ang vel 1.7 -> 1.17 rad/s

The solver now expresses each segment's orientation as a SWING of that
segment's animation basis onto the new IK bone direction — the same
delta-from-animation approach the foot already used for slope correction.
When the IK direction equals the animation direction (no adjustment
needed) the swing is identity, so the target equals the animation pose and
there is no spurious rotation error for the spring to chase. This is
convention-agnostic: it no longer assumes a Mixamo local axis, so
non-Mixamo rigs benefit too.

Foot planting, pelvis drop, and leg lengths are unchanged — only segment
ORIENTATIONS are corrected; positions (knee, foot target, pelvis) are
untouched. Removes _basis_looking_along; adds a degeneracy-hardened _swing.

The remaining ~1 rad/s residual on the foot is the spring's steady-state
floor, addressed separately by the spring-hardening change.

GUT 113/113. Headless import clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@blugart-dev blugart-dev merged commit 327aadd into main Jun 23, 2026
1 check passed
@blugart-dev blugart-dev deleted the fix/foot-ik-leg-orientation branch June 23, 2026 20:19
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.

1 participant