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
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ ignore-words-list = "haa,slq,collapsable,buss,reacher,thirdparty"

markers = [
"isaacsim_ci: mark test to run in isaacsim ci",
"device_split: re-invoke this file once per device (CPU and GPU) in CI due to process-global device locks (e.g., ovphysx<=0.3.7 gap G5)",
]

# Add pypi.nvidia.com so that `uv pip install isaaclab[isaacsim]` works without --extra-index-url.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Changed
^^^^^^^

* Changed ``./isaaclab.sh --install`` (and ``--install all``) to automatically
install the publicly available :mod:`ovphysx` wheel alongside the Newton
extras, so the OVPhysX backend is usable out of the box. The OVRTX renderer
wheel remains opt-in via ``--install 'ov[ovrtx]'`` or ``--install 'ov[all]'``.
Use ``--install none`` to opt out of all extras.
5 changes: 3 additions & 2 deletions source/isaaclab/isaaclab/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ def cli() -> None:
"\n"
"* Special values:\n"
" all - Core + optional submodules (mimic, teleop) + auto extra\n"
" features (newton, rl, visualizer). Does not install contrib/ov\n"
" dependency extras (default).\n"
" features (newton, ov, rl, visualizer). 'ov' defaults to\n"
" ovphysx only; use ov[ovrtx] or ov[all] for OVRTX. Does not\n"
" install contrib dependency extras (default).\n"
" none - Core submodules only; no optional submodules, no extra features.\n"
" <empty> (-i with no value) - Same as 'all'.\n"
"\n"
Expand Down
39 changes: 20 additions & 19 deletions source/isaaclab/isaaclab/cli/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ def _install_isaacsim() -> None:
}

# Extra features excluded from the automatic ``-i all`` / ``-i`` install.
MANUAL_EXTRA_FEATURES: set[str] = {"contrib", "ov"}
MANUAL_EXTRA_FEATURES: set[str] = {"contrib"}


def _split_install_items(install_type: str) -> list[str]:
Expand Down Expand Up @@ -565,31 +565,32 @@ def _install_contrib_extra_dependencies(selector: str) -> None:
def _install_ov_extra_dependencies(selector: str) -> None:
"""Install optional OV runtime dependencies.

The default ``ov`` invocation (empty selector) installs the publicly
available :mod:`ovphysx` wheel so the OVPhysX backend is usable out of
the box; the OVRTX renderer wheel remains opt-in via ``ov[ovrtx]`` or
``ov[all]``.

Args:
selector: One or more OV selectors from ``ov[ovrtx]``,
``ov[ovphysx]``, or ``ov[all]``.
``ov[ovphysx]``, or ``ov[all]``. Empty defaults to ``ovphysx``.
"""
if not selector:
print_info(
"OV source packages are installed with the core submodules. "
"Use 'ov[ovrtx]', 'ov[ovphysx]', or 'ov[all]' to install OV runtime dependencies."
)
return

python_exe = extract_python_exe()
pip_cmd = get_pip_command(python_exe)
source_dir = ISAACLAB_ROOT / "source"

selectors = {item.strip().lower() for item in selector.split(",") if item.strip()}
valid_selectors = {"all", "ovrtx", "ovphysx"}
unknown_selectors = selectors - valid_selectors
if unknown_selectors:
print_warning(
f"Unknown ov selector(s): {', '.join(sorted(unknown_selectors))}. "
f"Valid selectors: {', '.join(sorted(valid_selectors))}."
)
if "all" in selectors:
selectors.update({"ovrtx", "ovphysx"})
if not selector:
selectors = {"ovphysx"}
else:
selectors = {item.strip().lower() for item in selector.split(",") if item.strip()}
valid_selectors = {"all", "ovrtx", "ovphysx"}
unknown_selectors = selectors - valid_selectors
if unknown_selectors:
print_warning(
f"Unknown ov selector(s): {', '.join(sorted(unknown_selectors))}. "
f"Valid selectors: {', '.join(sorted(valid_selectors))}."
)
if "all" in selectors:
selectors.update({"ovrtx", "ovphysx"})
if "ovrtx" in selectors:
print_info("Installing OVRTX optional dependency...")
run_command(pip_cmd + ["install", "--editable", f"{source_dir}/isaaclab_ov[ovrtx]"])
Expand Down
17 changes: 13 additions & 4 deletions source/isaaclab/test/install_ci/test_install_command_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def test_manual_extra_features_subset_of_valid(self):
assert MANUAL_EXTRA_FEATURES <= VALID_EXTRA_FEATURES

