Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions docs/source/concepts/solver-tuning/tune_vbd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,41 @@ Core Solve
- Description
* - ``iterations``
- Default: ``10``. Number of VBD iterations per substep. Increasing this value improves deformation and contact convergence, especially for stiff materials or rigid gripper contacts, but increases runtime.
* - ``rigid_compliant_alm``
- Default: ``None``. Preserves Newton's rigid solver mode. In Newton 1.6, ``None`` selects deprecated legacy AVBD. Set to ``True`` to use compliant ALM for rigid joints and body-body contacts, or ``False`` to explicitly retain legacy AVBD.
* - ``rigid_body_contact_buffer_size``
- Default: ``64``. Per-body capacity for body-body contacts when VBD integrates rigid bodies. Increase it if Newton reports a per-body body-body contact buffer overflow.
* - ``rigid_body_particle_contact_buffer_size``
- Default: ``256``. Per-body capacity for particle, edge, and face soft contacts. Increase it if Newton reports a per-body contact buffer overflow.
* - ``integrate_with_external_rigid_solver``
- Default: ``False``. Set to ``True`` only when a manual manager integrates rigid bodies in the shared model. Proxy-coupled entries use partitioned model views and leave this ``False``.


Rigid Cables
^^^^^^^^^^^^

For new rigid-cable configurations, explicitly enable compliant ALM:

.. code-block:: python

from isaaclab_newton.physics import VBDSolverCfg

cable_solver_cfg = VBDSolverCfg(
rigid_compliant_alm=True,
rigid_body_contact_buffer_size=256,
)

Compliant ALM uses finite material stiffness for rigid joints and body-body
contacts. Validate the cable's stretch, bend, and contact stiffness under the
intended loads and timestep when switching from legacy AVBD. Increasing contact
capacity only increases the available storage; it does not change stiffness.

``VBDSolverCfg`` leaves Newton's C0 stabilization parameter ``rigid_avbd_alpha``
unset. Newton 1.6 defaults it to ``0.0`` for compliant ALM and ``0.95`` for legacy
AVBD, for both rigid joints and body-body contacts. Setting alpha to zero alone
does not enable ALM.


Self-Contact
^^^^^^^^^^^^

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Added
^^^^^

* Exposed ``rigid_compliant_alm`` and ``rigid_body_contact_buffer_size`` on
``VBDSolverCfg`` for compliant ALM selection and per-body contact capacity,
while preserving Newton's existing defaults.
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,24 @@ class VBDSolverCfg(NewtonSolverCfg):
particle_rest_shape_contact_exclusion_radius: float = 0.0
"""Rest-shape separation threshold for filtering contacts [m]."""

rigid_compliant_alm: bool | None = None
"""Whether to use compliant ALM for rigid joints and body-body contacts.

``None`` preserves Newton's default, which selects deprecated legacy AVBD in Newton 1.6.
Set to ``True`` for new rigid-cable configurations and validate their finite material stiffnesses.
Newton's default C0 stabilization strength is ``0.0`` with compliant ALM and ``0.95`` with legacy AVBD.
"""

rigid_contact_k_start: float = 1.0e2
"""Initial stiffness seed for rigid-body contacts [N/m]."""

rigid_body_contact_buffer_size: int = 64
"""Per-body capacity of the body-body contact list.

Increase this value when Newton reports a per-body body-body contact buffer overflow.
Only used when :attr:`integrate_with_external_rigid_solver` is ``False``.
"""

rigid_body_particle_contact_buffer_size: int = 256
"""Per-body capacity of the particle, edge, and face soft-contact list.

Expand Down
60 changes: 60 additions & 0 deletions source/isaaclab_newton/test/physics/test_vbd_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
from __future__ import annotations

import importlib
import inspect
from types import SimpleNamespace

import pytest
from isaaclab_newton.physics import NewtonBackendCfg, NewtonManager, NewtonSoftContactCfg
from newton import ModelBuilder
from newton.solvers import SolverVBD

from isaaclab.sim import SimulationContext

Expand Down Expand Up @@ -205,6 +208,63 @@ def test_vbd_solver_force_input_capability(monkeypatch, external_rigid_solver):
assert NewtonManager._supports_rigid_body_force_input is not external_rigid_solver


@pytest.mark.parametrize(
"overrides",
[
pytest.param({}, id="newton-defaults"),
pytest.param(
{"rigid_compliant_alm": True, "rigid_body_contact_buffer_size": 256},
id="compliant-alm",
),
pytest.param({"rigid_compliant_alm": False}, id="legacy-mode"),
],
)
def test_vbd_rigid_solver_controls(overrides):
Comment thread
rebeccazhang0707 marked this conversation as resolved.
"""Public VBD controls preserve Newton defaults and survive kwargs filtering."""
physics = importlib.import_module("isaaclab_newton.physics")
solver_cfg = physics.VBDSolverCfg(**overrides)
kwargs = NewtonManager._filter_solver_kwargs(SolverVBD, solver_cfg)
parameters = inspect.signature(SolverVBD).parameters
for name in ("rigid_compliant_alm", "rigid_body_contact_buffer_size"):
assert kwargs[name] == overrides.get(name, parameters[name].default)


def test_vbd_compliant_alm_cable_stiffness():
"""The manager's ALM solver retains finite cable stiffness under gravity."""
physics = importlib.import_module("isaaclab_newton.physics")
gravity = 9.81
stretch_stiffness = 1.0e3
builder = ModelBuilder(gravity=(0.0, 0.0, -gravity))
body = builder.add_link()
builder.add_shape_capsule(body=body, radius=0.01, half_height=0.1)
mass = builder.body_mass[body]
joint = builder.add_joint_rod(
parent=-1,
child=body,
stretch_stiffness=stretch_stiffness,
stretch_damping=2.0 * (mass * stretch_stiffness) ** 0.5,
bend_stiffness=5.0,
bend_damping=1.0,
)
builder.add_articulation([joint])
builder.color()
model = builder.finalize(device="cpu")
solver_cfg = physics.VBDSolverCfg(rigid_compliant_alm=True, rigid_body_contact_buffer_size=256)
solver = physics.NewtonVBDManager._create_solver(model, solver_cfg)
assert solver.rigid_compliant_alm is True

state_0, state_1 = model.state(), model.state()
control = model.control()
for _ in range(120):
state_0.clear_forces()
solver.step(state_0, state_1, control, None, 1.0 / 240.0)
state_0, state_1 = state_1, state_0

# At equilibrium the spring force balances the weight: k * extension = m * g.
expected_extension = mass * gravity / stretch_stiffness
assert state_0.body_q.numpy()[body, 2] == pytest.approx(-expected_extension, rel=0.01)


def test_vbd_rebuilds_particle_bvh_before_physics_step(monkeypatch):
"""VBD rebuilds its particle BVH before the base physics step."""
physics = importlib.import_module("isaaclab_newton.physics")
Expand Down
Loading