-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Description
Summary
Continuous Collision Detection (CCD) is effectively not applied for mesh/box/hfield pairs when both geoms have margin = 0. The code path behaves like a discrete contact check that hits the iteration limit and exits early. Because of that, the "ccd_iterations needs to be increased" warning was firing every time, so it is currently commented out in the code. True tolerance-based CCD only runs when at least one geom has a non-zero margin (e.g. 0.001).
Environment
- Isaac Lab (dev/newton)
- MuJoCo warp / Newton (mujoco_warp collision pipeline)
- Relevant code:
mujoco_warp/_src/collision_gjk.py(and related CCD/GJK usage)
Root cause (from code)
-
is_discrete
For mesh/box/hfield pairs, when both geoms havemargin == 0, the CCD path setsis_discrete = True(seecollision_gjk.py, e.g. around_discrete_geomsand theis_discreteassignment inccd()). -
GJK convergence when
is_discrete=True
Whenis_discreteis True, the GJK convergence threshold is set to:epsilon = 0(e.g.epsilon = wp.where(is_discrete, 0.0, 0.5 * tolerance * tolerance)),
so the loop only stops when the distance to the origin is exactly 0 (or within that strict criterion).
-
Numerical behavior
With finite precision, that condition is almost never satisfied. The loop therefore runs untilgjk_iterations(orccd_iterations) is reached and then exits. So:- There is no meaningful "tolerance-based" convergence.
- The code behaves like a discrete "are they touching?" check that always hits the iteration limit.
-
Result
- Name: "CCD" (continuous collision detection).
- Actual behavior for margin=0 mesh/box/hfield: discrete-style check + iteration limit, with the "iteration limit reached" warning printed repeatedly.
- True CCD (trajectory tracking, tolerance-based convergence) is not applied in this configuration.
-
When CCD actually runs
If margin is non-zero (e.g.0.001) for at least one of the geoms,is_discretebecomes False. Then:- A non-zero
epsilon(tolerance) is used for GJK convergence. - The loop can terminate on tolerance, and tolerance-based continuous collision detection is applied as intended.
- A non-zero
Repeated warning and current workaround
Because GJK almost always runs to the iteration limit when is_discrete=True (margin=0 mesh/box/hfield), the warning that indicates "ccd_iterations needs to be increased" was triggered every time this code path ran (e.g. per contact pair per step). That made the warning effectively spam the log. As a result, that warning is currently commented out in the code (see collision_gjk.py around lines 670–671: the wp.printf("Warning: opt.ccd_iterations, ...") is commented). So the situation is: (1) CCD is effectively disabled for margin=0 discrete geoms, (2) the only visible symptom was this repeated warning, and (3) the immediate mitigation was to comment out the warning rather than fix the root cause. A proper fix is to enable tolerance-based CCD (e.g. via non-zero contact_margin / geom margin) so that convergence is achieved and the warning is no longer needed, or to treat the margin=0 discrete case explicitly (e.g. as discrete contact only, without claiming CCD).
Expected vs actual
| Aspect | Expected | Actual (margin=0 mesh/box/hfield) |
|---|---|---|
| CCD role | Tolerance-based continuous collision detection (trajectory, penetration depth). | Effectively disabled; behaves like discrete check + iteration limit. |
| Warnings | None or rare. | "Iteration limit" warning fired repeatedly → now commented out. |
| Convergence | GJK stops when distance < tolerance. | GJK almost always runs to full iteration count. |
Suggested fix / Newton integration
- Solver / model: The solver should pass
model.shape_contact_margin(or equivalent) to the MuJoCo geom margin so that mesh/box/hfield pairs do not always getmargin=0in the CCD path. - Builder / defaults: In Newton,
builder.default_shape_cfg.contact_margin(or equivalent) should be set to a small non-zero value (e.g.0.001) where appropriate, and that value should flow through to the geom margin used in the collision/CCD code.
That way, the CCD path uses the tolerance-based (is_discrete=False) branch and real CCD is applied instead of the current "discrete + iteration limit" behavior.
Conclusion
For mesh/box/hfield pairs with margin=0, CCD was effectively disabled; the iteration-limit warning was a side effect (GJK never converging under epsilon=0) and was eventually commented out to avoid log spam. Enabling non-zero margin (via contact_margin / shape_contact_margin) restores proper tolerance-based CCD behavior and makes the warning unnecessary.