def test_manual_extra_features(self):
assert {"contrib", "ov"} == MANUAL_EXTRA_FEATURES
assert {"contrib"} == MANUAL_EXTRA_FEATURES

def test_no_overlap_between_optional_submodules_and_extra_features(self):
assert not (set(OPTIONAL_ISAACLAB_SUBMODULES.keys()) & VALID_EXTRA_FEATURES)
Expand Down Expand Up @@ -237,7 +237,16 @@ def test_all_does_not_install_manual_extra_dependencies(self):
mocks = self._run("all")
called_features = {c.args[0] for c in mocks["_install_extra_feature"].call_args_list}
assert "contrib" not in called_features
assert "ov" not in called_features

def test_all_installs_ov_with_default_ovphysx_selector(self):
# `ov` is in the auto-installed set so the publicly available
# OVPhysX wheel is pulled in by default; OVRTX remains opt-in via
# `ov[ovrtx]` / `ov[all]`.
mocks = self._run("all")
calls = mocks["_install_extra_feature"].call_args_list
ov_calls = [c for c in calls if c.args[0] == "ov"]
assert ov_calls, "`ov` should be auto-installed by `-i all`"
assert ov_calls[0].args[1] == "", f"Expected empty selector, got {ov_calls[0].args[1]!r}"

def test_all_does_not_call_install_isaacsim(self):
mocks = self._run("all")
Expand Down Expand Up @@ -303,12 +312,12 @@ def test_mimic_adds_mimic_to_submodules(self):
mocks["_install_extra_feature"].assert_not_called()
mocks["_install_optional_submodule_extra_dependencies"].assert_not_called()

def test_ov_without_selector_dispatches_manual_extra_feature(self):
def test_ov_without_selector_dispatches_extra_feature(self):
mocks = self._run("ov")
mocks["_install_extra_feature"].assert_called_once_with("ov", "")
mocks["_install_optional_submodule_extra_dependencies"].assert_not_called()

def test_ov_with_selector_dispatches_manual_extra_feature(self):
def test_ov_with_selector_dispatches_extra_feature(self):
mocks = self._run("ov[ovrtx]")
mocks["_install_extra_feature"].assert_called_once_with("ov", "ovrtx")
mocks["_install_optional_submodule_extra_dependencies"].assert_not_called()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Changed
^^^^^^^

* Removed ``pytest.importorskip("ovphysx.types")`` guards from the
``isaaclab_ovphysx`` test suite now that the ``ovphysx`` wheel is publicly
available on PyPI and installed by default via ``./isaaclab.sh --install``.
Tests now fail loudly if the wheel is missing instead of silently skipping.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Fixed
^^^^^

* Re-enabled both CPU and GPU coverage in CI for
:file:`test/sim/test_views_xform_prim_ovphysx.py` and
:file:`test/sensors/test_contact_sensor.py` by tagging them with the new
``device_split`` pytest marker, which causes the CI driver to invoke each
file once per device in separate subprocesses. Works around the
``ovphysx<=0.3.7`` process-global device lock (gap G5).
34 changes: 14 additions & 20 deletions source/isaaclab_ovphysx/test/assets/test_articulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,20 @@
import pytest
import torch
import warp as wp

