Data Structure Reference

This page lists all common data type field definitions in the Wuji SDK.

For device-specific data structures, see the corresponding device documentation: Wuji Glove SDK data reference.

Common Types

FrameHeader

Header information for each data frame.

FieldTypeDescription
seqintIncrementing sequence number
timestamp_usintDevice timestamp (microseconds)
frame_idstrCoordinate frame ID (e.g., "l_wrist"), max 32 characters

Vector3 / Vector3F64

Three-dimensional vector. Vector3 uses f32 precision, Vector3F64 uses f64 precision (used for IMU data, ROS compatible).

FieldTypeDescription
xfloatX component
yfloatY component
zfloatZ component

Quaternion

f64 precision quaternion representing 3D rotation.

FieldTypeDescription
xfloatX component
yfloatY component
zfloatZ component
wfloatW component

Pose

Position and orientation.

FieldTypeDescription
positionList[float]Position [x, y, z] (meters)
orientationQuaternionRotation quaternion

Handedness

Device handedness enum, used for connecting by handedness.

ValueDescription
Handedness.LeftLeft hand (fourth character of serial number is J)
Handedness.RightRight hand (fourth character of serial number is K)

ImuData

IMU sensor data, following the ROS sensor_msgs/Imu convention.

FieldTypeDescription
headerFrameHeaderFrame header
orientationQuaternionOrientation quaternion
orientation_covariancelist[float]Orientation covariance (length 9). A first element of -1 marks the orientation as unavailable
angular_velocityVector3F64Angular velocity (rad/s)
angular_velocity_covariancelist[float]Angular velocity covariance (length 9)
linear_accelerationVector3F64Linear acceleration (m/s²)
linear_acceleration_covariancelist[float]Linear acceleration covariance (length 9)

Wuji Hand 2 does not run onboard orientation fusion, so orientation_covariance[0] is always -1 when subscribing through hand.imu().

Coordinate Transforms

FrameTransform

Single coordinate transform.

FieldTypeDescription
timestamp_usintTimestamp (microseconds)
parent_frame_idstrParent frame
child_frame_idstrChild frame
translationList[float]Translation [x, y, z] (meters)
rotationQuaternionRotation quaternion

FrameTransforms

Collection of coordinate transforms.

FieldTypeDescription
transformsList[FrameTransform]Transform list

Recording Types

For complete usage and code examples, see Data Recording.

TopicRecorder

MCAP recording session configurator. Register channels, then call start() to begin recording.

MethodParametersDescription
__init__()compression: str = "lz4", chunk_size: int = NoneCreate a recorder. Supports "lz4", "zstd", "none"
record()sub: SubscriptionRegister a subscription channel
start()output_path: strStart recording, returns RecordingHandle

RecordingHandle

Recording control handle returned by TopicRecorder.start().

MethodReturnsDescription
pause()Pause recording
resume()Resume recording
stop()RecordingSummaryStop recording and return summary
subscribe_metrics()MetricsStreamSubscribe to real-time quality metrics
subscribe_status()StatusStreamSubscribe to recording status updates
subscribe_alerts()AlertStreamSubscribe to quality alerts

RecordingSummary

Recording statistics returned by handle.stop().

FieldTypeDescription
total_framesintTotal frames recorded
file_sizeintMCAP file size in bytes
duration_sfloatRecording duration in seconds
qualityQualitySummaryQuality statistics summary

QualityMetrics

Real-time quality metrics (5-second sliding window).

FieldTypeDescription
frame_drop_ratefloatFrame drop rate (0.0–1.0)
frame_jitter_usfloatInter-frame jitter in microseconds
sync_offset_msfloatCross-channel sync offset in milliseconds
sync_ratefloatSync success rate (0.0–1.0)
timestamp_nsintNanosecond timestamp

QualitySummary

Aggregate recording quality statistics.

FieldTypeDescription
total_framesintTotal frames received
dropped_framesintTotal frames dropped
frame_drop_ratefloatDrop rate (0.0–1.0)
avg_sync_offset_msfloatAverage sync offset in milliseconds
max_sync_offset_msfloatMaximum sync offset in milliseconds
sync_ratefloatSync success rate (0.0–1.0)
spc_alert_countintTotal SPC alerts triggered
duration_sfloatRecording duration in seconds

RecordingAlert

Quality alert.

FieldTypeDescription
metricstrName of the metric that triggered the alert
current_valuefloatCurrent measured value
thresholdfloatAlert threshold
messagestrHuman-readable alert message

RecordingStatus

Recording runtime status.

FieldTypeDescription
statestrCurrent state ("recording" or "paused")
frame_countintFrames recorded so far
duration_sfloatElapsed duration in seconds

Wuji Hand 2 Types

