跳转到内容
English

1.x 到 2.0 迁移指南

本文说明如何把 Revo3 SDK v1.6.3 应用迁移到 2.0。旧接口名称以 v1.6.3 标签中的 python/bc_revo3_sdk/main_mod.pyi 和 dist/include/revo3-sdk.h 为核验基线;更早的 1.x 应用应先确认实际使用的符号。2.0 公共 API、参数和行为以 Revo3 API 参考手册 为准,高频流式控制与订阅进阶查阅 开发指南。

以下变化属于 1.x 到 2.0 的迁移:

  • Python 从 DeviceContext 及其 revo3_* 方法迁移到 Manager -> Hand 对象模型。
  • C 从 DeviceHandler *、手动 transport 初始化和独立函数迁移到 Revo3ManagerHandle * -> Revo3DeviceHandle *。
  • 1.x 的 DataCollector、Revo3MotorStatusBuffer 和 Revo3TouchDataBuffer 不再属于 2.0 公共 API;连续读取改用领域订阅对象。
  • 1.x 的运动函数族、直接寄存器式配置入口和协议专用 Touch 入口迁移到 Hand 的能力域。
  • C ABI 全面更换句柄和函数签名,必须使用 2.0 头文件重新编译,不能把 1.x 动态库与 2.0 头文件混用。

以下内容不是 v1.6.3 -> 2.0 迁移项,不应写进 1.x 符号替换表:

  • revo3_device_calibrate_touch_zero、revo3_device_pressure_touch_tare、revo3_device_matrix_touch_tare 等 revo3_device_* 过渡名称不在 v1.6.3 C 头文件中。
  • normal_force -> resultant_force_mn 不是该基线的字段迁移;v1.6.3 的六维力触觉数据已经公开 resultant_force_mn。
  • TouchFrame.mode、TouchFrame.summary 不是 1.x 公开 API,不能作为迁移依据。1.x 实际公开的是 Revo3TouchData.modules 和 Revo3TouchData.summary。

1.x 常见入口包括模块级 revo3_auto_detect()、init_from_detected()、init_device_handler()、modbus_open(),以及由调用方保存 DeviceContext 和 slave_id。2.0 由 Manager 发现并连接设备,连接结果是绑定单手身份的 Hand:

1.x Python 2.0 Python
await sdk.revo3_auto_detect(...) await manager.discover(...)
sdk.Revo3AutoDetector(...) manager.discover(..., on_found=...)
await sdk.init_from_detected(device) await manager.connect(device)
sdk.init_device_handler(...) / sdk.modbus_open(...) await manager.connect_auto(...)
ctx.revo3_*(slave_id, ...) hand.<domain>.<method>(...)
await sdk.close_device_handler(ctx) / await sdk.modbus_close(ctx) await hand.close(),最后 await manager.close()
import asyncio
from bc_revo3_sdk import main_mod as sdk
async def main():
manager = sdk.Manager()
hand = None
try:
hand = await manager.connect_auto(port="/dev/ttyUSB0")
state = await hand.state.snapshot()
print(state.positions_deg)
finally:
if hand is not None:
await hand.close()
await manager.close()
asyncio.run(main())

Hand 已保存设备身份、从站 ID、布局和 transport 归属。领域方法不再重复接收 DeviceContext 或 slave_id。断线重连后必须重新获取 Hand;旧的运动 Handle、订阅和 ServoSession 也随原连接失效。

1.x C 2.0 C
stark_auto_detect(...) revo3_auto_detect_start(...) 回调式发现
init_from_detected(...) revo3_manager_connect(manager, detected)
modbus_open(...)、init_device_handler_*() 先发现设备,再由 Manager 连接
DeviceHandler * Revo3DeviceHandle *
close_device_handler(...) / modbus_close(...) revo3_device_close() + revo3_device_destroy()
无 Manager 所有者 revo3_manager_close() + revo3_manager_destroy()

2.0 不再导出 1.x 的全局 Modbus/CAN callback setter、stark_* 查询入口或 transport 初始化函数。发现 handle、Manager、Device、操作 handle、订阅和 Servo handle 都有各自的 close/join/destroy 生命周期约定;不能只释放最外层指针。

revo3_auto_detect_start() 在 v1.6.3 中已经存在;原本使用该回调式入口的应用不需要迁移发现模型,但仍须按 2.0 头文件核对参数、发现结果结构和资源释放流程。

1.x Python 的运动入口是 DeviceContext.revo3_move_* 方法;C 使用同名的 revo3_move_* 独立函数。2.0 Python 映射如下:

1.x DeviceContext 方法族 2.0 Python
revo3_move_hand* await hand.motion.move_to(...)
revo3_move_joint* await hand.motion.move_joint(...)
revo3_move_finger* await hand.motion.move_finger(...)
revo3_move_thumb* await hand.motion.move_thumb(...)
*_wait 变体 先取得 OperationHandle,再 await handle.wait(timeout=...)
*_with_gains* 变体 使用 kp= 和 kd= 关键字参数
revo3_move_hand_with_speed* hand.motion.move_to(..., speed=...)
revo3_move_joint_with_speed* hand.motion.move_joint(..., speed=...)