# The CI isaaclab_ov* pattern unintentionally collects isaaclab_ovphysx tests,
# but the ovphysx wheel is not installed in that environment. Skip gracefully
# so the isaaclab_ov CI pipeline is not blocked by an unrelated dependency.
pytest.importorskip("ovphysx.types", reason="ovphysx wheel not installed")

from isaaclab_ovphysx import tensor_types as TT # noqa: E402
from isaaclab_ovphysx.assets import Articulation # noqa: E402
from isaaclab_ovphysx.physics import OvPhysxCfg # noqa: E402

import isaaclab.sim as sim_utils # noqa: E402
import isaaclab.utils.math as math_utils # noqa: E402
import isaaclab.utils.string as string_utils # noqa: E402
from isaaclab.actuators import ActuatorBase, IdealPDActuatorCfg, ImplicitActuatorCfg # noqa: E402
from isaaclab.assets import ArticulationCfg # noqa: E402
from isaaclab.envs.mdp.terminations import joint_effort_out_of_limit # noqa: E402
from isaaclab.managers import SceneEntityCfg # noqa: E402
from isaaclab.sim import SimulationCfg, build_simulation_context # noqa: E402
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR # noqa: E402
from isaaclab.utils.version import get_isaac_sim_version, has_kit # noqa: E402
from isaaclab_ovphysx import tensor_types as TT
from isaaclab_ovphysx.assets import Articulation
from isaaclab_ovphysx.physics import OvPhysxCfg

import isaaclab.sim as sim_utils
import isaaclab.utils.math as math_utils
import isaaclab.utils.string as string_utils
from isaaclab.actuators import ActuatorBase, IdealPDActuatorCfg, ImplicitActuatorCfg
from isaaclab.assets import ArticulationCfg
from isaaclab.envs.mdp.terminations import joint_effort_out_of_limit
from isaaclab.managers import SceneEntityCfg
from isaaclab.sim import SimulationCfg, build_simulation_context
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR
from isaaclab.utils.version import get_isaac_sim_version, has_kit

##
# Pre-defined configs
Expand Down
14 changes: 3 additions & 11 deletions source/isaaclab_ovphysx/test/assets/test_articulation_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,13 @@

from types import SimpleNamespace

import pytest
import warp as wp
from isaaclab_ovphysx.assets.articulation.articulation import Articulation
from isaaclab_ovphysx.physics import OvPhysxManager
from isaaclab_ovphysx.test.mock_interfaces.views import MockOvPhysxBindingSet

from pxr import Sdf, Usd, UsdPhysics

# The CI isaaclab_ov* pattern unintentionally collects isaaclab_ovphysx tests,
# but the ovphysx wheel is not installed in that environment. Skip gracefully
# so the isaaclab_ov CI pipeline is not blocked by an unrelated dependency.
pytest.importorskip("ovphysx.types", reason="ovphysx wheel not installed")

from isaaclab_ovphysx.assets.articulation.articulation import Articulation # noqa: E402
from isaaclab_ovphysx.physics import OvPhysxManager # noqa: E402
from isaaclab_ovphysx.test.mock_interfaces.views import MockOvPhysxBindingSet # noqa: E402

wp.init()


Expand Down Expand Up @@ -120,7 +113,6 @@ def test_process_tendons_scopes_to_articulation_root(tmp_path):


def test_mock_binding_set_rigid_object_shapes():
pytest.importorskip("isaaclab_ovphysx.tensor_types").RIGID_BODY_POSE # gates on wheel
from isaaclab_ovphysx import tensor_types as TT
from isaaclab_ovphysx.test.mock_interfaces.views import MockOvPhysxBindingSet

Expand Down
22 changes: 8 additions & 14 deletions source/isaaclab_ovphysx/test/assets/test_rigid_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,14 @@
import torch
import warp as wp
from flaky import flaky

