Skip to main content

Overview

Feed in a set of MediaPipe-format hand keypoints, get back a joint command you can send straight to a dexterous hand. This step connects to no device at all. This step performs computation only. The keypoints can come from anywhere. A camera, a Wuji Glove, a recorded replay, VR headset hand tracking — as long as the array has the same shape and units, everything downstream stays identical. Run this example first to confirm retargeting works and to see the input and output shapes. When you then attach real hardware, there’s far less ground to search. Matching examples: examples/python/retargeting/0.retarget_session.py and examples/c/retargeting/0_retarget_session.c. The C interface maps one to one onto Python. For the interface list, input format, and platform limits, see Retargeting. This page covers only how to run it and what the measurements show.

Prerequisites

Hardware

None. This example uses synthetic keypoints, so it neither scans for nor connects to a device.

Software

Before You Start

Nothing. This example is the smallest starting point on the retargeting path. Get it running, then move on to real hardware.

Data Flow

A single frame travels the path below. The session object keeps state across frames, so create it once and reuse it in your loop. Keypoints are in meters, joint commands in radians. The output is always float32 with a fixed shape that doesn’t vary with the number of online joints. float64 input is accepted and converted internally.

Runtime Handling

The session is stateful. Reuse one session across a continuous tracking segment, reset between segments, and never create one per frame.

Integration Steps

Three fixed steps in a fixed order. C adds an explicit free.
The only real difference between the two sides is the keypoint memory layout. Python takes a (21, 3) two-dimensional array, C takes a flat array of 63 laying out x, y, and z for each point in landmark order.

Running It

Both sides print the same structure: the joint command’s shape and dtype, then the 20 joint angles grouped by finger.
C skips the shape line and starts at the joint command:
These are actual results, measured on Wuji SDK v2026.8.31, Python 3.12, the C SDK for x86_64-linux-gnu, and Linux x86_64, with the example’s built-in synthetic open right-hand pose as input. For the same input, both interfaces produce bit-identical joint angles across all 20 values, because they share one solver implementation. Change the keypoints or the hand model and the numbers change, but the shape and grouping don’t.

Adapting It

Swap In a Real Keypoint Source

Replace the example’s make_open_hand_keypoints() with your source. As long as it produces (21, 3) keypoints in meters in MediaPipe landmark order, nothing downstream changes. The Wuji Glove’s hand_skeleton() stream is already in this format, and Retargeting shows how to connect it.

Change Hand Model and Handedness

Targeting a Wuji Hand instead, change HandModel.WujiHand2 to HandModel.WujiHand. For a left-hand assembly, change Handedness.Right to Handedness.Left and confirm the keypoints come from a left hand too.

Move to a Real-Time Loop

This example solves one frame. In a real-time setting, call step() on a fixed period in a loop and handle the case where no new frame arrived. For the full loop, see Retargeting.

Input Validity

Confirm the keypoints aren’t degenerate before solving. An all-zero array, or one holding NaN or Inf, makes step() raise invalid keypoints. When tracking is lost, repeating the last valid frame is safer than sending zeros.

Handling Tracking Gaps

The hand leaves the frame, the device disconnects, a replay cuts to a new segment — call reset() once after any of these. Skip it and the first few frames after recovery ease out of the old state, which looks like lag.