1.x 的 finger/thumb 方法没有 speed 变体;2.0 的 move_finger() 和 move_thumb() 同样使用 duration,不能把 hand/joint 的 speed= 迁移规则套用到这两个方法。

2.0 的目标运动调用返回 Handle,不表示动作已经完成:

motion = await hand.motion.move_joint(0, 10.0, duration=1.0)
result = await motion.wait(timeout=3.0)

1.x 的 revo3_servo_*、revo3_*_mit_control、批量 MIT 参数写入和连续 Drag 更新不能机械替换成反复调用 move_to()。2.0 使用一个有明确生命周期的 ServoSession。以下片段假设 hand 已连接,且 target_positions 已按当前 joint_layout 构造:

session = hand.motion.open_servo(command_timeout_ms=100)
try:
await session.send_position(target_positions)
finally:
session.close()

需要迁移的关键行为包括命令超时、会话关闭、断联失效和 operation_effect=Indeterminate。具体 send 方法与单位以 API 参考手册为准。

1.x 的对应接口不是 State 对象,而是 DeviceContext 读取方法以及可选 collector/shared buffer:

1.x Python 2.0 Python
await ctx.revo3_get_motor_status_data(slave_id) await hand.state.snapshot()
await ctx.revo3_get_system_status(slave_id) await hand.health.snapshot()
await ctx.revo3_get_all_motor_temperatures(slave_id) await hand.health.motor_module_temperatures_c()
await ctx.revo3_get_motor_online_status(slave_id) await hand.health.motor_online_mask()
DataCollector + Revo3MotorStatusBuffer hand.state.subscribe(period=...)
DataCollector + Revo3TouchDataBuffer hand.touch.subscribe(period=...)

2.0 的 subscription.next() 按订阅节奏拉取下一份快照,不提供 1.x shared buffer 的历史队列。以下片段假设 hand 已连接,外层仍须按 2.1 节关闭 Hand 和 Manager:

subscription = hand.state.subscribe(period=0.02)
try:
while True:
state = await subscription.next()
finally:
subscription.close()

需要历史数据时,应用自行维护有界队列并定义丢帧策略。不要把 period=0.02 解释为无条件 50 Hz 保证;实际速率受 transport、设备响应和主机调度影响。

1.x Python 2.0 Python
await ctx.revo3_get_all_touch_data(slave_id) await hand.touch.snapshot()
await ctx.revo3_get_touch_summary(slave_id) await hand.touch.snapshot() 后读取各 module 的 regional_forces_mn
await ctx.revo3_get_touch_module_data(slave_id, module_id) await hand.touch.module_snapshot(module_id)
Revo3TouchData.modules TouchFrame.modules[*].points
Revo3TouchData.summary TouchFrame.modules[*].regional_forces_mn
1.x 六维力触觉专用读取结果 同一 TouchFrame 中的 force3d、torque2d、resultant_force_mn 和 points

2.0 不再按触觉协议返回不同的数据类型。应用必须先读取 hand.touch.layout,再按 module_id 匹配 TouchFrame.modules,并检查 sample_state 和各可选信号字段。

1.x 的 Revo3TouchData.modules 总是列表;2.0 的 TouchModuleData.points 是可选字段。模块禁用、未采样、读取失败、当前模式不提供点阵或模块不可用时,points 可以为 None,不能把它当成全零有效采样。

1.x 的 TouchDataMode.ForceSummary 对应 2.0 的 TouchReadMode.LegacyForceSummary。该兼容模式只适用于既有设备;摘要值迁移到各 module 的 regional_forces_mn。它与 PointArray 互斥,切换前后的摘要和点阵不保证属于同一次物理采样。

下表使用 v1.6.3 DeviceContext 中的真实方法名:

1.x Python 2.0 Python
revo3_calibrate_touch_zero / revo3_calibrate_touch_zero_single hand.touch.tare(module_index=None)
revo3_calibrate_pressure_touch_zero / revo3_calibrate_pressure_touch_module_zero hand.touch.tare(module_index=None)
revo3_set_pressure_touch_force_tare / revo3_set_pressure_touch_module_force_tare 无 2.0 公共替代;这是二次标定清除/恢复入口,不能改写为 tare()
revo3_set_touch_module_enabled / revo3_get_touch_module_enabled hand.touch.set_module_enabled() / module_enabled()
revo3_set_all_touch_modules_enabled / revo3_get_all_touch_modules_enabled hand.touch.set_enabled_mask() / enabled_mask()
revo3_set_matrix_touch_tare / revo3_set_matrix_touch_module_tare hand.touch.tare() / cancel_tare();状态读取使用 tare_status()
revo3_set_touch_data_type / revo3_get_touch_data_type hand.touch.set_read_mode() / read_mode()
revo3_set_touch_module_value_type / revo3_get_touch_module_value_type hand.touch.set_value_mode() / value_mode()
revo3_set_matrix_touch_output_mode / revo3_get_matrix_touch_output_mode hand.touch.set_value_mode() / value_mode()
revo3_get_all_matrix_touch_module_point_counts hand.touch.point_counts()
revo3_get_all_matrix_touch_module_serial_numbers hand.device_info.touch_serial_numbers,必要时先 await hand.refresh_device_info()
revo3_restart_matrix_touch_modules / revo3_restart_matrix_touch_module hand.touch.restart(module_index=None)
revo3_set_touch_vendor / revo3_get_touch_vendor 不再使用公开 vendor 枚举;读取 hand.touch.layout,确需覆盖时传入完整 TouchLayout

