各设备特定的数据结构请参阅下方对应的产品文档。
通用类型
FrameHeader
每帧数据的头部信息。Vector3 / Vector3F64
三维向量。Vector3 使用 f32 精度,Vector3F64 使用 f64 精度(用于 IMU 数据,ROS 兼容)。
Quaternion
旋转四元数。Python 统一为Quaternion,C 按数据流的实际精度分为 WujiQuaternionF32 与 WujiQuaternionF64。
Pose
位姿,包含位置和朝向。Handedness
设备手性枚举,用于按手性连接。C 侧的等价常量是WUJI_HANDEDNESS_LEFT(0)与 WUJI_HANDEDNESS_RIGHT(1)。Wuji Hand 的两个 handedness 读取接口返回原始 uint8_t 而非该枚举,且两者编码彼此相反,取值约定见 Wuji Hand 数据订阅。
ImuData
IMU 传感器数据,遵循 ROSsensor_msgs/Imu 约定。
坐标变换
FrameTransform
单个坐标变换。FrameTransforms
坐标变换集合。录制类型
完整用法和代码示例详见 数据录制。TopicRecorder
MCAP 录制会话配置器。注册通道后调用start() 开始录制。
RecordingHandle
录制控制句柄,由TopicRecorder.start() 返回。
RecordingSummary
录制统计摘要,由handle.stop() 返回。
channels 按通道 ID 排序,包含已注册但未收到消息的通道。每项 ChannelRecordingSummary 包含 channel_id、channel_name 和 frame_count。duration_s 包含暂停时间和停止时排空录制缓冲的时间,不包含 MCAP 文件收尾、刷新及等待监控回调退出的时间。
QualityMetrics
实时质量指标(5 秒滑动窗口)。ChannelHealth
单通道健康明细(QualityMetrics 的channels 元素)。
QualitySummary
录制质量汇总统计。RecordingAlert
质量告警。RecordingStatus
录制运行状态。设备专属类型
错误码分类
以下三类错误码互不相通,数值不能跨类解读:
码值使用
设备故障码采用
0xSCNN 布局。不要自行拆解十六进制位,应把完整码值作为不透明标识,用于记录日志、展示给用户或写入故障报告。
读取解码结果
Python 的 describe_error() 返回 dict,按 key 读取,例如 info["severity"]、info["clear_policy"]。
以下字段的文案来自固件码表:
处理
None 返回值
当 describe_error(code) 返回 None 时,按原始错误码判断:
SDK 异常、C 返回码与设备侧码值的区别见 错误码索引。设备故障码的查询见 故障日志与错误码。
C SDK 通用约定
本节补充 C SDK 的初始化、错误处理、内存生命周期、回调约束和 CMake 构建约定。具体设备能力仍在对应产品页面中说明。初始化与约定
初始化 进程级初始化一次,结束时释放:WujiStatus— 多数操作(wuji_init/wuji_scan/wuji_connect/ 订阅打开等),WUJI_STATUS_OK表示成功,失败时通过wuji_last_error()获取当前线程错误描述。int32_t— 元信息读取(wuji_dev_serial_number/wuji_dev_device_name)返回写入字节数。uint8_t— 状态查询wuji_dev_is_connected。void—wuji_shutdown与资源释放函数。
wuji_discovered_free—wuji_scan后释放设备列表wuji_dev_release— 与wuji_connect配套,断开后释放设备句柄wuji_sub_close— 关闭订阅句柄
WujiUserInfo 含 7 个字段:user_id、display_name、description、external_id、is_default、created_at、updated_at。wuji_update_user 通过 WujiUserUpdate 只传要改的字段,置位 clear_description / clear_external_id 可清空对应值。用户管理的完整接口清单见 SDK 用户与标定数据。
使用约束
C SDK 用户必须遵守以下约束,否则会出现 use-after-free、死锁或读到失效错误描述:- typed 回调的 frame 指针仅在回调期间有效,返回后堆字段即被释放。需要保留的数据必须在回调内拷贝出来,不得保存指针。
- 不要在订阅自身的回调里调
wuji_sub_close。close会 join worker 线程,在自身回调中调用必死锁。请在外部线程上 close。 wuji_last_error()返回值仅在同线程下一次wuji_*调用前有效。需要保留的错误描述应立即拷贝。END/ERROR是终止帧,回调收到这两类帧后流不再有新数据,但仍需调用wuji_sub_close释放订阅句柄。- 字符串 getter 使用两步查询:先用
buf=NULL, buf_len=0获取*needed(所需字节,含 NUL),再分配缓冲第二次调用填充。直接传不足缓冲会返回WUJI_STATUS_ERR_BUFFER_TOO_SMALL,不做截断。 - 整手批量读(
get_all_effort_limit/get_all_mit_params)返回 flat-20 数组 + 在线 bitmap,用WUJI_JOINT_ONLINE(mask, i)宏判断槽位是否有效,否则读到离线关节的占位值(0 或 NaN)。 - 标定反馈回调在标定 worker 线程触发,
feedback指针仅回调期间有效。回调内调用 session 接口不会死锁,SDK 会拦截:wuji_glove_calibration_wait与wuji_glove_calibration_try_finish返回WUJI_STATUS_ERR_INVALID_ARG,wuji_glove_calibration_session_free把原因记录到wuji_last_error()并跳过这次释放——session 仍然存活,必须在回调返回后再释放一次。wuji_glove_calibration_cancel可以在回调内安全调用。session 使用完毕后调用wuji_glove_calibration_session_free,标定结果使用完毕后调用wuji_glove_calibration_result_free。 WujiUserInfo持堆字符串:单个结构用wuji_user_info_free,wuji_list_users返回的数组用wuji_user_info_array_free。
Python 接口对照
下表按功能列出 C 与 Python 的对应接口。跨设备能力与设备专属接口的完整用法见 C 接口参考。| 功能 | C | Python |
|---|---|---|
| 初始化 | wuji_init(NULL) | SdkManager.instance() |
| 扫描 | wuji_scan(&devs, &count) | manager.scan() |
| 连接 | wuji_connect(&target, alias, &opts, &dev) | manager.connect(…) / manager.auto_connect(…) |
| 连接选项默认值 | wuji_connect_options_default() | ConnectOptions() |
| 设备订阅 | wuji_glove_subscribe_tactile(dev, cb, user, &sub) | glove.tactile().subscribe_with_callback(…) |
| 全局订阅 | wuji_subscribe_tf(cb, user, &sub) | manager.tf().subscribe() |
| 订阅流输出率 | wuji_sub_set_rate(sub, hz, &actual) | sub.set_rate(hz) |
| Hand 2 控制动作 | wuji_hand_2_enable(dev, mask) | hand.enable(joints=mask) |
| Hand 2 实时指令 | wuji_hand_2_joint_command_publish + wuji_joint_command_publisher_send | hand.joint_command().publish().send([…]) |
| Hand 2 关节状态订阅 | wuji_hand_2_subscribe_joint_states | hand.joint_states().subscribe() |
| Hand 2 关节诊断订阅 | wuji_hand_2_subscribe_joint_diagnostics | hand.joint_diagnostics().subscribe() |
| Hand 2 IMU 订阅 | wuji_hand_2_subscribe_imu | hand.imu().subscribe() |
| Hand 2 nid 与关节索引换算 | wuji_hand_2_nid_to_joint_index(nid, &index) / wuji_hand_2_joint_index_to_nid(joint_index, &nid) | WujiHand2.nid_to_joint_index(nid) / WujiHand2.joint_index_to_nid(joint_index) |
| Hand 2 错误码描述 | wuji_hand_2_describe_error(code, &info) | WujiHand2.describe_error(code) |
| Hand 2 Flash 日志导出 | wuji_hand_2_export_flash_logs + wuji_hand_2_flash_log_export_free | hand.export_flash_logs() |
| Hand 连接(USB SN) | wuji_hand_connect_sn(sn, alias, &dev) | WujiHand.connect_sn(sn, alias) |
| Hand 关节状态订阅 | wuji_hand_subscribe_joint_states | hand.joint_states().subscribe() |
| Hand 实时指令 | wuji_hand_joint_command_publish + wuji_hand_joint_command_publisher_send | hand.joint_command().publish().send([…]) |
| Hand 实时控制器 | wuji_hand_realtime_controller_open / _set_target_position / get_actual* | hand.realtime_controller(LowPass(…)) |
| Glove 时间同步 | wuji_glove_sync_time(dev, &tsr) | glove.sync_time() |
| Glove 手部模型路径 | wuji_glove_get_hand_model_path / wuji_glove_set_hand_model_path | glove.hand_model_path().get() / .set(path) |
| SDK 用户管理 | wuji_create_user / wuji_switch_user / wuji_list_users | manager.create_user() / switch_user() / list_users() |
| 用户数据导入导出 | wuji_user_data_export / wuji_user_data_preview / wuji_user_data_import | manager.export_user_data() / preview_user_data() / import_user_data() |
| Glove 手部模型标定(异步) | wuji_glove_calibration_start + wuji_glove_calibration_try_finish | glove.calibrate() |
| Glove 手部模型标定(同步) | wuji_glove_calibrate | glove.calibrate_blocking() |
| Glove 触觉接触标定(同步) | wuji_glove_calibrate_tactile_blocking | glove.calibrate_tactile_blocking() |
| 断开 | wuji_dev_disconnect + wuji_dev_release | device.disconnect() |
CMake 工程示例
完整可运行 C 工程(含CMakeLists.txt + 订阅回调示例)见 wuji-sdk 仓库的 examples/c/ 目录,按设备分别存放在 examples/c/wuji_glove/(设置订阅流输出率、在线 IK 自定义手部模型、SDK 用户管理与手部模型标定)、examples/c/wuji_hand_2/(订阅关节状态、控制动作、设备信息、指尖触觉数据、设置订阅流输出率、Flash 日志导出、对掌回放与 MIT 扫频)与 examples/c/wuji_hand/(订阅、发布、抓握循环与触觉状态)子目录,构建步骤参见该目录 README。最小链接方式:
- Linux
- macOS arm64
${SDK} 使用发行包解压目录的绝对路径。CMake 项目将 WUJI_SDK_INCLUDE_DIR 设为 ${SDK}/include,将 WUJI_SDK_LIB 设为 ${SDK}/lib/libwuji_sdk_c.so(Linux)或 ${SDK}/lib/libwuji_sdk_c.dylib(macOS)。
接口清单
Python 与 C 的类型一一对应,字段语义相同,命名与内存表示按各自语言习惯:
表示方式的差异有三处。Python 的
str 字段在 C 是定长 char 数组,例如 frame_id[32]、parent_frame_id[32]。Python 的 list 字段在 C 是指针加长度,例如 WujiFrameTransforms 的 transforms 与 transforms_len。Python 只有一个 Quaternion,C 按数据流的实际精度分为 WujiQuaternionF32 与 WujiQuaternionF64。C 的帧指针仅在订阅回调期间有效,需要保留的数据必须在回调内拷贝,约束详见 C 接口参考。