The schemas below are exposed by wuji_sdk.WujiHand2 through the resource-style interface. Feedback frames all carry a FrameHeader. frame_id is l_wrist or r_wrist (filled by the firmware from the device's own handedness), and timestamp_us is the firmware send time. Whole-hand feedback frames are variable-length and contain only online joints, identified by nid.

JointStateFrame

Whole-hand joint state subscription frame (hand.joint_states().subscribe()).

FieldTypeDescription
headerFrameHeaderFrame header (seq + timestamp_us + frame_id)
num_jointsintNumber of online joints in this frame (equals len(joints))
jointslist[JointStateEntry]Online joint state entries, variable-length

JointStateEntry

Single-joint state.

FieldTypeDescription
nidintNode ID, identifies the joint across frames
positionfloatPosition in radians
velocityfloatVelocity in rad/s
effortfloatEffort in amperes (Kt=1 placeholder)

JointDiagnosticsFrame

Whole-hand joint diagnostics subscription frame (hand.joint_diagnostics().subscribe()), derived from the same realtime stream as joint_states.

FieldTypeDescription
headerFrameHeaderFrame header
num_jointsintNumber of online joints in this frame
jointslist[JointDiagnosticsEntry]Online joint diagnostics entries, variable-length
commHand2CommSummaryFrame-level communication health summary, refreshed at 1 Hz

JointDiagnosticsEntry

Single-joint diagnostics snapshot.

FieldTypeDescription
nidintNode ID
status_wordStatusWordDecoded status word
currentfloatPhase current in amperes
vbus_v_fbfloatBus voltage feedback in volts
mcu_temp_c_fbfloatMCU temperature feedback in Celsius
error_code_currentintCurrent error code (stop / warning bits), decode with WujiHand2.describe_error()
comm_response_rate_pctintThis joint's RS485 bus response rate over the last second, 0–100
comm_timeout_totalintThis joint's cumulative RS485 bus timeouts

Hand2CommSummary

Frame-level communication health, combining the device-internal (RS485) view with the SDK-local end-to-end (Ethernet) view. The device-internal part comes from a snapshot the SDK refreshes automatically at 1 Hz — no polling required.

FieldTypeDescription
age_msintAge of the device-internal snapshot in milliseconds. 65535 = never sampled successfully (the device-internal fields are zeros). 65534 = saturated, the snapshot is 65.5 s or older
tactile_online_maskintFingertip tactile online bitmap, bit0 = thumb … bit4 = pinky
e2e_receivedintFrames received across all subscribed streams (cumulative)
e2e_lostintFrames lost on the Ethernet segment, detected via sequence gaps (cumulative)
e2e_reorderedintLate/reordered frames (cumulative)
e2e_duplicatesintDuplicate frames (cumulative)
e2e_window_loss_x100intLoss rate over the last second, in 0.01% units
rpc_totalintRequests sent (cumulative). 0 means this transport does not report RPC statistics (only the wuji-proto transport does, and a live wuji-proto connection has always sent at least one request), so a zero here is not the same as "no retries happened"
rpc_retriesintRequest retransmissions (cumulative)
rpc_timeoutsintRequests that ultimately timed out (cumulative)
comm_get_failuresintFailed internal snapshot refreshes (cumulative)
tactile_response_rate_pctlist[int]Per-finger tactile (node 5) bus response rate, 0–100, index 0 = thumb … 4 = pinky
tactile_timeout_totallist[int]Per-finger tactile cumulative bus timeouts, same index order
sdk_droppedintFrames dropped inside the SDK because one of its in-process hops fell behind (cumulative) — either your subscription consumer or the internal stream handler. Distinct from e2e_lost, which is network loss

Reading the device-internal fields. age_ms, tactile_* and the per-joint comm_* fields all come from one snapshot the SDK refreshes at 1 Hz. The refresh is deliberately skipped while a firmware upgrade or a tactile calibration is running, so a briefly stale snapshot is expected rather than a fault. Tell the two cases apart with comm_get_failures: a growing age_ms while comm_get_failures stays flat means the refresh is being skipped on purpose, while comm_get_failures increasing means the refresh itself is failing.

Counters saturate, they do not wrap. Every counter in this table stops at its maximum (65535 for the 16-bit ones — e2e_reordered, e2e_duplicates, rpc_retries, rpc_timeouts, comm_get_failures — and 4294967295 for the 32-bit ones) and stays there. On a 1 kHz stream a long-running session can reach those ceilings, so read these as deltas between two samples rather than as absolute lifetime totals.

StatusWord

Decoded status word public view (lower 16 bits).

FieldTypeDescription
ext_stateintExtended state value (Init / Ready / Enabled / Stopped, and so on)
ext_state_namestrSemantic name of ext_state
position_limit_activeboolPosition limit triggered
velocity_limit_activeboolVelocity limit triggered
current_limit_activeboolCurrent limit triggered

JointCommand

Single-joint realtime command (an element of the publisher.send([JointCommand, ...×20]) argument).

FieldTypeDescription
positionfloatTarget position in radians
velocityfloatTarget velocity in rad/s, pass 0 when no feed-forward
effortfloatTarget effort in amperes, pass 0 when no feed-forward

Constructor: JointCommand(position, velocity, effort). Each publisher.send(joints) call must pass a list[JointCommand] of length exactly 20 — include placeholders for offline joints.

Wuji Hand Types

The schemas below are exposed by wuji_sdk.WujiHand for Wuji Hand. For full field definitions, see Wuji Hand SDK Guide.

HandJointStates

Real-time 20-joint state (the hand.joint_states().subscribe() frame). Joint order is finger-major: {left,right}_finger{1..5}_joint{1..4}.

FieldTypeDescription
headerFrameHeaderFrame header
positionlist[float]20 joint positions in radians, always length 20
velocitylist[float]Angular velocity, length 0 when not provided
effortlist[float]Joint effort, length 0 when not provided
{
  "header": { "seq": 42, "timestamp_us": 1709876543210, "frame_id": "" },
  "position": [0.001, -0.012, 0.087, 0.045, ...],
  "velocity": [],
  "effort": []
}

HandJointCommand

20-joint command frame. seq is client-incrementing so receivers can detect dropped frames.

FieldTypeDescription
seqintClient-incremented sequence number
positionlist[float]Target positions, length 20
velocitylist[float]Target velocity, optional
effortlist[float]Target effort, optional

TactileGloveFrame

A single pressure frame from the paired tactile glove, on a 20×31 grid.

FieldTypeDescription
handednessintHandedness (0 = Left, 1 = Right — note this is the opposite of the WujiHand SDO encoding)
sequenceintFrame sequence number
timestamp_msintDevice timestamp in milliseconds
pressurelist[float]620 f32 pressure values, row-major 20×31