RoboPocket APP简单介绍
- RoboPocket APP 是数据采集的控制中心与智能中枢。它不仅提供基础的录制与管理功能,更通过内置的算法模型,充当采集员的"实时教练"。APP 界面简洁直观,通过语音提示与屏幕可视化反馈,确保用户采集的数据符合训练标准。
| 功能 | 功能描述 |
|---|---|
| 设备自检与连接 | 开机自动检测传感器状态,手机靠近设备即可快速连接配对。 |
| 采集任务管理 | 支持采集任务管理,确保采集数据与云端下发任务严格对齐。 |
| 教学引导 | 支持离线播放任务引导视频,指导数采员动作 |
| 交互与控制 | 支持语音指令开始/停止,支持实体按键触发。 |
| 实时可视化 | 实时显示当前建图状态,支持第一人称视角预览。 |
| 实时采集指导 | 实时检测动作过快、SLAM异常、特征点缺失、超出机械臂工作空间等异常采集动作,通过语音和画面实时提示。 |
| 端侧质量筛查 | 支持采集回放与质量检查 |
| 数据上传 | 支持无线以及手动上传数据至云端 |
| 自动维护数据标签 | 包含任务名称、时长、数据质量问题等标签 |
RoboPocket 数据构成

| 数据项 | 说明 | 频率 |
|---|---|---|
| RGB图像(鱼眼镜头) | 默认分辨率 1280*960 | 默认 30 Hz |
| 深度图像(LiDAR) | 默认分辨率 640*480 | 默认 30 Hz |
| 末端执行器位姿 | pos + quat (7D) | 默认 30 Hz |
| 夹爪宽度 | 单位 m | 默认 30 Hz |
| SLAM数据 | SLAM日志信息 | 默认 30 Hz |
-
**时间戳:**各传感器之间的时间戳对齐需运行后处理脚本;时间戳误差≈15ms
-
**数据格式:**穹彻具身数据格式(NEDF3)
这 App 本质上在做什么
从 MainPage 的 Dependencies 可以看出,整个应用是围绕 一台 iPhone 上的 ARKit 会话 搭起来的:几乎所有重要能力都接到同一个 ArManagerV1 上
ArManagerV1 不是「随便放个 AR 预览」,它里面直接持有一个 ARSession,并且和 录制管线 绑在一起:有 VideoWriter、DepthMapRecorder、ArV2.RecordingSession、ArV2.ArtifactWriter,还有 ArUco 检测、夹爪检测、RobotTracker 等
所以可以把它理解成:用手机相机 + ARKit 做空间定位,同步录视频、深度、每一帧的位姿和夹爪等信号,最后落成一个带 metadata.json、视频、frame_data.bson、深度包的数据目录------这就是实验室要采集的「一条 episode」的形态。
ArtifactWriter.finish里写得很具体:写完frame_data.bson、metadata.json,对recording.mp4、frame_data.bson、depth_images.tar做 SHA256,若配置要求则UploadManager.addDirectoryToQueue把该目录丢进上传队列(ArV2.ArtifactWriter.swift)。
换句话说:Prepare / Record / Upload 三个 Tab,对应「开机准备 → 现场录数据 → 把录好的文件夹传到云上」,而不是三个无关功能。
四个 Tab 在代码里分别是什么感觉
- Prepare(
PrepareV2)
横屏时左右分栏:一侧欢迎/登录文案(代码里还有「口袋机采」、传感器说明那段 Text),另一侧是一堆控制项(蓝牙 BluetoothEncoderManager、Peers、AR、上传、RobotTracker 等)。作用是:在开始正式录制页之前,把账号/项目/设备/多机状态准备好,并能跳到 Record。它自己不负责「录一整条数据」的核心逻辑,但会动 UserConfig、CoScene 项目 id 等。

- Record(
RecordView)
这是 功能最挤的一屏:除了 ArManagerV1,还挂了 StreamManager(USB 往外推图像/位姿)、TeleopManager(按配置往 HTTP 地址发数据,默认路径像 /unity,明显是给仿真或上位机用)、InferenceManager、VoiceControl、音量键控制、StressTest.Manager、RecordV2View.Viz 等。
所以录制页不只是「点录制」:同一条 AR 数据流可能被同时用于本机落盘、USB 流、遥操作网络发送、以及推理可视化。

