Get SDK
The Revo Hand SDK is a cross-platform development toolkit for BrainCo Revo 3 robotic hands, providing 21-motor independent control, status queries (position, velocity, current, motor status), and firmware OTA upgrade APIs.
System Requirements
The host machine should meet the following specifications:
- Python: 3.9 ~ 3.12
- Linux: Ubuntu 20.04/22.04 LTS (x86_64/aarch64), glibc ≥ 2.31
- macOS: macOS 10.15+
- Windows: Windows 10/11
- Hardware Interface: RS485 module or CAN FD bus card supported by your SDK workflow
Download & Installation
1. GitHub Repository
Clone the SDK repository before running the examples:
git clone https://github.com/BrainCoTech/brainco-revo3-sdk.git
cd brainco-revo3-sdk2. Python Package Installation
Use a virtual environment (recommended: Conda) to install the Revo 3 SDK:
# Create and activate a Conda virtual environment (Python 3.10 recommended)
conda create -n revo3_env python=3.10 -y
conda activate revo3_env
# Install the Revo 3 core SDK package
pip3 install bc-revo3-sdk==1.2.2💡 Linux System Permissions & Port Latency Tuning
When executing serial communication programs on Linux hosts, please verify the following port access permissions and latency tuning parameters:
- Port Access Permissions (Generic Linux Requirement): Non-
rootusers under Linux do not possess read/write privileges for raw hardware ports (e.g.,/dev/ttyUSB0) by default. To securely open and communicate through the serial port, ensure the current Linux user is permanently added to thedialoutgroup before running the application (restart or log out to apply changes):bashsudo usermod -a -G dialout $USER - Automatic Latency Configuration (SDK Default): The SDK automatically reduces FTDI hardware latency to 1ms on Linux (via
ioctlwithASYNC_LOW_LATENCY). No manual configuration is needed when using the SDK. - Manual Port Tuning (For non-SDK users or Diagnostics): If developers bypass the official SDK (e.g., controlling raw ports using generic third-party Modbus libraries) or are troubleshooting communication latency issues, the following commands can be executed manually to optimize the port latency:bashAlternatively, configure the hardware latency timer to 1ms by writing directly to the device sysfs node:
# Optimize via setserial tool sudo setserial /dev/ttyUSB0 low_latencybashecho 1 | sudo tee /sys/class/tty/ttyUSB0/device/latency_timer
Running Examples
The python/ and c/ directories contain reference examples for the Revo 3. Default baud rate: 5M (5000000 bps). Slave ID: 126 (left hand), 127 (right hand).
1. Python Demos
Navigate into the python/ directory and install the requirements first:
cd python
pip install -r requirements.txt
# Run automatic port & Slave ID scan
python revo3/auto_detect.py
# Run basic motor control demo
python revo3/hand_demo.py
# Run motion trajectory planning
python revo3/hand_trajectory.py
# Run OTA firmware upgrade
python revo3/hand_dfu.py /path/to/firmware.bin
# Launch Qt GUI debug panel (supports mock mode)
python gui/main.py --mock💡 Expected Python Console Output
$ python revo3/hand_demo.py
[2026-05-27 10:10:02.124] [INFO] Stark SDK version 1.2.2 initialized.
[2026-05-27 10:10:02.125] [INFO] Scanning serial port: /dev/ttyUSB0 (Baudrate: 5000000 bps)
[2026-05-27 10:10:02.341] [INFO] Found Revo 3 Dexterous Hand [Right Hand, ID: 127]
[2026-05-27 10:10:02.342] [INFO] Performing initial joint origin calibration sweep...
[2026-05-27 10:10:04.512] [INFO] Calibration complete. All 21 motors successfully zeroed.
[2026-05-27 10:10:04.513] [INFO] Sending command: Move thumb flexion to 50.0°, index to 60.0°
[2026-05-27 10:10:05.102] [INFO] Feedback: Position[Thumb]=49.8°, Current[Thumb]=84mA | Status: MOTOR_RUNNING
[2026-05-27 10:10:05.612] [INFO] Feedback: Position[Thumb]=50.0°, Current[Thumb]=12mA | Status: MOTOR_IDLE
[2026-05-27 10:10:06.000] [INFO] Demo completed. Closing serial port.auto_detect.py: Scans serial ports to discover connected Revo 3 hands and validate ID/baud rate.hand_demo.py: Joint position control and status feedback example.hand_trajectory.py: Multi-finger trajectory planning and coordinated grasping example.hand_dfu.py: OTA firmware upgrade script.gui/main.py: Qt GUI debug tool with control sliders and live waveform plotting.
2. C++ Demos
Compile and run native C++ examples under c/:
# 1. Download core static/dynamic library assets
sh download-lib.sh
# 2. Build the C++ examples project
make -C c
# 3. Run target executables
# Scan device channels
./c/demo/auto_detect
# Run basic control flow
./c/demo/hand_demo
# Run trajectory demonstration
./c/demo/hand_trajectory
# Run local firmware OTA upgrade
./c/demo/hand_dfu firmware.bin💡 Expected C++ Console Output
$ ./c/demo/hand_demo
[STARK INFO] Serial port successfully opened on /dev/ttyUSB0 at 5000000 bps.
[STARK INFO] Connecting to device ID: 127...
[STARK INFO] Device acknowledged. Firmware version: v3.2.14
[STARK INFO] Launching motor sweep calibration...
[STARK SUCCESS] Joint calibration completed in 2.18s.
[STARK INFO] Write [Target: Position] | ID 127 -> Motor[0]=12000, Motor[1]=15000
[STARK INFO] Read [Feedback] | Motor[0]: Pos=12000, Vel=0, Cur=10 | Status=0x01
[STARK INFO] Execution successful. Terminating connection.auto_detect: Device channel scan and detection utility.hand_demo: Motor read/write control and feedback monitoring example.hand_trajectory: Multi-joint smooth trajectory planning example.hand_dfu: Firmware OTA upgrade tool.
Quick Start
The following code demonstrates the minimal workflow to control the hand from scratch: open serial port → write target angles → read status feedback.
# 1. Open serial connection
from bc_revo3_sdk import modbus_open
ctx = modbus_open("/dev/ttyUSB0", 5000000)
slave_id = 1
# 2. Write target angles (degrees) for 21 joints
target_positions = [0.0] * 21
target_positions[0] = 45.5 # Thumb joint
ctx.revo3_set_all_motor_positions(slave_id, target_positions)
# 3. Read 21-joint status feedback
positions = ctx.revo3_get_all_motor_positions(slave_id)
currents = ctx.revo3_get_all_motor_currents(slave_id)
print(f"Thumb pos: {positions[0]} deg, current: {currents[0]} mA")#include "revo3-sdk.h"
// 1. Open RS485 serial port
DeviceHandler* handle = modbus_open("/dev/ttyUSB0", 5000000);
if (!handle) return -1;
// 2. Write target angles for 21 joints
float target_positions[21] = {0.0f};
target_positions[0] = 45.5f;
revo3_set_all_motor_positions(handle, 1, target_positions);
// 3. Read 21-joint status feedback
CRevo3MotorStatusData* status = revo3_get_motor_status_data(handle, 127);
if (status) {
printf("Thumb pos: %f deg, current: %f mA\n", status->positions[0], status->currents[0]);
free_revo3_motor_status_data(status);
}
modbus_close(handle);💡 Production Recommendation: Prefer Trajectory APIs
Directly dispatching step target positions (e.g., revo3_set_all_motor_positions) induces instantaneous current spikes that accelerate mechanical wear on gearboxes and transmissions over time.
For production applications, prefer using the following trajectory APIs:
- Quintic Polynomial Trajectory:
revo3_move_finger_trajectory/revo3_move_thumb_trajectory— the SDK computes smooth interpolation internally, which helps reduce abrupt motion. - Trajectory Replay:
revo3_replay_hand— replays pre-recorded 21-joint trajectory frames, with tunable Kp/Kd gains for compliant grasping.
Control Modes Overview
The SDK automatically handles all x100 register scaling and encoding. When calling APIs, pass direct physical float values (angles in degrees like 45.5, velocities in RPM like 50.0, currents in mA like 120.0). No manual conversion is required.
| Mode ID | Mode Name | Parameter | Description |
|---|---|---|---|
| 0 | Position Control | Target Angle (deg) | Drives joints to target positions. |
| 1 | Speed Control | Target Velocity (RPM) | Rotates joints at target speeds. (1 RPM = 6 °/s) |
| 2 | Current Control | Target Current (mA) | Generates specific torque outputs. |
| 4 | Impedance Control | Stiffness (Kp) | Force-position hybrid with stiffness feedback only. |
| 5 | Damping Control | Damping (Kd) | Force-position hybrid with damping feedback only. |
The SDK also provides MIT force-position hybrid control (5-parameter: Kp + Kd + position + velocity + feedforward torque) and finger-level trajectory control interfaces. For detailed parameter ranges and the MIT control formula, refer to the Motor Control Protocol.
⚠️ Tactile Sensor Baseline Calibration
The hand features 11 tactile array modules (palm + tip/pad for each finger). Extended usage may cause baseline drift. Periodically call revo3_calibrate_touch_zero() in zero-contact conditions to reset baselines. For the full module layout and channel mapping, refer to the Tactile Array Protocol.
Advanced Reference
Interface Definition Files
For API reference and code auto-completion, use the following interface definition files. You can download them or view them inline below:
- Python Type Stub (.pyi): Download main_mod.pyi — type annotations for all classes, enums, and functions.
- C/C++ Header File (.h): Download revo3-sdk.h — C ABI export header generated by
cbindgen.
View Python Type Stub (main_mod.pyi)
# This file is automatically generated by pyo3_stub_gen
# ruff: noqa: E501, F401, F403, F405
import builtins
import enum
import typing
import typing_extensions
__all__ = [
"Baudrate",
"BaudrateCAN",
"CanFdBaudrate",
"ControlMode",
"DataCollector",
"DetectedDevice",
"DeviceContext",
"DeviceInfo",
"DfuCommandType",
"DfuExitReason",
"DfuState",
"EcRevo3TouchSdoSubIdx",
"EtherCATAddress",
"EtherCATConfigIndex",
"EtherCATFoeType",
"FingerUnitMode",
"FingertipPose",
"HandType",
"LogLevel",
"OtaTarget",
"RegAddrRevo3",
"Revo3MotorStatusBuffer",
"Revo3MotorStatusData",
"Revo3SystemStatus",
"Revo3TouchData",
"Revo3TouchDataBuffer",
"Rs485Baudrate",
"SerialPortCfg",
"SkuType",
"StarkError",
"StarkHardwareType",
"StarkProtocolType",
"TouchDataMode",
"TouchVendor",
"ZqwlDeviceInfo",
"available_usb_ports",
"close_device_handler",
"close_socketcan",
"close_zqwl",
"get_sdk_version",
"init_device_handler",
"init_from_detected",
"init_logging",
"init_socketcan_canfd",
"init_zqwl_canfd",
"is_socketcan_available",
"list_available_ports",
"list_zqwl_devices",
"modbus_close",
"modbus_open",
"revo3_auto_detect",
"revo3_auto_detect_device",
"revo3_auto_detect_modbus",
"scan_canfd_devices",
"set_can_rx_callback",
"set_can_tx_callback",
"set_modbus_read_holding_callback",
"set_modbus_read_input_callback",
"set_modbus_write_callback",
]
@typing.final
class DataCollector:
def get_motor_frequency(self) -> builtins.int: ...
def get_touch_frequency(self) -> builtins.int: ...
def is_running(self) -> builtins.bool: ...
@staticmethod
def new_revo3_basic(ctx: DeviceContext, motor_buffer: Revo3MotorStatusBuffer, slave_id: builtins.int = 1, motor_frequency: builtins.int = 60, enable_stats: builtins.bool = True) -> DataCollector: ...
@staticmethod
def new_revo3_full(ctx: DeviceContext, motor_buffer: Revo3MotorStatusBuffer, touch_buffer: Revo3TouchDataBuffer, slave_id: builtins.int = 1, motor_frequency: builtins.int = 60, touch_frequency: builtins.int = 5, enable_stats: builtins.bool = True) -> DataCollector: ...
def start(self) -> builtins.bool: ...
def stop(self) -> None: ...
def update_motor_frequency(self, freq: builtins.int) -> None: ...
def update_touch_frequency(self, freq: builtins.int) -> None: ...
def wait(self) -> None: ...
@typing.final
class DetectedDevice:
r"""
Detected device information
Contains information about a detected Stark device including protocol,
port, slave ID, and optional device details.
"""
@property
def baudrate(self) -> Baudrate:
r"""
Baudrate (for Modbus/serial protocols, or CAN arbitration baudrate)
"""
@property
def data_baudrate(self) -> builtins.int:
r"""
Data baudrate (for CANFD only, 0 for other protocols)
"""
@property
def firmware_version(self) -> typing.Optional[builtins.str]:
r"""
Firmware version (if detected)
"""
@property
def hardware_type(self) -> typing.Optional[StarkHardwareType]:
r"""
Hardware type (if detected)
"""
@property
def port_name(self) -> builtins.str:
r"""
Port name (serial port or CAN adapter port)
"""
@property
def protocol_type(self) -> StarkProtocolType:
r"""
Protocol type
"""
@property
def serial_number(self) -> typing.Optional[builtins.str]:
r"""
Serial number (if detected)
"""
@property
def sku_type(self) -> typing.Optional[SkuType]:
r"""
SKU type (if detected)
"""
@property
def slave_id(self) -> builtins.int:
r"""
Slave ID on the bus
"""
@typing.final
class DeviceContext:
r"""
Device context for Python API.
This class wraps the internal device context and provides async methods
for communicating with Stark devices. Create instances using:
- `modbus_open()` for Modbus/RS485 connections
- `init_device_handler()` for CAN/CANFD connections
- `init_from_detected()` after auto-detection
All methods are async and should be awaited.
"""
def __new__(cls) -> DeviceContext: ...
def close(self) -> typing.Any:
r"""
Close the device connection and release resources.
For Modbus: closes the serial port.
For CAN/CANFD: use `close_device_handler()` instead which also closes ZQWL.
"""
def ec_reserve_master(self) -> typing.Any: ...
def ec_setup_sdo(self, slave_id: builtins.int) -> typing.Any: ...
def ec_start_dfu(self, slave_pos: builtins.int, dfu_type: EtherCATFoeType, file_path: builtins.str) -> typing.Any: ...
def ec_start_loop(self, slave_positions: typing.Sequence[builtins.int], dc_assign_activate: builtins.int, sync0_cycle_time: builtins.int, sync0_shift_time: builtins.int, sync1_cycle_time: builtins.int, sync1_shift_time: builtins.int) -> typing.Any: ...
def ec_stop_loop(self) -> typing.Any: ...
def factory_set_device_sn(self, slave_id: builtins.int, sn: builtins.str) -> typing.Any:
r"""
Program the device serial number (requires factory_set_key first).
"""
def factory_set_key(self, slave_id: builtins.int, operation_key: builtins.str) -> typing.Any:
r"""
Unlock factory-only write registers.
"""
def revo3_abort_dfu(self, slave_id: builtins.int) -> typing.Any:
r"""
Abort the current Revo3 DFU transfer.
"""
def revo3_admittance_hand(self, slave_id: builtins.int, equilibrium_positions: typing.Sequence[builtins.float], mass: typing.Sequence[builtins.float], damping: typing.Sequence[builtins.float], stiffness: typing.Sequence[builtins.float], dt: builtins.float, duration: builtins.float) -> typing.Any:
r"""
[RESERVED] Full hand admittance control.
Requires tactile sensor integration (not yet implemented).
"""
def revo3_admittance_joint(self, slave_id: builtins.int, joint_id: builtins.int, equilibrium_pos: builtins.float, mass: builtins.float, damping: builtins.float, stiffness: builtins.float, dt: builtins.float, duration: builtins.float) -> typing.Any:
r"""
[RESERVED] Single joint admittance control.
Requires tactile sensor integration (not yet implemented).
"""
def revo3_calibrate_touch_zero(self, slave_id: builtins.int) -> typing.Any:
r"""
Calibrate touch sensors zero drift (tare/zero calibration) for all modules.
Args:
slave_id: Slave device ID
"""
def revo3_calibrate_touch_zero_single(self, slave_id: builtins.int, module_id: builtins.int) -> typing.Any:
r"""
Calibrate touch sensors zero drift (tare/zero calibration) for a single module.
Args:
slave_id: Slave device ID
module_id: Touch module ID (0~10)
"""
def revo3_clear_motor_errors(self, slave_id: builtins.int) -> typing.Any:
r"""
Clear all Revo3 motor error states.
"""
def revo3_factory_reset(self, slave_id: builtins.int) -> typing.Any:
r"""
Factory reset (restore all factory settings).
"""
def revo3_finger_control(self, slave_id: builtins.int, finger_index: builtins.int, mode: builtins.int, params: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Four-finger control (index/middle/ring/pinky).
Args:
finger_index: 1=index, 2=middle, 3=ring, 4=pinky
mode: ControlMode (0=Position, 1=Speed, 2=Current)
params: [Abd_MCP, MCP, PIP, DIP] — 4 float values (degrees/rpm/mA)
"""
def revo3_finger_mit_control(self, slave_id: builtins.int, finger_index: builtins.int, params: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Four-finger MIT control.
Args:
finger_index: 1=index, 2=middle, 3=ring, 4=pinky
params: 4 joints × 5 MIT params = 20 float values
"""
def revo3_get_all_joint_position_limits(self, slave_id: builtins.int) -> typing.Any:
r"""
Get position limits for all 21 joints.
"""
def revo3_get_all_joint_protect_currents(self, slave_id: builtins.int) -> typing.Any:
r"""
Get per-joint protection current for all 21 joints.
"""
def revo3_get_all_joint_speed_limits(self, slave_id: builtins.int) -> typing.Any:
r"""
Get speed limits for all 21 joints.
"""
def revo3_get_all_motor_currents(self, slave_id: builtins.int) -> typing.Any:
r"""
Read all Revo3 motor currents (mA).
Returns:
List of 21 float currents
"""
def revo3_get_all_motor_errors(self, slave_id: builtins.int) -> typing.Any:
r"""
Get all Revo3 motor error codes.
Returns:
List of 21 u16 error codes
"""
def revo3_get_all_motor_positions(self, slave_id: builtins.int) -> typing.Any:
r"""
Read all Revo3 motor positions (degrees).
Returns:
List of 21 float positions
"""
def revo3_get_all_motor_sns(self, slave_id: builtins.int) -> typing.Any:
r"""
Read all 21 motor serial numbers.
"""
def revo3_get_all_motor_status(self, slave_id: builtins.int) -> typing.Any:
r"""
Read all Revo3 motor status codes.
Returns:
List of 21 u16 status codes
"""
def revo3_get_all_motor_temperatures(self, slave_id: builtins.int) -> typing.Any:
r"""
Read all 21 motor temperatures (°C).
"""
def revo3_get_all_motor_velocities(self, slave_id: builtins.int) -> typing.Any:
r"""
Read all Revo3 motor velocities.
Returns:
List of 21 float velocities
"""
def revo3_get_all_touch_data(self, slave_id: builtins.int) -> typing.Any:
r"""
Read all Revo3 touch data (summary + all 11 module arrays).
Returns:
Revo3TouchData struct containing summary (List[int]) and modules (List[List[int]])
"""
def revo3_get_all_touch_modules_enabled(self, slave_id: builtins.int) -> typing.Any:
r"""
Read the enable state of all 11 touch modules.
Returns a 16-bit mask where bits 0~10 map to modules 0~10. 1 = enabled, 0 = disabled.
"""
def revo3_get_auto_calibration(self, slave_id: builtins.int) -> typing.Any:
r"""
Get auto calibration state on power-up.
"""
def revo3_get_auto_clear_motor_error(self, slave_id: builtins.int) -> typing.Any:
r"""
Get auto clear motor errors state.
"""
def revo3_get_buzzer_switch(self, slave_id: builtins.int) -> typing.Any:
r"""
Get buzzer switch state.
"""
def revo3_get_canfd_baudrate(self, slave_id: builtins.int) -> typing.Any:
r"""
Get CANFD Baudrate (enum value: 0=1M, 1=2M, 2=4M, 3=5M)
"""
def revo3_get_device_fw_version(self, slave_id: builtins.int) -> typing.Any:
r"""
Get device firmware version.
Args:
slave_id: The slave ID of the device
Returns:
str: Firmware version string
"""
def revo3_get_device_info(self, slave_id: builtins.int) -> typing.Any:
r"""
Get device information (serial number, firmware version, hardware type)
IMPORTANT: This method should be called after connecting to the device.
It automatically sets the hardware type (hw_type) internally based on the
device's serial number. This is required for touch-related APIs to work
correctly, especially for CAN/CANFD protocols.
NOTE: If the SN is not recognized, manually set a Revo3 hardware type with
`set_hardware_type()`.
Use `set_hardware_type()` to manually override if needed.
Args:
slave_id: The slave ID of the device
Returns:
DeviceInfo object containing serial_number, firmware_version, hardware_type
"""
def revo3_get_device_sn(self, slave_id: builtins.int) -> typing.Any:
r"""
Get device serial number.
Args:
slave_id: The slave ID of the device
Returns:
str: Device serial number
"""
def revo3_get_global_protect_current(self, slave_id: builtins.int) -> typing.Any:
r"""
Get global motor protection current.
"""
def revo3_get_hand_type(self, slave_id: builtins.int) -> typing.Any:
r"""
Get device hand type (Left/Right).
Args:
slave_id: The slave ID of the device
Returns:
int: Hand type mapped to SkuType (1: Right, 2: Left)
"""
def revo3_get_hardware_version(self, slave_id: builtins.int) -> typing.Any:
r"""
Read hardware version string.
"""
def revo3_get_max_continuous_current(self, slave_id: builtins.int) -> typing.Any:
r"""
Get max continuous current (mA).
"""
def revo3_get_motor_fw_versions(self, slave_id: builtins.int) -> typing.Any:
r"""
Read all 21 motor firmware versions.
"""
def revo3_get_motor_online_status(self, slave_id: builtins.int) -> typing.Any:
r"""
Read motor online status bitmask.
"""
def revo3_get_motor_sn(self, slave_id: builtins.int, motor_id: builtins.int) -> typing.Any:
r"""
Read a motor's serial number string.
Args:
motor_id: 0~20
"""
def revo3_get_motor_status_data(self, slave_id: builtins.int) -> typing.Any:
r"""
Read complete Revo3 motor status data.
Returns:
Revo3MotorStatusData with statuses, positions, velocities, currents, errors
"""
def revo3_get_motor_temperature(self, slave_id: builtins.int, joint_id: builtins.int) -> typing.Any:
r"""
Read a single motor's temperature (°C).
"""
def revo3_get_rs485_baudrate(self, slave_id: builtins.int) -> typing.Any:
r"""
Get RS485 Baudrate (enum value: 0=1M, 1=2M, 2=3M, 4=5M)
"""
def revo3_get_servo_damping_omega(self) -> typing.Any:
r"""
Get the current natural frequency (omega) for the second-order filter.
"""
def revo3_get_servo_filter_mode(self) -> typing.Any:
r"""
Get the current high-frequency real-time servo smoothing filter mode.
Returns:
0 = None, 1 = First-order LPF, 2 = Second-order Critically Damped system.
"""
def revo3_get_servo_lpf_alpha(self) -> typing.Any:
r"""
Get the current first-order Low-Pass Filter (LPF) coefficient.
"""
def revo3_get_slave_id(self, slave_id: builtins.int) -> typing.Any:
r"""
Get Slave ID
"""
def revo3_get_software_e_stop(self, slave_id: builtins.int) -> typing.Any:
r"""
Get software e-stop state.
"""
def revo3_get_system_current(self, slave_id: builtins.int) -> typing.Any:
r"""
Read system current (mA).
"""
def revo3_get_system_power(self, slave_id: builtins.int) -> typing.Any:
r"""
Read system power (W).
"""
def revo3_get_system_status(self, slave_id: builtins.int) -> typing.Any:
r"""
Read complete system status (state, error, current, voltage, power, temperature).
Internal sampling rate: 5Hz. Host should poll at ≤5Hz.
Returns:
Revo3SystemStatus object
"""
def revo3_get_system_temperature(self, slave_id: builtins.int) -> typing.Any:
r"""
Read system temperature (°C).
"""
def revo3_get_system_voltage(self, slave_id: builtins.int) -> typing.Any:
r"""
Read system voltage (V).
"""
def revo3_get_teaching_mode(self, slave_id: builtins.int) -> typing.Any:
r"""
Get teaching mode state.
"""
def revo3_get_touch_data_type(self, slave_id: builtins.int) -> typing.Any:
r"""
Read the Revo3 touch data type configuration.
"""
def revo3_get_touch_module_data(self, slave_id: builtins.int, module_id: builtins.int) -> typing.Any:
r"""
Read pressure array data for a single Revo3 touch module.
"""
def revo3_get_touch_module_enabled(self, slave_id: builtins.int, module_id: builtins.int) -> typing.Any:
r"""
Read the enable state of a single touch module.
Args:
slave_id: Slave device ID
module_id: 0~10
Returns: True if enabled, False otherwise
"""
def revo3_get_touch_screen(self, slave_id: builtins.int) -> typing.Any:
r"""
Get touch screen switch state.
"""
def revo3_get_touch_summary(self, slave_id: builtins.int) -> typing.Any:
r"""
Read Revo3 touch summary data.
Returns 42 u16 values:
[0] palm, [1] thumb tip 1, [2] thumb tip 2...
"""
def revo3_get_use_broadcast_id(self, slave_id: builtins.int) -> typing.Any:
r"""
Get broadcast ID usage state.
"""
def revo3_get_vibration_switch(self, slave_id: builtins.int) -> typing.Any:
r"""
Get vibration switch state.
"""
def revo3_get_zero_position(self, slave_id: builtins.int) -> typing.Any:
r"""
Get the zero position offsets (degrees) for all joints.
"""
def revo3_hand_mit_control(self, slave_id: builtins.int, kp_values: typing.Sequence[builtins.float], kd_values: typing.Sequence[builtins.float], positions: typing.Sequence[builtins.float], velocities: typing.Sequence[builtins.float], torques: typing.Sequence[builtins.float]) -> typing.Any:
r"""
MIT control for all 21 joints using the interleaved hand register block.
Args:
kp_values: 21 Kp values
kd_values: 21 Kd values
positions: 21 target positions (degrees)
velocities: 21 target velocities (rpm)
torques: 21 feed-forward torques (mA)
"""
def revo3_hand_mit_control_without_retry(self, slave_id: builtins.int, kp_values: typing.Sequence[builtins.float], kd_values: typing.Sequence[builtins.float], positions: typing.Sequence[builtins.float], velocities: typing.Sequence[builtins.float], torques: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Same as `revo3_hand_mit_control` but without retry.
Use this for high-frequency real-time control (e.g. trajectories/VR mapping).
"""
def revo3_joint_mit_control(self, slave_id: builtins.int, joint_id: builtins.int, kp: builtins.float, kd: builtins.float, pos: builtins.float, vel: builtins.float, torque_ff: builtins.float) -> typing.Any:
r"""
MIT control for a single joint.
Args:
slave_id: Slave device ID
joint_id: Joint index (0~20)
kp: Position gain [0.0, 10.0]
kd: Velocity gain [0.0, 10.0]
pos: Target position (degrees)
vel: Target velocity (rpm)
torque_ff: Feed-forward torque/current (mA)
"""
def revo3_manual_calibration(self, slave_id: builtins.int) -> typing.Any:
r"""
Trigger manual zero calibration.
"""
def revo3_move_finger(self, slave_id: builtins.int, finger_id: builtins.int, target_positions: typing.Sequence[builtins.float], duration: builtins.float, dt: builtins.float) -> None:
r"""
Move a specific finger using quintic polynomial trajectory.
Args:
slave_id: Slave device ID
finger_id: Finger index (1=index, 2=middle, 3=ring, 4=pinky)
target_positions: List of 4 target positions in degrees
duration: Total motion time in seconds
dt: Control period in seconds
Move a specific finger using quintic polynomial trajectory (Non-blocking).
Args:
slave_id: Slave device ID
finger_id: Finger index (1=index, 2=middle, 3=ring, 4=pinky)
target_positions: List of 4 target positions in degrees
duration: Total motion time in seconds
dt: Control period in seconds
"""
def revo3_move_finger_wait(self, slave_id: builtins.int, finger_id: builtins.int, target_positions: typing.Sequence[builtins.float], duration: builtins.float, dt: builtins.float) -> typing.Any:
r"""
Move a specific finger using quintic polynomial trajectory and wait for completion (Blocking).
Args:
slave_id: Slave device ID
finger_id: Finger index (1=index, 2=middle, 3=ring, 4=pinky)
target_positions: List of 4 target positions in degrees
duration: Total motion time in seconds
dt: Control period in seconds
"""
def revo3_move_finger_with_gains(self, slave_id: builtins.int, finger_id: builtins.int, target_positions: typing.Sequence[builtins.float], duration: builtins.float, dt: builtins.float, kp: builtins.float, kd: builtins.float) -> None:
r"""
Move a specific finger with custom Kp/Kd gains and quintic trajectory control (Non-blocking).
Args:
slave_id: Slave device ID
finger_id: Finger index (1=index, 2=middle, 3=ring, 4=pinky)
target_positions: List of 4 target positions in degrees
duration: Total motion time in seconds
dt: Control period in seconds
kp: Position gain
kd: Velocity damping gain
"""
def revo3_move_finger_with_gains_wait(self, slave_id: builtins.int, finger_id: builtins.int, target_positions: typing.Sequence[builtins.float], duration: builtins.float, dt: builtins.float, kp: builtins.float, kd: builtins.float) -> typing.Any:
r"""
Move a specific finger with custom Kp/Kd gains and wait for completion (Blocking).
Args:
slave_id: Slave device ID
finger_id: Finger index (1=index, 2=middle, 3=ring, 4=pinky)
target_positions: List of 4 target positions in degrees
duration: Total motion time in seconds
dt: Control period in seconds
kp: Position gain
kd: Velocity damping gain
"""
def revo3_move_finger_with_joint_gains(self, slave_id: builtins.int, finger_id: builtins.int, target_positions: typing.Sequence[builtins.float], duration: builtins.float, dt: builtins.float, kp: typing.Sequence[builtins.float], kd: typing.Sequence[builtins.float]) -> None:
r"""
Move a specific finger with joint-specific Kp/Kd gains (4 joints) (Non-blocking).
Args:
slave_id: Slave device ID
finger_id: Finger index (1=index, 2=middle, 3=ring, 4=pinky)
target_positions: List of 4 target positions in degrees
duration: Total motion time in seconds
dt: Control period in seconds
kp: List of 4 position gains
kd: List of 4 velocity damping gains
"""
def revo3_move_finger_with_joint_gains_wait(self, slave_id: builtins.int, finger_id: builtins.int, target_positions: typing.Sequence[builtins.float], duration: builtins.float, dt: builtins.float, kp: typing.Sequence[builtins.float], kd: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Move a specific finger with joint-specific Kp/Kd gains (4 joints) and wait for completion (Blocking).
Args:
slave_id: Slave device ID
finger_id: Finger index (1=index, 2=middle, 3=ring, 4=pinky)
target_positions: List of 4 target positions in degrees
duration: Total motion time in seconds
dt: Control period in seconds
kp: List of 4 position gains
kd: List of 4 velocity damping gains
"""
def revo3_move_hand(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], duration: builtins.float, dt: builtins.float) -> None:
r"""
Move all joints using quintic polynomial trajectories.
Args:
slave_id: Slave device ID
target_positions: List of target positions in degrees (length = joint count)
duration: Total motion time in seconds
dt: Control period in seconds
Move all joints using quintic polynomial trajectories (Non-blocking).
Args:
slave_id: Slave device ID
target_positions: List of target positions in degrees (length = joint count)
duration: Total motion time in seconds
dt: Control period in seconds
"""
def revo3_move_hand_wait(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], duration: builtins.float, dt: builtins.float) -> typing.Any:
r"""
Move all joints using quintic polynomial trajectories and wait for completion (Blocking).
Args:
slave_id: Slave device ID
target_positions: List of target positions in degrees (length = joint count)
duration: Total motion time in seconds
dt: Control period in seconds
"""
def revo3_move_hand_with_gains(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], duration: builtins.float, dt: builtins.float, kp: builtins.float, kd: builtins.float) -> None:
r"""
Move all joints with custom Kp/Kd gains (Non-blocking).
Args:
slave_id: Slave device ID
target_positions: List of target positions in degrees (length = joint count)
duration: Total motion time in seconds
dt: Control period in seconds
kp: Position gain
kd: Velocity damping gain
"""
def revo3_move_hand_with_gains_wait(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], duration: builtins.float, dt: builtins.float, kp: builtins.float, kd: builtins.float) -> typing.Any:
r"""
Move all joints with custom Kp/Kd gains and wait for completion (Blocking).
Args:
slave_id: Slave device ID
target_positions: List of target positions in degrees (length = joint count)
duration: Total motion time in seconds
dt: Control period in seconds
kp: Position gain
kd: Velocity damping gain
"""
def revo3_move_hand_with_speed(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], speed: builtins.float, dt: builtins.float) -> None:
r"""
Move all joints to target positions with uniform speed (Non-blocking).
Args:
slave_id: Slave device ID
target_positions: List of target positions in degrees (length = joint count)
speed: Target speed in rpm
dt: Control period in seconds
"""
def revo3_move_hand_with_speed_and_gains(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], speed: builtins.float, dt: builtins.float, kp: builtins.float, kd: builtins.float) -> None:
r"""
Move all joints with speed and custom Kp/Kd gains (Non-blocking).
Args:
slave_id: Slave device ID
target_positions: List of target positions in degrees (length = joint count)
speed: Target speed in rpm
dt: Control period in seconds
kp: Position gain
kd: Velocity damping gain
"""
def revo3_move_hand_with_speed_and_gains_wait(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], speed: builtins.float, dt: builtins.float, kp: builtins.float, kd: builtins.float) -> typing.Any:
r"""
Move all joints with speed and custom Kp/Kd gains and wait for completion (Blocking).
Args:
slave_id: Slave device ID
target_positions: List of target positions in degrees (length = joint count)
speed: Target speed in rpm
dt: Control period in seconds
kp: Position gain
kd: Velocity damping gain
"""
def revo3_move_hand_with_speed_wait(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], speed: builtins.float, dt: builtins.float) -> typing.Any:
r"""
Move all joints to target positions with uniform speed and wait for completion (Blocking).
Args:
slave_id: Slave device ID
target_positions: List of target positions in degrees (length = joint count)
speed: Target speed in rpm
dt: Control period in seconds
"""
def revo3_move_joint(self, slave_id: builtins.int, joint_id: builtins.int, target_pos: builtins.float, duration: builtins.float, dt: builtins.float) -> None:
r"""
Move a single joint using quintic polynomial trajectory.
Args:
slave_id: Slave device ID
joint_id: Joint index (0-based)
target_pos: Target position in degrees
duration: Total motion time in seconds
dt: Control period in seconds (e.g., 0.01 for 100Hz)
Move a single joint using quintic polynomial trajectory (Non-blocking).
"""
def revo3_move_joint_wait(self, slave_id: builtins.int, joint_id: builtins.int, target_pos: builtins.float, duration: builtins.float, dt: builtins.float) -> typing.Any:
r"""
Move a single joint and wait until completed (Blocking).
"""
def revo3_move_joint_with_gains(self, slave_id: builtins.int, joint_id: builtins.int, target_pos: builtins.float, duration: builtins.float, dt: builtins.float, kp: builtins.float, kd: builtins.float) -> None:
r"""
Move a single joint with custom Kp/Kd gains (Non-blocking).
"""
def revo3_move_joint_with_gains_wait(self, slave_id: builtins.int, joint_id: builtins.int, target_pos: builtins.float, duration: builtins.float, dt: builtins.float, kp: builtins.float, kd: builtins.float) -> typing.Any:
r"""
Move a single joint with custom Kp/Kd gains and wait until completed (Blocking).
"""
def revo3_move_joint_with_speed(self, slave_id: builtins.int, joint_id: builtins.int, target_pos: builtins.float, speed: builtins.float, dt: builtins.float) -> None:
r"""
Move a single joint to target position with specified speed.
Move a single joint to target position with specified speed (Non-blocking).
Args:
slave_id: Slave device ID
joint_id: Joint index (0-based)
target_pos: Target position in degrees
speed: Target speed in rpm
dt: Control period in seconds
"""
def revo3_move_joint_with_speed_and_gains(self, slave_id: builtins.int, joint_id: builtins.int, target_pos: builtins.float, speed: builtins.float, dt: builtins.float, kp: builtins.float, kd: builtins.float) -> None:
r"""
Move a single joint to target position with specified speed and custom Kp/Kd gains (Non-blocking).
Args:
slave_id: Slave device ID
joint_id: Joint index (0-based)
target_pos: Target position in degrees
speed: Target speed in rpm
dt: Control period in seconds
kp: Position gain
kd: Velocity damping gain
"""
def revo3_move_joint_with_speed_and_gains_wait(self, slave_id: builtins.int, joint_id: builtins.int, target_pos: builtins.float, speed: builtins.float, dt: builtins.float, kp: builtins.float, kd: builtins.float) -> typing.Any:
r"""
Move a single joint to target position with specified speed and custom Kp/Kd gains and wait until completed (Blocking).
Args:
slave_id: Slave device ID
joint_id: Joint index (0-based)
target_pos: Target position in degrees
speed: Target speed in rpm
dt: Control period in seconds
kp: Position gain
kd: Velocity damping gain
"""
def revo3_move_joint_with_speed_wait(self, slave_id: builtins.int, joint_id: builtins.int, target_pos: builtins.float, speed: builtins.float, dt: builtins.float) -> typing.Any:
r"""
Move a single joint to target position with specified speed and wait until completed (Blocking).
Args:
slave_id: Slave device ID
joint_id: Joint index (0-based)
target_pos: Target position in degrees
speed: Target speed in rpm
dt: Control period in seconds
"""
def revo3_move_thumb(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], duration: builtins.float, dt: builtins.float) -> typing.Any:
r"""
Move thumb using quintic polynomial trajectory.
Args:
slave_id: Slave device ID
target_positions: List of 5 target positions in degrees
duration: Total motion time in seconds
dt: Control period in seconds
"""
def revo3_move_thumb_with_gains(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], duration: builtins.float, dt: builtins.float, kp: builtins.float, kd: builtins.float) -> typing.Any:
r"""
Move thumb with custom Kp/Kd gains and quintic trajectory control.
Args:
slave_id: Slave device ID
target_positions: List of 5 target positions in degrees
duration: Total motion time in seconds
dt: Control period in seconds
kp: Position gain
kd: Velocity damping gain
"""
def revo3_move_thumb_with_joint_gains(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], duration: builtins.float, dt: builtins.float, kp: typing.Sequence[builtins.float], kd: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Move thumb with joint-specific Kp/Kd gains (5 joints) and quintic trajectory control.
Args:
slave_id: Slave device ID
target_positions: List of 5 target positions in degrees
duration: Total motion time in seconds
dt: Control period in seconds
kp: List of 5 position gains
kd: List of 5 velocity damping gains
"""
def revo3_multi_joint_control(self, slave_id: builtins.int, mode: builtins.int, params: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Multi-joint synchronous control.
Args:
slave_id: Slave device ID
mode: ControlMode enum value
params: List of 21 float control parameters (degrees, rpm, or mA)
"""
def revo3_reboot(self, slave_id: builtins.int) -> typing.Any:
r"""
Software reboot.
"""
def revo3_replay_hand(self, slave_id: builtins.int, trajectory: typing.Sequence[typing.Sequence[builtins.float]], dt: builtins.float, kp: builtins.float, kd: builtins.float) -> typing.Any:
r"""
Replay a recorded full-hand trajectory.
Args:
slave_id: Slave device ID
trajectory: List of position arrays
dt: Playback interval in seconds
kp: Position gain
kd: Velocity damping gain
"""
def revo3_replay_joint(self, slave_id: builtins.int, joint_id: builtins.int, positions: typing.Sequence[builtins.float], dt: builtins.float, kp: builtins.float, kd: builtins.float) -> typing.Any:
r"""
Replay a recorded single-joint trajectory.
Args:
slave_id: Slave device ID
joint_id: Joint index (0-based)
positions: List of recorded positions
dt: Playback interval in seconds
kp: Position gain
kd: Velocity damping gain
"""
def revo3_reset_finger_defaults(self, slave_id: builtins.int) -> typing.Any:
r"""
Reset finger parameters to defaults.
"""
def revo3_servo_finger(self, slave_id: builtins.int, finger_index: builtins.int, target_positions: typing.Sequence[builtins.float], target_velocities: typing.Sequence[builtins.float]) -> typing.Any:
r"""
High-frequency real-time servo control for a single non-thumb finger using default gains.
Args:
slave_id: Slave device ID
finger_index: 1=Index, 2=Middle, 3=Ring, 4=Pinky
target_positions: List of 4 target positions (degrees)
target_velocities: List of 4 target velocities (rpm)
"""
def revo3_servo_finger_with_gains(self, slave_id: builtins.int, finger_index: builtins.int, target_positions: typing.Sequence[builtins.float], target_velocities: typing.Sequence[builtins.float], kp: typing.Sequence[builtins.float], kd: typing.Sequence[builtins.float]) -> typing.Any:
r"""
High-frequency real-time servo control for a single non-thumb finger using custom gains (4 joints).
Args:
slave_id: Slave device ID
finger_index: 1=Index, 2=Middle, 3=Ring, 4=Pinky
target_positions: List of 4 target positions (degrees)
target_velocities: List of 4 target velocities (rpm)
kp: List of 4 Kp stiffness gains
kd: List of 4 Kd damping gains
"""
def revo3_servo_hand(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], target_velocities: typing.Sequence[builtins.float]) -> typing.Any:
r"""
High-frequency real-time servo control for all 21 joints using default gains.
Args:
slave_id: Slave device ID
target_positions: List of 21 target positions (degrees)
target_velocities: List of 21 target velocities (rpm)
"""
def revo3_servo_hand_with_gains(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], target_velocities: typing.Sequence[builtins.float], kp: builtins.float, kd: builtins.float) -> typing.Any:
r"""
High-frequency real-time servo control for all 21 joints using custom gains.
Args:
slave_id: Slave device ID
target_positions: List of 21 target positions (degrees)
target_velocities: List of 21 target velocities (rpm)
kp: Position gain [0.0, 10.0]
kd: Velocity gain [0.0, 10.0]
"""
def revo3_servo_joint(self, slave_id: builtins.int, joint_id: builtins.int, target_pos: builtins.float, target_vel: builtins.float) -> typing.Any:
r"""
High-frequency real-time servo control for a single joint using default gains.
Args:
slave_id: Slave device ID
joint_id: Joint index (0~20)
target_pos: Target position (degrees)
target_vel: Target velocity (rpm)
"""
def revo3_servo_joint_with_gains(self, slave_id: builtins.int, joint_id: builtins.int, target_pos: builtins.float, target_vel: builtins.float, kp: builtins.float, kd: builtins.float) -> typing.Any:
r"""
High-frequency real-time servo control for a single joint using custom gains.
Args:
slave_id: Slave device ID
joint_id: Joint index (0~20)
target_pos: Target position (degrees)
target_vel: Target velocity (rpm)
kp: Position gain [0.0, 10.0]
kd: Velocity gain [0.0, 10.0]
"""
def revo3_servo_thumb(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], target_velocities: typing.Sequence[builtins.float]) -> typing.Any:
r"""
High-frequency real-time servo control for the thumb using default gains (5 joints).
Args:
slave_id: Slave device ID
target_positions: List of 5 target positions (degrees)
target_velocities: List of 5 target velocities (rpm)
"""
def revo3_servo_thumb_with_gains(self, slave_id: builtins.int, target_positions: typing.Sequence[builtins.float], target_velocities: typing.Sequence[builtins.float], kp: typing.Sequence[builtins.float], kd: typing.Sequence[builtins.float]) -> typing.Any:
r"""
High-frequency real-time servo control for the thumb using custom gains (5 joints).
Args:
slave_id: Slave device ID
target_positions: List of 5 target positions (degrees)
target_velocities: List of 5 target velocities (rpm)
kp: List of 5 Kp stiffness gains
kd: List of 5 Kd damping gains
"""
def revo3_set_all_mit_kd(self, slave_id: builtins.int, kd_values: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Set all 21 joint KD values at once.
"""
def revo3_set_all_mit_kp(self, slave_id: builtins.int, kp_values: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Set all 21 joint KP values at once.
"""
def revo3_set_all_mit_params(self, slave_id: builtins.int, kp_values: typing.Sequence[builtins.float], kd_values: typing.Sequence[builtins.float], positions: typing.Sequence[builtins.float], velocities: typing.Sequence[builtins.float], torques: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Set all 5 grouped MIT parameter arrays in a single write (105 registers).
"""
def revo3_set_all_mit_params_without_retry(self, slave_id: builtins.int, kp_values: typing.Sequence[builtins.float], kd_values: typing.Sequence[builtins.float], positions: typing.Sequence[builtins.float], velocities: typing.Sequence[builtins.float], torques: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Same as `revo3_set_all_mit_params` but without retry.
"""
def revo3_set_all_mit_positions(self, slave_id: builtins.int, positions: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Set all 21 joint target positions at once.
"""
def revo3_set_all_mit_torques(self, slave_id: builtins.int, torques: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Set all 21 joint feed-forward torques at once.
"""
def revo3_set_all_mit_velocities(self, slave_id: builtins.int, velocities: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Set all 21 joint target velocities at once.
"""
def revo3_set_all_motor_currents(self, slave_id: builtins.int, currents: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Set all Revo3 motor currents at once (mA).
Args:
slave_id: Slave device ID
currents: List of 21 float currents
"""
def revo3_set_all_motor_positions(self, slave_id: builtins.int, positions: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Set all Revo3 motor positions at once (degrees).
Args:
slave_id: Slave device ID
positions: List of 21 float positions in degrees
"""
def revo3_set_all_motor_velocities(self, slave_id: builtins.int, velocities: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Set all Revo3 motor velocities at once (RPM).
Args:
slave_id: Slave device ID
velocities: List of 21 float velocities in RPM
"""
def revo3_set_all_touch_modules_enabled(self, slave_id: builtins.int, bits: builtins.int) -> typing.Any:
r"""
Enable or disable all 11 touch modules at once.
Args:
slave_id: Slave device ID
bits: A 16-bit mask where bits 0~10 map to modules 0~10. 1 = on, 0 = off.
"""
def revo3_set_auto_calibration(self, slave_id: builtins.int, enabled: builtins.bool) -> typing.Any:
r"""
Enable or disable auto calibration on power-up.
"""
def revo3_set_auto_clear_motor_error(self, slave_id: builtins.int, enabled: builtins.bool) -> typing.Any:
r"""
Enable or disable auto clear motor errors.
"""
def revo3_set_buzzer_switch(self, slave_id: builtins.int, enabled: builtins.bool) -> typing.Any:
r"""
Set buzzer switch.
"""
def revo3_set_calibration_current(self, slave_id: builtins.int, current: builtins.float) -> typing.Any:
r"""
Set Revo3 calibration current.
"""
def revo3_set_canfd_baudrate(self, slave_id: builtins.int, baudrate_enum_val: builtins.int) -> typing.Any:
r"""
Set CANFD Baudrate (enum value: 0=1M, 1=2M, 2=4M, 3=5M)
"""
def revo3_set_current_position_as_zero(self, slave_id: builtins.int) -> typing.Any:
r"""
Set the current position as zero calibration.
Recommended Calibration Workflow:
1. Disable the motors to allow free manual movements of the fingers.
2. Manually pose the hand into the desired zero-reference pose.
3. Enable the motors to lock the pose.
4. Call this API to register the current feedback positions as zero.
"""
def revo3_set_global_protect_current(self, slave_id: builtins.int, current: builtins.float) -> typing.Any:
r"""
Set global motor protection current.
"""
def revo3_set_joint_mit_params(self, slave_id: builtins.int, joint_id: builtins.int, kp: builtins.float, kd: builtins.float, pos: builtins.float, vel: builtins.float, torque_ff: builtins.float) -> typing.Any:
r"""
Set all 5 MIT parameters for a single joint in the interleaved register block.
Args:
joint_id: 0~20
kp: Position gain [0, 10]
kd: Velocity gain [0, 10]
pos: Target position (degrees)
vel: Target velocity (rpm)
torque_ff: Feed-forward torque (mA)
"""
def revo3_set_joint_position_limits(self, slave_id: builtins.int, joint_id: builtins.int, min_pos: builtins.float, max_pos: builtins.float) -> typing.Any:
r"""
Set joint position limits (min, max).
"""
def revo3_set_joint_protect_current(self, slave_id: builtins.int, joint_id: builtins.int, current: builtins.float) -> typing.Any:
r"""
Set per-joint protection current.
"""
def revo3_set_joint_speed_limits(self, slave_id: builtins.int, joint_id: builtins.int, min_speed: builtins.float, max_speed: builtins.float) -> typing.Any:
r"""
Set joint speed limits (min, max).
"""
def revo3_set_max_continuous_current(self, slave_id: builtins.int, current: builtins.float) -> typing.Any:
r"""
Set Revo3 max continuous current.
"""
def revo3_set_motor_current(self, slave_id: builtins.int, motor_id: builtins.int, current: builtins.float) -> typing.Any:
r"""
Set target current for a single Revo3 motor (mA).
Args:
slave_id: Slave device ID
motor_id: Motor index (0~22)
current: Target current in mA
"""
def revo3_set_motor_mit(self, slave_id: builtins.int, motor_id: builtins.int, position_deg: builtins.float, velocity: builtins.float, current: builtins.float, kp: builtins.float, kd: builtins.float) -> typing.Any:
r"""
Full MIT mode control for a single Revo3 motor.
τ = Kp * (P_des - P_actual) + Kd * (V_des - V_actual) + T_ff
Args:
slave_id: Slave device ID
motor_id: Motor index (0~22)
position_deg: Target position (degrees)
velocity: Target velocity
current: Feedforward current (mA)
kp: Position stiffness (0~10)
kd: Velocity damping (0~10)
"""
def revo3_set_motor_position(self, slave_id: builtins.int, motor_id: builtins.int, position_deg: builtins.float) -> typing.Any:
r"""
Set target position for a single Revo3 motor (degrees).
Args:
slave_id: Slave device ID
motor_id: Motor index (0~22)
position_deg: Target position in degrees
"""
def revo3_set_motor_velocity(self, slave_id: builtins.int, motor_id: builtins.int, velocity: builtins.float) -> typing.Any:
r"""
Set target velocity for a single Revo3 motor (RPM).
Args:
slave_id: Slave device ID
motor_id: Motor index (0~22)
velocity: Target velocity in RPM
"""
def revo3_set_rs485_baudrate(self, slave_id: builtins.int, baudrate_enum_val: builtins.int) -> typing.Any:
r"""
Set RS485 Baudrate (enum value: 0=1M, 1=2M, 2=3M, 4=5M)
"""
def revo3_set_servo_damping_omega(self, omega: builtins.float) -> typing.Any:
r"""
Set the natural frequency (omega) for the second-order critically damped servo filter.
Args:
omega: Higher values mean faster tracking but less smoothing. Default is 20.0.
"""
def revo3_set_servo_filter_mode(self, mode: builtins.int) -> typing.Any:
r"""
Set the high-frequency real-time servo smoothing filter mode.
Args:
mode: 0 = None, 1 = First-order LPF, 2 = Second-order Critically Damped system.
"""
def revo3_set_servo_lpf_alpha(self, alpha: builtins.float) -> typing.Any:
r"""
Set the first-order Low-Pass Filter (LPF) coefficient for servo control.
Args:
alpha: Filter coefficient in range (0.0, 1.0]. Default is 1.0 (no filtering).
"""
def revo3_set_slave_id(self, slave_id: builtins.int, new_slave_id: builtins.int) -> typing.Any:
r"""
Set Slave ID
"""
def revo3_set_software_e_stop(self, slave_id: builtins.int, enabled: builtins.bool) -> typing.Any:
r"""
Enable or disable software e-stop.
"""
def revo3_set_teaching_mode(self, slave_id: builtins.int, enabled: builtins.bool) -> typing.Any:
r"""
Enter or exit teaching mode.
"""
def revo3_set_touch_data_type(self, slave_id: builtins.int, data_type: TouchDataMode) -> typing.Any:
r"""
Set the data type for Revo3 touch sensor reading.
Args:
data_type: `TouchDataMode` (PressureArray = 0, ForceSummary = 1)
"""
def revo3_set_touch_module_enabled(self, slave_id: builtins.int, module_id: builtins.int, enabled: builtins.bool) -> typing.Any:
r"""
Enable or disable a single touch module.
Args:
slave_id: Slave device ID
module_id: 0~10
enabled: True to enable, False to disable
"""
def revo3_set_touch_screen(self, slave_id: builtins.int, enabled: builtins.bool) -> typing.Any:
r"""
Set touch screen switch.
"""
def revo3_set_use_broadcast_id(self, slave_id: builtins.int, enabled: builtins.bool) -> typing.Any:
r"""
Enable or disable using broadcast ID.
"""
def revo3_set_vibration_switch(self, slave_id: builtins.int, enabled: builtins.bool) -> typing.Any:
r"""
Set vibration switch.
"""
def revo3_set_zero_position(self, slave_id: builtins.int, offsets_deg: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Set the zero position with explicit motor offsets (degrees).
`offsets_deg` must contain the degree offset values for each motor
up to 21 (matching the hand SKU DOF count, e.g. 13, 16, or 21).
"""
def revo3_single_joint_control(self, slave_id: builtins.int, joint_id: builtins.int, mode: builtins.int, param: builtins.float) -> typing.Any:
r"""
Single joint control.
Args:
slave_id: Slave device ID
joint_id: Joint index (0~20)
mode: ControlMode (0=Position, 1=Speed, 2=Current, 4=Impedance)
param: Control parameter (float degrees, rpm, or mA depending on mode)
"""
def revo3_start_dfu(self, slave_id: builtins.int, file_path: builtins.str, wait_secs: typing.Optional[builtins.int], on_dfu_state: typing.Optional[typing.Any], on_dfu_progress: typing.Optional[typing.Any]) -> typing.Any:
r"""
Start Revo3 firmware upgrade over Modbus RTU or CANFD.
Note: Modbus OTA is only supported on Revo3 firmware >= 0.0.4.
Args:
slave_id: Device slave ID
file_path: Firmware file path
wait_secs: Reserved wait seconds parameter for compatibility
Returns:
None when the transfer completes successfully
"""
def revo3_start_dfu_with_target(self, slave_id: builtins.int, file_path: builtins.str, target: typing.Any, wait_secs: typing.Optional[builtins.int], on_dfu_state: typing.Optional[typing.Any], on_dfu_progress: typing.Optional[typing.Any]) -> typing.Any:
r"""
Start Revo3 firmware or resource upgrade with target type (V1.1+).
Args:
slave_id: Device slave ID
file_path: Firmware or resource file path
target: OtaTarget enum or integer (0=MainFw, 1=Image, 2=MotorFw)
wait_secs: Reserved wait seconds parameter for compatibility
Returns:
None when the transfer completes successfully
"""
def revo3_start_image_dfu(self, slave_id: builtins.int, file_path: builtins.str, wait_secs: typing.Optional[builtins.int], on_dfu_state: typing.Optional[typing.Any], on_dfu_progress: typing.Optional[typing.Any]) -> typing.Any:
r"""
Start Revo3 Image resource pack upgrade (V1.1+).
"""
def revo3_start_mcu_dfu(self, slave_id: builtins.int, file_path: builtins.str, wait_secs: typing.Optional[builtins.int], on_dfu_state: typing.Optional[typing.Any], on_dfu_progress: typing.Optional[typing.Any]) -> typing.Any:
r"""
Start Revo3 Main Board MCU firmware upgrade (V1.1+).
"""
def revo3_start_motor_dfu(self, slave_id: builtins.int, file_path: builtins.str, wait_secs: typing.Optional[builtins.int], on_dfu_state: typing.Optional[typing.Any], on_dfu_progress: typing.Optional[typing.Any]) -> typing.Any:
r"""
Start Revo3 Motor board firmware upgrade (V1.1+).
"""
def revo3_teach_hand(self, slave_id: builtins.int, dt: builtins.float, duration: builtins.float) -> typing.Any:
r"""
Enter teaching (backdrive) mode for all joints.
Sets Kp=0, Kd=0, τ_ff=0 on all joints for free manual movement.
Records all joint positions at each dt interval.
Args:
slave_id: Slave device ID
dt: Recording interval in seconds
duration: Total recording time in seconds
Returns:
List of position arrays (each of length = joint count)
"""
def revo3_teach_joint(self, slave_id: builtins.int, joint_id: builtins.int, dt: builtins.float, duration: builtins.float) -> typing.Any:
r"""
Enter teaching (backdrive) mode for a single joint.
Sets Kp=0, Kd=0, τ_ff=0 for free manual movement.
Records joint position at each dt interval.
Args:
slave_id: Slave device ID
joint_id: Joint index (0-based)
dt: Recording interval in seconds
duration: Total recording time in seconds
Returns:
List of recorded positions (one per dt sample)
"""
def revo3_thumb_control(self, slave_id: builtins.int, mode: builtins.int, params: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Thumb control.
Args:
mode: ControlMode (0=Position, 1=Speed, 2=Current)
params: [CMC_flex, CMC_abd, MCP, IP, DIP] — 5 float values (degrees/rpm/mA)
"""
def revo3_thumb_mit_control(self, slave_id: builtins.int, params: typing.Sequence[builtins.float]) -> typing.Any:
r"""
Thumb MIT control.
Args:
params: 5 joints × 5 MIT params = 25 float values
"""
def revo3_uses_motor_api(self, slave_id: builtins.int) -> builtins.bool:
r"""
Check if device uses Revo3 Motor API (Revo3 protocol, MIT control).
Returns:
True if uses Revo3 Motor API.
"""
def set_hardware_type(self, slave_id: builtins.int, hw_type: StarkHardwareType) -> typing.Any:
r"""
Set hardware type for a specific slave.
Use this to manually override the hardware type when SN-based auto-detection
in `revo3_get_device_info()` fails or returns an incorrect result.
Call this after `revo3_get_device_info()` if the detected `hardware_type` is wrong.
This is also needed for CAN protocol where hardware type may not be auto-detected.
Args:
slave_id: The slave ID
hw_type: StarkHardwareType enum value
Example:
# Override hardware type after get_device_info
info = await ctx.revo3_get_device_info(slave_id)
if info.hardware_type != expected_type:
await ctx.set_hardware_type(slave_id, StarkHardwareType.Revo3Ultra)
"""
def start_dfu(self, slave_id: builtins.int, file_path: builtins.str, wait_secs: typing.Optional[builtins.int], on_dfu_state: typing.Optional[typing.Any], on_dfu_progress: typing.Optional[typing.Any]) -> typing.Any:
r"""
Compatibility alias for older examples.
"""
@typing.final
class DeviceInfo:
def __new__(cls, sku_type: SkuType, hand_type: HandType, hardware_type: StarkHardwareType, serial_number: builtins.str, firmware_version: builtins.str, hardware_version: builtins.str) -> DeviceInfo: ...
def desc(self) -> builtins.str: ...
@property
def description(self) -> builtins.str: ...
@property
def firmware_version(self) -> builtins.str:
r"""
Firmware version
"""
def get_hardware_type(self) -> StarkHardwareType: ...
@property
def hand_type(self) -> HandType:
r"""
Hand type (Left/Right)
"""
@property
def hardware_type(self) -> StarkHardwareType:
r"""
Hardware type
"""
@property
def hardware_version(self) -> builtins.str:
r"""
Hardware version.
"""
def is_touch(self) -> builtins.bool:
r"""
Check if device has any touch sensor.
"""
def new(self, sku_type: SkuType, hand_type: HandType, hardware_type: StarkHardwareType, serial_number: builtins.str, firmware_version: builtins.str, hardware_version: builtins.str) -> DeviceInfo: ...
def revo3_uses_motor_api(self) -> builtins.bool:
r"""
Check if device uses Revo3 Motor API (Revo3 protocol, MIT control).
"""
@property
def serial_number(self) -> builtins.str:
r"""
Serial number
"""
@typing_extensions.deprecated("Use hand_type instead")
@property
def sku_type(self) -> SkuType:
r"""
Hand SKU (Deprecated, use hand_type instead)
"""
@typing.final
class FingertipPose:
r"""
Fingertip 6-DoF pose in cartesian space
"""
def __new__(cls, x: builtins.float, y: builtins.float, z: builtins.float, rx: builtins.float, ry: builtins.float, rz: builtins.float) -> FingertipPose: ...
def desc(self) -> builtins.str: ...
@property
def description(self) -> builtins.str: ...
def new(self, x: builtins.float, y: builtins.float, z: builtins.float, rx: builtins.float, ry: builtins.float, rz: builtins.float) -> FingertipPose: ...
@property
def rx(self) -> builtins.float: ...
@property
def ry(self) -> builtins.float: ...
@property
def rz(self) -> builtins.float: ...
@property
def x(self) -> builtins.float: ...
@property
def y(self) -> builtins.float: ...
@property
def z(self) -> builtins.float: ...
@typing.final
class Revo3MotorStatusBuffer:
def __new__(cls, max_size: builtins.int) -> Revo3MotorStatusBuffer: ...
def clear(self) -> None: ...
def is_empty(self) -> builtins.bool: ...
def len(self) -> builtins.int: ...
def peek_latest(self) -> typing.Optional[Revo3MotorStatusData]: ...
def pop_all(self) -> builtins.list[Revo3MotorStatusData]: ...
def pop_latest(self, count: builtins.int) -> builtins.list[Revo3MotorStatusData]: ...
@typing.final
class Revo3MotorStatusData:
r"""
Revo3 motor status data for all 21 motors
"""
def __new__(cls, statuses: typing.Sequence[builtins.int], velocities: typing.Sequence[builtins.float], positions: typing.Sequence[builtins.float], currents: typing.Sequence[builtins.float], errors: typing.Sequence[builtins.int]) -> Revo3MotorStatusData: ...
@property
def currents(self) -> builtins.list[builtins.float]:
r"""
Motor currents in float (21 values)
"""
def desc(self) -> builtins.str: ...
@property
def description(self) -> builtins.str: ...
@property
def errors(self) -> builtins.list[builtins.int]:
r"""
Motor error codes (21 values)
"""
def new(self, statuses: typing.Sequence[builtins.int], velocities: typing.Sequence[builtins.float], positions: typing.Sequence[builtins.float], currents: typing.Sequence[builtins.float], errors: typing.Sequence[builtins.int]) -> Revo3MotorStatusData: ...
@property
def positions(self) -> builtins.list[builtins.float]:
r"""
Motor positions in float (21 values)
"""
@property
def statuses(self) -> builtins.list[builtins.int]:
r"""
Motor status codes (21 values)
"""
@property
def velocities(self) -> builtins.list[builtins.float]:
r"""
Motor velocities in float (21 values)
"""
@typing.final
class Revo3SystemStatus:
r"""
Revo3 system status data from registers 1800–1804.
Internal sampling rate: 5Hz. Host should poll at ≤5Hz.
"""
def __new__(cls, system_state: builtins.int, error_code: builtins.int, current_ma: builtins.int, voltage_v: builtins.int, power_w: builtins.int, temperature_c: builtins.int) -> Revo3SystemStatus: ...
@property
def current_ma(self) -> builtins.int:
r"""
System current (mA)
"""
def desc(self) -> builtins.str: ...
@property
def description(self) -> builtins.str: ...
@property
def error_code(self) -> builtins.int:
r"""
System error code: 0=Normal, 1=CommError, 2=NoCalibration, 3=TempAbnormal (low 8-bit of register 1800)
"""
def is_normal(self) -> builtins.bool:
r"""
Check if system is in normal state
"""
def new(self, system_state: builtins.int, error_code: builtins.int, current_ma: builtins.int, voltage_v: builtins.int, power_w: builtins.int, temperature_c: builtins.int) -> Revo3SystemStatus: ...
@property
def power_w(self) -> builtins.int:
r"""
System power (W)
"""
@property
def system_state(self) -> builtins.int:
r"""
System state: 0=Normal, 1=Fault (high 8-bit of register 1800)
"""
@property
def temperature_c(self) -> builtins.int:
r"""
System temperature (°C)
"""
@property
def voltage_v(self) -> builtins.int:
r"""
System voltage (V)
"""
@typing.final
class Revo3TouchData:
r"""
Revo3 touch data for all 11 modules
"""
def desc(self) -> builtins.str: ...
@property
def description(self) -> builtins.str: ...
@property
def modules(self) -> builtins.list[builtins.list[builtins.int]]:
r"""
Per-module pressure array data (11 modules, varying point counts)
"""
@property
def summary(self) -> builtins.list[builtins.int]:
r"""
Summary force values (42 values exactly mapping to 4100~4141)
"""
@typing.final
class Revo3TouchDataBuffer:
def __new__(cls, max_size: builtins.int) -> Revo3TouchDataBuffer: ...
def clear(self) -> None: ...
def is_empty(self) -> builtins.bool: ...
def len(self) -> builtins.int: ...
def peek_latest(self) -> typing.Optional[Revo3TouchData]: ...
def pop_all(self) -> builtins.list[Revo3TouchData]: ...
@typing.final
class SerialPortCfg:
def __new__(cls, slave_id: builtins.int, baudrate: Baudrate) -> SerialPortCfg: ...
@property
def baudrate(self) -> Baudrate:
r"""
Baud rate for the serial communication
"""
def desc(self) -> builtins.str: ...
@property
def description(self) -> builtins.str: ...
def new(self, slave_id: builtins.int, baudrate: Baudrate) -> SerialPortCfg: ...
@property
def slave_id(self) -> builtins.int:
r"""
Slave ID for the Revo3 transport.
For Modbus/CANFD, range is 1~247 and common defaults are 126/127.
"""
@typing.final
class ZqwlDeviceInfo:
r"""
ZQWL Device Information
"""
@property
def channel_count(self) -> builtins.int:
r"""
Number of channels
"""
@property
def description(self) -> builtins.str:
r"""
Device description
"""
@property
def pid(self) -> builtins.int:
r"""
USB PID
"""
@property
def port_name(self) -> builtins.str:
r"""
Serial port name
"""
@property
def supports_canfd(self) -> builtins.bool:
r"""
Whether CANFD is supported
"""
@property
def vid(self) -> builtins.int:
r"""
USB VID
"""
@typing.final
class Baudrate(enum.Enum):
Baud115200 = ...
Baud57600 = ...
Baud19200 = ...
Baud460800 = ...
Baud1Mbps = ...
Baud2Mbps = ...
Baud3Mbps = ...
Baud5Mbps = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> Baudrate: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class BaudrateCAN(enum.Enum):
Baud100Kbps = ...
Baud125Kbps = ...
Baud200Kbps = ...
Baud250Kbps = ...
Baud400Kbps = ...
Baud500Kbps = ...
Baud800Kbps = ...
Baud1Mbps = ...
Baud2Mbps = ...
Baud4Mbps = ...
Baud5Mbps = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> BaudrateCAN: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class CanFdBaudrate(enum.Enum):
Baud1Mbps = ...
Baud2Mbps = ...
Baud4Mbps = ...
Baud5Mbps = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> CanFdBaudrate: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class ControlMode(enum.Enum):
Position = ...
Speed = ...
Current = ...
Impedance = ...
Damping = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> ControlMode: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class DfuCommandType(enum.Enum):
RequestDeviceInfo = ...
StartUpgrade = ...
TransferData = ...
TransferDone = ...
ExitUpgrade = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> DfuCommandType: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class DfuExitReason(enum.Enum):
FirmwareVersionMismatch = ...
HardwareVersionMismatch = ...
FirmwareFileCorrupted = ...
Unknown = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> DfuExitReason: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class DfuState(enum.Enum):
Idle = ...
Starting = ...
Started = ...
Transfer = ...
Completed = ...
Aborted = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> DfuState: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class EcRevo3TouchSdoSubIdx(enum.Enum):
SwitchBase = ...
FwVersionBase = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> EcRevo3TouchSdoSubIdx: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class EtherCATAddress(enum.Enum):
TX = ...
RX = ...
Config = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> EtherCATAddress: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class EtherCATConfigIndex(enum.Enum):
SkuType = ...
LedSwitch = ...
BuzzerSwitch = ...
VibrationSwitch = ...
UnitMode = ...
ManualCalibration = ...
AutoCalibration = ...
CtrlFirmwareVersion = ...
CtrlSerialNumber = ...
FoeFileType = ...
FoeAuthCode = ...
HardwareVersion = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> EtherCATConfigIndex: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class EtherCATFoeType(enum.Enum):
Wrist = ...
Control = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> EtherCATFoeType: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class FingerUnitMode(enum.Enum):
Normalized = ...
Physical = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> FingerUnitMode: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class HandType(enum.Enum):
Left = ...
Right = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> HandType: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class LogLevel(enum.Enum):
Error = ...
Warn = ...
Info = ...
Debug = ...
Trace = ...
@typing.final
class OtaTarget(enum.Enum):
MainFw = ...
Image = ...
MotorFw = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> OtaTarget: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class RegAddrRevo3(enum.Enum):
MotorZeroOffsetBase = ...
SetCurrentPositionAsZero = ...
FactoryKey = ...
EnterOta = ...
HandType = ...
ResetFingerDefaults = ...
FactoryReset = ...
BuzzerSwitch = ...
VibrationSwitch = ...
TouchScreenSwitch = ...
SlaveId = ...
Rs485Baudrate = ...
CanFdBaudrate = ...
SoftwareReboot = ...
AutoCalibration = ...
ManualCalibration = ...
CalibrationCurrent = ...
MaxContinuousCurrent = ...
ClearMotorError = ...
TeachingMode = ...
SoftwareEStop = ...
UseBroadcastId = ...
SetSerialNumber = ...
AutoClearMotorError = ...
GlobalProtectCurrent = ...
JointProtectCurrentBase = ...
JointMinPositionBase = ...
JointMaxPositionBase = ...
JointMinSpeedBase = ...
JointMaxSpeedBase = ...
OtaCmd = ...
OtaStatus = ...
OtaTotalSizeH = ...
OtaTotalSizeL = ...
OtaOffsetH = ...
OtaOffsetL = ...
OtaPacketSize = ...
OtaErrorCode = ...
OtaTarget = ...
OtaDataBase = ...
SingleJointId = ...
SingleJointCtrlMode = ...
SingleJointCtrlParam = ...
MultiJointCtrlMode = ...
MultiJointParamBase = ...
MitJointId = ...
MitKp = ...
MitKd = ...
MitPos = ...
MitVel = ...
MitTorqueFf = ...
MultiMitBase = ...
MitBatchKpBase = ...
MitBatchKdBase = ...
MitBatchPosBase = ...
MitBatchVelBase = ...
MitBatchTorqueBase = ...
FingerIndex = ...
FingerCtrlMode = ...
FingerParamBase = ...
ThumbCtrlMode = ...
ThumbParamBase = ...
FingerMitIndex = ...
FingerMitParamBase = ...
ThumbMitParamBase = ...
SystemStatus = ...
SystemCurrent = ...
SystemVoltage = ...
SystemPower = ...
SystemTemperature = ...
MotorSpeedBase = ...
MotorPositionBase = ...
MotorCurrentBase = ...
MotorErrorCodeBase = ...
MotorTemperatureBase = ...
MotorOnlineBase = ...
FirmwareVersion = ...
HardwareVersion = ...
SerialNumber = ...
Motor0Sn = ...
Motor1Sn = ...
Motor2Sn = ...
Motor3Sn = ...
Motor4Sn = ...
Motor5Sn = ...
Motor6Sn = ...
Motor7Sn = ...
Motor8Sn = ...
Motor9Sn = ...
Motor10Sn = ...
Motor11Sn = ...
Motor12Sn = ...
Motor13Sn = ...
Motor14Sn = ...
Motor15Sn = ...
Motor16Sn = ...
Motor17Sn = ...
Motor18Sn = ...
Motor19Sn = ...
Motor20Sn = ...
MotorFwVersionBase = ...
TouchEnableBase = ...
TouchClearAll = ...
TouchClearBase = ...
TouchDataType = ...
TouchSummaryBase = ...
TouchPalmArray = ...
TouchThumbTipArray = ...
TouchThumbPadArray = ...
TouchIndexTipArray = ...
TouchIndexPadArray = ...
TouchMiddleTipArray = ...
TouchMiddlePadArray = ...
TouchRingTipArray = ...
TouchRingPadArray = ...
TouchPinkyTipArray = ...
TouchPinkyPadArray = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> RegAddrRevo3: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class Rs485Baudrate(enum.Enum):
Baud1Mbps = ...
Baud2Mbps = ...
Baud3Mbps = ...
Baud5Mbps = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> Rs485Baudrate: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class SkuType(enum.Enum):
MediumRight = ...
MediumLeft = ...
SmallRight = ...
SmallLeft = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> SkuType: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class StarkError(enum.Enum):
Success = ...
Unknown = ...
InvalidParams = ...
InvalidData = ...
ParseFailed = ...
AllocFailed = ...
ReadFailed = ...
OperationFailed = ...
SystemIsBusy = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> StarkError: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class StarkHardwareType(enum.Enum):
Revo3Ultra = ...
Revo3UltraTouch = ...
Revo3UltraVisionTouch = ...
Revo3Pro = ...
Revo3ProTouch = ...
Revo3Basic = ...
Revo3BasicTouch = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> StarkHardwareType: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class StarkProtocolType(enum.Enum):
Auto = ...
Modbus = ...
CanFd = ...
EtherCAT = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> StarkProtocolType: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class TouchDataMode(enum.Enum):
PressureArray = ...
ForceSummary = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> TouchDataMode: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
@typing.final
class TouchVendor(enum.Enum):
Unknown = ...
Pressure = ...
def __int__(self) -> builtins.int:
r"""
Support int(enum) conversion
"""
def __new__(cls, value: builtins.int) -> TouchVendor: ...
@property
def int_value(self) -> builtins.int:
r"""
Get the integer value of the enum
"""
def available_usb_ports(vid: builtins.int, pid: builtins.int) -> typing.Any: ...
def close_device_handler(client: DeviceContext) -> typing.Any:
r"""
Close device handler and release resources.
This is the counterpart to init_from_detected() and init_device_handler().
It automatically handles cleanup based on the protocol type:
- For CANFD: Closes CANFD adapters
- For Modbus: Closes serial port
Args:
client: PyDeviceContext to close
Examples:
ctx = await sdk.init_from_detected(device)
# ... use ctx ...
await sdk.close_device_handler(ctx)
"""
def close_socketcan() -> None:
r"""
Close SocketCAN device (Linux only)
"""
def close_zqwl() -> None:
r"""
Close ZQWL CANFD device
"""
def get_sdk_version() -> builtins.str: ...
def init_device_handler(protocol_type: StarkProtocolType, master_id: builtins.int = 0, slave_id: typing.Optional[builtins.int] = None, hw_type: typing.Optional[StarkHardwareType] = None) -> DeviceContext: ...
def init_from_detected(device: DetectedDevice) -> typing.Any:
r"""
Initialize device handler from detected device info.
This function initializes the appropriate transport (Modbus, CAN, CANFD)
based on the detected device's protocol and returns a ready-to-use handler.
This is the recommended way to initialize after `revo3_auto_detect()` as it:
- Automatically initializes the correct transport (BrainCo/ZQWL/SocketCAN or Modbus)
- Sets hardware type from detected device info
- Simplifies the initialization process
Args:
device: DetectedDevice from revo3_auto_detect()
Returns:
PyDeviceContext: Ready-to-use device context
Raises:
RuntimeError: If initialization fails
Examples:
devices = await sdk.revo3_auto_detect()
if devices:
ctx = await sdk.init_from_detected(devices[0])
# ctx is ready to use, no need to call get_device_info
"""
def init_logging(level: typing.Optional[LogLevel] = LogLevel.Info) -> None: ...
def init_socketcan_canfd(iface: typing.Optional[builtins.str] = None) -> None:
r"""
Initialize SocketCAN CANFD device (Linux only)
Args:
iface: Interface name (e.g. "can0"). If None, uses STARK_SOCKETCAN_IFACE env var or "can0"
Raises:
RuntimeError: Initialization failed or not on Linux
"""
def init_zqwl_canfd(port_name: builtins.str, arb_baudrate: builtins.int = 1000000, data_baudrate: builtins.int = 5000000) -> None:
r"""
Initialize ZQWL CANFD device
Revo3 default arbitration baudrate is 1Mbps; data baudrate is 5Mbps.
Args:
port_name: Serial port name
arb_baudrate: Arbitration baudrate (bps), default 1000000
data_baudrate: Data baudrate (bps), default 5000000
Raises:
RuntimeError: Initialization failed
"""
def is_socketcan_available(iface: builtins.str) -> builtins.bool:
r"""
Check if SocketCAN interface is available (Linux only)
Args:
iface: Interface name (e.g. "can0")
Returns:
bool: True if interface exists and is up
"""
def list_available_ports() -> typing.Any: ...
def list_zqwl_devices() -> builtins.list[ZqwlDeviceInfo]:
r"""
List all ZQWL USB CANFD-capable devices
Returns:
List[ZqwlDeviceInfo]: List of devices
"""
def modbus_close(client: DeviceContext) -> typing.Any: ...
def modbus_open(port_name: builtins.str, baudrate: Baudrate) -> typing.Any: ...
def revo3_auto_detect(scan_all: builtins.bool = False, port: typing.Optional[builtins.str] = None, protocol: typing.Optional[builtins.str] = None) -> typing.Any:
r"""
Auto-detect Revo3 devices
Scans for devices across all supported protocols in priority order:
1. CANFD adapters (BrainCo/ZQWL/SocketCAN)
2. Modbus/RS485 (5 Mbps; IDs 1, 2, 0x7E, 0x7F)
Args:
scan_all: If True, scan for all devices. If False, stop at first found. Default False.
port: Optional port name to scan. If None, scans all available ports.
protocol: Optional protocol to use ("CanFd", "Modbus"). If None, tries all.
Returns:
List[DetectedDevice]: List of detected devices (empty if none found)
Examples:
# Auto-detect (simplest)
devices = await sdk.revo3_auto_detect()
# Scan all devices
devices = await sdk.revo3_auto_detect(scan_all=False)
# Scan specific port
devices = await sdk.revo3_auto_detect(port="/dev/ttyUSB0")
# Scan specific protocol
devices = await sdk.revo3_auto_detect(protocol="CanFd")
"""
def revo3_auto_detect_device(port_name: typing.Optional[builtins.str] = None, quick: typing.Optional[builtins.bool] = True) -> typing.Any: ...
def revo3_auto_detect_modbus(port_name: typing.Optional[builtins.str] = None) -> typing.Any: ...
def scan_canfd_devices(ctx: DeviceContext, candidate_ids: typing.Optional[typing.Sequence[builtins.int]] = None, timeout_ms: builtins.int = 500) -> typing.Any:
r"""
Scan CANFD bus for devices
Uses Revo3 device-info registers to detect devices.
Args:
ctx: PyDeviceContext
candidate_ids: Candidate device ID list, default [1, 2, 0x7E, 0x7F]
timeout_ms: Timeout in milliseconds, default 500
Returns:
Optional[int]: Found device ID, None if not found
"""
def set_can_rx_callback(func: typing.Any) -> None:
r"""
Set callback for receiving CAN FD frames.
Args:
func: Callback function to receive CAN FD frames.
Returns:
None
"""
def set_can_tx_callback(func: typing.Any) -> None:
r"""
Set callback for transmitting CAN FD frames.
Args:
func: Callback function to transmit CAN FD frames.
Returns:
None
"""
def set_modbus_read_holding_callback(func: typing.Any) -> None:
r"""
Set callback for reading Modbus holding registers (FC03).
Args:
func: Callback function for reading holding registers.
Returns:
None
"""
def set_modbus_read_input_callback(func: typing.Any) -> None:
r"""
Set callback for reading Modbus input registers (FC04).
Args:
func: Callback function for reading input registers.
Returns:
None
"""
def set_modbus_write_callback(func: typing.Any) -> None:
r"""
Set callback for writing Modbus holding registers (FC16).
Args:
func: Callback function for writing holding registers.
Returns:
None
"""View C/C++ Header File (revo3-sdk.h)
#ifndef REVO3_SDK_H
#define REVO3_SDK_H
/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>
/// Maximum touch points buffer capacity allocated per module (matching the 57-point Thumb Pad).
constexpr static const uintptr_t REVO3_TOUCH_MAX_POINTS = 57;
enum DfuState : uint8_t {
DFU_STATE_IDLE = 0,
DFU_STATE_STARTING = 1,
DFU_STATE_STARTED = 2,
DFU_STATE_TRANSFER = 3,
DFU_STATE_COMPLETED = 4,
DFU_STATE_ABORTED = 5,
};
enum EtherCATFoeType : uint8_t {
ETHER_CAT_FOE_TYPE_WRIST = 1,
ETHER_CAT_FOE_TYPE_CONTROL = 2,
};
/// Revo3 hand side.
enum HandType : uint8_t {
HAND_TYPE_LEFT = 0,
HAND_TYPE_RIGHT = 1,
};
enum LogLevel : uint8_t {
LOG_LEVEL_ERROR = 0,
LOG_LEVEL_WARN = 1,
LOG_LEVEL_INFO = 2,
LOG_LEVEL_DEBUG = 3,
LOG_LEVEL_TRACE = 4,
};
/// Revo3 hand side and reserved size marker.
enum SkuType : uint8_t {
SKU_TYPE_MEDIUM_RIGHT = 1,
SKU_TYPE_MEDIUM_LEFT = 2,
SKU_TYPE_SMALL_RIGHT = 3,
SKU_TYPE_SMALL_LEFT = 4,
};
/// Revo3 hardware variants only.
enum StarkHardwareType : uint8_t {
STARK_HARDWARE_TYPE_REVO3_ULTRA = 20,
STARK_HARDWARE_TYPE_REVO3_ULTRA_TOUCH = 21,
STARK_HARDWARE_TYPE_REVO3_ULTRA_VISION_TOUCH = 22,
STARK_HARDWARE_TYPE_REVO3_PRO = 23,
STARK_HARDWARE_TYPE_REVO3_PRO_TOUCH = 24,
STARK_HARDWARE_TYPE_REVO3_BASIC = 26,
STARK_HARDWARE_TYPE_REVO3_BASIC_TOUCH = 27,
};
enum StarkProtocolType : uint8_t {
STARK_PROTOCOL_TYPE_AUTO = 0,
STARK_PROTOCOL_TYPE_MODBUS = 1,
STARK_PROTOCOL_TYPE_CAN_FD = 3,
STARK_PROTOCOL_TYPE_ETHER_CAT = 4,
};
struct CDataCollector;
struct CRevo3MotorStatusBuffer;
struct CRevo3TouchDataBuffer;
/// Opaque device handle for the C API.
struct DeviceHandler;
struct CRevo3MotorStatusData {
uint16_t statuses[21];
float positions[21];
float velocities[21];
float currents[21];
uint16_t errors[21];
};
struct CRevo3TouchData {
uint16_t summary[42];
uint16_t modules[11][REVO3_TOUCH_MAX_POINTS];
uint16_t module_counts[11];
};
struct CDeviceConfig {
StarkProtocolType protocol;
const char *port_name;
uint32_t baudrate;
uint8_t slave_id;
};
/// ZQWL device info struct (C interface)
struct CZqwlDeviceInfo {
/// Device type (0x0100=dual-channel CANFD, 0x0101=single-channel CANFD, 0x0102=dual-channel CAN, etc.)
uint16_t device_type;
/// Serial port name
char *port_name;
/// USB VID
uint16_t vid;
/// USB PID
uint16_t pid;
/// Whether CANFD is supported
bool supports_canfd;
/// Number of channels
uint8_t channel_count;
};
/// ZQWL device list struct (C interface)
struct ZqwlDeviceList {
/// Device array pointer
CZqwlDeviceInfo *devices;
/// Device count
uintptr_t count;
};
/// SocketCAN device info struct (C interface)
struct CSocketCanDeviceInfo {
/// Interface name (e.g. "can0")
char *iface;
/// Whether CANFD is supported
bool supports_canfd;
/// Whether interface is up
bool is_up;
};
/// SocketCAN device list struct (C interface)
struct SocketCanDeviceList {
/// Device array pointer
CSocketCanDeviceInfo *devices;
/// Device count
uintptr_t count;
};
/// Detected device information (C interface)
struct CDetectedDevice {
/// Protocol type
StarkProtocolType protocol;
/// Port name (serial port or CAN adapter port)
char *port_name;
/// Slave ID on the bus
uint8_t slave_id;
/// Baudrate (for Modbus/serial protocols, or CAN arbitration baudrate)
uint32_t baudrate;
/// Data baudrate (for CANFD only, 0 for other protocols)
uint32_t data_baudrate;
/// Hardware type
StarkHardwareType hardware_type;
/// SKU type
SkuType sku_type;
/// Serial number (NULL if not detected)
char *serial_number;
/// Firmware version (NULL if not detected)
char *firmware_version;
};
/// Detected device list (C interface)
struct CDetectedDeviceList {
/// Device array pointer
CDetectedDevice *devices;
/// Device count
uintptr_t count;
};
/// Modbus async read/write result callback.
/// This callback processes results of asynchronous Modbus operations.
/// Return value: 0 on success, non‑zero on failure.
using ModbusOperationResultCallback = void(*)(uint8_t*, int, int, void*);
/// Modbus async read/write callback type.
/// Return value: 0 on success, non‑zero on failure.
using ModbusOperationCallback = int32_t(*)(const uint8_t *values,
int len,
ModbusOperationResultCallback callback,
void *user_data);
/// Custom Modbus RX callback.
/// Return value: 0 on success, non‑zero on failure.
using ModbusRxCallback = int32_t(*)(uint8_t slave_id,
uint16_t register_address,
uint16_t *data_out,
uint16_t count);
/// Custom Modbus TX callback.
/// Return value: 0 on success, non‑zero on failure.
using ModbusTxCallback = int32_t(*)(uint8_t slave_id,
uint16_t register_address,
const uint16_t *data,
uint16_t count);
/// CANFD RX callback.
///
/// # Parameters
/// - `slave_id`: Slave ID
/// - `expected_can_id`: Expected CANFD ID; matches by slave_id and master_id
/// - `expected_frames`: `0` = auto-detect multi-frame, `> 0` = specific frame count
/// - `can_id_out`: Output CAN ID
/// - `data_out`: Output data buffer (at least 512 bytes for multi-frame)
/// - `data_len_out`: Output data length
///
/// # Return value
/// 0 on success, non‑zero on failure.
using CanRxCallback = int32_t(*)(uint8_t slave_id,
uint32_t expected_can_id,
uint8_t expected_frames,
uint32_t *can_id_out,
uint8_t *data_out,
uintptr_t *data_len_out);
/// CANFD TX callback.
/// Return value: 0 on success, non‑zero on failure.
using CanTxCallback = int32_t(*)(uint8_t slave_id,
uint32_t can_id,
const uint8_t *data,
uintptr_t data_len);
/// DFU state callback, `state` corresponds to `DfuState`.
using DfuStateCallback = void(*)(uint8_t slave_id, uint8_t state);
/// DFU progress callback.
using DfuProgressCallback = void(*)(uint8_t slave_id, float progress);
struct CDeviceInfo {
SkuType sku_type;
HandType hand_type;
StarkHardwareType hardware_type;
const char *serial_number;
const char *firmware_version;
const char *hardware_version;
};
/// Revo3 system status data (C-compatible).
struct CRevo3SystemStatus {
uint8_t system_state;
uint8_t error_code;
uint16_t current_ma;
uint16_t voltage_v;
uint16_t power_w;
uint16_t temperature_c;
};
extern "C" {
CRevo3MotorStatusBuffer *revo3_motor_buffer_new(uintptr_t max_size);
void revo3_motor_buffer_free(CRevo3MotorStatusBuffer *buffer);
int revo3_motor_buffer_pop_all(CRevo3MotorStatusBuffer *buffer,
CRevo3MotorStatusData *out_data,
uintptr_t max_count);
uintptr_t revo3_motor_buffer_len(const CRevo3MotorStatusBuffer *buffer);
void revo3_motor_buffer_clear(CRevo3MotorStatusBuffer *buffer);
int revo3_get_all_touch_data(DeviceHandler *handle,
unsigned char slave_id,
CRevo3TouchData *out_data);
CRevo3TouchDataBuffer *revo3_touch_buffer_new(uintptr_t max_size);
void revo3_touch_buffer_free(CRevo3TouchDataBuffer *buffer);
int revo3_touch_buffer_pop_all(CRevo3TouchDataBuffer *buffer,
CRevo3TouchData *out_data,
uintptr_t max_count);
uintptr_t revo3_touch_buffer_len(const CRevo3TouchDataBuffer *buffer);
void revo3_touch_buffer_clear(CRevo3TouchDataBuffer *buffer);
CDataCollector *data_collector_new_revo3_basic(DeviceHandler *handle,
CRevo3MotorStatusBuffer *motor_buffer,
unsigned char slave_id,
uint32_t motor_frequency,
int enable_stats);
CDataCollector *data_collector_new_revo3_full(DeviceHandler *handle,
CRevo3MotorStatusBuffer *motor_buffer,
CRevo3TouchDataBuffer *touch_buffer,
unsigned char slave_id,
uint32_t motor_frequency,
uint32_t touch_frequency,
int enable_stats);
int data_collector_start(CDataCollector *collector);
int data_collector_stop(CDataCollector *collector);
int data_collector_wait(CDataCollector *collector);
int data_collector_is_running(const CDataCollector *collector);
void data_collector_free(CDataCollector *collector);
/// Initialize SDK logging.
/// log_level: Log level (Debug, Info, Warn, Error). Default is Info.
void init_logging(LogLevel log_level);
/// List all available Stark serial ports.
void list_available_ports();
/// Automatically detect a Revo3 device on a serial port.
/// port: Serial port name; when NULL, the function will auto‑detect ports.
/// quick: Whether to use quick detection. Default is true, which only checks
/// a subset of baudrates and slave IDs.
/// Returns a pointer to `DeviceConfig` (protocol, port, baudrate, slave ID);
/// call `free_device_config` to free the memory.
/// On failure, returns NULL.
/// Note: When `quick` is false, this function scans slave IDs in [1, 247],
/// which may take a long time.
///
/// @deprecated Use `stark_auto_detect` + `init_from_detected` instead for better
/// multi-protocol support (Modbus, CANFD).
CDeviceConfig *auto_detect_device(const char *port, bool quick);
/// Automatically detect a Revo3 hand over Modbus.
/// port: Serial port name; when NULL, the function will auto‑detect ports.
/// Revo3 uses 5Mbps baudrate and slave_id 1.
/// Returns a pointer to `DeviceConfig` (protocol, port, baudrate, slave ID);
/// call `free_device_config` to free the memory.
/// On failure, returns NULL.
CDeviceConfig *auto_detect_modbus_revo3(const char *port);
/// Open a serial port.
/// port: Serial port name, for example "/dev/ttyUSB0" or "COM1".
/// baudrate: Revo3 RS485 baud rate. 5 Mbps is the default factory setting.
/// Returns a pointer to `DeviceHandler`; call `modbus_close` to free it.
/// On failure, returns NULL.
DeviceHandler *modbus_open(const char *port, uint32_t baudrate);
/// Close serial port
void modbus_close(DeviceHandler *handle);
/// @brief Create a device handler with specified protocol and optional master ID.
/// @param protocol_type Protocol type (Modbus, CanFd, EtherCAT)
/// @param master_id Master ID (required for CanFd and EtherCAT, 0 for others)
/// @return Pointer to the newly created `DeviceHandler`. Call
/// `close_device_handler` to release it.
DeviceHandler *init_device_handler(StarkProtocolType protocol_type, uint8_t master_id);
/// @brief Create a device handler for CANFD protocol.
///
/// This function creates a device handler and stores the CAN baudrate information.
///
/// @param protocol_type Protocol type (STARK_PROTOCOL_TYPE_CAN_FD)
/// @param master_id Master ID (typically 1)
/// @param arb_baudrate Arbitration baudrate in bps (e.g., 1000000 for 1 Mbps)
/// @param data_baudrate Data baudrate in bps
/// @return Pointer to the newly created `DeviceHandler`. Call
/// `close_device_handler` to release it.
DeviceHandler *init_device_handler_can(StarkProtocolType protocol_type,
uint8_t master_id,
uint32_t arb_baudrate,
uint32_t data_baudrate);
/// @brief Create a device handler for CANFD protocol with hardware type pre-set.
///
/// @param protocol_type Protocol type (STARK_PROTOCOL_TYPE_CAN_FD)
/// @param master_id Master ID (typically 1)
/// @param slave_id Slave ID to set hardware type for
/// @param arb_baudrate Arbitration baudrate in bps (e.g., 1000000 for 1 Mbps)
/// @param data_baudrate Data baudrate in bps
/// @param hw_type Hardware type (StarkHardwareType enum value)
/// @return Pointer to the newly created `DeviceHandler`. Call
/// `close_device_handler` to release it.
DeviceHandler *init_device_handler_can_with_hw_type(StarkProtocolType protocol_type,
uint8_t master_id,
uint8_t slave_id,
uint32_t arb_baudrate,
uint32_t data_baudrate,
StarkHardwareType hw_type);
/// @brief Create a device handler with hardware type pre-set.
///
/// This is useful when you already know the hardware type (e.g., from auto_detect)
/// and want to avoid an extra get_device_info call.
///
/// @param protocol_type Protocol type (Modbus, CanFd, EtherCAT)
/// @param master_id Master ID (required for CanFd and EtherCAT, 0 for others)
/// @param slave_id Slave ID to set hardware type for
/// @param hw_type Hardware type (StarkHardwareType enum value)
/// @return Pointer to the newly created `DeviceHandler`. Call
/// `close_device_handler` to release it.
DeviceHandler *init_device_handler_with_hw_type(StarkProtocolType protocol_type,
uint8_t master_id,
uint8_t slave_id,
StarkHardwareType hw_type);
/// List all ZQWL USB CANFD-capable devices
///
/// Returns device list pointer. Call `free_zqwl_device_list` to free memory after use.
/// Returns list with count=0 if no devices found.
///
/// @note This is a low-level API. Recommend using high-level API `stark_auto_detect` + `init_from_detected`
/// for automatic device detection and initialization. Low-level API is for advanced users
/// who need manual control of CAN adapter.
ZqwlDeviceList *list_zqwl_devices();
/// Free ZQWL device list memory
void free_zqwl_device_list(ZqwlDeviceList *list);
/// Initialize ZQWL CANFD device
///
/// Revo3 default arbitration baudrate is 1 Mbps; data baudrate is 5 Mbps.
///
/// @param port_name Serial port name
/// @param arb_baudrate Arbitration baudrate (bps), typically 1000000
/// @param data_baudrate Data baudrate (bps), typically 5000000
/// @return 0: success, -1: failure
///
/// @note This is a low-level API. Recommend using high-level API `stark_auto_detect` + `init_from_detected`
/// for automatic device detection and initialization. Low-level API is for advanced users
/// who need manual control of CAN adapter.
int init_zqwl_canfd(const char *port_name,
uint32_t arb_baudrate,
uint32_t data_baudrate);
/// Close ZQWL CANFD device
///
/// @note This is a low-level API. If device was initialized with `init_from_detected`,
/// use `close_device_handler` instead, which automatically handles ZQWL resource cleanup.
void close_zqwl();
/// List all SocketCAN interfaces (Linux only)
///
/// Scans /sys/class/net/ for CAN interfaces.
/// Returns device list pointer. Call `free_socketcan_device_list` to free memory.
/// Returns list with count=0 on non-Linux platforms or if no interfaces found.
SocketCanDeviceList *list_socketcan_devices();
/// Free SocketCAN device list memory
void free_socketcan_device_list(SocketCanDeviceList *list);
/// Initialize SocketCAN CANFD device (Linux only)
///
/// @param iface Interface name (e.g. "can0"). If NULL, uses STARK_SOCKETCAN_IFACE env var or "can0"
/// @return 0: success, -1: failure (or non-Linux platform)
int init_socketcan_canfd(const char *iface);
/// Close SocketCAN device (Linux only)
void close_socketcan();
/// Check if a SocketCAN interface is available and up (Linux only)
///
/// @param iface Interface name (e.g. "can0")
/// @return true if interface exists and is up, false otherwise
bool is_socketcan_available(const char *iface);
/// Auto-detect Revo3 devices across supported protocols.
///
/// Scans for devices in priority order:
/// 1. CANFD adapters (BrainCo/ZQWL/SocketCAN)
/// 2. Modbus/RS485 (5 Mbps; IDs 1, 2, 0x7E, 0x7F)
///
/// When a specific protocol is requested, only that protocol is scanned.
///
/// # Parameters
/// - scan_all: If true, scan for all devices. If false, stop at first found.
/// - port: Optional port name to scan. If NULL, scans all available ports.
/// - protocol: Protocol filter:
/// - STARK_PROTOCOL_TYPE_AUTO: Auto-detect all protocols (recommended)
/// - STARK_PROTOCOL_TYPE_MODBUS: Modbus only
/// - STARK_PROTOCOL_TYPE_CAN_FD: CANFD only
///
/// # Returns
/// Pointer to CDetectedDeviceList. Call `free_detected_device_list` to free.
/// Returns empty list (count=0) if no devices found.
CDetectedDeviceList *stark_auto_detect(bool scan_all, const char *port, StarkProtocolType protocol);
/// Free detected device list memory
void free_detected_device_list(CDetectedDeviceList *list);
/// Initialize device handler from detected device info.
///
/// This function initializes the appropriate transport (Modbus, CANFD)
/// based on the detected device's protocol and returns a ready-to-use handler.
///
/// # Parameters
/// - device: Pointer to CDetectedDevice from stark_auto_detect()
///
/// # Returns
/// - Pointer to DeviceHandler on success
/// - NULL on failure
///
/// # Notes
/// - For CANFD: Initializes BrainCo/ZQWL/SocketCAN adapter automatically
/// - For Modbus: Opens serial port with detected baudrate
/// - Call `close_from_detected` to cleanup
DeviceHandler *init_from_detected(const CDetectedDevice *device);
/// Close device handler based on protocol type.
///
/// Convenience function that handles cleanup for any protocol type.
/// Automatically closes CANFD adapters when needed.
///
/// # Parameters
/// - handle: Device handler to close
/// - protocol: Protocol type (from CDetectedDevice.protocol)
void close_device_handler(DeviceHandler *handle, uint8_t protocol);
/// Configure SDO for an EtherCAT slave device.
void ethercat_setup_sdo(DeviceHandler *handle, uint16_t slave_pos);
void ethercat_reserve_master(DeviceHandler *handle);
/// Start EtherCAT cyclic loop with PDO communication (control & read).
/// dc_assign_activate: DC flags; 0x0000 means DC is not enabled.
/// sync0_cycle_time: SYNC0 cycle time in nanoseconds. The loop period matches
/// SYNC0 cycle time.
/// sync0_shift_time: SYNC0 phase shift in nanoseconds.
/// sync1_cycle_time: SYNC1 cycle time in nanoseconds.
/// sync1_shift_time: SYNC1 phase shift in nanoseconds.
void ethercat_start_loop(DeviceHandler *handle,
const uint16_t *slave_positions,
int count,
uint16_t dc_assign_activate,
uint32_t sync0_cycle_time,
int32_t sync0_shift_time,
uint32_t sync1_cycle_time,
int32_t sync1_shift_time);
/// Stop the EtherCAT cyclic loop.
void ethercat_stop_loop(DeviceHandler *handle);
/// EtherCAT DFU: upgrade firmware via FoE protocol.
/// slave_pos: Slave position.
/// dfu_type: DFU type, Control or Wrist.
/// file_path: Firmware file path.
void ethercat_start_dfu(DeviceHandler *handle,
uint16_t slave_pos,
EtherCATFoeType dfu_type,
const char *file_path);
/// Set Modbus async read/write callback.
void set_modbus_operation_callback(ModbusOperationCallback cb);
/// Set Modbus read callback for input registers.
void set_modbus_read_input_callback(ModbusRxCallback cb);
/// Set Modbus read callback for holding registers.
void set_modbus_read_holding_callback(ModbusRxCallback cb);
/// Set Modbus write callback.
void set_modbus_write_callback(ModbusTxCallback cb);
/// Set CAN/CANFD RX callback.
void set_can_rx_callback(CanRxCallback cb);
/// Set CAN/CANFD TX callback.
void set_can_tx_callback(CanTxCallback cb);
/// Set DFU state callback.
void set_dfu_state_callback(DfuStateCallback cb);
/// Set DFU progress callback.
void set_dfu_progress_callback(DfuProgressCallback cb);
/// Get device information.
/// Returns a pointer to `DeviceInfo`; you must call `free_device_info` to free
/// it. Returns NULL on failure.
///
/// NOTE: Hardware type is determined by Revo3 SN prefix. If the SN is not
/// recognized, hardware_type defaults to Revo3Ultra.
CDeviceInfo *stark_get_device_info(DeviceHandler *handle, uint8_t slave_id);
/// Revo3-prefixed alias for `stark_get_device_info`.
CDeviceInfo *revo3_get_device_info(DeviceHandler *handle, uint8_t slave_id);
/// Free device info returned by `stark_get_device_info`.
void free_device_info(CDeviceInfo *info);
/// Get Revo3 device serial number string.
/// Returns a C string pointer; call `free_string` to release.
/// Returns NULL on failure.
const char *revo3_get_serial_number(DeviceHandler *handle, uint8_t slave_id);
/// Revo3-prefixed alias for `revo3_get_serial_number`.
const char *revo3_get_device_sn(DeviceHandler *handle, uint8_t slave_id);
/// Get Revo3 firmware version string.
/// Returns a C string pointer; call `free_string` to release.
/// Returns NULL on failure.
const char *revo3_get_firmware_version(DeviceHandler *handle, uint8_t slave_id);
/// Revo3-prefixed alias for `revo3_get_firmware_version`.
const char *revo3_get_device_fw_version(DeviceHandler *handle, uint8_t slave_id);
/// Get Revo3 hand type mapped to SkuType-compatible value.
/// Returns the enum value or -1 on failure.
int revo3_get_hand_type(DeviceHandler *handle, uint8_t slave_id);
/// Check if the configured hardware type uses the Revo3 motor API.
bool revo3_uses_motor_api(DeviceHandler *handle, uint8_t slave_id);
/// Set hardware type for a specific slave device.
///
/// Use this to manually override the hardware type when SN-based auto-detection
/// in `stark_get_device_info()` returns an incorrect result.
///
/// Can also be used to modify `CDetectedDevice.hardware_type` before calling
/// `init_from_detected()`, or to override after initialization.
///
/// # Parameters
/// - handle: Device handler
/// - slave_id: The slave ID
/// - hw_type: StarkHardwareType enum value
void stark_set_hardware_type(DeviceHandler *handle, uint8_t slave_id, StarkHardwareType hw_type);
/// Read holding registers (fast, no retry).
/// address: Start register address.
/// count: Number of registers to read.
/// out_data: Pointer to array to store data (caller must allocate enough space).
/// Returns 0 on success, -1 on failure.
int32_t stark_read_holding_registers(DeviceHandler *handle,
uint8_t slave_id,
uint16_t address,
uint16_t count,
uint16_t *out_data);
/// Read input registers (fast, no retry).
/// address: Start register address.
/// count: Number of registers to read.
/// out_data: Pointer to array to store data (caller must allocate enough space).
/// Returns 0 on success, -1 on failure.
int32_t stark_read_input_registers(DeviceHandler *handle,
uint8_t slave_id,
uint16_t address,
uint16_t count,
uint16_t *out_data);
/// Get the protocol type of the device handler.
/// Returns: StarkProtocolType enum value:
/// - STARK_PROTOCOL_TYPE_MODBUS = 1
/// - STARK_PROTOCOL_TYPE_CAN_FD = 3
/// - STARK_PROTOCOL_TYPE_ETHER_CAT = 4
StarkProtocolType stark_get_protocol_type(DeviceHandler *handle);
/// Get the serial port name of the device handler.
/// Returns: Port name string (e.g., "/dev/ttyUSB0" or "COM3"), or NULL if not available.
/// The returned string is owned by the DeviceHandler and should not be freed.
/// For CAN/CANFD protocols, this may return an empty string.
const char *stark_get_port_name(DeviceHandler *handle);
/// Get the baudrate of the device handler.
/// Returns: Baudrate in bps (e.g., 115200, 460800), or 0 if not applicable.
/// For Modbus: returns serial baudrate
/// For CANFD/EtherCAT: returns 0 (use stark_get_can_arb_baudrate/stark_get_can_data_baudrate instead)
///
/// Note: This function only returns serial port baudrate.
/// For CAN baudrate information, use:
/// - stark_get_can_arb_baudrate() - Get CAN arbitration baudrate
/// - stark_get_can_data_baudrate() - Get CAN data baudrate (CANFD only)
uint32_t stark_get_baudrate(DeviceHandler *handle);
/// Get the CAN arbitration baudrate.
/// Returns: CANFD arbitration baudrate in bps (e.g., 1000000 for 1 Mbps), or 0 if not CANFD protocol.
uint32_t stark_get_can_arb_baudrate(DeviceHandler *handle);
/// Get the CAN data baudrate.
/// Returns: CANFD data phase baudrate in bps (e.g., 5000000 for 5 Mbps), or 0 if not CANFD protocol.
uint32_t stark_get_can_data_baudrate(DeviceHandler *handle);
/// Get Revo3 touch sensor vendor type.
/// Returns: 0=Unknown, 2=Pressure.
uint8_t stark_get_touch_vendor(DeviceHandler *handle, uint8_t slave_id);
/// Enter Revo3 OTA mode.
void revo3_enter_ota(DeviceHandler *handle, uint8_t slave_id);
/// Start Revo3 DFU.
/// file_path: Path to the firmware file.
/// wait_secs: Seconds to wait after sending enter OTA command. Use 0 for default.
int32_t revo3_start_dfu(DeviceHandler *handle,
uint8_t slave_id,
const char *file_path,
uintptr_t wait_secs);
/// Start Revo3 DFU with target type (V1.1+).
/// file_path: Path to the firmware file.
/// target: Upgrade target (0=MainFw, 1=Image, 2=MotorFw).
/// wait_secs: Seconds to wait after sending enter OTA command. Use 0 for default.
int32_t revo3_start_dfu_with_target(DeviceHandler *handle,
uint8_t slave_id,
const char *file_path,
uint8_t target,
uintptr_t wait_secs);
/// Start Revo3 Main Board MCU firmware upgrade (V1.1+).
/// file_path: Path to the firmware file.
/// wait_secs: Seconds to wait after sending enter OTA command. Use 0 for default.
int32_t revo3_start_mcu_dfu(DeviceHandler *handle,
uint8_t slave_id,
const char *file_path,
uintptr_t wait_secs);
/// Start Revo3 Image resource pack upgrade (V1.1+).
/// file_path: Path to the image resource pack file.
/// wait_secs: Seconds to wait. Use 0 for default.
int32_t revo3_start_image_dfu(DeviceHandler *handle,
uint8_t slave_id,
const char *file_path,
uintptr_t wait_secs);
/// Start Revo3 Motor board firmware upgrade (V1.1+).
/// file_path: Path to the motor firmware file.
/// wait_secs: Seconds to wait. Use 0 for default.
int32_t revo3_start_motor_dfu(DeviceHandler *handle,
uint8_t slave_id,
const char *file_path,
uintptr_t wait_secs);
/// Stop Revo3 DFU.
void revo3_stop_dfu(uint8_t slave_id);
/// Abort Revo3 DFU.
void revo3_abort_dfu(uint8_t slave_id);
/// Reset Revo3 DFU state.
void revo3_reset_dfu_state(uint8_t slave_id);
/// Enable/disable a single Revo3 touch module.
/// module_id: 0=Palm, 1=ThumbTip, 2=ThumbPad, ... 10=PinkyPad
void revo3_set_touch_module_enabled(DeviceHandler *handle,
uint8_t slave_id,
uint8_t module_id,
bool enabled);
/// Read whether a single Revo3 touch module is enabled.
/// Returns 1 if enabled, 0 if disabled, -1 on failure.
int revo3_get_touch_module_enabled(DeviceHandler *handle, uint8_t slave_id, uint8_t module_id);
/// Set target position for a single Revo3 motor (degrees).
void revo3_set_motor_position(DeviceHandler *handle,
uint8_t slave_id,
uint16_t motor_id,
float position_deg);
/// Set target current for a single Revo3 motor (mA).
void revo3_set_motor_current(DeviceHandler *handle,
uint8_t slave_id,
uint16_t motor_id,
float current);
/// Full MIT mode control for a single Revo3 motor.
/// τ = Kp * (P_des - P_actual) + Kd * (V_des - V_actual) + T_ff
void revo3_set_motor_mit(DeviceHandler *handle,
uint8_t slave_id,
uint16_t motor_id,
float position_deg,
float velocity,
float current,
float kp,
float kd);
/// Set all 21 Revo3 motor positions at once (degrees).
/// `positions` must point to an array of at least 21 f32 values.
void revo3_set_all_motor_positions(DeviceHandler *handle, uint8_t slave_id, const float *positions);
/// Set target velocity for a single Revo3 motor (RPM).
void revo3_set_motor_velocity(DeviceHandler *handle,
uint8_t slave_id,
uint16_t motor_id,
float velocity);
/// Set all 21 Revo3 motor velocities at once (RPM).
/// `velocities` must point to an array of at least 21 f32 values.
void revo3_set_all_motor_velocities(DeviceHandler *handle,
uint8_t slave_id,
const float *velocities);
/// Set all 21 Revo3 motor currents at once (mA).
/// `currents` must point to an array of at least 21 f32 values.
void revo3_set_all_motor_currents(DeviceHandler *handle, uint8_t slave_id, const float *currents);
/// Clear all Revo3 motor error states.
void revo3_clear_motor_errors(DeviceHandler *handle, uint8_t slave_id);
/// Set Revo3 calibration current.
void revo3_set_calibration_current(DeviceHandler *handle, uint8_t slave_id, float current);
/// Trigger Revo3 manual zero calibration.
void revo3_manual_calibration(DeviceHandler *handle, uint8_t slave_id);
/// Enable or disable Revo3 auto calibration on power-up.
void revo3_set_auto_calibration(DeviceHandler *handle, uint8_t slave_id, bool enabled);
/// Set Revo3 max continuous current.
void revo3_set_max_continuous_current(DeviceHandler *handle, uint8_t slave_id, float current);
/// Read complete Revo3 motor status data.
/// Returns NULL on failure. Call `free_revo3_motor_status_data` to release.
CRevo3MotorStatusData *revo3_get_motor_status_data(DeviceHandler *handle, uint8_t slave_id);
/// Read all 21 Revo3 motor positions (degrees).
/// `out_positions` must point to an array of at least 21 f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_get_all_motor_positions(DeviceHandler *handle, uint8_t slave_id, float *out_positions);
/// Check if hardware type uses Revo3 motor API.
bool stark_uses_revo3_motor_api(uint8_t hw_type);
/// Read all 21 Revo3 motor velocities.
/// `out_velocities` must point to an array of at least 21 f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_get_all_motor_velocities(DeviceHandler *handle, uint8_t slave_id, float *out_velocities);
/// Read all 21 Revo3 motor currents.
/// `out_currents` must point to an array of at least 21 f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_get_all_motor_currents(DeviceHandler *handle, uint8_t slave_id, float *out_currents);
/// Read all 21 Revo3 motor error codes.
/// `out_errors` must point to an array of at least 21 u16 values.
/// Returns 0 on success, -1 on failure.
int revo3_get_all_motor_errors(DeviceHandler *handle, uint8_t slave_id, uint16_t *out_errors);
/// Free Revo3 motor status data returned by `revo3_get_motor_status_data`.
void free_revo3_motor_status_data(CRevo3MotorStatusData *data);
/// Read all 21 Revo3 motor status codes.
/// `out_statuses` must point to an array of at least 21 u16 values.
/// Returns 0 on success, -1 on failure.
int revo3_get_all_motor_status(DeviceHandler *handle, uint8_t slave_id, uint16_t *out_statuses);
/// Set all Revo3 touch modules enabled/disabled via bitmask.
/// Bits 0~10 correspond to modules 0~10.
void revo3_set_all_touch_modules_enabled(DeviceHandler *handle,
uint8_t slave_id,
uint16_t enabled_bits);
/// Set Revo3 touch data output type.
/// data_type: 0=Pressure Array, 1=Force Summary
void revo3_set_touch_data_type(DeviceHandler *handle, uint8_t slave_id, uint16_t data_type);
/// Read Revo3 touch data output type.
/// Returns 0=Pressure Array, 1=Force Summary, or -1 on failure.
int revo3_get_touch_data_type(DeviceHandler *handle, uint8_t slave_id);
/// Read Revo3 touch summary (42 pad force values).
/// `out_summary` must point to an array of at least 42 u16 values.
/// Returns 0 on success, -1 on failure.
int revo3_get_touch_summary(DeviceHandler *handle, uint8_t slave_id, uint16_t *out_summary);
/// Read Revo3 touch module pressure data.
/// `out_data` must point to a buffer large enough (at least 57 u16 for the largest module).
/// `out_count` will be set to the number of values written.
/// Returns 0 on success, -1 on failure.
int revo3_get_touch_module_data(DeviceHandler *handle,
uint8_t slave_id,
uint8_t module_id,
uint16_t *out_data,
uint16_t *out_count);
/// Single joint control.
/// mode: ControlMode (0=Position, 2=Current, 4=Impedance, 5=Damping)
void revo3_single_joint_control(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
uint16_t mode,
float param);
/// Multi-joint synchronous control (21 joints).
/// `params` must point to an array of at least 21 f32 values.
void revo3_multi_joint_control(DeviceHandler *handle,
uint8_t slave_id,
uint16_t mode,
const float *params);
/// Grouped MIT params: set all 21 Kp values (registers 1300–1320).
/// `kp_values` must point to at least 21 f32 values.
void revo3_set_all_mit_kp(DeviceHandler *handle, uint8_t slave_id, const float *kp_values);
/// Grouped MIT params: set all 21 Kd values.
/// `kd_values` must point to at least 21 f32 values.
void revo3_set_all_mit_kd(DeviceHandler *handle, uint8_t slave_id, const float *kd_values);
/// Grouped MIT params: set all 21 position values.
/// `positions` must point to at least 21 f32 values.
void revo3_set_all_mit_positions(DeviceHandler *handle, uint8_t slave_id, const float *positions);
/// Grouped MIT params: set all 21 velocity values.
/// `velocities` must point to at least 21 f32 values.
void revo3_set_all_mit_velocities(DeviceHandler *handle, uint8_t slave_id, const float *velocities);
/// Grouped MIT params: set all 21 torque values (mA).
/// `torques` must point to at least 21 f32 values.
void revo3_set_all_mit_torques(DeviceHandler *handle, uint8_t slave_id, const float *torques);
/// Move a single joint using quintic polynomial trajectory (Non-blocking).
/// Returns 0 on success, -1 on failure.
int revo3_move_joint(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float target_pos,
float duration,
float dt);
/// Move a single joint using quintic polynomial trajectory and block until completion.
/// Returns 0 on success, -1 on failure.
int revo3_move_joint_wait(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float target_pos,
float duration,
float dt);
/// Move a single joint with custom Kp/Kd gains (Non-blocking).
/// Returns 0 on success, -1 on failure.
int revo3_move_joint_with_gains(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float target_pos,
float duration,
float dt,
float kp,
float kd);
/// Move a single joint with custom Kp/Kd gains and block until completion.
/// Returns 0 on success, -1 on failure.
int revo3_move_joint_with_gains_wait(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float target_pos,
float duration,
float dt,
float kp,
float kd);
/// Move a single joint to `target_pos` with a specified `speed` (rpm) (Non-blocking).
/// Returns 0 on success, -1 on failure.
int revo3_move_joint_with_speed(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float target_pos,
float speed,
float dt);
/// Move a single joint to `target_pos` with a specified `speed` (rpm) and wait until completed (Blocking).
/// Returns 0 on success, -1 on failure.
int revo3_move_joint_with_speed_wait(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float target_pos,
float speed,
float dt);
/// Move a single joint with a specified `speed` (rpm) and custom Kp/Kd gains (Non-blocking).
/// Returns 0 on success, -1 on failure.
int revo3_move_joint_with_speed_and_gains(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float target_pos,
float speed,
float dt,
float kp,
float kd);
/// Move a single joint with a specified `speed` (rpm) and custom Kp/Kd gains and wait until completed (Blocking).
/// Returns 0 on success, -1 on failure.
int revo3_move_joint_with_speed_and_gains_wait(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float target_pos,
float speed,
float dt,
float kp,
float kd);
/// Move all joints using quintic polynomial trajectories (Non-blocking).
/// `target_positions` must point to an array of `num_joints` f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_move_hand(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
uint16_t num_joints,
float duration,
float dt);
/// Move all joints using quintic polynomial trajectories and block until completion.
/// `target_positions` must point to an array of `num_joints` f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_move_hand_wait(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
uint16_t num_joints,
float duration,
float dt);
/// Move all joints with custom Kp/Kd gains (Non-blocking).
/// `target_positions` must point to an array of `num_joints` f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_move_hand_with_gains(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
uint16_t num_joints,
float duration,
float dt,
float kp,
float kd);
/// Move all joints with custom Kp/Kd gains and block until completion.
/// `target_positions` must point to an array of `num_joints` f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_move_hand_with_gains_wait(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
uint16_t num_joints,
float duration,
float dt,
float kp,
float kd);
/// Move all joints to `target_positions` with a uniform `speed` (rpm) (Non-blocking).
/// `target_positions` must point to an array of `num_joints` f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_move_hand_with_speed(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
uint16_t num_joints,
float speed,
float dt);
/// Move all joints to `target_positions` with a uniform `speed` (rpm) and block until completion.
/// `target_positions` must point to an array of `num_joints` f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_move_hand_with_speed_wait(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
uint16_t num_joints,
float speed,
float dt);
/// Move all joints with uniform `speed` and custom Kp/Kd gains (Non-blocking).
/// `target_positions` must point to an array of `num_joints` f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_move_hand_with_speed_and_gains(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
uint16_t num_joints,
float speed,
float dt,
float kp,
float kd);
/// Move all joints with uniform `speed` and custom Kp/Kd gains and block until completion.
/// `target_positions` must point to an array of `num_joints` f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_move_hand_with_speed_and_gains_wait(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
uint16_t num_joints,
float speed,
float dt,
float kp,
float kd);
/// Get all 21 motor temperatures.
/// `out_temps` must point to an array of at least 21 u16 values.
/// Returns 0 on success, -1 on failure.
int revo3_get_all_motor_temperatures(DeviceHandler *handle, uint8_t slave_id, uint16_t *out_temps);
/// Set global protection current (mA).
void revo3_set_global_protect_current(DeviceHandler *handle, uint8_t slave_id, float current_ma);
/// Enable or disable software e-stop.
void revo3_set_software_e_stop(DeviceHandler *handle, uint8_t slave_id, bool enabled);
/// Get broadcast ID usage state. Returns 1 for true, 0 for false, -1 on error.
int revo3_get_use_broadcast_id(DeviceHandler *handle, uint8_t slave_id);
/// Enable or disable using the broadcast ID.
void revo3_set_use_broadcast_id(DeviceHandler *handle, uint8_t slave_id, bool enabled);
/// Get auto calibration state. Returns 1 for true, 0 for false, -1 on error.
int revo3_get_auto_calibration(DeviceHandler *handle, uint8_t slave_id);
/// Get global protection current (mA). Returns 0 on success, -1 on error.
int revo3_get_global_protect_current(DeviceHandler *handle, uint8_t slave_id, float *out_current);
/// Get per-joint protection currents for all 21 joints (mA).
/// `out_currents` must point to an array of at least 21 f32 values.
/// Returns 0 on success, -1 on error.
int revo3_get_all_joint_protect_currents(DeviceHandler *handle,
uint8_t slave_id,
float *out_currents);
/// Get per-joint position limits for all 21 joints.
/// `out_min_positions` and `out_max_positions` must point to arrays of at least 21 f32 values.
/// Returns 0 on success, -1 on error.
int revo3_get_all_joint_position_limits(DeviceHandler *handle,
uint8_t slave_id,
float *out_min_positions,
float *out_max_positions);
/// Get per-joint speed limits for all 21 joints.
/// `out_min_speeds` and `out_max_speeds` must point to arrays of at least 21 f32 values.
/// Returns 0 on success, -1 on error.
int revo3_get_all_joint_speed_limits(DeviceHandler *handle,
uint8_t slave_id,
float *out_min_speeds,
float *out_max_speeds);
/// Get max continuous current (mA). Returns 0 on success, -1 on error.
int revo3_get_max_continuous_current(DeviceHandler *handle, uint8_t slave_id, float *out_current);
/// Get auto clear motor errors state. Returns 1 for true, 0 for false, -1 on error.
int revo3_get_auto_clear_motor_error(DeviceHandler *handle, uint8_t slave_id);
/// Enable or disable auto clear motor errors.
void revo3_set_auto_clear_motor_error(DeviceHandler *handle, uint8_t slave_id, bool enabled);
/// Get teaching mode state. Returns 1 for true, 0 for false, -1 on error.
int revo3_get_teaching_mode(DeviceHandler *handle, uint8_t slave_id);
/// Enter or exit teaching mode.
void revo3_set_teaching_mode(DeviceHandler *handle, uint8_t slave_id, bool enabled);
/// Get touch screen switch state. Returns 1 for true, 0 for false, -1 on error.
int revo3_get_touch_screen(DeviceHandler *handle, uint8_t slave_id);
/// Enable or disable the touch screen switch.
void revo3_set_touch_screen(DeviceHandler *handle, uint8_t slave_id, bool enabled);
/// Reset finger parameters to defaults.
void revo3_reset_finger_defaults(DeviceHandler *handle, uint8_t slave_id);
/// Set the zero position with explicit motor offsets (degrees).
///
/// `offsets_deg` must point to an array containing exactly 21 f32 degree offset
/// values, which are written to registers starting from 60.
void revo3_set_zero_position(DeviceHandler *handle, uint8_t slave_id, const float *offsets_deg);
/// Set the current position as zero calibration.
///
/// Recommended Calibration Workflow:
/// 1. Disable the motors to allow free manual movements of the fingers.
/// 2. Manually pose the hand into the desired zero-reference pose.
/// 3. Enable the motors to lock the pose.
/// 4. Call this API to register the current feedback positions as zero.
void revo3_set_current_position_as_zero(DeviceHandler *handle, uint8_t slave_id);
/// Get the zero position offsets (degrees).
/// `out_offsets` must point to a buffer of sufficient size to store all motor
/// offsets (e.g. 13, 16, or 21 f32 values depending on the hand SKU).
/// Returns 0 on success, -1 on error.
int revo3_get_zero_position(DeviceHandler *handle, uint8_t slave_id, float *out_offsets);
/// Factory reset.
void revo3_factory_reset(DeviceHandler *handle, uint8_t slave_id);
/// Software reboot.
void revo3_reboot(DeviceHandler *handle, uint8_t slave_id);
/// Get RS485 Baudrate (Returns enum value or -1 on error)
int revo3_get_rs485_baudrate(DeviceHandler *handle, uint8_t slave_id);
/// Set RS485 Baudrate
void revo3_set_rs485_baudrate(DeviceHandler *handle, uint8_t slave_id, uint16_t baudrate_enum_val);
/// Get CANFD Baudrate (Returns enum value or -1 on error)
int revo3_get_canfd_baudrate(DeviceHandler *handle, uint8_t slave_id);
/// Set CANFD Baudrate
void revo3_set_canfd_baudrate(DeviceHandler *handle, uint8_t slave_id, uint16_t baudrate_enum_val);
/// Set buzzer switch.
void revo3_set_buzzer_switch(DeviceHandler *handle, uint8_t slave_id, bool enabled);
/// Get buzzer switch state. Returns 1 for true, 0 for false, -1 on error.
int revo3_get_buzzer_switch(DeviceHandler *handle, uint8_t slave_id);
/// Set vibration switch.
void revo3_set_vibration_switch(DeviceHandler *handle, uint8_t slave_id, bool enabled);
/// Get vibration switch state. Returns 1 for true, 0 for false, -1 on error.
int revo3_get_vibration_switch(DeviceHandler *handle, uint8_t slave_id);
/// Get software e-stop state. Returns 1 for true, 0 for false, -1 on error.
int revo3_get_software_e_stop(DeviceHandler *handle, uint8_t slave_id);
/// Set per-joint protection current (mA).
void revo3_set_joint_protect_current(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float current_ma);
/// Set per-joint position limits (degrees).
void revo3_set_joint_position_limits(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float min_pos,
float max_pos);
/// Set per-joint speed limits.
void revo3_set_joint_speed_limits(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float min_speed,
float max_speed);
/// Get hardware version string.
/// Returns a C string pointer; call `free_string` to release.
/// Returns NULL on failure.
const char *revo3_get_hardware_version(DeviceHandler *handle, uint8_t slave_id);
/// Get motor online status (bitmask).
/// Returns bitmask as u32, or 0 on failure.
uint32_t revo3_get_motor_online_status(DeviceHandler *handle, uint8_t slave_id);
/// Decode a Revo3 motor status bitmask into a human-readable C string.
/// Returns a C string pointer; call `free_string` to release.
const char *revo3_motor_status_desc(uint16_t status);
/// Read complete system status (registers 1800–1804).
/// Returns NULL on failure. Call `free_revo3_system_status` to release.
/// Internal sampling rate: 5Hz. Host should poll at ≤5Hz.
CRevo3SystemStatus *revo3_get_system_status(DeviceHandler *handle, uint8_t slave_id);
/// Read system current (mA). Returns 0xFFFF on failure.
uint16_t revo3_get_system_current(DeviceHandler *handle, uint8_t slave_id);
/// Read system voltage (V). Returns 0xFFFF on failure.
uint16_t revo3_get_system_voltage(DeviceHandler *handle, uint8_t slave_id);
/// Read system power (W). Returns 0xFFFF on failure.
uint16_t revo3_get_system_power(DeviceHandler *handle, uint8_t slave_id);
/// Read system temperature (°C). Returns 0xFFFF on failure.
uint16_t revo3_get_system_temperature(DeviceHandler *handle, uint8_t slave_id);
/// Free system status data returned by `revo3_get_system_status`.
void free_revo3_system_status(CRevo3SystemStatus *status);
void free_string(const char *s);
/// Get Slave ID (Returns slave id or -1 on error)
int revo3_get_slave_id(DeviceHandler *handle, uint8_t slave_id);
/// Set Slave ID
void revo3_set_slave_id(DeviceHandler *handle, uint8_t slave_id, uint8_t new_slave_id);
/// Unlock factory-only write registers.
void factory_set_key(DeviceHandler *handle, uint8_t slave_id, const char *operation_key);
/// Program the device serial number.
void factory_set_device_sn(DeviceHandler *handle, uint8_t slave_id, const char *sn);
/// Set the first-order Low-Pass Filter (LPF) coefficient for servo control.
/// `alpha` must be in the range (0.0, 1.0]. Default is 1.0 (no filtering).
void revo3_set_servo_lpf_alpha(DeviceHandler *handle, float alpha);
/// Get the current first-order Low-Pass Filter (LPF) coefficient.
float revo3_get_servo_lpf_alpha(DeviceHandler *handle);
/// Set the high-frequency real-time servo smoothing filter mode.
/// `mode`: 0 = None, 1 = First-order LPF, 2 = Second-order Critically Damped system.
void revo3_set_servo_filter_mode(DeviceHandler *handle, uint8_t mode);
/// Get the current high-frequency real-time servo smoothing filter mode.
/// Returns: 0 = None, 1 = First-order LPF, 2 = Second-order Critically Damped system.
uint8_t revo3_get_servo_filter_mode(DeviceHandler *handle);
/// Set the natural frequency (omega) for the second-order critically damped servo filter.
/// Higher values mean faster tracking but less smoothing. Default is 20.0.
void revo3_set_servo_damping_omega(DeviceHandler *handle, float omega);
/// Get the current natural frequency (omega) for the second-order filter.
float revo3_get_servo_damping_omega(DeviceHandler *handle);
/// High-frequency real-time servo control for a single joint using custom gains.
void revo3_servo_joint_with_gains(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float target_pos,
float target_vel,
float kp,
float kd);
/// High-frequency real-time servo control for a single joint using default gains.
void revo3_servo_joint(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float target_pos,
float target_vel);
/// High-frequency real-time servo control for all 21 joints using custom gains.
/// `target_positions` and `target_velocities` must each point to an array of at least 21 f32 values.
void revo3_servo_hand_with_gains(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
const float *target_velocities,
float kp,
float kd);
/// High-frequency real-time servo control for all 21 joints using default gains.
/// `target_positions` and `target_velocities` must each point to an array of at least 21 f32 values.
void revo3_servo_hand(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
const float *target_velocities);
/// High-frequency real-time servo control for a single non-thumb finger using custom gains.
/// `target_positions`, `target_velocities`, `kp`, and `kd` must each point to an array of at least 4 f32 values.
/// `finger_index`: 1 = Index, 2 = Middle, 3 = Ring, 4 = Pinky.
void revo3_servo_finger_with_gains(DeviceHandler *handle,
uint8_t slave_id,
uint16_t finger_index,
const float *target_positions,
const float *target_velocities,
const float *kp,
const float *kd);
/// High-frequency real-time servo control for a single non-thumb finger using default gains.
/// `target_positions` and `target_velocities` must each point to an array of at least 4 f32 values.
/// `finger_index`: 1 = Index, 2 = Middle, 3 = Ring, 4 = Pinky.
void revo3_servo_finger(DeviceHandler *handle,
uint8_t slave_id,
uint16_t finger_index,
const float *target_positions,
const float *target_velocities);
/// High-frequency real-time servo control for the thumb using custom gains.
/// `target_positions`, `target_velocities`, `kp`, and `kd` must each point to an array of at least 5 f32 values.
void revo3_servo_thumb_with_gains(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
const float *target_velocities,
const float *kp,
const float *kd);
/// High-frequency real-time servo control for the thumb using default gains.
/// `target_positions` and `target_velocities` must each point to an array of at least 5 f32 values.
void revo3_servo_thumb(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
const float *target_velocities);
/// Read all Revo3 touch modules enabled bitmask.
/// Returns bitmask (bits 0~10), or 0xFFFF on failure.
uint16_t revo3_get_all_touch_modules_enabled(DeviceHandler *handle, uint8_t slave_id);
/// Calibrate zero drift for all Revo3 touch modules (tare/zero calibration).
void revo3_calibrate_touch_zero(DeviceHandler *handle, uint8_t slave_id);
/// Calibrate zero drift for a single Revo3 touch module.
void revo3_calibrate_touch_zero_single(DeviceHandler *handle, uint8_t slave_id, uint8_t module_id);
/// MIT control for a single joint.
/// τ = Kp*(pos_ref − pos) + Kd*(vel_ref − vel) + τ_ff
void revo3_joint_mit_control(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float kp,
float kd,
float position,
float velocity,
float torque_ff);
/// Set all 5 MIT parameters for a single joint in the interleaved register block.
void revo3_set_joint_mit_params(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float kp,
float kd,
float position,
float velocity,
float torque_ff);
/// MIT control for all 21 joints using the interleaved hand register block.
/// All arrays must point to at least 21 f32 values.
void revo3_hand_mit_control(DeviceHandler *handle,
uint8_t slave_id,
const float *kp_values,
const float *kd_values,
const float *positions,
const float *velocities,
const float *torques);
/// Same as revo3_hand_mit_control but without retry (for high-freq control).
void revo3_hand_mit_control_without_retry(DeviceHandler *handle,
uint8_t slave_id,
const float *kp_values,
const float *kd_values,
const float *positions,
const float *velocities,
const float *torques);
/// Set all 5 grouped MIT parameter arrays in a single write (105 registers).
void revo3_set_all_mit_params(DeviceHandler *handle,
uint8_t slave_id,
const float *kp_values,
const float *kd_values,
const float *positions,
const float *velocities,
const float *torques);
/// Same as revo3_set_all_mit_params but without retry.
void revo3_set_all_mit_params_without_retry(DeviceHandler *handle,
uint8_t slave_id,
const float *kp_values,
const float *kd_values,
const float *positions,
const float *velocities,
const float *torques);
/// Enter teaching (backdrive) mode for a single joint.
/// `out_positions` must point to a buffer of at least `max_samples` f32 values.
/// `out_count` will be set to the number of samples actually recorded.
/// Returns 0 on success, -1 on failure.
int revo3_teach_joint(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float dt,
float duration,
float *out_positions,
uint32_t max_samples,
uint32_t *out_count);
/// Enter teaching (backdrive) mode for all joints.
/// `out_positions` must point to a buffer of at least `max_samples * num_joints` f32 values
/// (stored as row-major: [sample0_j0, sample0_j1, ..., sample1_j0, ...]).
/// `out_count` will be set to the number of samples actually recorded.
/// Returns 0 on success, -1 on failure.
int revo3_teach_hand(DeviceHandler *handle,
uint8_t slave_id,
float dt,
float duration,
uint16_t num_joints,
float *out_positions,
uint32_t max_samples,
uint32_t *out_count);
/// Replay a recorded single-joint trajectory.
/// `positions` must point to an array of `count` f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_replay_joint(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
const float *positions,
uint32_t count,
float dt,
float kp,
float kd);
/// Replay a recorded full-hand trajectory.
/// `positions` must point to an array of `num_frames * num_joints` f32 values (row-major).
/// Returns 0 on success, -1 on failure.
int revo3_replay_hand(DeviceHandler *handle,
uint8_t slave_id,
const float *positions,
uint32_t num_frames,
uint16_t num_joints,
float dt,
float kp,
float kd);
/// [RESERVED] Single joint admittance control.
/// Returns 0 on success, -1 on failure (currently always -1).
int revo3_admittance_joint(DeviceHandler *handle,
uint8_t slave_id,
uint16_t joint_id,
float equilibrium_pos,
float mass,
float damping,
float stiffness,
float dt,
float duration);
/// [RESERVED] Full hand admittance control.
/// All arrays must point to at least `num_joints` f32 values.
/// Returns 0 on success, -1 on failure (currently always -1).
int revo3_admittance_hand(DeviceHandler *handle,
uint8_t slave_id,
const float *equilibrium_positions,
const float *mass_values,
const float *damping_values,
const float *stiffness_values,
uint16_t num_joints,
float dt,
float duration);
/// Finger control (non-thumb, 4 params).
/// finger_id: 1=index, 2=middle, 3=ring, 4=pinky
/// `params` must point to an array of 4 f32 values (degrees/rpm/mA).
void revo3_finger_control(DeviceHandler *handle,
uint8_t slave_id,
uint8_t finger_id,
uint16_t mode,
const float *params);
/// Thumb control (5 params).
/// `params` must point to an array of 5 f32 values (degrees/rpm/mA).
void revo3_thumb_control(DeviceHandler *handle,
uint8_t slave_id,
uint16_t mode,
const float *params);
/// Four-finger MIT control.
/// finger_id: 1=index, 2=middle, 3=ring, 4=pinky
/// `params` must point to an array of 20 f32 values: 4 joints × 5 MIT params.
void revo3_finger_mit_control(DeviceHandler *handle,
uint8_t slave_id,
uint8_t finger_id,
const float *params);
/// Thumb MIT control.
/// `params` must point to an array of 25 f32 values: 5 joints × 5 MIT params.
void revo3_thumb_mit_control(DeviceHandler *handle, uint8_t slave_id, const float *params);
/// Get single motor temperature.
/// Returns temperature as u16, or 0xFFFF on failure.
uint16_t revo3_get_motor_temperature(DeviceHandler *handle, uint8_t slave_id, uint16_t motor_id);
/// Get motor SN string.
/// Returns a C string pointer; call `free_string` to release.
/// Returns NULL on failure.
const char *revo3_get_motor_sn(DeviceHandler *handle, uint8_t slave_id, uint16_t motor_id);
/// Get all motor SN strings.
/// `out_sns` must point to an array of at least 21 char pointers.
/// Each returned string must be released with `free_string`.
/// Returns 0 on success, -1 on failure.
int revo3_get_all_motor_sns(DeviceHandler *handle, uint8_t slave_id, const char **out_sns);
/// Get all motor firmware versions (21 values).
/// `out_versions` must point to an array of at least 21 u16 values.
/// Returns 0 on success, -1 on failure.
int revo3_get_motor_fw_versions(DeviceHandler *handle, uint8_t slave_id, uint16_t *out_versions);
/// Get all motor firmware versions as raw u16 values.
/// `out_versions` must point to an array of at least 21 u16 values.
/// Returns 0 on success, -1 on failure.
int revo3_get_motor_fw_versions_raw(DeviceHandler *handle,
uint8_t slave_id,
uint16_t *out_versions);
/// Move a specific finger with quintic trajectory control (Non-blocking).
/// finger_id: 1=index, 2=middle, 3=ring, 4=pinky
/// `target_positions` must point to an array of 4 f32 values: [Abd, MCP, PIP, DIP].
/// Returns 0 on success, -1 on failure.
int revo3_move_finger(DeviceHandler *handle,
uint8_t slave_id,
uint8_t finger_id,
const float *target_positions,
float duration,
float dt);
/// Move a specific finger with quintic trajectory control and block until completion.
/// finger_id: 1=index, 2=middle, 3=ring, 4=pinky
/// `target_positions` must point to an array of 4 f32 values: [Abd, MCP, PIP, DIP].
/// Returns 0 on success, -1 on failure.
int revo3_move_finger_wait(DeviceHandler *handle,
uint8_t slave_id,
uint8_t finger_id,
const float *target_positions,
float duration,
float dt);
/// Move a specific finger with custom Kp/Kd gains and quintic trajectory control (Non-blocking).
/// finger_id: 1=index, 2=middle, 3=ring, 4=pinky
/// `target_positions` must point to an array of 4 f32 values: [Abd, MCP, PIP, DIP].
/// Returns 0 on success, -1 on failure.
int revo3_move_finger_with_gains(DeviceHandler *handle,
uint8_t slave_id,
uint8_t finger_id,
const float *target_positions,
float duration,
float dt,
float kp,
float kd);
/// Move a specific finger with custom Kp/Kd gains and block until completion.
/// finger_id: 1=index, 2=middle, 3=ring, 4=pinky
/// `target_positions` must point to an array of 4 f32 values: [Abd, MCP, PIP, DIP].
/// Returns 0 on success, -1 on failure.
int revo3_move_finger_with_gains_wait(DeviceHandler *handle,
uint8_t slave_id,
uint8_t finger_id,
const float *target_positions,
float duration,
float dt,
float kp,
float kd);
/// Move a specific finger with joint-specific Kp/Kd gains (4 joints) and quintic trajectory control (Non-blocking).
/// finger_id: 1=index, 2=middle, 3=ring, 4=pinky
/// `target_positions` must point to an array of 4 f32 values: [Abd, MCP, PIP, DIP].
/// `kp` must point to an array of 4 f32 values.
/// `kd` must point to an array of 4 f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_move_finger_with_joint_gains(DeviceHandler *handle,
uint8_t slave_id,
uint8_t finger_id,
const float *target_positions,
float duration,
float dt,
const float *kp,
const float *kd);
/// Move a specific finger with joint-specific Kp/Kd gains (4 joints) and block until completion.
/// finger_id: 1=index, 2=middle, 3=ring, 4=pinky
/// `target_positions` must point to an array of 4 f32 values: [Abd, MCP, PIP, DIP].
/// `kp` must point to an array of 4 f32 values.
/// `kd` must point to an array of 4 f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_move_finger_with_joint_gains_wait(DeviceHandler *handle,
uint8_t slave_id,
uint8_t finger_id,
const float *target_positions,
float duration,
float dt,
const float *kp,
const float *kd);
/// Move thumb with quintic trajectory control.
/// `target_positions` must point to an array of 5 f32 values: [CMC_flex, CMC_abd, MCP, IP, DIP].
/// Returns 0 on success, -1 on failure.
int revo3_move_thumb(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
float duration,
float dt);
/// Move thumb with custom Kp/Kd gains and quintic trajectory control.
/// `target_positions` must point to an array of 5 f32 values: [CMC_flex, CMC_abd, MCP, IP, DIP].
/// Returns 0 on success, -1 on failure.
int revo3_move_thumb_with_gains(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
float duration,
float dt,
float kp,
float kd);
/// Move thumb with joint-specific Kp/Kd gains (5 joints) and quintic trajectory control.
/// `target_positions` must point to an array of 5 f32 values: [CMC_flex, CMC_abd, MCP, IP, DIP].
/// `kp` must point to an array of 5 f32 values.
/// `kd` must point to an array of 5 f32 values.
/// Returns 0 on success, -1 on failure.
int revo3_move_thumb_with_joint_gains(DeviceHandler *handle,
uint8_t slave_id,
const float *target_positions,
float duration,
float dt,
const float *kp,
const float *kd);
} // extern "C"
#endif // REVO3_SDK_HProtocol & Hardware Reference
These documents define the Modbus register mappings and hardware specifications behind the SDK APIs, for developers who need low-level control details:
- Revo 3 Motor Control Protocol (REVO3_MOTOR_API) — control mode parameters, MIT hybrid control formula, servo APIs, protection current configuration, etc.
- Revo 3 Tactile Array Protocol (REVO3_TOUCH_API) — 11-module physical layout, channel count mapping, data type switching, etc.