
TLabel v0.16.0 开放了平台架构任何人 30 分钟就能为自己的触觉传感器写一个适配器把私有数据格式接入统一的 22 维触觉特征空间。本文手把手带你从零写一个完整的数据适配器包含可运行的代码、CLI 验证、以及社区贡献全流程。---你是不是也遇到过这个问题实验室新买了一台触觉传感器数据格式和之前的完全不同。为了跑下游模型你不得不把数据处理管线重写一遍——改字段名、改解析逻辑、改特征提取、改校验规则。换一台传感器又是一遍。触觉数据标注的碎片化是具身智能领域一个被严重低估的基础设施问题。每个传感器厂商都在用自己的格式每种数据集都在重复造轮子。TLabel v0.16.0 就是来解决这个问题的。这个版本正式开放了平台架构——双基类、外部注册、CLI 工具链、社区贡献模板——任何人 30 分钟就能写一个适配器。本文用完整的代码示例带你走一遍这个流程。---1. 什么是 TLabelTLabel 是全球首个传感器无关的触觉数据标注工具包。核心设计思路很简单定义一个统一的特征空间然后为每种传感器写一个适配器把原始数据映射进来。22 维统一特征空间tlabel_v2TLabel v2 定义了 22 个维度的触觉特征分两大类静态特征18 维# 字段 物理含义1 contact 接触状态二值2 deformation_magnitude 表面形变强度3 force_magnitude 法向力大小4 force_peak 窗口内峰值力5 force_direction 力方向角°6 slip_entropy 滑移检测不确定性7 slip_event 滑移事件标记8 texture_energy 表面纹理频率能量9 edge_density 接触边缘像素比10 contact_area 接触区域面积比11 centroid_x 接触质心 X 坐标12 normal_field_magnitude 法向压力场幅值13 normal_field_variance 法向场空间方差14 shear_field_magnitude 剪切应力幅值15 shear_field_direction 剪切方向角°16 delta_force_normal 帧间法向力变化17 delta_force_shear 帧间剪切力变化18 friction_cone_ratio 切向/法向力比时序特征4 维v0.2.0 新增# 字段 说明19 optical_flow_magnitude 帧间运动幅度Farneback20 optical_flow_direction 光流方向角°21 temporal_deformation_rate 形变变化率22 contact_transition 接触状态转移概率不是每个传感器都能输出全部 22 维。适配器通过 capabilities 声明自己支持哪些维度不支持的填 0.0——这是尽力而为的设计不强迫你做不到的事。目前支持的适配器当前内置 9 个适配器覆盖主流触觉传感器和数据集格式类别 适配器 数据源数据集 gelsight GelSight Mini / DIGIT数据集 paxini PaXini PXCap 数据集数据集 daimon Daimon DM-TacClaw 数据集数据集 touchd ToucHD-Force / AnyTouch 2数据集 univtac UniVTAC 跨数据集数据集 vtouch VTouch 视觉触觉数据集 ycb_slide YCB-Slide CMU DIGIT数据集 tacquad TacQuad 多传感器格式 tlabel TLabel Format 原生 JSON截至目前TLabel 在 PyPI 上的累计下载量已超过 14,000 次。 GitHub: github.com/liesliy/tlabel---2. v0.16.0 的核心升级v0.16.0 的主题是一个关键词开放平台。 双基类架构之前所有适配器都继承同一个 BaseAdapter但离线数据集和实时传感器流的场景差异很大。v0.16.0 把它们拆成了两个基类基类用途典型场景DataAdapterBase数据集适配器.h5、.pkl、.json 等离线文件SensorAdapterBase实时传感器适配器连接 USB/UVC/SDK 实时数据流分离的好处很直接数据集适配器关注文件解析和批量转换传感器适配器关注连接管理和帧率——各干各的事接口更干净。 外部适配器注册这是最重要的升级。以前想加适配器必须改 TLabel 源码然后提 PR。现在有两种方式方式一API 手动注册pythonfrom tlabel.adapters import register_external_adapterfrom my_package import MySensorAdapterregister_external_adapter(MySensorAdapter)方式二entry_points 自动发现在你的 Python 包的 pyproject.toml 里声明toml[project.entry-points.tlabel.adapters]my_sensor my_package.adapter:MySensorAdapter安装你的包之后TLabel 会自动发现并注册——完全不需要修改 TLabel 源码。 CLI 命令行工具新增 tlabel 命令行工具四个子命令覆盖日常使用tlabel version # 查看版本tlabel list # 列出所有适配器tlabel info # 查看适配器详情tlabel validate # 校验数据文件 社区贡献工具包在仓库 contrib/adapter-template 目录下提供了完整的适配器开发模板配合 PR 模板和贡献指南降低了社区参与门槛。---3. 环境准备3.1 安装bashpip install tlabel0.16.03.2 确认版本bashtlabel version预期输出tlabel 0.16.03.3 查看当前可用适配器bashtlabel list预期输出TLabel Adapters Dataset Adapters:gelsight - GelSight Mini / DIGIT (.pkl)paxini - PaXini PXCap dataset (.h5, .hdf5)daimon - Daimon DM-TacClaw dataset (.parquet)touchd - ToucHD-Force / AnyTouch 2 (.npy)univtac - UniVTAC cross-dataset (.hdf5, .h5)vtouch - VTouch visual-tactile (.h5, .hdf5)ycb_slide - YCB-Slide CMU DIGIT (.npy)tacquad - TacQuad multi-sensor Sensor Adapters:paxini_gen3 - PaXini GEN3 realtime (SDK)daimon_dm_tac - Daimon DM-Tac realtime (USB/UVC) Format:tlabel - TLabel Format native (.json)Total: 9 dataset, 2 sensor, 1 format---4. 实战写一个数据适配器假设你是一家触觉传感器公司就叫 MySensor的工程师你的传感器输出一份 JSON 文件包含逐帧的接触数据。现在要为它写一个适配器让数据能无缝接入 TLabel 生态。4.1 你的原始数据格式json{sensor_name: MySensor v1,frame_count: 100,frames: [{timestamp: 0.00,is_contact: true,depth: 0.85,max_force: 1.23,area_ratio: 0.42,center_x: 0.51,center_y: 0.48,vibration: 0.07},{timestamp: 0.01,is_contact: true,depth: 0.91,max_force: 1.35,area_ratio: 0.45,center_x: 0.52,center_y: 0.47,vibration: 0.09}]}你的传感器能提供接触状态、深度形变、力、面积、质心位置、振动信号。但无法提供剪切场、法向场分布、光流等。没问题TLabel 的 capabilities 机制就是为这种情况设计的。4.2 完整适配器代码pythonmy_sensor_adapter.py为 MySensor 触觉传感器编写的 TLabel 数据适配器import jsonfrom pathlib import Pathfrom typing import Optionalfrom tlabel.adapters.base import DataAdapterBasefrom tlabel.core.types import TLabelData, TLabelFrameclass MySensorAdapter(DataAdapterBase):MySensor 触觉传感器数据适配器将 MySensor 的 JSON 输出格式转换为 TLabel v2 统一格式。支持维度contact, deformation_magnitude, force_peak,contact_area, centroid_x, centroid_y, texture_energypropertydef name(self) - str:适配器唯一标识符return my_sensorpropertydef supported_extensions(self) - list:支持的文件扩展名return [.json, .csv]propertydef description(self) - str:适配器描述return MySensor tactile sensor adapter (JSON/CSV)def load(self,file_path: str,trajectory_id: Optional[str] None,**kwargs) - TLabelData:将 MySensor JSON 文件转换为 TLabel v2 格式Args:file_path: 输入文件路径trajectory_id: 可选的轨迹 ID默认从文件名提取Returns:TLabelData: 统一格式的触觉数据path Path(file_path)if not path.exists():raise FileNotFoundError(fFile not found: {file_path})if path.suffix not in self.supported_extensions:raise ValueError(fUnsupported format: {path.suffix}. fSupported: {self.supported_extensions})# 读取原始数据with open(path, r, encodingutf-8) as f:raw_data json.load(f)# 逐帧转换frames []for i, frame_data in enumerate(raw_data.get(frames, [])):frame TLabelFrame(frame_indexi,timestampframe_data.get(timestamp, i * 0.01),tlabel_v2{# 你的传感器能提供的维度 contact: float(frame_data.get(is_contact, False)),deformation_magnitude: float(frame_data.get(depth, 0.0)),force_peak: float(frame_data.get(max_force, 0.0)),contact_area: float(frame_data.get(area_ratio, 0.0)),centroid_x: float(frame_data.get(center_x, 0.5)),centroid_y: float(frame_data.get(center_y, 0.5)),texture_energy: float(frame_data.get(vibration, 0.0)),# 你的传感器不支持的维度填 0.0 force_magnitude: 0.0,force_direction: 0.0,slip_entropy: 0.0,slip_event: 0.0,edge_density: 0.0,normal_field_magnitude: 0.0,normal_field_variance: 0.0,shear_field_magnitude: 0.0,shear_field_direction: 0.0,delta_force_normal: 0.0,delta_force_shear: 0.0,friction_cone_ratio: 0.0,# 时序特征optical_flow_magnitude: 0.0,optical_flow_direction: 0.0,temporal_deformation_rate: 0.0,contact_transition: 0.0,})frames.append(frame)return TLabelData(sensorself.get_sensor_info(),framesframes,capabilitiesself.get_capabilities(),metadata{source_file: str(path),original_frame_count: len(frames),})def get_capabilities(self) - dict:声明本适配器支持的维度True 能提供有效数据False 不支持输出为 0.0return {# 你的传感器能提供的contact: True,deformation_magnitude: True,force_peak: True,contact_area: True,centroid_x: True,centroid_y: True,texture_energy: True,# 你的传感器不能提供的force_magnitude: False,force_direction: False,slip_entropy: False,slip_event: False,edge_density: False,normal_field_magnitude: False,normal_field_variance: False,shear_field_magnitude: False,shear_field_direction: False,delta_force_normal: False,delta_force_shear: False,friction_cone_ratio: False,optical_flow_magnitude: False,optical_flow_direction: False,temporal_deformation_rate: False,contact_transition: False,}def get_sensor_info(self) - dict:返回传感器硬件信息return {type: optical,manufacturer: MySensor Inc.,model: MySensor v1,resolution: 220x160,frame_rate: 100,}4.3 代码要点解析这段代码虽然只有 80 多行但覆盖了适配器的所有核心要素① 继承 DataAdapterBase离线数据集适配器继承 DataAdapterBase。如果是实时传感器比如 USB 连接的设备则继承 SensorAdapterBase。② 必须实现的属性和方法name适配器的唯一标识符用于 CLI 和注册supported_extensions声明支持的文件格式load()核心转换逻辑把原始数据变成 TLabelDataget_capabilities()声明哪些维度可用get_sensor_info()传感器硬件元信息③ load() 方法的关键设计TLabel 的 load() 返回 TLabelData 对象它包含三个核心部分sensor传感器信息来自 get_sensor_info()frames帧列表每帧是 TLabelFrame包含 22 维的 tlabel_v2 字典capabilities能力声明来自 get_capabilities()④ 不支持的维度填 0.0这是 TLabel 的设计哲学——统一 schema尽力而为。你的传感器只有 7 个维度有效没问题其他 15 个填 0.0。下游消费者会根据 capabilities 判断哪些维度值得用。---5. 验证你的适配器5.1 Python 中验证python# test_adapter.pyfrom my_sensor_adapter import MySensorAdapter# 实例化适配器adapter MySensorAdapter()# 检查能力声明print(f适配器名称: {adapter.name})print(f支持格式: {adapter.supported_extensions})print(f有效维度: {[k for k, v in adapter.get_capabilities().items() if v]})# 加载数据data adapter.load(sample_data.json)# 检查结果print(f\n加载完成:)print(f 传感器: {data.sensor[manufacturer]} {data.sensor[model]})print(f 帧数: {len(data.frames)})print(f 首帧 contact: {data.frames[0].tlabel_v2[contact]})print(f 首帧 deformation: {data.frames[0].tlabel_v2[deformation_magnitude]})print(f 首帧 force_peak: {data.frames[0].tlabel_v2[force_peak]})运行结果适配器名称: my_sensor支持格式: [.json, .csv]有效维度: [contact, deformation_magnitude, force_peak, contact_area, centroid_x, centroid_y, texture_energy]加载完成:传感器: MySensor Inc. MySensor v1帧数: 2首帧 contact: 1.0首帧 deformation: 0.85首帧 force_peak: 1.235.2 CLI 校验TLabel 的 CLI 工具可以直接校验数据文件是否符合 TLabel v2 格式bashtlabel validate sample_data.json预期输出TLabel Validator v0.16.0File: sample_data.jsonAdapter: my_sensorFrames: 2✅ Schema validation passed✅ Dimension count: 22/22✅ Contact detection: valid (binary 0/1)✅ Value ranges: all within expected bounds✅ Timestamp continuity: valid (Δt 0.01s ± 0.001s)⚠️ Coverage: 7/22 dimensions active (31.8%)Active: contact, deformation_magnitude, force_peak,contact_area, centroid_x, centroid_y, texture_energyResult: PASS (with warnings)覆盖率只有 31.8%没关系CLI 只是告诉你哪些维度是空的不会因此判定为 FAIL。关键是你的 7 个维度都是有效数据。---6. CLI 工具详解v0.16.0 新增的 CLI 工具是日常开发的好帮手下面逐个演示。6.1 tlabel versionbash$ tlabel versiontlabel 0.16.0简单直接用于确认环境版本。写 issue 的时候贴上这个维护者能更快定位问题。6.2 tlabel listbash$ tlabel listTLabel Adapters Dataset Adapters:gelsight - GelSight Mini / DIGIT (.pkl)paxini - PaXini PXCap dataset (.h5, .hdf5)... Sensor Adapters:paxini_gen3 - PaXini GEN3 realtime (SDK)... Format:tlabel - TLabel Format native (.json)Total: 9 dataset, 2 sensor, 1 format如果你注册了外部适配器它会出现在对应的分类下。比如你安装了 tlabel-mysensor 包my_sensor 就会自动出现在列表里。6.3 tlabel info查看某个适配器的详细信息bash$ tlabel info gelsightAdapter: gelsightType: Dataset AdapterExtensions: .pklDimensions: 18/22 activeSensor: GelSight Mini / DIGITDescription: Adapter for GelSight-series visual tactile sensors.Supports both single-file and batch loading.Active dimensions:✅ contact, deformation_magnitude, force_magnitude,force_peak, force_direction, slip_entropy, slip_event,texture_energy, edge_density, contact_area, centroid_x,normal_field_magnitude, normal_field_variance,shear_field_magnitude, shear_field_direction,delta_force_normal, delta_force_shear, friction_cone_ratioInactive dimensions:❌ optical_flow_magnitude, optical_flow_direction,temporal_deformation_rate, contact_transition这在做技术选型时很有用——一眼就能看出某个适配器覆盖了哪些维度。6.4 tlabel validate前面已经演示过了。补充一个批量校验的用法bash# 校验整个目录tlabel validate ./dataset/ --recursive# 输出 CSV 报告tlabel validate ./dataset/ --format csv --output report.csv---7. 贡献到社区写好适配器后你有两种方式把它贡献给社区方式一提交 PR 到 TLabel 主仓库适合通用性强、受众广的传感器适配器。步骤1. Fork 仓库→ github.com/liesliy/tlabel → Fork2. 克隆你的 Fork→ git clone https://github.com/YOUR_NAME/tlabel.git3. 从模板创建适配器→ 复制 contrib/adapter-template/ 到 tlabel/adapters/my_sensor/→ 按模板结构填充代码4. 注册适配器→ 在 tlabel/adapters/__init__.py 中 import 并注册5. 编写测试→ 在 tests/adapters/ 下添加测试用例→ 确保 pytest 全部通过6. 提交 PR→ 使用 PR 模板填写信息→ 附上 sample data 和测试截图CI 会自动运行格式校验和单元测试通过后 3 个工作日内会有 review。方式二发布独立 Python 包适合专用传感器或商业场景。通过 entry_points 自动发现无需修改 TLabel 源码。步骤1. 创建你的 Python 包tlabel-mysensor/├── pyproject.toml├── tlabel_mysensor/│ ├── __init__.py│ └── adapter.py # 你的适配器代码└── tests/└── test_adapter.py2. 在 pyproject.toml 中声明 entry_point[project.entry-points.tlabel.adapters]my_sensor tlabel_mysensor.adapter:MySensorAdapter3. 发布到 PyPIpython -m buildtwine upload dist/*4. 用户使用pip install tlabel-mysensortlabel list # my_sensor 自动出现两种方式对比维度 PR 到主仓库 独立包审核 需要 review 不需要安装 pip install tlabel 即可 额外 pip install tlabel-mysensor更新节奏 跟随 TLabel 发版 独立发版适用场景 通用传感器 商业/专用/快速迭代---8. 总结回顾一下我们今天做了什么了解了 TLabel22 维统一特征空间9 个内置适配器14,000 下载量理解了 v0.16.0 的开放架构双基类分离、外部注册、CLI 工具链写了一个完整的数据适配器继承 DataAdapterBase实现 5 个核心接口用 CLI 验证了数据tlabel validate 一键校验格式合规性了解了社区贡献路径PR 和独立包两种方式触觉数据的碎片化不是某一个团队能解决的——它需要整个社区一起来建设。你的传感器值得一个适配器。 资源汇总GitHub: github.com/liesliy/tlabelPyPI: pypi.org/project/tlabel适配器模板: contrib/adapter-template22 维格式规范: docs/tlabel-format.md如果对你有帮助欢迎点赞、收藏、关注三连 有问题评论区交流也欢迎在 GitHub 提 Issue 或 PR 参与贡献---