- Upload(
UploadQueueView+UploadManager)
UploadManager维护fileStatus列表,持久化在 Documents 下的uploadQueue.json;每条记录对应 一个文件夹(episode) ,带任务标签、帧数、时长、问题标记、UploadStatus等(UploadManager.swift里FileStatus)。上传时还会通过EventBus发IDontWantToSleep,避免传一半屏幕熄灭------这是很具体的工程细节。

- Profile
个人/设置类界面(从 MainPage 看是独立一块),和上面三条主路径相比更偏账户与偏好。

ps:用的公司手机展示的界面 我没有苹果手机。。。力图方便了
代码

顶层每个文件夹/条目是干嘛的
Ardc2.xcodeproj/: Xcode 工程本体(编译设置、文件引用、build phases 都在这里)。src/: App 主要 Swift/ObjC 代码(SwiftUI、AR、录制、上传、硬件等几乎都在这)。assets/: 非 Xcode asset catalog 的资源(音频 mp3 就在这里)。media.xcassets/: Xcode 的 Asset Catalog(图片、颜色等,供Image("...")这类调用)。frameworks/: 三方/自编 xcframework 之类(README 里提到的 OpenCV xcframework 会落在这)。rust/: Rust 侧逻辑(主要是运动学/IK 这一类"算得快/跨平台"的东西),通过脚本构建成 iOS 可用产物。prototype/: 原型/实验性子项目(不一定进主 App 流程,更多用于验证想法/可视化工具)。tests/: 测试相关docs/: 项目内文档/踩坑记录(比如 Xcode+git 问题、已知 bug 等)。scripts/: 构建/打包/辅助脚本(比如构建 Rust、整理产物等)。.github/workflows/: CI 流水线Ardc2.xcconfig/Ardc2.xcconfig.example: Xcode 编译配置(环境差异、开关、路径等)。buildServer.json: VSCode/SourceKit-LSP 相关配置(配合xcode-build-server)。cspell.json: 拼写检查配置(开发体验用)。README.md/CLAUDE.md: 项目说明 + 代码风格/约定
src/ 里每个子文件夹做什么(按"功能域"讲人话)
ar/: AR 录制/状态/问题检测的"V1"实现与 UI 容器(ARView 承载、overlay、Aruco 检测入口等)。ar_v2/: AR 录制数据结构与管线的"V2"实现(比如RecordingSession、FramePipeline、ArtifactWriter把 episode 落盘成目录)。bluetooth/: 蓝牙外设通信(例如编码器/夹爪相关的 BLE 管理)。calib/: 标定相关(让传感器/机器人/坐标系对得上)。config/: 配置系统与服务端地址等(核心是UserConfig作为全局配置中心)。coscene/: 与 CoScene 相关的配置/接口封装(偏"对接某个后端/平台")。expr/: 实验性页面/小试验(教程、临时 overlay、demo 之类)。gripper/: 夹爪检测/跟踪/配置/事件(和 BLE 数据、视觉检测、录制字段会交织)。image/: 图像管线更偏工程化的部分(视频写入、深度录制、去畸变等)。img/: 更偏"视觉算法小模块"的集合(例如 ArUco detector、镜头检查等)。inference/: 在线推理与动作可视化(从 AR 帧取观测、发请求、收结果并在画面里展示)。log/: 日志系统与日志查看 UI(例如LogViewerSheet)。math/: 小型数学工具(滤波、向量/矩阵辅助等)。nedf2/: 一套数据格式/录制会话/转换链(偏"数据协议/落盘格式/兼容"那层)。opencv/: OpenCV 相关桥接/封装(与frameworks/的 OpenCV 产物配合)。peers/: 多机协同(MultipeerConnectivity、时间同步、心跳、广播/typed event 等)。prepare/: 老版准备页/准备流程组件。prepare_v2/: 新版准备页/准备流程(在MainPage看到的PrepareV2就在这里)。pubsub/:EventBus(Combine 的类型安全事件总线,很多模块靠它解耦通信)。py_like/: 一些"写起来像 Python"的小封装(例如 requests 风格的网络请求等)。quality/: 质量检测/问题标注(录制后检查、生成problems,并影响上传/展示)。record/: 录制主页面(V1)与录制期间的控制、任务、语音、音量键、工具面板等。record_v2/: 录制 UI 的 V2/新组件(计时器、样式、可视化组件等)。robot/: 机器人相关视图/跟踪/约束(如RobotTracker、视角优化等)。s3/: S3 协议相关(签名、put object、连接测试、object key 规则等),供上传使用。stream/: 数据流输出(例如从ar.current取帧,经 USB 或其它通道以 ~30fps 推送)。stress_test/: 压测/稳定性相关入口与配置(项目里还把它当"单模块风格最佳实践"示例)。task/: 任务选择/任务控制台(采集任务的选择、展示、执行 id 等可能在此汇聚)。thread/: 线程/队列相关抽象或小工具(减少并发杂乱)。tools/: 工具页/工具事件(录制时的辅助工具集合)。totp/: 一次性验证码(TOTP)相关(通常用于登录/鉴权流程)。ui/: 通用 UI 组件与动效/样式(各种 overlay、小组件、颜色等)。upload/: 上传队列 UI +UploadManager(落盘目录加入队列、进度统计、失败重试等)。usb/: USB 相关管理(与stream/配合,把数据推到外部设备/上位机)。user/: 用户/登录/会话(User.Hub、User.Login等都在这条线上)。utils/: 低层通用能力(文件系统Fs、时间、数学、ObsRw并发安全封装等)。
流程线
下面按三条「故事线」把 src/ 里那些文件夹串起来,方便你建立心智模型(都是代码里真实存在的主路径,不是概念图)。
线 1:录一条 episode(从准备到可上传)
-
user/登录后进主界面;
UserConfig里带着你是谁、任务 id、夹爪版本等,后面全程都会读。 -
prepare_v2/(老路径在prepare/)横屏准备页:检查/配置蓝牙、Peers、任务、项目 id 等,能安心点进录制。
-
ar/+ar_v2/ar/:AR 会话、界面容器、Aruco、状态、问题提示等「壳」。ar_v2/:真正的一条录制会话数据结构(RecordingSession)、帧管线、收尾写盘(ArtifactWriter:mp4、bson、depth tar、metadata.json、哈希)。
-
image/+img/视频编码、深度打包、去畸变、ArUco 等------都是「这一帧/这一条数据」的工程细节。
-
gripper/+bluetooth/夹爪宽度/角度等进
RecordData;外设往往走 BLE,和录制时间轴对齐。 -
robot/机器人几何/约束/跟踪(和 Rust 运动学侧配合),用来在录制里做合理性检查或辅助信息。
-
quality/收尾时对整段数据做检查,问题写进
problems,影响你是否该上传、UI 怎么提示。 -
upload/+s3/若配置要上传:
UploadManager把整个目录登记进队列(uploadQueue.json),再用 S3 相关代码真正 PUT 到 bucket。
一句话:prepare_* → record → ar/ar_v2 落盘 → quality → upload/s3。
线 2:多机 / 协同(Peers)
-
peers/MultipeerConnectivity:发现设备、时间同步、心跳、广播会话信息;让多台手机/角色在「同一时间轴、同一任务语义」下工作。
-
config/多机模式、相机位(左手腕/右手腕等)存在
UserConfig里,影响 UI 和同步语义。 -
ar/(与 Peers 交叉部分)广播 session id、参与者锚点等,和 AR 里的「谁在录、谁在从机」有关。
-
inference/(可选)会通过 Peers 发推理命令、同步「硬币/抓取」一类状态------多机时谁算、谁显示会绕这里。
一句话:config 定角色 → peers 对齐时间与状态 → ar 里体现多机会话。
线 3:录制进行时「往外送」的三条路(可选)
同一条 ArManagerV1 的当前帧,可能被并行用于:
-
stream/+usb/约 30fps 取
ar.current,经 USB 推到外设/上位机(仿真或别的管线)。 -
stream/里的TeleopManager(在stream/目录)HTTP 推到 Unity 等(端点可配),偏遥操作/仿真闭环。
-
inference/取图像+位姿+夹爪,请求模型,把动作可视化叠在 AR 上;通过
pubsub/的EventBus和别处解耦。
一句话:落盘是主产品;USB / HTTP 遥操作 / 推理是同帧数据的副出口。
横切(几乎所有线都会碰到)
pubsub/:EventBus,模块间发事件(上传防息屏、推理完成等)。log/:日志与查看。utils/:Fs、ObsRw、时间等基础设施。math//thread/:数值与并发小件。nedf2/+coscene/:偏「某种数据协议/平台对接」,在落盘或上传链路上出现。expr/、tools/、stress_test/、task/:实验页、工具箱、压测、任务 UI------不每条录制都必须经过,但会碰配置和事件。
更精简的讲解代码
技术栈和目录结构
技术栈
RoboPocket实际用到的核心技术栈是:
-
SwiftUI:页面和交互主框架。
-
Combine:状态发布、订阅和 manager 间联动。
-
ARKit / RealityKit:相机追踪、协同会话、AR 画面承载。
-
CoreBluetooth:夹爪蓝牙通信。
-
MultipeerConnectivity:多机发现、配对、同步、广播。
-
URLSession:登录、任务、CoScene、通用上传、S3 等网络请求。
-
OpenCV:图像处理、Aruco、标定。
-
Rust + UniFFI:机器人运动学和部分底层能力,最终编成
Mobile.xcframework给 Swift 调用。
目录结构
核心源码均在 src/ 下:
-
src/user:登录、用户状态、CoScene 远程配置刷新。 -
src/prepare_v2:采集前准备页,当前主入口。(prepare_v2.*) -
src/record:当前正在使用的采集页主实现。(RecordView) -
src/upload:上传队列、上传设置、上传执行。(*manager uploadqueueview) -
src/ar和src/ar_v2:AR 会话、录制状态机、录制产物落盘。 -
src/peers:多机同步、发现、心跳、时间同步。(peermanager) -
src/bluetooth:夹爪蓝牙连接与数据解析。 -
src/inference:推理请求、动作可视化、联机触发。 -
src/robot:机器人配置、运动学封装、RobotView。 -
src/coscene:CoScene 配置和 API Client。 -
src/s3:S3 配置、连通性测试、SigV4 上传。 -
src/stream:USB 流和 Teleop 数据发送。 -
src/config:UserConfig,全局配置总线。 -
src/utils:文件路径、只读写封装、通用工具。
启动流程
App 入口
src/Ardc2App.swift。
它的职责可以理解成 以下4 个:
-
根据
User.Hub.isLoggedIn决定先展示登录页还是主页面。 -
设置方向锁定。
-
通过
IDontWantToSleep/ImOkToSleep控制系统不熄屏。 -
在进入后台或退出时 flush 日志。
用户状态与配置入口
用户状态与配置入口在 src/user/User.Manager.swift中的User.Hub
它手里最重要的东西有两个:
-
cfg: Utils.ObsRw<UserConfig>,也就是整个 App 的配置对象。 -
CoSceneConfigFacade,负责把本地配置和远程配置合并成当前有效的 CoScene 上传配置。
主依赖注入
依赖注入集中在 src/MainPage.swift 的 MainPage.Dependencies,实际初始化的是:
-
PeersManager -
BluetoothEncoderManager -
UploadManager -
ArManagerV1 -
InferenceManager
其中:
-
UploadManager依赖PeersManager和配置。 -
ArManagerV1同时依赖PeersManager、BluetoothEncoderManager、UploadManager。 -
InferenceManager又依赖ArManagerV1和PeersManager。
页面和业务主流程
登录
登录相关代码在:
-
src/user/User.Login.swift -
src/user/User.Api.swift
实际接的主业务后端是DM3平台的账户体系:
代码里已经直接用到的接口包括:
-
登录
/api/v1/auth/login-by-phone -
登出
/api/v1/auth/logout -
任务分发
/api/v1/daq/task-execution/my -
回写文件信息
/api/v1/daq/task-execution/{id}/files -
系统配置(目前仅存储Coscene平台的bucket路径以及Token)
/api/v1/system/setting/{key}
登录成功后,会在配置里持久化这些字段:
-
isLoggedIn -
isGuest -
loginPhone -
token -
userId -
userFingerprint
Prepare 页
Prepare 页入口在 src/prepare_v2/PrepareV2.swift。
这个页面本质上是采集前的准备页。可以把它理解成 4 步:
-
System Checks -
Connect Gripper(UMI2.0) -
Peers Syncing -
Select Task
几个关键文件:
-
src/prepare_v2/PrepareV2.GripVer.swift -
src/prepare_v2/PrepareV2.Peers.swift -
src/prepare_v2/PrepareV2.Ble.swift
这里要特别提醒几个业务约束:
-
ego设备默认不需要 BLE、鱼眼/标定和多机同步,只用头部机位。 -
umi3某些机位会隐藏任务选择。 -
切换不同夹爪版本会改
savedVideo分辨率。 -
访客模式下允许在首页直接改
groupId。 -
夹爪版本变化会自动尝试切到匹配的 CoScene project。
Record 页
采集主页面在 src/record/RecordView.swift。
这个页面用户主要交互入口,但需要注意它不是单纯的 UI 页,因为它把很多 manager 都拉起来了:
-
ArManagerV1 -
PeersManager -
BluetoothEncoderManager -
InferenceManager -
UploadManager -
StreamManager -
TeleopManager -
VoiceControl -
VolumeButtonControl -
StressTest.Manager -
RecordV2View.Viz
同时它还承担了很多编排职责(UI、状态联动、事件发布、控制台入口等),而且在 MainPage 里被直接挂载,周边还有 Record.* 一系列扩展围绕它组织。
AR 录制主干
AR 主干在 src/ar/ArManagerV1.swift。
它负责:
-
持有
ARSession -
接收相机帧和追踪结果
-
维护录制状态
idle / recording / cancelling / finishing -
持有机器人 tracker
-
在录制过程中采集当前帧、位姿、夹爪状态和问题标签
-
在录制结束时调用
ArtifactWriter落盘 -
处理多人协作的 AR session 数据同步
跟它直接相关的重要文件有:
-
src/ar/ArManagerV1.swift -
src/ar/Ar.Data.swift -
src/ar/Ar.Event.swift -
src/ar_v2/ArV2.Recording.swift -
src/ar_v2/ArV2.ArtifactWriter.swift
需要注意的是,由于目前一直在把录制链路从旧的命名和结构逐步往 V2 方向迁,但这个迁移没有收完,所以你现在会看到:
-
类名还是
ArManagerV1 -
但录制状态和产物落盘已经大量用了
ArV2.*
这不是两套完全独立的系统并行,而是一个还没收口的迁移态。所以后面维护时千万不要看到 V1 / V2 就以为能简单删一边。
录制产物
录制结束后,ArtifactWriter 会在文档目录下生成一个记录目录,里面会有:
-
metadata.json -
frame_data.bson -
recording.mp4 -
depth_images.tar
来源分别是:
-
metadata.json:src/ar/Ar.Data.swift里的RecordMeta -
frame_data.bson:RecordData -
recording.mp4:VideoWriter -
depth_images.tar:DepthMapRecorder
metadata.json 这一层很关键,因为上传、恢复队列、后台回写、数据质检都依赖 metadata.json 能被稳定解码。所以添加一些字段的时候要谨慎,处理好兼容问题
Upload 页和上传队列
上传相关主逻辑在:
-
src/upload/UploadManager.swift -
src/upload/UploadQueueView.swift -
src/upload/UploadQueueView.ServerSettings.swift
UploadManager 干的事情很多:
-
管理
fileStatus -
管理
uploadQueue.json -
从磁盘恢复已存在但队列丢失的记录
-
把记录目录打包成
.tar.gz -
按目标平台执行上传
-
追踪上传进度
-
支持取消上传
-
同步删除广播
目前支持了 3 种上传目标:
-
General -
coScene -
S3
General
General 是实验室同学在使用的,基本上不会再进行改动。但要注意,在开发或者修改其他上传功能的时候千万要确保General依旧可用。逻辑在 CrazyStuffOfUpload。
主要配置项是:
-
dataUploaderIp -
dataUploaderPort -
dataUploaderEndpoint
CoScene
CoScene 客户端配置在:
-
src/coscene/CoSceneApiClient.swift -
src/coscene/CoSceneConfig.swift -
src/coscene/CoSceneConfigFacade.swift
上传流程是:
-
读取有效 CoScene 配置。
-
根据
metadata.json构造 record title、label、custom fields。 -
查 record 是否存在,不存在就创建。
-
请求上传 URL。
-
PUT 上传
.tar.gz。 -
如果任务执行 ID 存在,再回写业务后台文件信息。
CoScene 这块还有一个配置优先级:
-
访客模式优先用 bundle 里的默认配置。
-
登录用户优先用远程拉到的
cosceneRemoteCache。 -
本地
UserConfig.coscene作为兜底。
S3
S3 实现在:
-
src/s3/S3Config.swift -
src/s3/S3ConnectionTester.swift -
src/s3/S3PutObjectUploader.swift -
src/s3/S3SigV4Signer.swift
这里的实现是客户端直接做 SigV4 PUT Object,不是向后端换临时凭证。
这意味着:
-
AK / SK 直接存本地配置,有安全风险。
-
endpoint、bucket、region 配错时,问题会直接暴露在客户端。
-
证书校验目前比较宽松,
serverTrust是直通的,后续要不要继续这样要再判断。
S3上传是近期刚开发的功能,稳定性未知。
Profile 页
Profile 这块是历史遗留,基本就是静态页面,没有任何逻辑。
核心模块职责
UserConfig
文件:
src/config/UserConfig.swift
它负责全局配置持久化:
-
承载几乎所有模块的运行配置。
-
作为模块间共享状态的持久化入口。
-
持久化到文档目录下的
UserConfig.json。
PeersManager
文件:
-
src/peers/PeersManager.swift -
src/peers/PeersConfig.swift
它主要负责多机同步相关内容:
-
基于
MultipeerConnectivity做设备发现、配对、广播、同步。 -
维护 host / client 角色和同步状态。
-
维护心跳、低电量、是否在录制页、AR 状态等共享信息。
-
计算时间同步偏移和最大延迟。
这也是高复杂度类,而且同时有主线程状态和自己的串行队列 dq。后面只要是多机录制问题,基本绕不开它。
BluetoothEncoderManager
文件:
src/bluetooth/BluetoothEncoderManager.swift
它负责:
-
搜索和连接 BLE 夹爪设备。
-
读取编码器角度。
-
触发和录制有关的事件。
Prepare 阶段依赖它判断夹爪是否 ready,Record 阶段依赖它补充 gripper 信息。
主要是UMI2.0用的比较多,目前UMI3.0用的不多
ArManagerV1
文件:
src/ar/ArManagerV1.swift
这是 AR 会话主控制器,也是我最建议优先读的文件之一。
UploadManager
文件:
src/upload/UploadManager.swift
这是上传队列中心,也是最建议优先读的文件之一。它负责:
-
队列恢复
-
目录打包
-
上传执行
-
状态落盘
InferenceManager(不常修改)
文件:
src/inference/InferenceManager.swift
它负责:
-
从 AR 当前帧拿观测。
-
裁图、转 base64、发送推理请求。
-
处理协同触发和动作可视化。
3.5.7 RobotTracker / RobotPreset(不常修改)
文件:
-
src/robot/RobotTracker.swift -
src/robot/RobotConfig.swift
它负责:
-
读取机器人预设和 URDF。
-
初始化运动学模型。
-
为 RobotView、推理可视化和记录附加机器人相关信息。
StreamManager / TeleopManager(不常修改)
文件:
-
src/stream/StreamManager.swift -
src/stream/TeleopManager.swift
它们负责:
-
StreamManager把当前 AR 帧转成 Record3D 类似结构经 USB 发送。 -
TeleopManager把位姿、夹爪状态和录制状态 POST 到远端。
本地数据、文件和持久化
iOS 文档目录
通用路径封装在 src/utils/Fs.swift。
关键方法有:
-
Fs.doc() -
Fs.docUrl(_:) -
Fs.log() -
Fs.calib(bundle:)
重要落盘内容
文档目录里的重要内容包括:
-
UserConfig.json -
uploadQueue.json -
uploadQueue.json.bak -
每次录制生成的记录目录
-
CalibrationImages/ -
calib/ -
log/
队列恢复机制
UploadManager 有三层恢复逻辑:
-
优先读
uploadQueue.json -
失败则读
uploadQueue.json.bak -
再失败则扫描文档目录里所有包含
metadata.json的目录重建队列
这套机制很实用,但也意味着:
-
本地有残留目录时,上传队列可能会"自己长回来"。
-
删除记录不能只删 UI 状态,必须删磁盘目录。
外部依赖和接口边界
业务后端
客户端里已经硬编码使用的业务域名是:
https://dm3.noematrix.cn
负责:
-
登录 / 登出
-
拉取采集任务
-
拉Coscene相关配置
-
回写已上传文件信息
CoScene
默认 CoScene 服务端是:
https://openapi.coscene.cn
负责:
-
record 查询或创建
-
获取文件上传 URL
-
实际文件上传
General 上传服务器
UI 里内置了一些通用上传服务器样例,定义在:
src/upload/UploadQueueView.ServerSettings.swift
这几组地址是实验室内部所需,一般不会进行改动。
BLE 设备(主要是UMI2.0)
BLE 是夹爪链路依赖,直接决定:
-
是否能读到 gripper 宽度
-
是否满足采集前准备条件
-
某些按钮事件是否能正确触发
多机局域网
PeersManager 依赖:
-
本地网络权限
-
Multipeer 广播 / 发现能力
-
同组设备的
groupId
如果局域网权限、热点环境、设备角色配置异常,多机大概率会直接不可用。
一些常见问题
对于大部分问题,都可以通过埋点打log的方式来定位到原因。
以下是一些到目前为止出现频率较高的问题。
录制结束但没有进上传队列
其实这个问题大概率是因为深度图丢失或者某些文件没有完全写入就计算了哈希
一般看后台log输出内容
-
深度图相关
-
hash计算部分
上传队列显示异常
大概率是读写冲突导致uploadQueue损坏,或者出现11.1中提到的的情况
可以着重看一下log以及uploadQueue的记录
-
uploadQueue.json -
uploadQueue.json.bak -
文档目录下记录目录还在不在
-
recoverFromDisk()有没有把磁盘残留重新加回来
CoScene 上传失败
大概率是网络环境是否正常或者没有填写任务信息(任务名、任务描述)
APP崩溃!!!!
这是最难排查也是最难受的一种情况。需要我们自己去iPhone的
设置->隐私与安全性->分析与改进->分析数据
来找到我们的崩溃对应ips文件进行分析。 (可以拿到ips文件后让AI去阅读分析)
但有概率AI会犯神经瞎说,需要自己认真辨别。
如果是可复现的崩溃 可以结合Instruments工具进行进行分析,大部分情况下都能很快定位到问题所在。
如果是很难复现的崩溃 那就只能"凭感觉"了T^T.
最后归纳一下
主要技术栈 / 框架
-
客户端基础
- Swift 6 + SwiftUI:整套 UI 和页面结构(
MainPage多 Tab、PrepareV2、RecordView、UploadQueueView等)。 - Combine:
EventBus做全局事件总线,各个 manager 的状态联动(录制状态、上传进度、防息屏等)。 - URLSession:登录、任务分发、CoScene API、DM3 平台接口、通用上传 HTTP 调用。
- Swift 6 + SwiftUI:整套 UI 和页面结构(
-
空间感知与图像
- ARKit + RealityKit:相机追踪、AR 会话管理、多机 AR 会话同步,
ArManagerV1持有ARSession,驱动录制主干。 - OpenCV:图像处理、Aruco 检测、标定等(通过
opencvframework +img/、image/模块)。 - AVFoundation / CoreImage / CoreVideo:视频编码(
VideoWriter)、深度图录制(DepthMapRecorder)、像素缓冲处理。
- ARKit + RealityKit:相机追踪、AR 会话管理、多机 AR 会话同步,
-
硬件与多机
- CoreBluetooth:夹爪蓝牙连接、编码器数据采集(
BluetoothEncoderManager)。 - MultipeerConnectivity:多机发现 / 心跳 / 时间同步 / 状态广播(
PeersManager)。 - USB 自定义协议:通过
StreamManager+ArdcUsbManager以 ~30 FPS 推送 AR 帧(类似 Record3D 的结构)。
- CoreBluetooth:夹爪蓝牙连接、编码器数据采集(
-
机器人 / 低维数据
- Rust + UniFFI + Mobile.xcframework:机器人运动学、机器人视角优化等重计算逻辑,下沉到 Rust 编译成 iOS framework,再由
Mobile.swift调用。 - 自定义数据格式 & NEDF 生态兼容:App 侧产出
recording.mp4 + frame_data.bson + depth_images.tar + metadata.json,配合下游 NEDF2/NEDF3 转换脚本。
- Rust + UniFFI + Mobile.xcframework:机器人运动学、机器人视角优化等重计算逻辑,下沉到 Rust 编译成 iOS framework,再由
-
云与存储
- 直连 S3 SigV4:
s3/模块在客户端直接做签名、PUT Object 上传 tar 包。 - CoScene 平台集成:
coscene/模块把本地元数据和 CoScene record / 上传 URL / 回写任务执行信息打通。
- 直连 S3 SigV4:
项目的核心逻辑 / 特点
-
端到端的数据采集流水线
- 从 登录 → Prepare 检查设备/Peers/任务 → Record 页录制 → 产出一条 episode 目录 → 入本地上传队列 → 上传到 General / CoScene / S3,是完整闭环。
- 录制时同步采集:RGB 视频 + 深度 + 每帧 AR 位姿 + 夹爪状态 + 质量问题标签,统一封装到
RecordData&RecordMeta,保证后处理可重放和可分析。
-
复杂但集中管理的 AR 录制状态机
ArManagerV1集中管理 ARSession 生命周期、录制状态、当前帧快照、多机 AR session 同步、机器人 tracker、gripper 检测。- 录制结束调用
ArV2.ArtifactWriter,负责阻塞式等待视频/深度写盘完成、质量检查(Quality)、生成 metadata、计算 SHA256,并决定是否入UploadManager队列。
-
多机同步与协作
PeersManager基于 Multipeer 做 host/client 角色管理、groupId 分组、时间同步偏移计算、心跳/电量/低电量模式/是否在 Record 页等共享状态。- 录制和推理都会依赖这些多机信息(例如多视角设备的 session id、角色、主从机)。
-
多出一份「在线」能力:遥操作 / 推理 / USB 流
- 在录制时,同一条 AR 数据被多路复用:
- USB 流:
StreamManager把当前帧转成 Record3D 类结构经 USB 发出。 - Teleop:
TeleopManager周期性 POST 位姿、夹爪、录制状态到远端(默认是 Unity/仿真端点)。 - Inference:
InferenceManager从当前帧裁图 + 位姿 + gripper,发推理请求,再用ActionVizV2/ActionVisualizer在 AR 中叠加动作可视化。
- USB 流:
- 在录制时,同一条 AR 数据被多路复用:
-
健壮的本地持久化与恢复机制
UserConfig.json持有几乎所有模块运行配置,ObsRw<UserConfig>提供线程安全读写。UploadManager对uploadQueue.json+.bak+ 磁盘扫描有三层恢复逻辑,避免 crash 或中断后队列"丢失但文件还在"。