Files
worldmodel/plans/PRISM/08_runtime_timeline.md
gaojie 0b12ff023c
Sync to site1 / sync (push) Has been cancelled
chore: update PRISM categories from worldmodel to PRISM
2026-05-21 02:25:22 +08:00

14 KiB
Raw Permalink Blame History

title, date, draft, tags, categories
title date draft tags categories
Chapter 08 — 端到端运行时序 2026-05-20 false
PRISM
世界模型
空间记忆
机器人
iOS
ZED2i
PRISM

Chapter 08 — 端到端运行时序

本章目标:把 Chapter 04–07 的四个管线串成一条完整的时间线,用一个具体酒店场景的"剧本"展示 PRISM 如何在 T0 到 T4 的全生命周期工作。


8.1 场景设定

某商务酒店 3 楼,共 8 间客房 + 走廊 + 电梯厅,约 300 m²。 部署一台轮式服务机器人「Robo-Concierge」,搭载 ZED 2i,需要:

  • 自主巡逻
  • 接受客人语音指令"去 308 取一下遥控器"
  • 早晨给打扫清单上的房间送备品
  • 检测家具异常移动(防盗 / 维护提醒)

8.2 时间线全景

timeline
    title PRISM 端到端运行时序 T0 -- T6
    section 部署前
      T0 D-7 : iPhone 离线扫描 → 灌入 LTM
    section 开机当天
      T1 9点 : 机器人首次开机<br/>重定位握手
      T2 全天 : 巡逻/任务<br/>delta 累积
      T3 14点30 : 取遥控器任务
      T4 22点 : 充电桩<br/>记忆巩固
    section 长期维护
      T5 D+30 : 月度深度巩固
      T6 D+90 : 装修后部分重扫

8.3 T0iPhone 离线扫描(D-7,运维人员)

物理动作

09:00  运维进入 3 楼电梯厅
09:01  放置 ArUco 标识在地面(id=42, 30 cm×30 cm
09:03  打开 PRISMScanner App
09:05  ── 单 session 开始 ──
       1) 在电梯厅扫一圈,看到 ArUco ✓
       2) 沿走廊缓慢推进
       3) 进 301,扫描 12 分钟
       4) 退出 301,沿走廊
       5) 进 302...... 重复直到 304
09:55  暂停 session4 个房间)
10:00  换电池 + 第二 session305308
10:50  全部完成

数据落地(D-6,工作站)

data/scans/
├── 2026-05-09_3F_session1/        # 301-304
│   ├── Hotel.usdz
│   ├── roomplan.json
│   └── arkit/  (rgb + depth + pose)
└── 2026-05-09_3F_session2/        # 305-308
    └── ...

IngestD-5,工程师)

# Session 1
python -m tools.prism_ingest_iphone \
  --scan data/scans/2026-05-09_3F_session1/ \
  --out  robot_memory/ltm/ \
  --aruco-id 42

# Session 2(追加进同一 LTM
python -m tools.prism_ingest_iphone \
  --scan data/scans/2026-05-09_3F_session2/ \
  --out  robot_memory/ltm/ \
  --aruco-id 42 \
  --merge

# 检查
python -m tools.check_anchors      # 期望 ≥ 16 个 anchor(每房 2 个)
python -m tools.viz_octomap        # 人眼检查走廊可通行

输出:

nodes:     289   (8 房 + 8 走廊 + ~273 家具)
edges:     312
anchors:    21
LTM size:  3.4 GB

部署

D-3:  把 robot_memory/ 拷贝到机器人 SSD
D-2:  机器人在测试间预演重定位(不到现场)
D-1:  机器人运到 3 楼电梯厅,关机待命

8.4 T1:机器人首次开机(D 早上 9:00)

时序(精确到毫秒)

