Skip to content

MuJoCo Warp MultiCCD returns one alternating contact for a cylinder-box pair #1555

Description

@lyd405121

Context

Image

We found this while developing a robotic battery pick-and-install task. When
the battery fell onto its side on a table, it penetrated the tabletop and
oscillated instead of settling. The battery collider is a cylinder.

We removed the robot, the installation target, visual meshes, and unrelated
scene objects. The resulting minimal scene contains only:

  • one dynamic horizontal cylinder representing the battery;
  • one static box representing the tabletop.

The penetration and oscillation remain reproducible in this reduced scene.

Environment

Component Version
MuJoCo 3.10.0
MuJoCo Warp 3.10.0.2
Warp 1.15.0
Python 3.12.13
Newton commit 82285bb51368c987dd11a0093b52e1ad4dc19817
GPU NVIDIA GeForce RTX 5070 Ti Laptop GPU
NVIDIA driver 580.159.03
OS Linux 7.0.0-28-generic x86_64

Reproduction

The reproduction folder contains the USD asset and three small runners:

  • run_newton_native.py: Newton contact generation;
  • run_mujoco_warp.py: MuJoCo Warp contact generation;
  • run_mujoco_cpu.py: MuJoCo CPU contact generation.

The MuJoCo solver configuration is identical except for the contact backend:

SolverMuJoCo(
    model,
    nconmax=1024,
    njmax=4096,
    iterations=100,
    cone="elliptic",
    impratio=1.0,
    use_mujoco_contacts=backend != "newton_native",
    use_mujoco_cpu=backend == "mujoco_cpu",
    enable_multiccd=True,
)

Additional shared settings:

dt = 1 / 600 s
shape gap = 0.001 m
contact stiffness = 25000
contact damping = 200
friction coefficient = 0.95

Expected behavior

MuJoCo Warp should produce a persistent multi-contact support manifold that is
consistent with MuJoCo CPU for this cylinder-box configuration. The cylinder
should settle without the support contact jumping between its two ends.

Actual behavior

cylinder_box_contacts_comparison.mp4
Contact backend Settled contacts Contact behavior Negative contact distance
Newton native 2 Stable at both cylinder ends about 0.0053 mm
MuJoCo Warp 1 Alternates between cylinder ends about 0.355-0.381 mm
MuJoCo CPU 2 Stable at both cylinder ends about 0.0053 mm

For MuJoCo Warp, the single contact moves along the cylinder axis between
approximately y=-0.03913 m and y=+0.03913 m. In the final 120 simulation
substeps, its sign changed 60 times. Consecutive observed frames include:

MuJoCo CPU produced two persistent contacts near y=+/-0.03913 m over the
same interval.

Relevant MuJoCo behavior

The MuJoCo documentation states that general-purpose GJK/EPA normally returns
one contact, while MultiCCD can return multiple points per geom pair. It also
states that collisions involving cylinders and capsules use the legacy
multi-run pipeline, which perturbs the geoms and can add up to four contacts:

https://mujoco.readthedocs.io/en/stable/computation/index.html#multiple-contacts

MuJoCo CPU appears to exercise this multi-run behavior in the reproduction,
while MuJoCo Warp returns only the single GJK/EPA witness contact.

Questions

  1. Is the legacy MultiCCD multi-run path for cylinder-box pairs implemented in
    MuJoCo Warp 3.10.0.2?
  2. Should MuJoCo Warp produce a manifold equivalent to MuJoCo CPU for this
    model?
  3. If this is a known limitation, can it be detected or documented so that
    users can avoid unstable single-contact support for cylinders and capsules?

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions