120 Hz 手部数据怎么存:MANUS Metagloves Pro Haptic数据手套从 CSV 到 Parquet 的工程方法

📅 2026/7/31 11:45:59 👁️ 阅读次数 📝 编程学习
120 Hz 手部数据怎么存:MANUS Metagloves Pro Haptic数据手套从 CSV 到 Parquet 的工程方法

关键词:MANUS 数据手套;Metagloves Pro Haptic;Parquet;Apache Arrow;时序数据;机器人数据集

120 Hz 到底会产生多少数据

一心科研平台官方MANUS规格显示,Metagloves Pro Haptic 的五个 EMF 指尖传感器以 120 Hz 提供位置和旋转数据,Hand Solver 3 可输出 25 DoF 手部骨架。120 Hz 意味着每秒目标采样 120 帧:

1 分钟:7,200 帧 1 小时:432,000 帧 8 小时:3,456,000 帧

如果一帧保存 25 个关节的旋转、五个指尖位置和旋转、手腕姿态、时间戳与状态字段,单帧很容易达到数百个数值。CSV 还要把每个浮点数转换为文本,并反复写入逗号和列名,因此实际容量通常远大于“字段数 × 4 字节”的理论二进制大小。

更重要的是,文件大小只是表面问题。采集数周以后,真正困难的是:某一列到底是什么单位、哪一版求解器生成、缺失帧如何表示、左右手是否混在一起,以及处理脚本能否只读取需要的几列。

CSV 为什么适合调试,却不适合做唯一主格式

CSV 的优势很明确:可以用文本编辑器查看,几乎所有语言都能读取,适合导出几十秒样本和排查接口。但它缺少统一的类型与元数据约束。

同一个值1可能是整数、浮点数、布尔值或字符串。时间戳可能被表格软件改写,NaN 和空字段的含义也可能不同。四元数列如果只叫q1、q2、q3、q4,无法判断分量顺序;关节角如果没有单位,后续人员也无法确定是度还是弧度。

CSV 还不适合随机读取少量字段。分析程序即使只需要食指 MCP 屈伸角,也往往要扫描整行文本并解析全部列。

因此,比较稳妥的原则是:

  • CSV 用于小样本交换和人工检查;
  • 结构化二进制格式作为长期主数据;
  • 原始数据与派生数据分开保存;
  • 每个数据文件都由清单描述,而不是依赖文件名猜测。

先设计数据模型:宽表还是长表

宽表

每一行对应一个采样时刻,每个关节或指尖字段各占一列:

timestamp_ns, frame_id, index_mcp_flex, index_mcp_abduction, index_tip_px, index_tip_py, index_tip_pz, index_tip_qx, index_tip_qy, index_tip_qz, index_tip_qw, ...

宽表适合固定骨骼拓扑和高频批量分析。同一行天然表示同一帧,各列也容易进行压缩。缺点是字段很多,骨骼版本变化时需要升级 schema。

长表

每一行只记录一个骨骼或传感器实体:

timestamp_ns, frame_id, hand, entity, field, value

长表容易增加新实体,但一帧会展开成大量行,连接和重建成本很高。对于固定的 120 Hz 手骨架主数据,通常不如宽表高效;它更适合低频事件、标签或稀疏诊断记录。

实践中可以混合使用:手部姿态采用宽表,触觉命令、任务事件、异常日志和标注采用独立事件表,通过session_id、frame_id和统一时间轴关联。

字段名称就是数据合同

字段名应携带稳定语义,但不必把全部说明塞进列名。推荐至少建立数据字典,说明:

  • 字段名称与数据类型;
  • 单位,例如米、弧度、纳秒;
  • 局部还是全局坐标;
  • 父坐标系名称;
  • 四元数分量顺序;
  • 左右手和关节命名规则;
  • 缺失值含义;
  • 字段来自设备、求解器还是二次计算。

25 DoF 是 MANUS Hand Solver 输出的完整手部骨架自由度,不表示存在 25 个独立物理传感器。若数据表同时保存指尖传感信息和求解后的骨骼结果,应通过前缀或数据层明确区分,例如:

