diff --git a/examples/oglo_tactile/README.md b/examples/oglo_tactile/README.md index 48fd827f4a..7a51182448 100644 --- a/examples/oglo_tactile/README.md +++ b/examples/oglo_tactile/README.md @@ -31,10 +31,11 @@ session, records, and draws the overlay). `oglo_heatmap.py` is the renderer. ```bash sudo apt install libdbus-1-dev # BlueZ for the BLE plugin sudo apt install pkg-config glslang-tools libvulkan-dev # BUILD_VIZ=ON below - pip install pillow numpy # heatmap renderer - pip install cupy-cuda12x # headset overlay GPU upload (match your CUDA) + uv pip install -e ./examples/oglo_tactile # heatmap renderer + deps + uv pip install -e './examples/oglo_tactile[gpu]' # adds the CUDA overlay upload ``` - `cupy` is only needed for the in-headset overlay; recording works without it. + The `gpu` extra is only needed for the in-headset overlay; recording works + without it. Match your CUDA major version if you edit the pin. 2. **Build** (plugin + viz + python wheel) @@ -76,8 +77,7 @@ python -m isaacteleop.cloudxr.service start --accept-eula # flag needed on fir cd ~/Documents/IsaacTeleop source scripts/setup_cloudxr_env.sh source ~/.cloudxr/run/cloudxr.env # path printed by step above -cd examples/oglo_tactile -python oglo_teleop_record.py +python -m isaacteleop_examples.oglo_tactile.oglo_teleop_record ``` The script: connects both gloves over BLE, starts recording to `oglo_teleop_.mcap`, and shows the **two-hand tactile heatmap** in the diff --git a/examples/oglo_tactile/pyproject.toml b/examples/oglo_tactile/pyproject.toml new file mode 100644 index 0000000000..524577bcf3 --- /dev/null +++ b/examples/oglo_tactile/pyproject.toml @@ -0,0 +1,32 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +# The dist name mirrors the import path, so an installed example claims no bare +# top-level name in site-packages. +name = "isaacteleop-examples-oglo-tactile" +version = "0.0.0" # Internal example - not versioned +description = "OGLO tactile glove: heatmap renderer and teleop recording" +requires-python = ">=3.11,<3.14" +dependencies = [ + "isaacteleop[cloudxr]", + "numpy>=1.23.0", + "pillow", +] + +[project.optional-dependencies] +# The in-headset overlay uploads the heatmap through CUDA; match your CUDA +# major version. Without it the renderer still writes PNGs. +gpu = ["cupy-cuda12x"] + +# `isaacteleop_examples` is a PEP 420 namespace shared by every example dist and +# must stay without an __init__.py. `only-include` + `sources`, not `packages`: +# the latter keeps only the last path component and would root the wheel at a +# bare top-level `oglo_tactile/`. +[tool.hatch.build.targets.wheel] +only-include = ["python/isaacteleop_examples/oglo_tactile"] +sources = ["python"] diff --git a/examples/oglo_tactile/python/isaacteleop_examples/oglo_tactile/__init__.py b/examples/oglo_tactile/python/isaacteleop_examples/oglo_tactile/__init__.py new file mode 100644 index 0000000000..52a7a9daf0 --- /dev/null +++ b/examples/oglo_tactile/python/isaacteleop_examples/oglo_tactile/__init__.py @@ -0,0 +1,2 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 diff --git a/examples/oglo_tactile/oglo_heatmap.py b/examples/oglo_tactile/python/isaacteleop_examples/oglo_tactile/oglo_heatmap.py similarity index 100% rename from examples/oglo_tactile/oglo_heatmap.py rename to examples/oglo_tactile/python/isaacteleop_examples/oglo_tactile/oglo_heatmap.py diff --git a/examples/oglo_tactile/oglo_teleop_record.py b/examples/oglo_tactile/python/isaacteleop_examples/oglo_tactile/oglo_teleop_record.py similarity index 97% rename from examples/oglo_tactile/oglo_teleop_record.py rename to examples/oglo_tactile/python/isaacteleop_examples/oglo_tactile/oglo_teleop_record.py index bb7dab1477..7a0438b0ae 100755 --- a/examples/oglo_tactile/oglo_teleop_record.py +++ b/examples/oglo_tactile/python/isaacteleop_examples/oglo_tactile/oglo_teleop_record.py @@ -36,7 +36,7 @@ import isaacteleop.deviceio as deviceio import isaacteleop.viz as viz -from oglo_heatmap import NUM_TAXELS, Normalizer, TactileHeatmapRenderer +from .oglo_heatmap import NUM_TAXELS, Normalizer, TactileHeatmapRenderer OVERLAY_W, OVERLAY_H = 1024, 512 COLLECTION_PREFIX = "oglo" @@ -50,8 +50,12 @@ def _on_signal(signum: int, frame: FrameType | None) -> None: def _default_plugin_bin() -> str: + # Only meaningful from a source checkout: examples/oglo_tactile/python/ + # isaacteleop_examples/oglo_tactile/ is five levels below the repo root. An + # installed copy lands in site-packages, where this finds nothing and the + # PATH fallback below takes over. here = Path(__file__).resolve() - root = here.parents[2] # repo root + root = here.parents[5] for cand in ( root / "build/src/plugins/oglo_tactile/oglo_tactile_plugin", root / "install/plugins/oglo_tactile/oglo_tactile_plugin",