Control Guide

This page explains how to control Wuji Hand 2 correctly and safely: unit conventions, the MIT control law, the joint table, parameter safety limits, and a safe control loop. For interface definitions and the full API, see SDK Reference.

Units and Symbols

QuantityUnitSource and notes
positionrad (joint side)The joint_states stream, the only recommended path for joint angles
velocityrad/s (joint side)The joint_states stream
effortA (current, not N·m)Feedback in joint_states and feedforward in joint_command share this unit

The joint_diagnostics stream carries no joint angles. Read joint angles only from joint_states.

MIT Control Law

The device runs in MIT force-position hybrid control by default, and the control mode isn't switched from the Python API:

τ = Kp · (q_d − q) + Kd · (dq_d − dq) + τ_ff
  • q_d / dq_d / τ_ff come from the position / velocity / effort fields of joint_command, with exactly 20 JointCommand entries per publish
  • Read and write Kp / Kd through mit_params, and the torque cap through effort_limit. Writes reject NaN, Inf, negative values, and values above the device ceiling. A rejected write leaves the value in effect unchanged

The power-on defaults are kp = 5.0, kd = 0.01, and effort_limit = 1.0 A. Restarting the device restores these defaults. When setting control parameters, keep kp at or above 3.0, use kd in the 0.01–0.05 range, and keep effort_limit at or below 1.5 A. The device hard ceiling for effort_limit is 2.0 A.

Joint Table

Numbering: thumb 0–3, index 4–7, middle 8–11, ring 12–15, pinky 16–19. SDK labels use the format {finger}_S{1..4}.

IndexSDK labelJoints (S1 → S4)Motion rangeModel joint nameModel actuator name
0–3thumb_S1..S4Base abduction/adduction (cmc_flex) / base lateral swing (cmc_abd) / MCP flexion/extension (mcp) / IP flexion/extension (ip)-68°~74° / -85°~40° / -60°~90° / -60°~90°{l,r}_thumb_*{l,r}_THJ{0-3}
4–7index_S1..S4MCP flexion/extension (mcp_flex) / MCP lateral swing (mcp_abd) / PIP flexion/extension (pip) / DIP flexion/extension (dip)-60°~90° / -40°~40° / -60°~120° / -60°~90°{l,r}_index_finger_*{l,r}_FFJ{0-3}
8–11middle_S1..S4Same as the four fingersSame as the four fingers{l,r}_middle_finger_*{l,r}_MFJ{0-3}
12–15ring_S1..S4Same as the four fingersSame as the four fingers{l,r}_ring_finger_*{l,r}_RFJ{0-3}
16–19pinky_S1..S4Same as the four fingersSame as the four fingers{l,r}_pinky_*{l,r}_LFJ{0-3}

The motion ranges match the joint limits in the model files (URDF / MJCF / USD) and are mirrored between the left and right hands. Model joints and links are named with an {l,r}_ prefix plus the finger name, and the root link is {l,r}_wrist ({l,r}_mount in the variant with a mount). For details, see the Wuji Description docs.

The axis-order mapping between the SDK labels S1..S4 and the model actuators J0..J3 isn't available yet and will be added later.

Origin and Motion Direction

  • set_origin / clear_origin calibrate the current physical position as the user origin. While a joint moves, the change is deferred to the next IDLE, see SDK Reference

Control Rate and Command Rate

  • The device control rate is 1000 Hz × 20 axes. The 1 kHz figure is the uplink and downlink message rate, and one message carries the control and status data of all 20 axes
  • The native output rate of joint_states is 1000 Hz, and the subscription handle lowers the push rate, see SDK Reference
  • Keep GET queries at or below 100 Hz. PUB commands support rates up to 1 kHz

Parameter Safety Limits

Sending a large target position with a high kp and no rate limiting drives the joints at full speed, which risks pinch injuries and impacts. Before changing control parameters, make sure nobody is near the device and the workspace is clear.

  • Start first-time debugging with a low torque cap (such as effort_limit().set(0.5), in A), then raise it once the behavior matches your expectations
  • For gentle position holding, use kp = 3.0, kd = 0.05, and effort_limit = 1.5 A as a conservative parameter example
  • Split large position changes into small steps instead of one step change
  • In grasping tasks, probe contact at a low cap first, then raise it as needed

Safe Control Loop

A recommended control loop: send commands → read state → check error codes → stop on a fault.

  • Read state from joint_states, and decode error codes from joint_diagnostics with describe_error
  • On a fault, call disable(). In an emergency, call emergency_stop() (the whole hand stops immediately and the call takes no mask)
  • For fault severity, stop behavior, and the fault-clearing flow, see Troubleshooting, Recovery, and Maintenance

For a full beginner example of a small single-joint motion, see Quick Start. For more reference implementations, see examples/python/wuji_hand_2/.

Subscribe to Updates