Motion control
Choose between target motion, application-driven Servo, and SDK-managed drag control.
| Task | Entry point | Behavior |
|---|---|---|
| Hand or local target motion | move_to(), move_joint(), move_finger(), move_thumb() | Returns MotionHandle; can be waited on or cancelled |
| Continuous high-rate targets | open_servo() | Application owns send timing, timeout, and shutdown |
| SDK-managed drag | start_servo_drag() | SDK owns the drag-control loop |
| Teaching and replay | Teach / Replay APIs | Records and replays full-hand trajectories |
Do not emulate Servo by repeatedly calling move_to(). Target operations may preempt one another, so check the final OperationState.
Single-command control (SDK 2.1.2)
hand.motion.set_position(), set_current(), and set_mit() send one full-hand command without open_servo(), a heartbeat, or automatic resend. These controls currently support enabled 21-DOF models only. Arrays use logical joint order, degrees, rpm, and mA; MIT feedforward current is also in mA.
Use set_joint_*, set_finger_*, or set_thumb_* for scoped commands. Joint indices are 0–20; finger indices 1–4 identify Index, Middle, Ring, and Pinky, with a separate thumb scope. Finger and thumb writes are sequential, not atomic; inspect device state after failure.
Run these read-only commands from the public example repository root:
python python/revo3/discrete_control.py --scope joint --joint-index 0 --mode position
python python/revo3/discrete_control.py --scope finger --finger-index 1 --mode mit
./c/build/demo/discrete_control --scope thumb --mode currentAdd --run to send a command. Position mode sends the current pose; current mode sends zero current; MIT mode sends the current pose with kp=1, kd=0.1, zero velocity, and zero feedforward current. These commands can change support or motor behavior. Clear the workspace and confirm the stop procedure first. Firmware determines target retention; closing the connection does not stop control. A command may have taken effect despite an error, so inspect state before retrying.
Upstream final-wheel validation covered scoped controls on UV5 firmware 0.1.2 over CAN FD. Modbus passed with a candidate implementation, but the final-wheel retest found no device; this does not establish final-release Modbus validation. See the public example notes.
Preflight
- Match every target array to
joint_layout. - Read State and preserve joints that should not change.
- Check Health and motor fault codes.
- Pass degree, rpm, and mA values directly; do not apply register scaling.
- Use a bounded wait for every motion.
Run the examples
Preview a motion from the public example repository root without connecting a device:
python python/revo3/gesture_dance_demo.pyThe opposition, finger motion, gesture choreography, and sinusoidal Servo examples connect and move only with --run. Calibrate candidate poses for the actual device and validate left and right hands separately. See the motion demonstration guide for commands and tuning.
MIT round trips should validate full-hand targets, including stationary joints, and the speed limits for both outbound and return motion. The default initial position tolerance is 0.1°; clamp accepted feedback overruns to the configured limits before using them as command targets. The Python teaching example uses teaching_mode.py read FILE to record and save a trajectory and teaching_mode.py load FILE to load and immediately replay it. Check the motion area and stop procedure before replay.
Wait for the result
handle = await hand.motion.move_joint(
joint_index=0,
target_position=20.0,
duration=1.0,
)
result = await handle.wait(timeout=3.0)
if result != sdk.OperationState.Succeeded:
raise RuntimeError(f"Motion ended in {result}")Timeout only stops the caller from waiting; it does not guarantee that physical motion stopped. For Indeterminate, read State before retrying. See the Motion API.