sensor.index_tip.position_x solver.index_mcp.flexion derived.index_tip.velocity_x

时间戳优先使用整数,不要使用格式化日期字符串

高频数据的主时间列适合保存为int64,例如相对于统一时基的纳秒或微秒计数。格式化日期字符串适合人阅读,却会增加空间、解析成本和时区歧义。

至少建议保存:

  • sample_time_ns:样本对应的采样时间或经过映射的统一时间;
  • arrival_time_ns:主机接收时间,如果项目需要分析链路延迟;
  • frame_id:单调递增帧序号;
  • clock_domain:时间戳属于设备时钟、系统时钟还是 ROS Time。

不能获得设备采样时间时,应把主机到达时间明确标注为 arrival time,不要为了字段整齐而把它命名成 sample time。

跨 Session 不建议只用“从零开始的秒数”。文件移动或合并后容易失去绝对关联。可以同时保存 UTC 参考时间和 Session 内单调时间,但隐私敏感项目要评估绝对时间是否属于需要脱敏的元数据。

缺帧不要用上一帧悄悄填满

用文件行数除以时长,只能得到平均帧率,发现不了连续缺帧。每帧保存frame_id后,可以直接检查编号间断;时间戳则用于分析实际帧间隔和抖动。

推荐保留如下字段:

frame_id is_valid quality_flags is_interpolated source_frame_before source_frame_after

若下游算法要求固定 120 Hz,可以创建派生数据集进行重采样,但原始层仍保留真实缺口。插值帧不能伪装成设备原始输出。

关节角可以根据任务选择线性或模型约束插值;位置可在短间隔内线性插值;四元数旋转应使用 SLERP 等旋转空间方法。连续缺失时间超过阈值后,宁可保留缺失,也不要编造一段平滑动作。

float32 还是 float64

把所有数值保存为 float64 最简单,但容量较大;float32 容量减半,很多机器学习流程也以 float32 计算。选择不能只看小数位数,而要结合单位和误差预算。

例如,以米保存指尖位置时,float32 在常见手部尺度上通常能提供很细的数值分辨率,但这不等于传感器本身具有同等准确度。存储精度高于测量精度不会创造新信息,存储精度过低却可能引入额外量化误差。

建议做一次往返测试:

  1. 将代表性 float64 数据转换为目标类型;
  2. 再转换回 float64;
  3. 计算位置、关节角和相对旋转误差;
  4. 与项目允许误差及设备实际噪声比较。

四元数转换为较低精度后应检查模长,并在需要时重新归一化。不要把四元数四个分量分别保留不一致的小数位。

为什么 Parquet 适合分析型数据

Apache Parquet 是面向分析的列式文件格式。它按列组织数据,并支持压缩、编码、统计元数据和选择性读取。对宽表手部数据而言,重复的列类型和相近数值通常比 CSV 文本更容易压缩;分析程序也可以只读取食指、时间戳和标签等少数列。

Parquet 与 Apache Arrow 生态配合良好,Python、R、Java、C++ 和多种数据平台都可读取。它适合:

  • 机器学习特征准备;
  • 按参与者或 Session 批量查询;
  • 只读取部分关节字段;
  • 与标签表和实验条件表连接;
  • 保存明确的数据类型与空值。

但 Parquet 不是实时数据库,也不是所有数据的唯一选择。采集程序可以先写入安全的分块缓冲或日志格式,在 Session 结束后转换为 Parquet,并进行完整性检查。不要让一次程序崩溃导致数小时数据只存在于内存中。

HDF5 什么时候更合适

HDF5 支持层级组织、多维数组、分块、压缩和丰富属性。若项目数据天然是规则张量,例如:

[frame, joint, quaternion_component]

或者需要在一个容器中管理多种数组,HDF5 会很方便。它也常用于科研计算工具链。

Parquet 更接近带 schema 的分析表,HDF5 更接近层级化数组容器。选择应考虑团队语言、并发模式、读取方式和长期维护能力,而不是简单判断谁“更先进”。

