概述
本篇实践介绍如何读取 Wuji Hand 2 指尖传感器元数据,并按自描述格式订阅和解析触觉数据。应用场景包括接入不同传感器布局、监控指尖触觉和记录接触数据。 对应的 Python 示例为 3.fingertip_typed.py,C 示例为 3_fingertip.c。 接口清单、自描述格式的字段定义与标定接口见 Wuji Hand 2 指尖触觉。本页说明集成流程、兼容性要求和运行时行为。前置条件
硬件
2.2 的交付形态是触点阵列:拇指 40 触点,其余手指各 34 触点,每触点三轴力加温度,100 Hz 推送。
软件
- Python
- C
前序步骤
先确认设备支持该能力,方法见下一节。数据流
顺序不能颠倒。没有 info 就无法解码 data,帧里没有自描述头。判定设备是否支持该能力
最可靠的运行时判定是看资源清单,不要靠版本号推断:topics() 里未返回 fingertip 条目。具备的设备会列出五条 fingertip/<finger>/data。
这个判定不需要 try/except,也不依赖硬件或固件版本号的映射关系。
format 契约
info.format 是一个 JSON 字符串,示例把它当唯一真相源,一个字段都不硬编码。关键字段:
字段类型到解包格式的映射,示例写死成一张表并对未知类型直接抛错:
数据长度自校验
解码前先算期望长度,对不上直接报错:根据 format 读取单位
firmware v2.4.0 及以上版本,每触点的力归一化到传感器满量程:法向轴 0 到 1,切向轴 -1 到 1,超出部分截断。更早的固件按牛顿上报。合力与温度在两者上都是牛顿和摄氏度。 所以接触阈值要按声明的单位选,不能写死:scale 与 unit。
将触点坐标转换到手模型
positions 与 point_rpy 在传感器模块自身坐标系里,base_xyz 与 base_rpy 给出这个坐标系相对手指 tip_sensor_frame 的位姿。所以触点 i 在手指坐标系里的位置是:
R(base_rpy) @ R(point_rpy[i])。
合力可以还原成真正的力旋量:力为 R(base_rpy) @ R(aggregate_rpy) @ (fx, fy, fz),作用点为 R(base_rpy) @ aggregate_xyz + base_xyz,对连杆原点的力矩是 p × f。
这三个安装位姿键是一起加进契约的。 示例据此做了一条判定:三个全缺表示固件较早、位置信息不可用,只缺一部分说明元数据本身坏了,直接抛错。缺 aggregate_xyz 的固件不报作用点也不报力矩——在那里猜一个点等于凭空编造力臂。
设备会按自己的左右手上报位姿,同一份代码在左手和右手上都对。
SDK 接口版本兼容性
这是接入时需要确认的兼容性要求。
C 侧同理,
wuji_hand_2_get_fingertip_thumb_info(dev, &out) 取代了 wuji_hand_2_get_fingertip_info(dev, finger, &out)。
SDK 不提供兼容适配层。 在 v2026.8.31 上调用新接口:
0=thumb, 1=index, 2=middle, 3=ring, 4=pinky。
仓库里的示例跟随最新接口。使用旧版 SDK 运行示例时,会在读取 info 的步骤抛出
AttributeError。此错误与设备无关。设备不支持该能力时的行为
设备信息:firmware_version = 1.3.0,hw_version = HwVersion(major=0, minor=2, patch=0)。
四条路径全部失败,错误来自不同层:
五根手指的
get_fingertip_info 报的是同一条。topics() 里也未返回 fingertip 条目。
注意 Python 对象上有 fingertip_thumb_data、get_fingertip_info、tactile_calibrate、tactile_status 这些方法——方法存在不代表设备支持,SDK 的接口面是按产品定义的,能不能用要看设备的资源清单。
集成步骤
以下以拇指为例,依次连接设备、读取格式、接收数据和释放资源。完整五指读取代码见 Python 示例 和 C 示例。 下文复用 Python 示例 和 C 示例 中的辅助函数和类型:Python 的fetch_format、make_decoder,以及 C 的 finger_ctx_t、parse_format、on_fingertip_data、snapshot、status_line。这些辅助函数负责解析格式、检查数据帧和显示结果,并非 SDK 接口。
1. 连接指定设备
先按回调订阅实践完成 SDK 初始化和设备连接。多设备环境按目标 SN 选择设备。后续 Python 片段使用已连接的hand 和 manager,C 片段使用已连接的 dev。
2. 读取拇指格式并准备解码器
读取info,保存格式摘要,并按 format 描述的字段类型、偏移和比例建立解码器。只有这一步成功,才订阅对应手指。读取失败时跳过该手指,或结束单指程序并断开设备。
- Python
- C
fetch_format(hand, 0) 内部调用 hand.fingertip_thumb_info().get()。C 的 parse_format 同时准备后续回调所需的长度、单位和字段信息。两种语言都从格式读取布局,避免写死触点数量或字节偏移。
3. 订阅并处理数据帧
Python 在主循环读取订阅队列,C 由后台回调接收帧。先检查info_digest 与保存的摘要一致,再解码。摘要为 0 时不解码,摘要变化时重新读取 info 并建立解码器。帧长度必须与格式声明一致。
- Python
- C
g_stop、信号处理和 REFRESH_US。on_fingertip_data 检查帧状态、摘要和长度,并在互斥锁保护下复制数据,主线程通过 snapshot 读取。摘要变化时,C 示例 丢弃该帧并显示状态,应用需关闭订阅、重新读取格式后再订阅。
4. 关闭订阅并断开设备
先关闭订阅,等回调工作线程结束,再释放回调上下文和设备。Python 已在上一步的finally 中处理正常退出、异常和中断。C 的成功路径与失败路径共用以下清理段。
运行与输出
- Python
- C
注意事项
单根手指读不到 info 是正常情况,不是故障。示例的处理是跳过它继续解码其余手指,只有五根全读不到才停。
重新标定与状态查询
具备该能力的设备上,hand.tactile_calibrate() 把五个指尖重置到全新零基线。C 侧是 wuji_hand_2_tactile_calibrate(dev)。
标定期间传感器表面必须无负载,不能触碰、不能压在任何东西上。标定完用 hand.tactile_status(finger) 查各传感器的型号与标定状态,确认已完成。
joint_diagnostics 流的每帧汇总里带指尖触觉在线位图,可以用来持续监控哪些指尖在线,不用轮询。
扩展用法
降低输出率
100 Hz 五路触点阵列的数据量不小。fingertip/*/data 是速率控制的入口点,可以用订阅句柄的 set_rate() 降频,需要固件 v2.3.0 及以上版本,见 Wuji Hand 2 输出率调节。
固件升级后重读 info
format 里的 scale、unit、安装位姿都可能随固件变。升级之后不重读 info,解码器会按旧契约解析新数据,结果是数值全错但不报错。把读 info 放在每次连接之后,别缓存到磁盘。
仅判断是否接触
不需要每个触点的三轴力时,用合力段的fx/fy/fz 加一个阈值就够了,不用解每个触点。合力在任何固件上都是牛顿,不受归一化影响。
逐指容错
五根手指各自独立上报 info。写生产代码时按指处理失败,别让一根手指的问题中断整条流水线——示例就是这么改的。相关内容
- Wuji Hand 2 数据订阅:回调:订阅模型与回调线程约束
- Wuji Hand 2 输出率调节:给
fingertip/*/data降频 - Wuji Hand 2 设备信息:读取固件版本与资源清单
- 通用数据类型:
FingertipSensorInfo与FingertipSensorData