概述
本篇实践介绍如何订阅 Wuji Hand 2 的joint_states 实时状态流,并在回调中读取在线关节的位置(position)、速度(velocity)和力矩代理值(effort)。应用场景包括实时监控关节状态、记录和分析运动数据,以及为上层控制器提供位置、速度和力矩反馈。
对应的 Python 示例为 0.subscribe_callback.py,C 示例为 0_subscribe_joint_states.c。字段定义见 joint_states 字段定义。
前置条件
硬件
本示例只读取,不使能电机,手指不会动。
软件
- Python
- C
前序步骤
无。设备上电、网络连通即可。数据流
每帧是一个自描述的变长聚合体:header 带 seq、timestamp_us 与 frame_id,joints 只包含固件本周期上报的关节。
帧结构实测
在 20 关节全在线的设备上,单帧实测如下:nid 不连续,而且与数组索引是两套编号。 实测 20 个在线关节的 nid 依次是 1 2 3 4、6 7 8 9、11 12 13 14、16 17 18 19、21 22 23 24,跳过 5、10、15、20。每根手指占用 5 个 nid 号段但只用前 4 个。
两者的换算关系实测吻合全部 20 个关节:
thumb_S1(nid 1),索引 4 是 index_S1(nid 6),索引 19 是 pinky_S4(nid 24)。拿 nid 直接当数组下标会整体错位,关节标签与完整对照见设备信息。
运行时处理
C 侧回调在专用工作线程上触发,
frame 指针只在回调期间有效,其堆上的 joints 数组在回调返回后立即释放,不能留存指针。
集成步骤
- Python
- C
运行与输出
- Python
- C
position 稳定,velocity 在零附近抖动。
输出率约 1 kHz。 实测 5 秒收到 5555 帧,按设备端 seq 差计算为每秒约 1000 帧。回调中执行阻塞操作会导致积压。
配置与适配
多设备环境必须指定设备
这是本示例最容易踩的坑,两侧行为还不一样:
Python 侧的示例没有
--sn 参数(Glove 的同类示例有)。共用网络里跑之前,把连接那段改成指定 SN:
Session already exists,此前已连的设备订阅随之终止,整轮只收到 1 帧数据。
订阅更多数据流
joint_states 之外,设备还提供 joint_diagnostics、imu、指尖触觉等。订阅方式相同,换成对应的资源方法即可。指尖触觉的解码方式见 Wuji Hand 2 指尖触觉。
降低输出率
约 1 kHz 对多数应用偏高。用订阅句柄的set_rate() 降频,见输出率调节。