sequenceDiagram
    autonumber
    participant U as 用户 电源
    participant R as ROS 2 PRISM
    participant Z as ZED 2i SDK
    participant FP as Frame Producer
    participant RL as Relocalizer
    participant NAV as Avoidance Nav
    participant FSM as 状态机

    U->>R: 09:00:00.000 Power on
    R-->>R: 09:00:02.500 节点 launch 完成
    R->>Z: 09:00:02.600 启动 ZED 2i SDK
    Z->>FP: 09:00:03.100 第一帧到达
    FP->>RL: 09:00:03.150 触发 cold_start
    RL-->>RL: 09:00:03.230 CLIP 编码当前帧
    RL-->>RL: 09:00:03.310 L3 Top-3 lobby_3F 0.82 room_308 0.41 hallway_3F 0.39
    RL-->>RL: 09:00:03.320 几何配准 FPFH+RANSAC 0.74 ICP refine 0.91 通过
    RL->>R: 09:00:03.510 发布 TF map to zed2i_init
    R->>NAV: 09:00:03.550 Avoidance Nav 上线
    R->>FSM: 09:00:03.600 状态机 to IDLE
    FSM-->>U: 09:00:04.000 开始默认任务 巡逻
    Note over U,FSM: 总冷启动约 3.6 秒 其中 PRISM 握手约 400 ms

