Overview
Wuji Hand 2 fingertip tactile sensors describe their data format through metadata. Read each finger’sinfo metadata before subscribing, then use its format JSON to decode the data frame. The field describes the contact layout, units, and mounting pose.
The application must read the metadata before decoding data frames. When firmware changes the point count, units, or mounting pose, the decoder can use the updated metadata.
This capability depends on the hardware configuration. 2.1 hardware has no fingertip tactile sensors, which arrive with 2.2 hardware. The test device used for this page does not provide the capability. This page documents capability detection, failure behavior, and handling. For supported devices, follow the interface definition and product specification.
Matching examples: examples/python/wuji_hand_2/3.fingertip_typed.py and examples/c/wuji_hand_2/3_fingertip.c.
For the interface list, the field definitions of the self-describing format, and the calibration interface, see Wuji Hand 2 Fingertip Tactile. This page covers only how to run it and what the measurements show.
Prerequisites
Hardware
What 2.2 ships is a contact array: 40 contacts on the thumb and 34 on each other finger, each reporting three-axis force plus temperature at 100 Hz.
Software
- Python
- C
Before You Start
Confirm the device has this capability. The next section shows how.Detect Device Capability
The most reliable runtime check reads the resource list. Don’t infer it from a version number:topics() holds no fingertip entries at all. A device with it lists five fingertip/<finger>/data topics.
This check needs no try/except and doesn’t depend on mapping hardware or firmware versions.
Data Flow
Read the sensor metadata before subscribing to the data stream. The data frame does not contain a complete format description, so it cannot be decoded correctly without the metadata.The format Field
info.format is a JSON string that describes the data layout. The decoder is driven by its fields. The key fields:
The field-type to unpack-format mapping is defined in one table. Unknown types raise an error:
Self-Checking the Data Length
Compute the expected length before decoding and fail outright on a mismatch:Units Change With Firmware, So Read Them From format
Starting with firmware v2.4.0, per-contact force is normalized to the sensor’s full scale: 0 to 1 on the normal axis, −1 to 1 on the tangential axes, clipped beyond that. Earlier firmware reports newtons. The aggregate force and temperature stay in newtons and degrees Celsius on both. So pick your contact threshold from the declared unit rather than hard-coding it:scale and unit.
Placing Contacts on the Hand Model
positions and point_rpy live in the sensor module’s own frame, and base_xyz with base_rpy give that frame’s pose relative to the finger’s tip_sensor_frame. So contact i sits in finger coordinates at:
R(base_rpy) @ R(point_rpy[i]).
The aggregate can be recovered as a true wrench: the force is R(base_rpy) @ R(aggregate_rpy) @ (fx, fy, fz), the application point is R(base_rpy) @ aggregate_xyz + base_xyz, and the moment about the link origin is p × f.
These three mounting-pose keys were added to the contract together. The example branches on that: all three missing means older firmware where position information isn’t available, while only some missing means the metadata itself is broken, which raises. Firmware without aggregate_xyz reports neither an application point nor a moment. Do not calculate these values when the field is missing.
The device reports poses for its own handedness, so the same code is correct on left and right hands.
SDK Version Compatibility
This change affects interface compatibility.
The C side matches, where
wuji_hand_2_get_fingertip_thumb_info(dev, &out) replaces wuji_hand_2_get_fingertip_info(dev, finger, &out).
There’s no compatibility shim. Measured, calling the new interface on v2026.8.31:
0=thumb, 1=index, 2=middle, 3=ring, 4=pinky.
The examples in the repository follow the newest interface. Running them against an older SDK raises
AttributeError while reading info. That isn’t a device problem.Measured Behavior on Unsupported Devices
Device details:firmware_version = 1.3.0 and hw_version = HwVersion(major=0, minor=2, patch=0).
All four paths fail, with errors from different layers:
All five fingers report the same error from
get_fingertip_info, and topics() holds no fingertip entries either.
Note that the Python object does have fingertip_thumb_data, get_fingertip_info, tactile_calibrate, and tactile_status. A method existing doesn’t mean the device supports it, because the SDK’s interface surface is defined per product while what works depends on the device’s resource list.
Runtime Handling
One finger failing to report info is normal, not a fault. The example skips it and decodes the rest, stopping only when all five fail.
Integration Steps
- Python
- C
Running It
- Python
- C
Recalibration and Status Queries
On a device with the capability,hand.tactile_calibrate() resets all five fingertips to a fresh zero baseline. The C side is wuji_hand_2_tactile_calibrate(dev).
The sensor surfaces must be unloaded during calibration. Nothing touching them, nothing pressing against them. Afterward, hand.tactile_status(finger) reports each sensor’s model and calibration state, which confirms it finished.
Every frame summary on the joint_diagnostics stream carries a fingertip tactile online bitmap, so you can monitor which fingertips are online without polling.
Configuration and Adaptation
Lower the Stream Rate
Five contact arrays at 100 Hz add up.fingertip/*/data is a rate-control entry point, so a subscription handle’s set_rate() lowers it, which needs firmware v2.3.0 or later. See Wuji Hand 2 Adjusting Stream Rate.
Re-Read info After a Firmware Upgrade
scale, unit, and the mounting poses in format can all change with firmware. Skip the re-read and your decoder parses new data against the old contract, giving wrong numbers with no error. Read info right after every connection and don’t cache it to disk.
When You Only Care Whether Something Is Touched
If you don’t need three-axis force per contact, the aggregate section’sfx/fy/fz plus a threshold is enough, with no need to decode individual contacts. The aggregate is in newtons on every firmware and isn’t affected by normalization.
Tolerate Per-Finger Failure
All five fingers report info independently. In production code, handle failure per finger so one finger’s problem doesn’t break the whole pipeline. That’s how the example was changed.Related
- Wuji Hand 2 Subscribing With Callbacks: the subscription model and callback thread constraints
- Wuji Hand 2 Adjusting Stream Rate: lower the rate on
fingertip/*/data - Wuji Hand 2 Reading Device Info: read the firmware version and resource list
- Common Data Types:
FingertipSensorInfoandFingertipSensorData