Skip to content
Closed
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
6 changes: 6 additions & 0 deletions docs/source/api/lab_newton/isaaclab_newton.physics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
KaminoMaterialsCfg
KaminoPADMMCfg
KaminoPADMMSolverCfg
KaminoSolverCfgBase
MPMSolverCfg
HydroelasticSDFCfg

Expand Down Expand Up @@ -105,6 +106,11 @@ Physics Configuration
:show-inheritance:
:exclude-members: __init__

.. autoclass:: KaminoSolverCfgBase
:members:
:show-inheritance:
:exclude-members: __init__

.. autoclass:: KaminoPADMMSolverCfg
:members:
:show-inheritance:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,8 @@ Kamino Solver Parameters
------------------------

The following fields are shared by
:class:`~isaaclab_newton.physics.KaminoPADMMSolverCfg` and
:class:`~isaaclab_newton.physics.KaminoDVISolverCfg`. They are grouped by the part
of the solver they affect.
:class:`~isaaclab_newton.physics.KaminoSolverCfgBase`. They are grouped by the part of
the solver they affect.

Core Integration
^^^^^^^^^^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Internal coupler type-check update accompanying the public Kamino solver
configuration base class.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@

import warp as wp
from isaaclab_newton.physics import (
KaminoDVISolverCfg,
KaminoPADMMSolverCfg,
KaminoSolverCfgBase,
MJWarpSolverCfg,
MPMSolverCfg,
NewtonCollisionPipelineCfg,
Expand Down Expand Up @@ -64,7 +63,7 @@ def _requires_external_contacts(solver_cfg: NewtonSolverCfg) -> bool:
"""
if isinstance(solver_cfg, MJWarpSolverCfg):
return not solver_cfg.use_mujoco_contacts
if isinstance(solver_cfg, (KaminoPADMMSolverCfg, KaminoDVISolverCfg)):
if isinstance(solver_cfg, KaminoSolverCfgBase):
Comment thread
rubengrandia marked this conversation as resolved.
return not solver_cfg.use_collision_detector
if isinstance(solver_cfg, MPMSolverCfg):
return False
Expand Down Expand Up @@ -153,7 +152,7 @@ def _validate_config(cls, solver_cfg: CouplerCfg) -> None:
f"CouplerEntryCfg {entry.name!r} uses {type(nested_cfg).__name__}, whose manager "
"does not implement nested solver construction."
)
if isinstance(nested_cfg, (KaminoPADMMSolverCfg, KaminoDVISolverCfg)):
if isinstance(nested_cfg, KaminoSolverCfgBase):
raise NotImplementedError(
f"CouplerEntryCfg {entry.name!r} uses a Kamino solver config, whose manager-specific FK/reset "
"lifecycle cannot yet be preserved inside Newton's coupled-solver entry API."
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Added
^^^^^

* Added :class:`~isaaclab_newton.physics.KaminoSolverCfgBase` as the public
base configuration class for Kamino solvers.
2 changes: 2 additions & 0 deletions source/isaaclab_newton/isaaclab_newton/physics/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ __all__ = [
"KaminoMaterialsCfg",
"KaminoPADMMCfg",
"KaminoPADMMSolverCfg",
"KaminoSolverCfgBase",
Comment thread
rubengrandia marked this conversation as resolved.
"MPMSolverCfg",
"MJWarpSolverCfg",
"NewtonCfg",
Expand Down Expand Up @@ -43,6 +44,7 @@ from .kamino_manager_cfg import (
KaminoMaterialsCfg,
KaminoPADMMCfg,
KaminoPADMMSolverCfg,
KaminoSolverCfgBase,
)
from .mjwarp_manager import NewtonMJWarpManager
from .mjwarp_manager_cfg import MJWarpSolverCfg
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from isaaclab.physics import PhysicsManager

from .kamino_manager_cfg import _KaminoSolverCfgBase
from .kamino_manager_cfg import KaminoSolverCfgBase
from .newton_manager import NewtonManager

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -58,12 +58,12 @@ class NewtonKaminoManager(NewtonManager):
_solver: SolverKamino

@classmethod
def _get_kamino_solver_cfg(cls) -> _KaminoSolverCfgBase:
def _get_kamino_solver_cfg(cls) -> KaminoSolverCfgBase:
cfg = PhysicsManager._cfg
if cfg is None:
raise RuntimeError("Physics manager is not initialized.")
solver_cfg = getattr(cfg, "solver_cfg", None)
if not isinstance(solver_cfg, _KaminoSolverCfgBase):
if not isinstance(solver_cfg, KaminoSolverCfgBase):
raise TypeError(f"Expected a Kamino solver configuration, got {type(solver_cfg).__name__}.")
return solver_cfg

Expand Down Expand Up @@ -112,12 +112,12 @@ def _reset_solver_internals(cls, world_mask: wp.array | None) -> None:
"""

@classmethod
def _create_solver(cls, model: Model, solver_cfg: _KaminoSolverCfgBase) -> SolverKamino:
def _create_solver(cls, model: Model, solver_cfg: KaminoSolverCfgBase) -> SolverKamino:
"""Construct the configured Kamino solver."""
return SolverKamino(model, solver_cfg.to_solver_config())

@classmethod
def _build_solver(cls, model: Model, solver_cfg: _KaminoSolverCfgBase) -> None:
def _build_solver(cls, model: Model, solver_cfg: KaminoSolverCfgBase) -> None:
"""Construct :class:`SolverKamino` and populate the base-class slots.

Sets :attr:`NewtonManager._needs_collision_pipeline` to ``True`` only
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ class KaminoMaterialsCfg:


@configclass
class _KaminoSolverCfgBase(NewtonSolverCfg):
class KaminoSolverCfgBase(NewtonSolverCfg):
Comment thread
rubengrandia marked this conversation as resolved.
Comment thread
rubengrandia marked this conversation as resolved.
"""Common configuration for Kamino solver-related parameters.

Kamino simulates constrained rigid multi-body systems in maximal coordinates with
Expand Down Expand Up @@ -329,7 +329,9 @@ class _KaminoSolverCfgBase(NewtonSolverCfg):

def _get_dynamics_solver_config(self) -> tuple[Literal["padmm", "dvi"], dict[str, Any]]:
"""Return the selected Newton solver name and its configuration keyword arguments."""
raise NotImplementedError
raise NotImplementedError(
f"{type(self).__name__} is a base configuration. Use KaminoPADMMSolverCfg or KaminoDVISolverCfg."
)

def to_solver_config(self) -> SolverKamino.Config:
"""Build a :class:`SolverKamino.Config` from this configuration.
Expand Down Expand Up @@ -393,7 +395,7 @@ def to_solver_config(self) -> SolverKamino.Config:


@configclass
class KaminoPADMMSolverCfg(_KaminoSolverCfgBase):
class KaminoPADMMSolverCfg(KaminoSolverCfgBase):
"""Configuration for Kamino with the P-ADMM forward-dynamics solver."""

dynamics_solver_cfg: KaminoPADMMCfg = field(default_factory=KaminoPADMMCfg)
Expand All @@ -405,7 +407,7 @@ def _get_dynamics_solver_config(self) -> tuple[Literal["padmm"], dict[str, Any]]


@configclass
class KaminoDVISolverCfg(_KaminoSolverCfgBase):
class KaminoDVISolverCfg(KaminoSolverCfgBase):
"""Configuration for Kamino with the DVI forward-dynamics solver."""

dynamics_solver_cfg: KaminoDVICfg = field(default_factory=KaminoDVICfg)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
KaminoDynamicsCfg,
KaminoPADMMCfg,
KaminoPADMMSolverCfg,
KaminoSolverCfgBase,
MJWarpSolverCfg,
MPMSolverCfg,
NewtonCfg,
Expand Down Expand Up @@ -164,6 +165,15 @@ def test_newton_cfg_post_init_propagates_class_type(
assert cfg.class_type.__name__ == expected_manager.__name__


def test_kamino_solver_cfg_base_requires_concrete_configuration():
"""The public Kamino base config should direct users to a concrete solver config."""
with pytest.raises(
NotImplementedError,
match="KaminoSolverCfgBase is a base configuration. Use KaminoPADMMSolverCfg or KaminoDVISolverCfg.",
):
KaminoSolverCfgBase().to_solver_config()


@pytest.mark.parametrize(
"num_substeps, collision_decimation, should_warn",
[
Expand Down Expand Up @@ -1113,7 +1123,7 @@ def test_initialize_solver_populates_canonical_state(
# something to work with.
body = builder.add_body(mass=1.0)
builder.add_joint_revolute(parent=-1, child=body, axis=(0, 0, 1))
if isinstance(solver_cfg, (KaminoPADMMSolverCfg, KaminoDVISolverCfg)) and solver_cfg.use_collision_detector:
if isinstance(solver_cfg, KaminoSolverCfgBase) and solver_cfg.use_collision_detector:
builder.add_shape_sphere(body=body, radius=0.05)
builder.add_ground_plane()
NewtonManager.set_builder(builder)
Expand Down
Loading