diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 4fd3a69de84a..d86d995e8e15 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -179,6 +179,7 @@ Guidelines for modifications: * Rosario Scalise * Ruben D'Sa * Ruben Grandia +* ruziniuuuuu * Ryan Gresia * Ryley McCarroll * Sahara Yuta diff --git a/source/isaaclab_contrib/changelog.d/ruzini-vbd-coupling.minor.rst b/source/isaaclab_contrib/changelog.d/ruzini-vbd-coupling.minor.rst new file mode 100644 index 000000000000..d9f67f818fb8 --- /dev/null +++ b/source/isaaclab_contrib/changelog.d/ruzini-vbd-coupling.minor.rst @@ -0,0 +1,5 @@ +Added +^^^^^ + +* Added rigid-contact stability controls to + :class:`~isaaclab_contrib.deformable.VBDSolverCfg`. diff --git a/source/isaaclab_contrib/isaaclab_contrib/deformable/newton_manager_cfg.py b/source/isaaclab_contrib/isaaclab_contrib/deformable/newton_manager_cfg.py index 70d04ed2f7fd..fa535cc47fcd 100644 --- a/source/isaaclab_contrib/isaaclab_contrib/deformable/newton_manager_cfg.py +++ b/source/isaaclab_contrib/isaaclab_contrib/deformable/newton_manager_cfg.py @@ -116,7 +116,41 @@ class VBDSolverCfg(NewtonModelSolverCfg): """ rigid_contact_k_start: float = 1.0e2 - """Initial stiffness seed for all rigid body contacts [N/m].""" + """Initial stiffness seed for all rigid body contacts [N/m]. + + This only takes effect when :attr:`rigid_avbd_beta` is greater than zero; + otherwise the penalty stiffness stays fixed at the contact stiffness. + """ + + rigid_contact_hard: bool = True + """Whether rigid contacts use the augmented-Lagrangian hard-contact model. + + Disable this for compliant penalty contacts, such as moving kinematic + proxies grasping a light rigid object. + """ + + rigid_contact_history: bool = False + """Whether rigid contacts warm-start penalties, duals, and stick anchors.""" + + rigid_avbd_contact_alpha: float | None = None + """Body-contact C0 stabilization strength in ``[0, 1]``. + + ``None`` uses SolverVBD's shared ``rigid_avbd_alpha`` default. Lower values + correct more current penetration and strengthen contacts when history is + disabled or the iteration count is modest. + """ + + rigid_avbd_beta: float = 0.0 + """Penalty ramp rate per rigid-body AVBD iteration; zero disables ramping. + + :attr:`rigid_contact_k_start` only takes effect when this is greater than + zero; at zero the penalty stiffness is fixed at the contact stiffness. + Set to e.g. ``1e5`` to enable ramping. Shared by linear [m] and angular + [rad] constraints, which have different units. + """ + + rigid_body_contact_buffer_size: int = 64 + """Maximum rigid contacts stored per body during one VBD solve.""" @configclass diff --git a/source/isaaclab_contrib/test/deformable/test_deformable_builder_hooks.py b/source/isaaclab_contrib/test/deformable/test_deformable_builder_hooks.py index fa886612ca1e..c73271e277f0 100644 --- a/source/isaaclab_contrib/test/deformable/test_deformable_builder_hooks.py +++ b/source/isaaclab_contrib/test/deformable/test_deformable_builder_hooks.py @@ -3,6 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause +import inspect import math import sys from types import SimpleNamespace @@ -12,6 +13,7 @@ from isaaclab_newton.cloner.replicate import NewtonReplicateContext from isaaclab_newton.physics import NewtonManager from isaaclab_newton.sim.spawners.materials import NewtonDeformableMaterialCfg +from newton.solvers import SolverVBD from isaaclab_contrib.deformable import DeformableObject, VBDSolverCfg from isaaclab_contrib.deformable.deformable_object import ( @@ -19,6 +21,7 @@ add_deformable_entry_to_builder, setup_registered_deformable_fabric_sync, ) +from isaaclab_contrib.deformable.vbd_manager import NewtonVBDManager class _FakeBuilder: @@ -145,6 +148,26 @@ def test_newton_physics_context_is_replicate_context(): assert PHYSICS_CONTEXT is NewtonReplicateContext +def test_vbd_cfg_forwards_rigid_contact_stability_controls(): + """Forward VBD rigid-contact controls with Newton-compatible defaults.""" + configured_values = { + "rigid_contact_hard": False, + "rigid_contact_history": True, + "rigid_avbd_contact_alpha": 0.0, + "rigid_avbd_beta": 100.0, + "rigid_body_contact_buffer_size": 256, + } + cfg = VBDSolverCfg(**configured_values) + + solver_kwargs = NewtonVBDManager._filter_solver_kwargs(SolverVBD, cfg) + + assert {name: solver_kwargs[name] for name in configured_values} == configured_values + solver_parameters = inspect.signature(SolverVBD.__init__).parameters + default_cfg = VBDSolverCfg() + for name in configured_values: + assert getattr(default_cfg, name) == solver_parameters[name].default + + def test_fabric_particle_sync_skips_missing_fabric_prim(monkeypatch): """Test that missing Fabric prims are skipped before attributes are authored.""" entry = _make_surface_entry()