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
10 changes: 5 additions & 5 deletions docs/source/device/haptic_feedback.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ graph outputs and writes them *out* to a device after the graph runs.
Example
-------

``examples/haptic_feedback/python/controller_haptic_example.py`` is the minimal
``examples/haptic_feedback`` provides the minimal
end-to-end wiring: pull a controller's trigger and that **same** controller
rumbles. ``TriggerToTactile`` turns the trigger value into a ``TactileVector``,
``TactileVectorToControllerPulse`` turns that into a ``ControllerHapticPulse``,
Expand All @@ -67,12 +67,12 @@ Running

The example connects through the CloudXR / OpenXR runtime, which it starts
itself if nothing is serving (see :ref:`dedicated-cloudxr-runtime` to manage
that service yourself). Run it from the ``examples/haptic_feedback/python``
directory:
that service yourself). Install the example, then run it:

.. code-block:: bash

uv run controller_haptic_example.py
uv pip install -e ./examples/haptic_feedback
python -m isaacteleop_examples.haptic_feedback.controller_haptic_example

No arguments — pull either trigger to rumble that controller. Press Ctrl+C to
exit. Runtimes that do not expose ``xrApplyHapticFeedback`` silently no-op rather
Expand All @@ -94,6 +94,6 @@ foundation.
See also
--------

- Example + tests: ``examples/haptic_feedback/python/`` and
- Example + tests: ``examples/haptic_feedback`` and
``tests/python/core/retargeting_engine/test_haptic_devices.py`` /
``test_haptic_sink.py``.
2 changes: 1 addition & 1 deletion examples/haptic_feedback/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
cmake_minimum_required(VERSION 3.20)

include(${CMAKE_SOURCE_DIR}/cmake/InstallPythonExample.cmake)
install_python_example(DESTINATION examples/haptic_feedback/python)
install_python_example(DESTINATION examples/haptic_feedback)
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ flushes to an `IHapticDevice` adapter each frame.

| Example | What it demonstrates |
| --- | --- |
| `controller_haptic_example.py` | Pull a controller trigger to rumble that same controller — the minimal in-process `HapticSink` → `ControllerHapticDevice` wiring. |
| `hand_pinch_haptic_example.py` | Pinch a fingertip toward the thumb to vibrate a haptic glove — the cross-process path (`HapticSink` → `PushTensorHapticDevice`, pushing a `HapticCommand` to a glove plugin such as Manus). |
| `controller_haptic_example` | Pull a controller trigger to rumble that same controller — the minimal in-process `HapticSink` → `ControllerHapticDevice` wiring. |
| `hand_pinch_haptic_example` | Pinch a fingertip toward the thumb to vibrate a haptic glove — the cross-process path (`HapticSink` → `PushTensorHapticDevice`, pushing a `HapticCommand` to a glove plugin such as Manus). |

```bash
uv run controller_haptic_example.py # motion-controller rumble
uv run hand_pinch_haptic_example.py # haptic glove (needs a glove plugin running)
uv pip install -e ./examples/haptic_feedback
python -m isaacteleop_examples.haptic_feedback.controller_haptic_example # motion-controller rumble
python -m isaacteleop_examples.haptic_feedback.hand_pinch_haptic_example # haptic glove (needs a glove plugin running)
```

Both connect through the CloudXR / OpenXR runtime, so start the runtime first.
Expand Down
26 changes: 26 additions & 0 deletions examples/haptic_feedback/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-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-haptic-feedback"
version = "0.0.0" # Internal examples - not versioned
description = "Isaac Teleop haptic feedback CLI examples (OpenXR controller)."
requires-python = ">=3.11,<3.14"
dependencies = [
"isaacteleop",
"numpy>=1.23.0",
]

# `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 `haptic_feedback/`.
[tool.hatch.build.targets.wheel]
only-include = ["python/isaacteleop_examples/haptic_feedback"]
sources = ["python"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
12 changes: 0 additions & 12 deletions examples/haptic_feedback/python/pyproject.toml

This file was deleted.

Loading