# The CI isaaclab_ov* pattern unintentionally collects isaaclab_ovphysx tests,
# but the ovphysx wheel is not installed in that environment. Skip gracefully
# so the isaaclab_ov CI pipeline is not blocked by an unrelated dependency.
pytest.importorskip("ovphysx.types", reason="ovphysx wheel not installed")

from isaaclab_ovphysx.assets import RigidObject # noqa: E402
from isaaclab_ovphysx.physics import OvPhysxCfg, OvPhysxManager # noqa: E402

import isaaclab.sim as sim_utils # noqa: E402
from isaaclab.assets import RigidObjectCfg # noqa: E402
from isaaclab.sim import SimulationCfg, build_simulation_context # noqa: E402
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR, ISAACLAB_NUCLEUS_DIR # noqa: E402
from isaaclab.utils.math import ( # noqa: E402
from isaaclab_ovphysx.assets import RigidObject
from isaaclab_ovphysx.physics import OvPhysxCfg, OvPhysxManager

import isaaclab.sim as sim_utils
from isaaclab.assets import RigidObjectCfg
from isaaclab.sim import SimulationCfg, build_simulation_context
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR, ISAACLAB_NUCLEUS_DIR
from isaaclab.utils.math import (
combine_frame_transforms,
default_orientation,
quat_apply_inverse,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,14 @@
import pytest
import torch
import warp as wp

# The CI isaaclab_ov* pattern unintentionally collects isaaclab_ovphysx tests,
# but the ovphysx wheel is not installed in that environment. Skip gracefully
# so the isaaclab_ov CI pipeline is not blocked by an unrelated dependency.
pytest.importorskip("ovphysx.types", reason="ovphysx wheel not installed")

from isaaclab_ovphysx.assets import RigidObjectCollection # noqa: E402
from isaaclab_ovphysx.physics import OvPhysxCfg # noqa: E402

import isaaclab.sim as sim_utils # noqa: E402
from isaaclab.assets import RigidObjectCfg, RigidObjectCollectionCfg # noqa: E402
from isaaclab.sim import SimulationCfg, build_simulation_context # noqa: E402
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR # noqa: E402
from isaaclab.utils.math import ( # noqa: E402
from isaaclab_ovphysx.assets import RigidObjectCollection
from isaaclab_ovphysx.physics import OvPhysxCfg

import isaaclab.sim as sim_utils
from isaaclab.assets import RigidObjectCfg, RigidObjectCollectionCfg
from isaaclab.sim import SimulationCfg, build_simulation_context
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR
from isaaclab.utils.math import (
combine_frame_transforms,
default_orientation,
quat_apply_inverse,
Expand Down
13 changes: 2 additions & 11 deletions source/isaaclab_ovphysx/test/assets/test_rigid_object_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,14 @@

from __future__ import annotations

import pytest
import warp as wp

# The CI isaaclab_ov* pattern unintentionally collects isaaclab_ovphysx tests,
# but the ovphysx wheel is not installed in that environment. Skip gracefully
# so the isaaclab_ov CI pipeline is not blocked by an unrelated dependency.
pytest.importorskip("ovphysx.types", reason="ovphysx wheel not installed")

from isaaclab_ovphysx import tensor_types as TT # noqa: E402
from isaaclab_ovphysx.test.mock_interfaces.views import MockOvPhysxBindingSet # noqa: E402
from isaaclab_ovphysx import tensor_types as TT
from isaaclab_ovphysx.test.mock_interfaces.views import MockOvPhysxBindingSet

wp.init()


def test_mock_binding_set_rigid_object_shapes():
pytest.importorskip("isaaclab_ovphysx.tensor_types").RIGID_BODY_POSE # gates on wheel

bindings = MockOvPhysxBindingSet(
num_instances=4,
num_joints=0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@

from types import SimpleNamespace

import pytest

# The CI isaaclab_ov* pattern unintentionally collects isaaclab_ovphysx tests,
# but the ovphysx wheel is not installed in that environment. Skip gracefully
# so the isaaclab_ov CI pipeline is not blocked by an unrelated dependency.
pytest.importorskip("ovphysx.types", reason="ovphysx wheel not installed")


def _make_stub_binding(prim_paths: list[str]) -> SimpleNamespace:
"""Stub an ovphysx ``TensorBinding`` exposing ``shape``, ``count``, ``prim_paths``, and ``read(dst)``."""
Expand Down
30 changes: 13 additions & 17 deletions source/isaaclab_ovphysx/test/sensors/test_contact_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,22 @@
import torch
import warp as wp
from flaky import flaky

# The CI isaaclab_ov* pattern unintentionally collects isaaclab_ovphysx tests,
# but the ovphysx wheel is not installed in that environment. Skip gracefully
# so the isaaclab_ov CI pipeline is not blocked by an unrelated dependency.
pytest.importorskip("ovphysx.types", reason="ovphysx wheel not installed")

from isaaclab_ovphysx.assets import RigidObject # noqa: E402
from isaaclab_ovphysx.physics import OvPhysxCfg # noqa: E402
from isaaclab_ovphysx.sensors import ContactSensor, ContactSensorCfg # noqa: E402

import isaaclab.sim as sim_utils # noqa: E402
from isaaclab.assets import RigidObjectCfg # noqa: E402
from isaaclab.scene import InteractiveScene, InteractiveSceneCfg # noqa: E402
from isaaclab.sim import SimulationCfg, SimulationContext, build_simulation_context # noqa: E402
from isaaclab.sim.utils.stage import get_current_stage # noqa: E402
from isaaclab.terrains import HfRandomUniformTerrainCfg, TerrainGeneratorCfg, TerrainImporterCfg # noqa: E402
from isaaclab.utils.configclass import configclass # noqa: E402
from isaaclab_ovphysx.assets import RigidObject
from isaaclab_ovphysx.physics import OvPhysxCfg
from isaaclab_ovphysx.sensors import ContactSensor, ContactSensorCfg

import isaaclab.sim as sim_utils
from isaaclab.assets import RigidObjectCfg
from isaaclab.scene import InteractiveScene, InteractiveSceneCfg
from isaaclab.sim import SimulationCfg, SimulationContext, build_simulation_context
from isaaclab.sim.utils.stage import get_current_stage
from isaaclab.terrains import HfRandomUniformTerrainCfg, TerrainGeneratorCfg, TerrainImporterCfg
from isaaclab.utils.configclass import configclass

wp.init()

pytestmark = pytest.mark.device_split

# ---------------------------------------------------------------------------
# Device-lock autouse fixture
# ---------------------------------------------------------------------------
Expand Down
16 changes: 6 additions & 10 deletions source/isaaclab_ovphysx/test/sim/test_views_xform_prim_ovphysx.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,16 @@
from __future__ import annotations

import pytest
from isaaclab_ovphysx.physics import OvPhysxCfg

# The CI isaaclab_ov* pattern unintentionally collects isaaclab_ovphysx tests,
# but the ovphysx wheel is not installed in that environment. Skip gracefully
# so the isaaclab_ov CI pipeline is not blocked by an unrelated dependency.
pytest.importorskip("ovphysx.types", reason="ovphysx wheel not installed")

from isaaclab_ovphysx.physics import OvPhysxCfg # noqa: E402

import isaaclab.sim as sim_utils # noqa: E402
from isaaclab.sim import SimulationCfg, build_simulation_context # noqa: E402
from isaaclab.sim.views import FrameView # noqa: E402
import isaaclab.sim as sim_utils
from isaaclab.sim import SimulationCfg, build_simulation_context
from isaaclab.sim.views import FrameView

OVPHYSX_SIM_CFG = SimulationCfg(physics=OvPhysxCfg())

pytestmark = pytest.mark.device_split


@pytest.mark.parametrize("device", ["cpu", "cuda:0"])
def test_factory_dispatches_to_ovphysx_frame_view(device):
Expand Down
Loading
Loading