diff --git a/source/isaaclab_newton/changelog.d/fanes-rslrl-contact-buffer-naconmax.rst b/source/isaaclab_newton/changelog.d/fanes-rslrl-contact-buffer-naconmax.rst new file mode 100644 index 000000000000..5fe8375593d9 --- /dev/null +++ b/source/isaaclab_newton/changelog.d/fanes-rslrl-contact-buffer-naconmax.rst @@ -0,0 +1,9 @@ +Fixed +^^^^^ + +* Fixed :class:`~isaaclab_newton.physics.NewtonManager` sizing its contact buffer from the + collision pipeline alone when ``use_mujoco_contacts=False``, which raised + ``MuJoCo naconmax (25600) exceeds contacts.rigid_contact_max (3840)`` at reset whenever the + MuJoCo Warp solver's ``nconmax`` demanded more contacts than the pipeline estimate. The + buffer now grows to the solver's maximum contact count, matching the + ``use_mujoco_contacts=True`` path. diff --git a/source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py b/source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py index 7527f95fdc95..d52b64497e8d 100644 --- a/source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py +++ b/source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py @@ -1657,6 +1657,22 @@ def _initialize_contacts(cls) -> None: NewtonManager._collision_pipeline = CollisionPipeline(cls._model, broad_phase="explicit") if cls._contacts is None: NewtonManager._contacts = cls._collision_pipeline.contacts() + # Grow the collision-pipeline contact buffer to the solver's max when the + # solver (e.g. MuJoCo/mujoco_warp) requires more contacts than the pipeline + # auto-estimate. Without this, the RSL-RL sensor path (use_mujoco_contacts= + # False) sizes _contacts from the pipeline alone and solver.update_contacts() + # raises when naconmax (nconmax * num_envs) exceeds rigid_contact_max. + # Mirrors the mjwarp_manager.py override for the use_mujoco_contacts=True path. + _solver = cls._solver + if _solver is not None and hasattr(_solver, "get_max_contact_count"): + _need = _solver.get_max_contact_count() + if _need > NewtonManager._contacts.rigid_contact_max: + NewtonManager._contacts = Contacts( + rigid_contact_max=_need, + soft_contact_max=0, + device=PhysicsManager._device, + requested_attributes=cls._model.get_requested_contact_attributes(), + ) # ----- Solver construction (subclass contract) ------------------------