Skip to content

[BUG] SolverMuJoCo graph-color fallback overflows contype at color 31 #3770

Description

@kioxli

Bug Description

SolverMuJoCo fails to construct a MuJoCo model when its collision-filter graph requires the highest documented supported color.

Newton documents support for 32 graph colors, one per MuJoCo contype bit, and says colors with index >= 32 should fall back to contype=1 / conaffinity=1. Instead, _color_collision_shapes() currently numbers colors from 1. The 31st color is encoded as 1 << 31 == 2147483648, which the MuJoCo Python MjSpec binding rejects because the field is exposed as a signed 32-bit integer.

Consequently, only 30 graph colors are currently safe. A graph requiring 31 colors already fails, and the documented overflow fallback is never reached for larger complete graphs.

Expected behavior:

  • Colors 0 through 31 use all 32 MuJoCo mask bits and construct successfully.
  • Colors with index >= 32 use the documented contype=1 / conaffinity=1 fallback and the model remains runnable with potentially degraded collision filtering.

Actual behavior:

TypeError: add_geom(): incompatible function arguments
...
contype=2147483648, conaffinity=2147483647

This also remains reachable in the legacy graph-color fallback on #3714. The new collision-mask compiler makes the simple complete-graph reproduction fit without using the fallback, but a graph that exceeds the compiler bounds and requires 31 colors still reaches the unchanged code and fails in the same way.

Related: #3713, #3714.

Reproduction Script

import numpy as np

import newton
from newton.solvers import SolverMuJoCo


builder = newton.ModelBuilder()
for i in range(32):
    body = builder.add_link(label=f"body_{i}")
    builder.add_shape_sphere(body, radius=0.1, label=f"shape_{i}")
    joint = builder.add_joint_free(body)
    builder.add_articulation([joint])

model = builder.finalize(device="cpu")
colors = SolverMuJoCo._color_collision_shapes(model, np.arange(model.shape_count))
print(f"colors: {colors.min()}..{colors.max()}")  # 1..32

SolverMuJoCo(model, use_mujoco_cpu=True)

System Information

  • Newton: 1.4.0 and main at ee84505a
  • Warp: 1.15.0
  • MuJoCo: 3.10.0 (also reproduced with 3.8.1)
  • Python: 3.11.15
  • OS: Ubuntu Linux 6.8.0-117-generic, x86_64
  • GPU: NVIDIA GeForce RTX 5090 D v2, driver 595.71.05 (reproduction uses CPU)

Proposed Fix

  • Number graph colors from 0 so bits 0 through 31 are all available.
  • Encode the 32-bit mask bit pattern using its signed int32 representation before passing it to MuJoCo (0x80000000 becomes -2147483648).
  • Use the full 0xFFFFFFFF affinity mask instead of INT32_MAX.
  • Assign contype=1 / conaffinity=1 explicitly for color indices >= 32.
  • Add regression coverage for all 32 exact colors and the overflow fallback.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    In Progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions