AI news ·
Nvidia tutorial shows how to build a retargeting engine in numpy without hardware
NVIDIA's IsaacTeleop tutorial builds a full robot teleoperation pipeline in a CPU-only Colab notebook, removing the need for headsets or simulators. It generates synthetic hand and controller data, composes custom retargeters into an 8-D action vector, and persists tuning parameters via JSON.

A new tutorial from MarkTechPost walks through the retargeting engine inside NVIDIA IsaacTeleop, the framework that converts XR hand tracking and motion-controller input into robot commands. The guide builds every input from scratch in NumPy, running entirely on a Colab CPU, so developers can prototype and test teleoperation pipelines without headsets or simulators.
The tutorial covers the full pipeline: generating synthetic hand and controller data, writing custom retargeters with live-tunable parameters, composing them with built-in gripper and SE(3) retargeters, and producing an 8-D action vector per step. State persistence across restarts is handled through JSON, and the type system catches mismatched dtypes and unwritten slots at the point of error.
Building the pipeline without hardware
The engine's contract rests on TensorGroupType, an ordered list of typed slots, and TensorGroup, the runtime container that validates each write. HandInput carries four NumPy arrays for 26 OpenXR hand joints, while ControllerInput holds fourteen slots for poses, buttons, and axes. OptionalType marks inputs a tracker may not deliver; the matching OptionalTensorGroup starts absent and becomes present on first write, giving every downstream node one explicit way to learn that tracking was lost.
Synthetic data generation replaces what a headset would supply. The make_hand function lays out 26 joints in OpenXR order, runs finger chains away from the palm, and places the thumb tip a chosen pinch distance from the index tip. The make_controller function fills grip and aim poses with validity flags, four buttons, thumbstick axes, and analog squeeze and trigger values. Both return ordinary TensorGroups - the same format a retargeter sees whether numbers come from OpenXR or NumPy.
Custom retargeters and built-in components
A retargeter is a BaseRetargeter subclass that declares input and output specifications and implements a compute function. The PinchRetargeter measures thumb-to-index distance and emits a float and bool, reporting -1 when no hand is tracked. Its parameters live in a ParameterState whose sync functions write onto the instance before every compute, so a value set from another thread takes effect on the next frame.
The built-in GripperRetargeter turns pinch distance into the -1/+1 gripper command Isaac Lab expects, with hysteresis: the gripper closes below 3 cm, opens above 5 cm, and holds its state in between. Se3AbsRetargeter maps the controller grip pose to a 7-D end-effector target, holding the last pose when grip validity drops rather than passing a zero quaternion downstream. Se3RelRetargeter emits deltas, with EMA smoothing applied to a constant step per frame.
Composing the graph and managing state
ValueInput nodes stand in for DeviceIO sources as graph leaves. Wires connect each retargeter's inputs to upstream outputs with type checking at connect time. TensorReorderer flattens the 7-D pose and gripper scalar into the action layout an environment expects, and OutputCombiner exposes the result under a single action key. The execute_pipeline function runs the DAG once per step against a shared ExecutionCache, so a controller leaf wired into multiple retargeters computes exactly once per frame.
The DefaultTeleopStateManager handles run, pause, and kill states. A rising edge on the run toggle walks STOPPED to PAUSED to RUNNING and back. The kill input forces STOPPED and pulses a reset event. Losing the kill or run signal fails safe to STOPPED. Those events reach every other node through ComputeContext.execution_events, allowing retargeters like LocomotionRootCmdRetargeter to snap back to initial height on reset before integrating again.
The TriHandMotionControllerRetargeter provides a controller-only route to dexterous hand control: trigger drives the index finger, squeeze drives the middle finger, and the larger of the two curls the thumb while their difference rotates it. Seven named joint angles emerge with no hand tracking and no optimization library. Tuning sticks across sessions: setting rotation and position offsets on a ParameterState and calling save_to_file writes a JSON file, and a fresh instance loads it on startup to produce identical end-effector poses.
Why this matters for operations and research professionals
For teams in operations, real estate, construction, and research who are evaluating robotic teleoperation, this tutorial removes the hardware barrier to entry. The entire pipeline - type validation, graph composition, state management, and parameter persistence - runs in a notebook on CPU. The same graph that works with synthetic NumPy inputs becomes a live headset pipeline by swapping ValueInput leaves for HandsSource and ControllersSource inside a TeleopSession. A recording becomes an MCAP replay, and the anchor transform applied by hand arrives from the simulator. Understanding this architecture before investing in XR equipment lets teams prototype control logic, test gripper hysteresis thresholds, and verify action vector layouts against their simulation environments at zero hardware cost.