无论选哪种格式,都应通过小规模基准测试比较:

  • 写入速度;
  • 文件大小;
  • 读取全部数据的耗时;
  • 读取少量关节列的耗时;
  • 随机访问单个 Session 的耗时;
  • 程序异常退出后的恢复能力。

分块大小要围绕 Session 和访问模式设计

不要把整个项目保存成一个无限增长的大文件,也不要每一帧生成一个小文件。两种极端都会造成管理和性能问题。

推荐以 Session 为基本管理单位,再按时长或文件大小分块。例如一段较长采集可以保存为:

P017/ 2026-07-30_session-A/ manifest.json hand_raw_000.parquet hand_raw_001.parquet events.parquet calibration.json checksums.sha256

Parquet 的 row group 或 HDF5 chunk 大小应通过实际查询模式选择。块太小会增加元数据和文件系统开销;块太大则会让局部读取和故障恢复变差。

原始层、标准层和特征层分开

一套可维护的数据目录至少区分三层:

Raw

尽量保留 SDK 或采集接口能够提供的原始字段、原始时间戳与状态,不覆盖、不平滑。

Standardized

完成字段命名、单位统一、坐标转换、四元数连续化和质量标记,但仍保留与原始帧的映射。

Features

保存速度、加速度、抓握类别、窗口统计量或模型输入等可重新生成的数据。

特征层不应成为唯一副本。算法更新后,如果原始层仍在,就能重新计算;如果只保存最终特征,错误可能无法修复。

每个 Session 都需要 manifest

数据文件本身不能解释全部实验上下文。建议为每个 Session 保存一份 JSON 或 YAML 清单:

{"schema_version":"hand-data-1.0.0","participant_id":"P017","session_id":"2026-07-30-A","hand":"right","glove_size":"M","target_rate_hz":120,"connection":"wired","core_version":"recorded_at_runtime","sdk_version":"recorded_at_runtime","coordinate_system":"documented-reference","rotation_order":"quaternion_xyzw","position_unit":"meter","storage_format":"parquet","compression":"recorded-at-write-time"}

版本字段不能只写“最新版”。软件更新可能改变求解器行为、骨骼字段或导出流程,未来无法重建“最新版”指的是哪一版。

校验和解决什么问题

为每个数据文件计算 SHA-256 等校验和,可以发现传输、复制或归档后的内容变化。校验和不能证明实验设计正确,也不能替代备份,但能回答“这个文件是否与入库时完全一致”。

推荐流程是:

  1. Session 正常结束并关闭文件;
  2. 读取文件完成 schema、行数和时间戳检查;
  3. 生成统计摘要和异常报告;
  4. 计算校验和;
  5. 将数据复制到独立存储;
  6. 在目标端再次验证校验和。

清洗或格式转换会合法改变文件内容,应生成新的数据层、处理版本和校验和,而不是覆盖 Raw 文件。

一套最低验收清单

  • 实际帧数、目标帧数和 Session 时长可相互核对;
  • frame_id的间断、重复和逆序均有统计;
  • 时间戳单调性与单位经过验证;
  • 左右手、坐标系和四元数顺序写入数据字典;
  • NaN、无穷值、零四元数和越界值有明确处理;
  • 抽取任意一分钟数据可以回放并与视频或任务事件对齐;
  • Parquet/HDF5 文件可以被第二种独立工具读取;
  • manifest、schema、处理代码版本和校验和齐全;
  • Raw 数据保持只读,派生数据能够重新生成。

结语

120 Hz 只是采样目标,不是数据工程方案。MANUS Metagloves Pro Haptic 可以提供丰富的手部姿态和指尖数据,但这些数据能否用于长期科研、机器人训练和跨团队协作,取决于字段合同、时间戳、缺失标记、格式选择、版本记录和完整性验证。

准备建设 MANUS 数据手套采集平台、机器人示教数据集或多人实验数据库的团队,可联系 MANUS 数据手套中国区代理商一心科研,并通过官网 www.yixinkeyan.com 了解产品与技术支持信息。项目沟通时建议同时提供预计采集人数、单次时长、数据字段、同步设备和后续分析工具,以便在正式采集前确定存储方案。