18 网络传输 · TCP、UDP、ADB 与时间同步

返回 00 - 项目总览与学习路线 | 前置 17 位姿追踪 - Unity 与 Meta Quest 开发

为什么学这个(项目关联)

UMI 是三路异构数据流的融合系统:

  1. 相机流(板载/头显,图像到主机有传输延迟)
  2. 编码器流(ESP32 → USB 串口)
  3. 控制器位姿流(Quest → Wi-Fi UDP)

原文明确做了时延补偿:“把两组读数做时间对齐后,运动测试中标记与编码器读数匹配度最好;所有结果都做了该时延补偿。” 没有同步,融合数据就是错位的,训练数据直接污染。

知识点清单

1. 传输协议选型(原文的三方案对比)

方案协议特点适用
TCP over ADB via USB可靠、有序、重传;经 ADB 隧道成品系统(原文认为最适合最终产品)
TCP over ADB via Wi-Fi同上,无线有可靠要求的无线场景
UDP via Wi-Fi(原文选)无连接、不重传、不等待实时调试:不因丢包阻塞,接口不受限
  • TCP 三次握手、确认重传、队头阻塞(head-of-line blocking)
  • UDP 尽力而为:丢一帧无所谓(下帧马上来),控制/追踪数据天然适合
  • 关键思维:实时流要”新”,不要”全”;文件传输要”全”

2. ADB(Android Debug Bridge)

  • Quest 是 Android 设备:adb devices、adb install、adb forward 端口转发、adb over Wi-Fi 配对
  • Unity 的 Build and Run 本质走 adb 装 APK

3. 多源时间同步(本节核心难点)

问题:三路流各有各的时钟与延迟——

  • 相机:曝光时刻 ≠ 到达主机时刻(传输+解码延迟,几十~几百 ms)
  • 串口:USB 缓冲
  • UDP:网络抖动

策略:

  1. 源端打时间戳:数据包内带设备时钟时间(Quest 的 timestamp、ESP32 的 micros()),而非到达时间
  2. 时钟对齐:各设备时钟 ↔ 主机时钟的偏移估计(简单法:线性回归 offset 估计;进阶:PTP/NTP 思想、软件同步触发)
  3. 时延估计:互相关法——两路信号都包含同一运动(如快速开合夹爪),对时间序列做互相关找使相关度最大的 lag(原文做法即此类)
  4. 插值重采样:以最低频流(相机 ~30-60Hz)为主时钟,把高位姿流插值到相机时间戳

4. 数据 pipeline 工程实践

  • 接收端架构:每路一个线程/协程 + 环形缓冲区(ring buffer),按时间戳归并
  • 丢包容错:序列号检测,只告警不重传
  • 落盘格式:分 episode 目录;rosbag 不必需(无 ROS 时用自定 zarr/npz/mp4)
  • 后处理 pipeline 衔接 14 模仿学习 - ACT 与 Diffusion Policy 的数据格式

学习资源

资源用途
《计算机网络:自顶向下方法》传输层章节TCP/UDP 原理
Python socket / asyncio 文档收发实现
ADB 官方文档Quest 调试
numpy 互相关 np.correlate / scipy.signal.correlate时延估计

实践任务

  1. 💻 Python 写 UDP 收发对:发送端 100Hz 推递增序列号,接收端统计丢包率与时延分布(直方图)
  2. 💻 同一 UDP 流改 TCP,对比在人为丢包(防火墙/断连 1s)下的行为差异(TCP 阻塞 vs UDP 丢弃)
  3. 💻 时延估计实验:同一事件(如快速开合夹爪)同时被相机与编码器记录,对两路信号互相关求 offset——复现原文”时延补偿”思想
  4. 💻 三流融合 demo:相机 30Hz + 模拟位姿 200Hz,按时间戳归并插值输出统一采样率的表

掌握标准(自测)

  • 能画出本系统三路数据流的时间线图并标注各延迟来源
  • 能写代码估计两路信号之间的时延并做补偿
  • 能说清为什么 UDP 适合实时追踪、TCP 适合最终产品
  • 理解”源端时间戳 > 到达时间戳”的原因

关联笔记

实践记录

(学习时在这里追加:日期 / 做了什么 / 踩坑 / 疑问)