Skip to content

Contact lever arms about the link world COM, not the collider pose - #27

Open
haixuanTao wants to merge 1 commit into
dimforge:mainfrom
haixuanTao:fix/upstream-lever-arm
Open

Contact lever arms about the link world COM, not the collider pose#27
haixuanTao wants to merge 1 commit into
dimforge:mainfrom
haixuanTao:fix/upstream-lever-arm

Conversation

@haixuanTao

Copy link
Copy Markdown
Contributor

Bug

The multibody contact init builds angular lever arms as pt_world − link_origin, where link_origin is the contacting collider's world translation — a documented proxy (links_workspace was left unbound over a 10-storage-buffer concern that no longer holds; backends in use request 14). The body jacobians measure link velocity at the link world COM, so for any link whose collider is offset from its COM, the contact jacobian rows are wrong by that offset.

Impact

Measured on a G1 humanoid (foot collider ~4.6 cm from the link COM), comparing GPU contact rows against an analytic MuJoCo mj_jac reference at an identical pose:

quantity before after
ankle-pitch column of a foot contact row 8× too small (0.008 vs 0.056) within 3%
full row max error 0.047 0.016
J·M⁻¹·Jᵀ effective mass vs same-model reference 2–8%

With the ankle column ~8× under, ground reactions transmit almost no ankle torque — a quiet stand is impossible at any motor stiffness (the statue topples identically at kp ×1 through ×64, which was the diagnostic signature).

Fix

Bind links_static + links_workspace and use local_to_world · local_mprops.com for the A side and the self-contact B side. Compiles clean; ~20 net lines.

🤖 Generated with Claude Code

https://claude.ai/code/session_01B7NC7U2wDx2tSmT9mkeF9h

The MB contact init used the contacting collider world translation as a
proxy for the link origin when building angular lever arms (a documented
follow-up: links_workspace was unbound over a 10-storage-buffer concern
that no longer holds). The body jacobians measure link velocity at the
link WORLD COM, so for any link whose collider is offset from its COM
the contact rows are wrong by that offset.

Measured on a G1 humanoid (foot collider ~4.6cm from the link COM),
against an analytic MuJoCo mj_jac reference at an identical pose: the
ankle-pitch column of a foot contact row was 8x too small (0.008 vs
0.056) — ground reactions transmitted almost no ankle torque, making
quiet standing impossible at any motor stiffness. With this fix the
contact rows match the reference to ~2% (ankle column within 3%) and
J·M⁻¹·Jᵀ effective masses agree with a same-model MuJoCo reference to
2-8%.

Fix: bind links_static + links_workspace and use
local_to_world · local_mprops.com for both the A side and the
self-contact B side.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B7NC7U2wDx2tSmT9mkeF9h
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