Skip to main content
Wuji Glove offline solving turns emf_poses into joint angles, fingertip poses, and a hand skeleton, and raw IMU frames into fused orientation. Data Recording saves input frames to an MCAP file. The replay code reads that file and rebuilds the frames. Pass the rebuilt frames directly to the offline solving API without connecting to a device.

Solving Steps

Create the Pipeline

Create an offline processing pipeline with the capture device’s serial number and hand side. The serial number accepts 1–64 bytes of ASCII letters, digits, ., _, and -, excluding . and .. alone. Use the optional urdf_path to pin a hand model when processing the same data again. The examples use a right hand. Replace these values with those of the recording.
hand_side accepts "left" or "right". An invalid value raises WujiException. Set urdf_path=None to use the model lookup rules below.

Recompute Joint Angles, Fingertip Poses, and Skeleton

When processing recorded data, read input frames from the /<serial_number>/emf_poses channel in the MCAP file. The offline API takes EmfPoseArray in Python or WujiEmfPoseArray in C. See the Python replay code for MCAP reading and frame reconstruction. Each frame contains five EMF poses. Request joint angles, fingertip poses, and the skeleton from the same frame to share one solve. These functions process one frame and print the result counts.

Recompute IMU Orientation

When processing recorded data, read input frames from the /<serial_number>/imu_raw/palm channel in the MCAP file. The offline API takes raw ImuData in Python or raw WujiImuData in C. See the Python replay code for MCAP reading and frame reconstruction. Pass each raw IMU frame to the matching fusion entry point to compute orientation. The six entry points correspond to palm, thumb, index, middle, ring, and pinky. Each keeps a separate fusion state and doesn’t depend on the calibration URDF. Python methods follow imu_data_<location>(), and C functions follow wuji_glove_offline_compute_imu_data_<location>.
ImuData.raw() sets orientation_covariance[0] to -1.0 to mark an unfused input.
Input and output use the same data type. The fused output has orientation_covariance[0] set to 0.0.

Example

These programs use a synthetic right-hand EMF frame and a raw palm IMU sample. They create a pipeline, compute hand outputs and IMU orientation, and release resources. No device connection is needed. For real data, use an MCAP file recorded from a Wuji Glove with both emf_poses and imu_raw/palm channels. Follow the replay code to rebuild the raw frames and submit them one by one. Check the serial number against the channel name. Record the hand side and URDF used during capture separately.
Save the program as offline_pipeline.py, then run python offline_pipeline.py.
Both programs should print Fingers: 5, tips: 5, skeleton joints: 21 and an Orientation with four components. IMU input determines the orientation values. Hand output values also depend on the hand model. A warning about the built-in model is expected for the default SDK user. This step confirms that the solving API runs. For MCAP reading, frame-by-frame replay, and a measured comparison with online solving, see SDK Usage Practices: Replaying Data Offline.

Usage Notes

Select and Verify the Hand Model

Hand outputs depend on the calibration model. Both languages select the URDF using the same rules:
  1. Explicit Path: use urdf_path when supplied. A read failure returns an error, without a fallback
  2. Managed Model: without an explicit path, use the current SDK user’s custom calibration.hand_model_path if it points outside the SDK-managed directory. Otherwise, use that user’s left_hand.urdf or right_hand.urdf. These are alternatives, not fallbacks for each other
  3. Built-In Model: if the selected managed file is missing, unreadable, or named for the other hand, use the built-in default URDF and log a warning
The default SDK user skips managed models and uses the built-in model unless you specify a path. To match the model used during capture, switch to that named user or specify its URDF. See Calibration. The built-in model can reduce hand-output accuracy. URDF selection doesn’t affect IMU fusion.
You can solve frames immediately after creating the pipeline. No query is required. The SDK may fall back to the built-in URDF if a managed model is unavailable. To confirm the model it selected, read urdf_source and urdf_source_path. You can also read back the serial number and hand side.
urdf_source is "override", "calibration_file", or "builtin_default". The built-in model’s urdf_source_path is None.

Process Frames in Capture Order

Submit frames in capture order. Each pipeline retains solver state and caches only the most recent hand frame for hand computations. Consecutive calls with the same hand frame reuse its result. Submitting frames A, B, and A in that order recomputes A. Use a separate pipeline for each independent stream, and process one pipeline serially. Create a new pipeline to restart playback or change the calibration model. Offline and online processing share the same solvers. Use the same input frames, calibration model, and processing order when comparing results.

Check Errors and Release Resources

Failed calls raise exceptions. Python manages result objects, so no manual release is needed. Use the pipeline and its resource objects on the thread that created them. Create a new pipeline for another replay.An invalid hand_side raises WujiException. An unreadable explicit URDF or a failed computation reports its cause through an exception.