Quick Start

Before running, complete the installation steps in Introduction and the hardware connection and network configuration in Getting Started.

The SDK ships with three complete examples demonstrating data subscription and recording. Full source code is available on GitHub. Connect the glove via Ethernet and configure the network before running.

Callback Subscription (0.subscribe_callback.py)

Uses subscribe_with_callback() to register callback functions that execute automatically on a background thread when data arrives. Best suited for synchronous programs that don't use asyncio, or when you need to decouple data processing from the main thread.

python 0.subscribe_callback.py

This example auto-discovers and connects to all available gloves, registering 6 data stream callbacks per glove (tactile, tactile_zones, emf_poses, hand_joint_angles, hand_skeleton, tactile_point_cloud). The main thread stays idle while callbacks fire continuously in the background. Subscriptions are cleaned up via sub.close() on exit.

Expected output:

Found 1 device(s)
  SN=WG1KA00XXXXXXXXX, Address=192.168.1.101:50001
Connected: WG1KA00XXXXXXXXX (FW=0.6.0, right)
[glove_0][Zones] palm=-0.0 thumb=-0.1
[glove_0][Tactile] max=0.7
[glove_0][EmfPoses] thumb=[+0.061, +0.019, -0.058]
[glove_0][JointAngles] conf=['0.26', '0.48', '0.43', '0.43', '0.40']
[glove_0][Skeleton] wrist=[+0.000, +0.000, +0.000] joints=21
Subscribed to 6 streams. Ctrl+C to stop.
...

For details on callback subscriptions, see Data Subscription.

Async Subscription (1.subscribe_async.py)

Uses Python async/await with recv_async() to receive data asynchronously. Best suited for applications that orchestrate multiple coroutines within the same event loop.

python 1.subscribe_async.py

This example auto-discovers and connects to all available gloves, subscribes to 6 data streams (tactile, tactile_zones, emf_poses, hand_joint_angles, hand_skeleton, tactile_point_cloud), and processes them concurrently with asyncio.gather.

Expected output:

Found 1 device(s)
  SN=WG1KA00XXXXXXXXX, Address=192.168.1.101:50001
Connected: WG1KA00XXXXXXXXX (FW=0.6.0, right)
Subscribed to 6 streams. Ctrl+C to stop.

[glove_0][EmfPoses] thumb=[+0.061, +0.019, -0.058]
[glove_0][JointAngles] conf=['0.26', '0.48', '0.43', '0.43', '0.40']
[glove_0][Zones] palm=-0.0 thumb=-0.1
[glove_0][Tactile] max=0.7
[glove_0][Zones] palm=-0.0 thumb=-0.1
[glove_0][Tactile] max=0.7
[glove_0][EmfPoses] thumb=[+0.062, +0.019, -0.058]
[glove_0][Skeleton] wrist=[+0.000, +0.000, +0.000] joints=21
[glove_0][JointAngles] conf=['0.55', '0.35', '0.63', '0.29', '0.34']
[glove_0][Skeleton] wrist=[+0.000, +0.000, +0.000] joints=21
...

For details on async subscriptions and cross-device merged subscription, see Data Subscription.

Data Recording (2.recording.py)

Uses TopicRecorder to record sensor data to an MCAP file with LZ4 compression.

python 2.recording.py

This example connects to one glove, registers 3 data streams (tactile, emf_poses, hand_skeleton) with the recorder, records for 10 seconds, then stops and prints a summary.

Expected output:

Connected: WG1KA00XXXXXXXXX
Recording to ./data/20260317_150357.mcap ...
Done — 3606 frames, 3.90 MB, 10.0s

For the full recording API (pause/resume, episode switching, quality monitoring, and more), see Data Recording.

Wuji Hand Quick Start

A minimal getting-started example for Wuji Hand through wuji-sdk. The SDK exposes Wuji Hand as a USB device during scan. After connecting, enable the motors, subscribe to 20-joint positions, and use realtime_controller with LowPass to drive the index, middle, ring, and pinky fingers through one smooth clench-and-release cycle. For more usage, see Device Connection, Data Subscription, and Data Reference.

Clear space around Wuji Hand before running so the fingers can move freely without hitting anything.

import asyncio
import math
import time
from wuji_sdk import SdkManager, TransportType, LowPass

async def main():
    manager = SdkManager.instance()
    usb_devices = [d for d in manager.scan() if d.transport_type == TransportType.Usb]
    if not usb_devices:
        print("No Wuji Hand found")
        return

    hand = manager.connect(sn=usb_devices[0].sn, device_name="wuji_hand")
    print(f"Connected: {hand.serial_number} ({hand.handedness_name()})")

    hand.enable()
    try:
        # Open the realtime controller before subscribing and publishing
        with hand.realtime_controller(LowPass(cutoff_hz=5.0)):
            # Subscribe to 5 joint state frames
            sub = hand.joint_state().subscribe()
            for _ in range(5):
                state = await sub.recv_async()
                joints = ", ".join(f"{p:+.3f}" for p in state.position[:4])
                print(f"[seq={state.header.seq}] joint[0..3]={joints}")
            sub.close()

            # Stream a cosine trajectory at 100 Hz — clench and release four fingers
            publisher = hand.joint_command().publisher()
            update_period = 1.0 / 100.0
            duration_s = 4.0
            start = time.monotonic()
            while True:
                t = time.monotonic() - start
                if t >= duration_s:
                    break
                # y ramps smoothly from 0 up to 1.6 and back to 0
                y = (1 - math.cos(2 * math.pi * t / duration_s)) * 0.8
                target = [0.0] * 20
                # Index, middle, ring, and pinky fingers — J1, J3, J4 follow y
                for finger in range(1, 5):
                    base = finger * 4
                    target[base + 0] = y
                    target[base + 2] = y
                    target[base + 3] = y
                publisher.send(target)
                time.sleep(update_period)
            publisher.close()
    finally:
        hand.disable()
        manager.disconnect(device_name="wuji_hand")

asyncio.run(main())

What You'll See

The terminal prints the connection info followed by 5 joint state frames:

Connected: XXXXXX.YYMMDD.NNN (Left)
[seq=0] joint[0..3]=-0.097, -0.016, -0.012, -0.006
[seq=1] joint[0..3]=-0.095, -0.017, -0.012, -0.006
[seq=2] joint[0..3]=-0.093, -0.017, -0.012, -0.006
...
[seq=4] joint[0..3]=-0.091, -0.016, -0.012, -0.006

After the prints, the index, middle, ring, and pinky fingers clench and release smoothly over 4 seconds. When the example finishes, the motors disable and the joints relax under their natural load.