Skip to content

Fix CCD narrowphase reporting margin-biased contact distances#1188

Merged
adenzler-nvidia merged 1 commit into
google-deepmind:mainfrom
adenzler-nvidia:adenzler/fix-ccd-margin-dist
Feb 26, 2026
Merged

Fix CCD narrowphase reporting margin-biased contact distances#1188
adenzler-nvidia merged 1 commit into
google-deepmind:mainfrom
adenzler-nvidia:adenzler/fix-ccd-margin-dist

Conversation

@adenzler-nvidia

Copy link
Copy Markdown
Collaborator

Summary

  • The CCD (GJK/EPA) path inflates each geom by 0.5 * pair_margin in the support() function, but the returned dist was never corrected back to the true surface-to-surface distance. This caused dist to be off by pair_margin compared to the primitive narrowphase, breaking the constraint pipeline (pos = dist - includemargin) which expects un-inflated distances.
  • Adds dist += margin after the early-exit check in eval_ccd_write_contact to restore consistency with the primitive narrowphase path.
  • Adds regression test test_ccd_margin_dist that verifies CCD contact distances match classic MuJoCo for two boxes separated by 0.05 m with margin=0.1, gap=0.1 on each geom.

Details

The support() function in collision_gjk.py inflates shapes by 0.5 * geom.margin (line 189-190). Both geoms are set to margin = pair_margin before CCD runs, so the total inflation is pair_margin. The GJK/EPA distance is therefore relative to the inflated geometry, not the true surfaces.

The primitive narrowphase (e.g. sphere_sphere, box_box) reports true geometric distances without margin. The constraint pipeline then checks pos = dist - includemargin < 0 to activate constraints. Without this fix, CCD pairs activate constraints too early because their dist is already margin-biased.

Example: Two boxes 0.05 m apart with pair_margin = 0.2:

  • Primitive path: dist = 0.05 (correct)
  • CCD path before fix: dist = -0.15 (wrong, off by pair_margin)
  • CCD path after fix: dist = 0.05 (correct)

Test plan

  • New test_ccd_margin_dist passes — CCD dist matches classic MuJoCo
  • All 52 existing collision_driver_test tests pass
  • Verified test fails without the fix (dist mismatch)

The CCD (GJK/EPA) path inflates each geom by 0.5 * pair_margin in the
support function, but the returned dist was never corrected back to the
true surface-to-surface distance.  This caused dist to be off by
pair_margin compared to the primitive narrowphase, breaking the
constraint pipeline which expects un-inflated distances.

Add `dist += margin` after the early-exit check in
eval_ccd_write_contact to restore consistency with the primitive path.
@adenzler-nvidia adenzler-nvidia merged commit 40d4d6f into google-deepmind:main Feb 26, 2026
10 checks passed
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