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. 先识别真实的 1.x 接口
Section titled “1. 先识别真实的 1.x 接口”以下变化属于 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.3C 头文件中。normal_force -> resultant_force_mn不是该基线的字段迁移;v1.6.3的六维力触觉数据已经公开resultant_force_mn。TouchFrame.mode、TouchFrame.summary不是 1.x 公开 API,不能作为迁移依据。1.x 实际公开的是Revo3TouchData.modules和Revo3TouchData.summary。
2. 连接与生命周期
Section titled “2. 连接与生命周期”2.1 Python
Section titled “2.1 Python”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 也随原连接失效。
2.2 C ABI
Section titled “2.2 C ABI”| 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 头文件核对参数、发现结果结构和资源释放流程。
3. 运动控制
Section titled “3. 运动控制”3.1 目标运动
Section titled “3.1 目标运动”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)3.2 高频连续控制
Section titled “3.2 高频连续控制”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 参考手册为准。
4. State、Health 与连续采集
Section titled “4. State、Health 与连续采集”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、设备响应和主机调度影响。
5. Touch
Section titled “5. Touch”5.1 读取结果
Section titled “5.1 读取结果”| 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 互斥,切换前后的摘要和点阵不保证属于同一次物理采样。
5.2 Python 配置与维护
Section titled “5.2 Python 配置与维护”下表使用 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() 只执行当前触觉类型定义的零偏操作,不等价于恢复工厂标定。
5.3 C ABI
Section titled “5.3 C ABI”下表左侧是 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。
6. 其他能力域
Section titled “6. 其他能力域”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() |
这些是按能力域重新组织,不是一对一改名。迁移时必须重新核对参数单位、异步返回值、超时、错误模型和设备效果。
7. 错误处理与验证
Section titled “7. 错误处理与验证”1.x 常见代码只判断空指针、整数返回码或 StarkError。2.0 Python 使用结构化 SdkError,C 使用 revo3_get_last_error() 读取 CRevo3ErrorInfo。写命令响应丢失且 operation_effect 为 Indeterminate 时,先读取设备实际状态,不得直接重试。
建议按以下顺序完成迁移验证:
- 静态删除
DeviceContext、DeviceHandler、1.x module-level API、collector/buffer 和旧 callback setter 的引用。 - 使用 mock 覆盖连接、只读 State/Health、Touch 可选字段、运动参数校验、错误分支和关闭流程。
- 在真机上先完成只读身份、固件、布局、State、Health 和 Touch 验证。
- 在具备独立断电能力的受控环境中验证低幅运动、断联、响应丢失和固件 Watchdog。
- 最后单独验证会改变设备持久状态的配置、标定、重启、factory reset 和 DFU。
mock 只能验证应用控制流,不能替代真机的单位、时序、运动效果或故障恢复验证。