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.
Bug Description
SolverMuJoCofails 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
contypebit, and says colors with index >= 32 should fall back tocontype=1/conaffinity=1. Instead,_color_collision_shapes()currently numbers colors from 1. The 31st color is encoded as1 << 31 == 2147483648, which the MuJoCo PythonMjSpecbinding 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:
contype=1/conaffinity=1fallback and the model remains runnable with potentially degraded collision filtering.Actual behavior:
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
System Information
ee84505aProposed Fix
int32representation before passing it to MuJoCo (0x80000000becomes-2147483648).0xFFFFFFFFaffinity mask instead ofINT32_MAX.contype=1/conaffinity=1explicitly for color indices >= 32.