Skip to main content

Overview

Subscribe to the Wuji Hand 2 joint_states broadcast to read position, velocity, and an effort proxy for every online joint. Callbacks fire on SDK background worker threads, so your main thread never blocks. This is the shortest path to live state from the hand. State monitoring, data logging, and feeding a higher-level controller all start here. Matching examples: examples/python/wuji_hand_2/0.subscribe_callback.py and examples/c/wuji_hand_2/0_subscribe_joint_states.c. For joint state and field definitions, see SDK Reference. This page covers only how to run it and what the measurements show.

Prerequisites

Hardware

This example only reads. It doesn’t enable the motors, and the fingers don’t move.

Software

Before You Start

Nothing. Power the device and connect the network.

Data Flow

Each frame is a self-describing variable-length aggregate: header carries seq, timestamp_us, and frame_id, while joints holds only the joints the firmware reported this cycle.

Frame Structure

On a device with all 20 joints online, a single frame measures as follows: nid isn’t contiguous, and it’s a different numbering from the array index. The 20 online joints report nids 1 2 3 4, 6 7 8 9, 11 12 13 14, 16 17 18 19, 21 22 23 24, skipping 5, 10, 15, and 20. Each finger occupies a block of 5 nids but uses only the first 4. The conversion holds across all 20 joints:
Index 0 is thumb_S1 (nid 1), index 4 is index_S1 (nid 6), and index 19 is pinky_S4 (nid 24). Using nid directly as an array subscript shifts everything, and the full joint label mapping lives in Reading Device Info.

Runtime Handling

C callbacks fire on dedicated worker threads, and the frame pointer is valid only for the duration of the callback. Its heap joints array is freed as soon as it returns, so never retain the pointer.

Integration Steps

Always close subscriptions before disconnecting. The other way around, a worker thread may still touch a device you’ve already released.

Running It

The Python side prints one line per frame, showing only the thumb’s 4 joints by default:
The C side lays out the whole frame as a table and throttles printing to about 1 Hz so it doesn’t flood the terminal:
Measured on a right-hand Wuji Hand 2 with all 20 joints online. At rest, position holds steady and velocity jitters around zero. The rate is about 1 kHz. Five seconds received 5555 frames, working out to roughly 1000 frames per second from the device-side seq difference. Doing anything heavier than printing inside the callback causes a backlog.

Adapting It

Name a Device When Several Share a Network

This is the easiest mistake to make with this example, and the two bindings behave differently: The Python example takes no --sn argument, unlike its glove counterpart. Before running on a shared network, change the connect call to name a serial number:
A counterexample came up in testing: with three Hand 2 devices on the network and one held by another client, the example raised Session already exists when it reached that device, subscriptions already open terminated with it, and the whole run received a single frame.

Subscribe to More Streams

Beyond joint_states, the device offers joint_diagnostics, imu, and fingertip tactile. Subscribing works the same way with the matching resource method. For decoding fingertip tactile, see Wuji Hand 2 Fingertip Tactile.

Lower the Rate

About 1 kHz is higher than most applications need. Use set_rate() on the subscription handle, described in Adjusting Stream Rate.

Keep Callbacks Light

Callbacks fire per frame on an SDK worker thread. File writes, algorithms, and lock waits all compete for that thread and cause a backlog. Copy the minimum inside the callback, push it onto a queue, and consume it on another thread.