TouchModuleValueType.RawValue 在 2.0 没有对应项;TouchValueMode 只保留 Adc (0) 和 Force (2)。不要把旧值 1 映射成新的公开枚举。

如果 1.x 应用使用了二次标定清除或恢复出厂标定命令,应把它登记为阻塞迁移项,并由设备/固件负责人确认替代维护流程。2.0 公共 tare() 只执行当前触觉类型定义的零偏操作,不等价于恢复工厂标定。

下表左侧是 v1.6.3 真实 C 符号,不带不存在的 revo3_device_ 中间前缀:

1.x C 2.0 C
revo3_get_all_touch_data revo3_device_touch_get_snapshot
revo3_get_touch_summary / revo3_get_touch_module_data revo3_device_touch_get_snapshot 后按 module 读取
revo3_set_touch_module_enabled / revo3_get_touch_module_enabled revo3_device_touch_set_module_enabled / revo3_device_touch_get_module_enabled
revo3_set_all_touch_modules_enabled / revo3_get_all_touch_modules_enabled revo3_device_touch_set_enabled_mask / revo3_device_touch_get_enabled_mask
revo3_calibrate_touch_zero*、revo3_calibrate_pressure_touch_zero* revo3_device_touch_tare
revo3_set_pressure_touch_force_tare / revo3_set_pressure_touch_module_force_tare 无 2.0 公共替代,不能映射到 revo3_device_touch_tare
revo3_set_matrix_touch_tare* / revo3_get_matrix_touch_*tare_status* revo3_device_touch_tare、revo3_device_touch_cancel_tare、revo3_device_touch_get_tare_status
revo3_set_touch_data_type / revo3_get_touch_data_type revo3_device_touch_set_read_mode / revo3_device_touch_get_read_mode
revo3_set_touch_module_value_type / revo3_get_touch_module_value_type revo3_device_touch_set_value_mode / revo3_device_touch_get_value_mode
revo3_set_matrix_touch_output_mode* / revo3_get_matrix_touch_output_mode* revo3_device_touch_set_value_mode / revo3_device_touch_get_value_mode
revo3_get_all_matrix_touch_module_point_counts revo3_device_touch_get_layout 后读取 modules[*].point_count
revo3_restart_matrix_touch_modules / revo3_restart_matrix_touch_module revo3_device_touch_restart

2.0 中 module_index 的值按公开 module_id 解释。不要沿用 1.x 应用中“数组下标必然等于模组 ID”的假设:纯 piezoresistive-array / high-density-matrix 布局为 0~10 密集编号,组合拓扑可能使用稀疏编号。C API 的 -1 表示对当前布局支持的全部模组执行操作;Python 使用 None。

1.x DeviceContext 方法 2.0 Python
revo3_get_device_info、固件/硬件版本读取 hand.device_info、hand.firmware_info、await hand.refresh_device_info()、await hand.refresh_firmware_info()
设备配置 getter/setter await hand.config.snapshot() 和 hand.config setter
revo3_manual_calibration、零位相关方法 hand.calibration
revo3_reboot、revo3_factory_reset、DFU 方法 hand.maintenance
revo3_set_collision_protection_config、状态与复位 hand.experimental_collision.configure(...)、active_joints()、reset()

这些是按能力域重新组织,不是一对一改名。迁移时必须重新核对参数单位、异步返回值、超时、错误模型和设备效果。

1.x 常见代码只判断空指针、整数返回码或 StarkError。2.0 Python 使用结构化 SdkError,C 使用 revo3_get_last_error() 读取 CRevo3ErrorInfo。写命令响应丢失且 operation_effect 为 Indeterminate 时,先读取设备实际状态,不得直接重试。

建议按以下顺序完成迁移验证:

  1. 静态删除 DeviceContext、DeviceHandler、1.x module-level API、collector/buffer 和旧 callback setter 的引用。
  2. 使用 mock 覆盖连接、只读 State/Health、Touch 可选字段、运动参数校验、错误分支和关闭流程。
  3. 在真机上先完成只读身份、固件、布局、State、Health 和 Touch 验证。
  4. 在具备独立断电能力的受控环境中验证低幅运动、断联、响应丢失和固件 Watchdog。
  5. 最后单独验证会改变设备持久状态的配置、标定、重启、factory reset 和 DFU。

mock 只能验证应用控制流,不能替代真机的单位、时序、运动效果或故障恢复验证。