pip install wuji-sdk numpy — numpy is used for keypoint/qpos arrays, and nothing else is required. The C SDK provides an equivalent API — the function names are in the interface list below, and the memory ownership and status code conventions are in the C API conventions.
Quick start
RetargetSession.for_hand(model, side) binds a session to a hand model with the built-in IK config. session.step(keypoints) accepts a (21, 3) float32 array and returns a (20,) float32 vector of joint angles — send the result to the hand as-is:
- Python
- C
session.reset() in Python or wuji_retarget_session_reset() in C.
API reference
Create a session
Class methodRetargetSession.for_hand(hand_model, side) builds a session bound to a hand model with the built-in config.
Retarget a frame
session.step(keypoints) runs retargeting on a single keypoint frame.
Returns
np.ndarray of shape (20,) float32. Send to the hand directly.
Reset state
session.reset() clears warm-start and low-pass-filter state, and wuji_retarget_session_reset() is the C equivalent. Call it when switching data sources or after a long pause before resuming.
For a measured single-frame run, degenerate input, and handling tracking gaps, see Retargeting Sessions: Keypoints to Joint Angles.
Input format
step input follows the MediaPipe Hands landmark convention — 21 fixed-order points (wrist + 5 fingers × 4 joints), coordinates in meters. Any source producing this format works: camera + MediaPipe, the Wuji Glove hand_skeleton subscription, VR hand tracking, and so on.
Live teleoperation example
RetargetSession is a pure retargeting interface — teleoperation (driving a hand from a live keypoint stream) is application-level code built on top. For full examples, see examples/python/retargeting/ and examples/c/retargeting/ in the wuji-sdk repo (Wuji Glove input → retarget → drive Wuji Hand 2 / Wuji Hand).
With a queue-based subscription, recv() returns the oldest unread frame, so reading one frame per loop falls behind. Drain to the latest frame each round before feeding step. A callback-based subscription (as in the C example) overwrites a shared buffer from the callback, so the main loop always reads the latest frame.
Choose the SDK User for Teleop
The hand model depends on the currently selected SDK user. Switch before or after connecting — either works. An already-connected glove picks up the new user’s model on its own, with no reconnect:- Default user — always runs on the SDK’s built-in default hand URDF. Calibrating under the default user has no effect.
- Named user — runs on that user’s calibrated hand model. When that user hasn’t calibrated yet, it falls back to the built-in default URDF too.
1.teleop_real.py and 1_teleop_real.c) behave the same: both list every SDK user before connecting the glove and prompt for a choice. Press Enter to keep the current user, and the example restores the previously selected user on exit. The menu doesn’t show whether a user is calibrated — no public API resolves a user’s hand model before connecting.
The built-in default URDF is currently more reliable than a per-user calibrated hand model, so start with the default user. If the built-in URDF doesn’t track your hand well, create a named SDK user, switch to it, then calibrate the glove under that user. After calibration, pick that user from the example menu. See SDK User Management and Calibration for details.
Platform and limits
- Linux x86_64 and aarch64 only. Precompiled wheels are not distributed for macOS, Windows, or other architectures.
- The algorithm is built into the SDK — no extra download. The only runtime dependency is
numpy(for keypoint/qpos arrays).
Interface List
Both sides run the same algorithm with the same built-in IK config. Python takes and returns numpy arrays of shape
(21, 3) and (20,), while C takes and returns caller-allocated row-major arrays of 63 and 20 floats. A degenerate or invalid keypoint frame raises WujiException in Python and returns WUJI_STATUS_ERR_ALGORITHM in C. Drop the frame in either case.