获取 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 仓库代码:
git clone https://github.com/BrainCoTech/brainco-revo3-sdk.git
cd brainco-revo3-sdk2. Python 依赖包安装
建议使用虚拟环境(推荐 Conda)安装 Revo 3 SDK:
# 创建并激活 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用户组(修改后需注销并重新登录以生效):bashsudo usermod -a -G dialout $USER - 自动低时延配置(SDK 默认处理):SDK 在 Linux 下打开串口时,已自动将 FTDI 硬件延迟降低至 1ms(通过
ioctl设置ASYNC_LOW_LATENCY),使用 SDK 时无需手动配置。 - 手动串口优化(非 SDK 或独立诊断场景):若开发者未使用官方 SDK(例如直接通过第三方通用 Modbus 库控制串口),或是作为独立的通信延迟诊断调试手段,仍可手动执行以下命令调整指定 USB 串口的延迟设置:bash或者直接将延迟定时器(Latency Timer)通过 sysfs 写入最低的 1ms:
# 使用 setserial 工具配置 sudo setserial /dev/ttyUSB0 low_latencybashecho 1 | sudo tee /sys/class/tty/ttyUSB0/device/latency_timer
运行示例
仓库 python/ 和 c/ 目录下包含 Revo 3 灵巧手的演示示例。设备默认通信波特率为 5M (5000000 bps),左手从机 ID 为 126,右手为 127。
1. Python 示例
进入 python/ 目录并安装依赖后,即可运行演示脚本:
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 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++ 环境下编译并执行示例程序:
# 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)
$ ./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 升级工具。
快速开始
以下代码展示了从零开始控制灵巧手的最小流程:打开串口 → 写入目标角度 → 读取状态反馈。
# 1. Open serial connection
from bc_revo3_sdk import modbus_open
ctx = modbus_open("/dev/ttyUSB0", 5000000)
slave_id = 1
# 2. Write target angles (degrees) for 21 joints
target_positions = [0.0] * 21
target_positions[0] = 45.5 # Thumb joint
ctx.revo3_set_all_motor_positions(slave_id, target_positions)
# 3. Read 21-joint status feedback
positions = ctx.revo3_get_all_motor_positions(slave_id)
currents = ctx.revo3_get_all_motor_currents(slave_id)
print(f"Thumb pos: {positions[0]} deg, current: {currents[0]} mA")#include "revo3-sdk.h"
// 1. Open RS485 serial port
DeviceHandler* handle = modbus_open("/dev/ttyUSB0", 5000000);
if (!handle) return -1;
// 2. Write target angles for 21 joints
float target_positions[21] = {0.0f};
target_positions[0] = 45.5f;
revo3_set_all_motor_positions(handle, 1, target_positions);
// 3. Read 21-joint status feedback
CRevo3MotorStatusData* status = revo3_get_motor_status_data(handle, 127);
if (status) {
printf("Thumb pos: %f deg, current: %f mA\n", status->positions[0], status->currents[0]);
free_revo3_motor_status_data(status);
}
modbus_close(handle);💡 生产开发建议:优先使用轨迹规划 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)
# 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)
#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 寄存器映射与硬件规格,适合需要理解协议层控制逻辑的开发者:
- Revo 3 电机控制协议 (REVO3_MOTOR_API) — 控制模式详细参数、MIT 混合控制公式、伺服 API、保护电流配置等。
- Revo 3 触觉阵列协议 (REVO3_TOUCH_API) — 11 个触觉模块的物理位置、通道数映射、数据类型切换等。