总冷启动时间:~ 3.6 秒(其中 PRISM 的握手 ~ 400 ms

内部状态变化

时刻 L1 L2 局部 L3 当前位置 L4 缓存 TF
09:00:00 未知 全部从盘加载 base_link→?
09:00:03.1 1 帧 未知 已加载 仍未对齐
09:00:03.5 多帧 开始融合 lobby_3F map→zed2i_init 发布✓

8.5 T2:日间巡逻(持续 ~ 8 小时)

高频循环(30 Hz 主循环)

每帧 33.3 ms:
  ZED grab → FrameProducer.append → 局部避障 → 30Hz 控制循环

中频循环(5 Hz TSDF

每 200 ms:
  取一个关键帧 → TSDFWorker.integrate
  - 检查 prior_mask: 卫生间镜面区被跳过
  - 检查 prior_weight: 走廊墙面 weight=0.1(轻微校准)
  - 走廊地面新发现的"水迹"区域:正常融合,weight=1.0

低频循环(2 Hz 检测)

每 500 ms:
  YOLO-World on 当前 RGB
  → 检出: bed_room_303, lamp_room_303, person, slipper

  Person → 隐私过滤,丢弃这帧的语义写入(只保留几何)
  bed_303 → 命中 LTM,更新 last_seen + EMA pose(微调)
  lamp_303 → 命中 LTMOK
  slipper → 未在 LTMpropose_new → DeltaEvent(object_added,
            payload=...),写 delta/pending.jsonl

异常事件(11:34

机器人巡逻到 305:
- TSDF 在沙发区域显示"空"
- LTM mesh 显示"有沙发"
- ChangeDetector 1 Hz 跑:
    diff > 5 cm → 聚类 → DeltaEvent(
       event_type="object_removed",
       target_uid="sofa_305",
       evidence=[kf_305_1134_01, kf_305_1134_07])
- 写入 delta/pending.jsonl

但机器人 *不立刻*认为沙发没了:
- LTM 中 sofa_305 仍在
- 后续路径规划仍把它当障碍(保守)
- 等下次累计观测足够 + 充电时巩固才真删

Anchor 校正(11:42

机器人路过 304 床前:
- YOLO 检到 'bed' (high conf)
- 与 LTM bed_304 关联成功
- 在线触发 fine_register_anchor:
    fitness=0.88 → 更新 T_zed→map
    drift 估计归零
- 自此重新校准过;与上次校准间隔 38 分钟(< 1 h 健康)

任务级中断(13:00

语音:"去 306 把客人遗忘的伞拿到前台"
LLM Agent 查 PRISM API:
  find("伞", room="room_306")
  → L4 检索: umbrella_xxx (source=zed2i, conf=0.5,
                          last_seen=今早 10:21, parent=nightstand_306)
  → L3 路径: cur(hallway) → 306
  → L2 度量路径
  → 执行

8.6 T3:完整任务剧本——"取遥控器"

13:00:00 用户输入

客人在 308 房间说:"请帮我去 308 桌上拿遥控器"
(机器人当前位于 hallway 走廊中段)

13:00:01 LLM Agent 查询

# Agent 不直接访问数据库;用 PRISM API
api = SpatialMemoryAPI("robot_memory/ltm/")

# 1) find 物品
result = api.find("remote control", filters={"parent_room": "room_308"})
# → [SpatialNode(uid='remote_xx33', label='remote_control',
#                parent_uid='tv_stand_308', confidence=0.6,
#                last_seen=2026-05-16T08:14:22)]

# 2) describe(给 LLM 看的自然语言)
print(api.describe(result[0].uid))
# "A black remote_control on tv_stand_308 in room_308 (Bedroom),
#  last seen 4h 45min ago, confidence 0.6."

# 3) 检查最近 delta(是否被搬过)
recent = api.changes_since(time.time() - 3*3600)
# 关于这个遥控器的 delta? → 没有
# OK,假定还在

# 4) 路径规划
path_rooms = api.path_rooms(src="hallway_3F", dst="room_308")
# → ["hallway_3F", "room_308"]
metric_path = api.l2.plan(start=cur_pose, goal=result[0].pose)

13:00:02 执行

13:00:02.300  开始驱动,沿走廊向东
13:00:14.200  到达 308 门前
13:00:14.300  ChangeDetector 注意到 308 的门 LTM 标 closed 但实际开着
              → 写 delta(object_state_change, door_308)
13:00:14.500  进入 308
13:00:16.800  到 tv_stand_308 前 0.5 m
13:00:17.000  ZED 视野中检出 remote_xx33 ✓(YOLO conf=0.78
              位置与 LTM 偏 12 cm(在桌面被人挪过 12 cm
              EMA 更新 pose,不写 delta< 20 cm 阈值)
13:00:18.000  机械臂伸出抓取
13:00:20.000  抓握成功,撤回
13:00:25.000  返回走廊
13:00:40.000  抵达前台,交接

任务耗时 38 秒;查询 PRISM 总耗时 < 50 ms。


8.7 T4:充电时记忆巩固(D 22:00)

触发

21:55:00  机器人电量 < 25%
21:55:05  返回充电桩(导航 ~ 8 min
22:03:00  上桩,开始充电
22:13:00  静止 > 10 min,触发 prism consolidate --mode=full

巩固内容(当天积累)

pending.jsonl 当天总计 1234 条事件:
  ├── object_added (slippers, towels, ...)         413
  ├── object_moved (人挪过的小物)                   382
  ├── object_removed                                 91
  ├── geometry_changed (走廊积水/物件堆放)           38
  └── 重复信号                                      310

Step 1: 筛选

观察累积 > 5 + 时间跨度 > 5 min + 多视点 > 2:
  → 162 条通过 confirm
  → 798 条 reject< 5 min 的短暂物)
  → 274 条 keep(继续等待第二天)

Step 2-3: 应用

其中:
- sofa_305 的 object_removed: 累积 47 次观测,跨越 6 小时
   → 通过 ✓,标记 sofa_305 state=removedconfidence ×= 0.3
- 12 个新增的 small_item(拖鞋、毛巾、水瓶)→ 加入 L4
- 41 个家具位置微调

Step 4: 锚点 / 索引刷新

21 → 20 个 anchorsofa_305 被淘汰)
受影响的 12 个新节点:渲染图像 + CLIP → 入 Faiss 索引
room_305 的房间 CLIP 重算(因为 sofa 不再)

Step 5: 增量重训

受影响房间:room_305
3DGS warmstart from outputs/room_305/last.ckpt
  3000 iter (~ 4 min on Orin AGX)
  → ply 替换 ltm/dense/3dgs/room_305.ply

TSDF 在 sofa_305 bbox 内 reset → 用今日 keyframes 重融合

Step 6: 验证 + 切换

sanity_relocalize on 10 历史关键帧:
  10/10 成功,RMSE 4.2 cm ✓
validate(new_mem):
  0 errors ✓
snapshot: robot_memory/snapshots/20260516_2230.tar.zst (3.4 GB)
原子切换:ltm.staging → ltm;旧 ltm → ltm.prevnext day 删除)

22:34:00  consolidate 完成,总用时 31 min
22:34:01  机器人继续充电

第二天早晨

07:00:00  机器人启动,加载新 LTM
07:00:03  重定位(在充电桩,看天花板灯)→ Top-1 = hallway_3F ✓
07:00:04  IDLE 等待任务

8.8 T5:月度深度巩固(D+30 凌晨)

01:00:00  定时任务触发 prism consolidate --mode=deep
01:00:30  完整巩固 + 全场景 3DGS 重训(每房间 5000 iter
03:45:00  全部完成 (8 房 × ~ 20 min)
03:46:00  自检:sanity_relocalize 20 张历史帧 → 19/20 通过 ✓

8.9 T6:装修后部分重扫(D+90)

酒店在 D+85 改造了 307 房间(新家具)
D+90: 运维带 iPhone 重扫 307 + 走廊端
ingest 时指定 --only-rooms room_307:
  - 仅替换 LTM 中 room_307 相关的 nodes/edges
  - 其他房间保持不变
  - 重新生成 room_307 的 anchor + CLIP
  - 重训 room_307 的 3DGS
ltm_version 从 v15 → v16

8.10 全生命周期 KPI(连续运行 90 天后回看)

重定位:
  冷启动成功率:    98.4% (1230/1250 次)
  平均冷启动时长:  670 ms
  绑架恢复成功率:  93% (用 ArUco 兜底后 100%)

记忆维护:
  pending 平均长度:   ~ 800 条/日
  每日 confirmed:     ~ 150 条
  reject 率:          ~ 64%(健康,说明门槛起作用)
  错误巩固撤销次数:    2 次(手工回滚)

任务表现:
  "取物"任务成功率:   94% (n=412)
  错误归因:
    - 物品已被移走 (delta 未及时巩固): 4%
    - 抓取失败:                       2%
    - 重定位失败:                     < 1%

资源占用 (Jetson Orin AGX):
  CPU 平均:    37%
  GPU 平均:    52%
  内存:        12.3 GB / 64 GB
  磁盘增长:    + 0.2 GB / 月(snapshots

8.11 完整状态图

stateDiagram-v2
    [*] --> BOOTING: power
    BOOTING --> IDLE: relocalize ok
    IDLE --> EXECUTING_TASK: task assigned
    EXECUTING_TASK --> IDLE: done
    IDLE --> RELOCALIZING: relocalize lost
    EXECUTING_TASK --> RELOCALIZING: relocalize lost
    RELOCALIZING --> IDLE: recovered
    RELOCALIZING --> FALLBACK_HUMAN: failed > N
    FALLBACK_HUMAN --> IDLE: human help
    IDLE --> CONSOLIDATING: charging + idle > 10min
    CONSOLIDATING --> IDLE: done

    note right of IDLE
      巡逻或待命
    end note
    note right of CONSOLIDATING
      Background (并行):
      • FrameProducer  (30 Hz, always)
      • TSDFWorker     (5 Hz when moving)
      • DetectorWorker (2 Hz when moving)
      • ChangeDetector (1 Hz when stationary)
      • HealthMonitor  (0.2 Hz)
    end note

8.12 本章小结

阶段 时间 主体 PRISM 角色
T0 D-7 人工 iPhone 扫描 LTM 灌入
T1 D 9:00 机器人 冷启动 重定位握手
T2 D 全天 机器人 巡逻 在线感知 + delta 累积
T3 D 13:00 机器人 任务 查询四层记忆 + 路径
T4 D 22:00 机器人 充电 巩固
T5 D+30 机器人 深夜 深度巩固
T6 D+90 人工 重扫部分 增量 LTM 更新

读完本章你应能:

  • 在脑中"播放"完整的 PRISM 一天
  • 解释为什么 sofa_305 不会被"瞬间删除"
  • 估算系统的资源占用
  • 设计 PRISM 的状态机

下一章 09_roadmap.md 给出 8 周内把这一切跑通的具体里程碑。


章节版本v1.0 估计阅读时间18 分钟 关键收获:把抽象架构变成"看得见的一天"