Skip to content

Apply the contact cfm_factor to normal rows only, not friction tangents - #26

Open
haixuanTao wants to merge 1 commit into
dimforge:mainfrom
haixuanTao:fix/upstream-friction-cfm
Open

Apply the contact cfm_factor to normal rows only, not friction tangents#26
haixuanTao wants to merge 1 commit into
dimforge:mainfrom
haixuanTao:fix/upstream-friction-cfm

Conversation

@haixuanTao

Copy link
Copy Markdown
Contributor

Bug

The multibody contact PGS sweep applies cfm_factor to every row:

let raw_imp = cons.cfm_factor * (cons.impulse - cons.inv_lhs * rhs_total);

Rapier applies the soft-contact cfm to the normal part onlyContactConstraintTangentPart::solve takes no cfm_factor (see contact_constraint_element.rs; only NormalPart::solve/generic_solve and the MLCP path receive it). Softening the tangents effectively multiplies the friction coefficient by cfm_factor.

Impact

At an overdamped contact config (contact_natural_frequency = 30 Hz, damping_ratio = 5, substep dt 1.25 ms), cfm_factor ≈ 0.02 — so μ = 1.0 colliders behave like μ ≈ 0.03. Measured on a G1 humanoid passive stand: the loaded feet slid steadily regardless of contact stiffness (the slide was insensitive to natural_frequency across a 16× range — the signature that friction, not the normal stack, was leaking), and the robot toppled. A per-row impulse dump showed tangent impulses saturating at ~0.02·N instead of μ·N; after the fix they reach the true cone.

Fix

Solve tangent rows without the cfm factor; normal rows unchanged. One site, a few lines.

🤖 Generated with Claude Code

https://claude.ai/code/session_01B7NC7U2wDx2tSmT9mkeF9h

The PGS sweep multiplied every contact row by cfm_factor, including the
friction tangents. Rapier applies the soft-constraint cfm only to the
normal part (ContactConstraintTangentPart::solve takes no cfm_factor);
softening the tangents multiplies the effective friction coefficient by
cfm_factor. At an overdamped contact config (natural_frequency 30 Hz,
damping_ratio 5, dt 1.25 ms) cfm_factor is ~0.02, so mu=1.0 colliders
behaved like mu~0.03: statically loaded feet on a humanoid slid
steadily and a passive stand toppled.

Measured (G1 passive stand): tangential slide insensitive to contact
stiffness before the fix, reduced ~15% by this change in isolation, and
the effective mu returned to the collider value (verified via a
per-row impulse dump: tangent impulses reach mu*N instead of ~0.02*N).

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