Skip to content

获取 SDK

灵巧手 SDK(Software Development Kit)是专为 BrainCo Revo 3 系列设备开发的跨平台软件开发包,提供 21 电机独立关节控制、状态读取(位置、速度、电流、电机状态)与固件 OTA 升级接口。

系统要求

宿主机环境需满足以下规格要求:

  • Python: 3.9 ~ 3.12 运行环境
  • Linux: Ubuntu 20.04/22.04 LTS 及以上 (支持 x86_64 / aarch64 架构)
  • macOS: 10.15+ 系统版本
  • Windows: Windows 10/11 系统环境
  • 通讯接口: SDK 工作流支持的 RS485 串口模块或 CAN FD 总线卡

下载与安装

1. 示例代码与 SDK 集成

运行示例前,请先拉取 SDK 仓库代码:

bash
git clone https://github.com/BrainCoTech/brainco-revo3-sdk.git
cd brainco-revo3-sdk

2. Python 依赖包安装

建议使用虚拟环境(推荐 Conda)安装 Revo 3 SDK:

bash
# 创建并激活 Conda 虚拟环境(推荐 Python 3.10)
conda create -n revo3_env python=3.10 -y
conda activate revo3_env

# 安装 Revo 3 核心 SDK 包
pip3 install bc-revo3-sdk==1.2.2

💡 Linux 系统权限与低时延调优说明

在 Linux 系统下运行串口程序时,需要关注以下串口读写权限及通信延迟配置:

  • 串口设备访问权限(非 root 通用要求):Linux 系统下非 root 用户默认不具备串口设备(如 /dev/ttyUSB0)的直接读写权限。为了能够正常打开并使用串口,请确保在运行示例前将当前 Linux 用户永久加入 dialout 用户组(修改后需注销并重新登录以生效):
    bash
    sudo usermod -a -G dialout $USER
  • 自动低时延配置(SDK 默认处理):SDK 在 Linux 下打开串口时,已自动将 FTDI 硬件延迟降低至 1ms(通过 ioctl 设置 ASYNC_LOW_LATENCY),使用 SDK 时无需手动配置。
  • 手动串口优化(非 SDK 或独立诊断场景):若开发者未使用官方 SDK(例如直接通过第三方通用 Modbus 库控制串口),或是作为独立的通信延迟诊断调试手段,仍可手动执行以下命令调整指定 USB 串口的延迟设置:
    bash
    # 使用 setserial 工具配置
    sudo setserial /dev/ttyUSB0 low_latency
    或者直接将延迟定时器(Latency Timer)通过 sysfs 写入最低的 1ms:
    bash
    echo 1 | sudo tee /sys/class/tty/ttyUSB0/device/latency_timer

运行示例

仓库 python/c/ 目录下包含 Revo 3 灵巧手的演示示例。设备默认通信波特率为 5M (5000000 bps),左手从机 ID 为 126,右手为 127

1. Python 示例

进入 python/ 目录并安装依赖后,即可运行演示脚本:

bash
cd python
pip install -r requirements.txt

# 运行自动检测串口与 ID
python revo3/auto_detect.py
# 运行灵巧手基础运动控制演示
python revo3/hand_demo.py
# 运行轨迹规划与示教演示
python revo3/hand_trajectory.py
# 运行 OTA 固件在线升级
python revo3/hand_dfu.py /path/to/firmware.bin
# 启动图形化 Qt 调试面板(含 Mock 模式)
python gui/main.py --mock
💡 预期 Python 控制台输出日志 (Expected Python Console Output)
python
$ 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:自动扫描系统串口,发现并检测绑定的 Revo 3 灵巧手 ID 和波特率。
  • hand_demo.py:关节位置控制与状态反馈示例。
  • hand_trajectory.py:多指轨迹规划与协调抓取示例。
  • hand_dfu.py:固件在线升级(OTA)脚本。
  • gui/main.py:图形化调试工具,支持控制下发与实时波形观测。

2. C++ 示例

在 C++ 环境下编译并执行示例程序:

bash
# 1. 下载核心动态依赖库
sh download-lib.sh
# 2. 编译 C++ 示例项目
make -C c

# 3. 运行对应可执行程序
# 自动检测设备
./c/demo/auto_detect
# 运行基本控制演示
./c/demo/hand_demo
# 运行轨迹演示
./c/demo/hand_trajectory
# 运行固件 OTA 升级
./c/demo/hand_dfu firmware.bin
💡 预期 C++ 控制台输出日志 (Expected C++ Console Output)
bash
$ ./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:设备通道自动扫描检测工具。
  • hand_demo:电机读写控制与反馈监控示例。
  • hand_trajectory:多关节平滑轨迹规划示例。
  • hand_dfu:固件 OTA 升级工具。

快速开始

以下代码展示了从零开始控制灵巧手的最小流程:打开串口 → 写入目标角度 → 读取状态反馈。

python
# 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")
cpp
#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);

💡 生产开发建议:优先使用轨迹规划 API

直接下发阶跃目标位置(如 revo3_set_all_motor_positions)会产生瞬时电流冲击,长期使用会加速减速箱与传动机构磨损。

在实际应用中,建议优先使用以下轨迹 API

  • 五次多项式轨迹控制revo3_move_finger_trajectory / revo3_move_thumb_trajectory — SDK 内部计算平滑插值,有助于减少突变运动。
  • 轨迹录制与回放revo3_replay_hand — 回放录制好的 21 轴轨迹,可通过 Kp、Kd 增益调节实现柔顺抓握。

控制模式速览

SDK 内部已自动处理所有 Modbus 寄存器的 x100 缩放编解码。调用 API 时直接传入标准物理量浮点数(角度 45.5 度、速度 50.0 RPM、电流 120.0 mA),无需手动换算。

模式值模式名称控制参数说明
0位置控制 (Position)目标角度 (deg)控制关节移动到指定角度。
1速度控制 (Speed)目标转速 (RPM)控制关节以指定转速持续转动。(1 RPM = 6 °/s)
2电流控制 (Current)目标电流 (mA)控制关节输出指定力矩。
4阻抗控制 (Impedance)刚度系数 (Kp)简易力-位混合控制,仅激活位置刚度。
5阻尼控制 (Damping)阻尼系数 (Kd)简易力-位混合控制,仅激活速度阻尼。

SDK 还提供 MIT 力-位混合控制(Kp + Kd + 位置 + 速度 + 前馈力矩的五参数联合控制)和手指级轨迹控制接口。详细参数范围与公式定义参见 电机控制协议文档

⚠️ 触觉传感器零点校准

灵巧手配备 11 个触觉阵列模块(手掌 + 每指指尖/指腹),长时间使用可能产生基准漂移。建议定期在无外力状态下调用 revo3_calibrate_touch_zero() 执行零点校准。各模块的物理位置与通道数参见 触觉阵列协议文档


进阶参考

接口定义文件

API 查阅与代码自动补全可参考以下接口定义文件,支持直接下载或在下方展开查看:

  • Python 类型存根 (.pyi): 下载 main_mod.pyi — 包含所有类、枚举、函数的类型注解。
  • C/C++ 头文件 (.h): 下载 revo3-sdk.h — 由 cbindgen 自动生成的 C ABI 导出头文件。
展开查看 Python 类型存根 (main_mod.pyi)
python
# 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
    """
展开查看 C/C++ 头文件 (revo3-sdk.h)
c
#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_H

协议与硬件参考文档

以下文档定义了 SDK API 背后的 Modbus 寄存器映射与硬件规格,适合需要理解协议层控制逻辑的开发者:

帮助