跳转至

TAMP_T6 不确定性下的 TAMP 与信念空间规划 (Task and Motion Planning under Uncertainty: Belief-Space Planning)

难度: ⭐⭐⭐ ~ ⭐⭐⭐⭐ (本章是 TAMP 线的进阶专题,把前五章"世界完全可知"的假设撤掉,整体偏研究级) 前置知识: TAMP_T1(PDDL/FF、符号-几何鸿沟、Mini-TAMP 累积项目)、TAMP_T2(删除松弛启发式)、TAMP_T3(PDDLStream 的 Stream 采样器);概率基础(条件概率、贝叶斯更新、期望);强烈建议先读 U 线 30_不确定性规划/50_POMDP与Belief规划(运动/决策层的 POMDP 机器) 核心参考: Kaelbling & Lozano-Pérez (2013, IJRR), "Integrated Task and Motion Planning in Belief Space"; Garrett, Paxton, Lozano-Pérez, Kaelbling & Fox (2020, ICRA), "Online Replanning in Belief Space for Partially Observable Task and Motion Problems"; Hoffmann & Brafman (2006, AIJ) Conformant-FF / (2005, ICAPS) Contingent-FF; Yoon, Fern & Givan (2007, ICAPS) FF-Replan; Younes & Littman (2004) PPDDL; Sanner (2010) RDDL 与既有章节的关系: 本章是总论 T0 §4.4"不确定性贯穿三个根问题"那一行的系统展开。它站在 T1-T3 的"确定性 TAMP"之上,把符号层的世界从"完全可知"放宽到"只有概率估计"。它不重复 U 线 30_不确定性规划/ 的运动层机器(POMDP 求解器、机会约束),而是讲任务层如何表示、规划、执行不确定性,并在 §10 把任务层信念规划与运动层 belief-space 接起来。


0. 前置自测

开始本章前,请先完成下面五道自测题。它们检验本章依赖的三块基础——确定性 TAMP(T1-T3:符号-几何鸿沟、PDDLStream 采样器)、概率与贝叶斯更新(信念怎么算)、以及 POMDP 直觉(U 线 U4:看不清世界时怎么决策)。如果三道以上答不出来,先回对应前置章节,再读本章会顺很多。

# 问题 期望掌握程度 答不出来回到
Q1 TAMP_T1-T3 里,规划器对世界的假设是什么?比如一个 pick(cup) 动作执行后,规划器是否 100% 确信 Holding(cup) 为真、On(cup, table) 为假? 能说出确定性 TAMP 假设"世界完全可知、动作效果确定" TAMP_T1 §2
Q2 给定先验 \(P(s)\)、动作的转移 \(P(s'\mid s,a)\)、观测的似然 \(P(o\mid s')\),写出执行 \(a\) 并收到观测 \(o\) 后,新信念 \(b'(s')\) 的贝叶斯更新公式。 能写出预测 + 校正两步(见 U 线 U4) 30_不确定性规划/50 §U4.1
Q3 POMDP 的核心洞察是"belief 是充分统计量,POMDP = belief 空间上的 MDP"。这句话什么意思?为什么它让"看不清世界"的问题至少在理论上可解? 能说出在信念空间上问题重新变成完全可观测的 MDP 30_不确定性规划/50 §U4.1
Q4 PDDLStream 的 Stream(如 sample-ik)做什么?它如何把一个连续几何量"引入"符号规划? 能说出 Stream 是采样器接口,认证事实把连续值喂回符号搜索 TAMP_T3 §3-§4
Q5 下面三个任务,哪些的"不确定性"应该在任务层(符号)处理、哪些应该在运动层(几何)处理?(a) 杯子可能在桌上也可能在水槽里,机器人要先去看再决定去哪拿;(b) 机械臂抓取时末端有 ±2cm 的定位误差;(c) 一扇门可能上锁也可能没锁,开之前不知道。 能按"离散命题的真假未知 vs 连续量的噪声"区分两层 本章 §2(学完即可)
参考答案 (点击展开) **Q1**: 确定性 TAMP(T1-T3)有两条隐含假设:(1) **世界完全可观测**——规划器开始时就完全知道每个命题的真假、每个物体的精确位姿;(2) **动作效果确定**——`pick(cup)` 执行后,规划器 100% 确信 `Holding(cup)` 变真、`On(cup,table)` 变假,不存在"抓滑了"的可能。本章正是要撤掉这两条假设:世界**只有概率估计**(看不全、看不准),动作**可能失败**(抓取有成功率)。 **Q2**: 两步。**预测(transition)**:$\bar b(s') = \sum_{s} P(s'\mid s,a)\, b(s)$,把旧信念按动作的转移模型推一步。**校正(observation)**:$b'(s') = \eta\, P(o\mid s')\, \bar b(s')$,用观测似然加权,其中 $\eta = 1/\sum_{s'} P(o\mid s')\bar b(s')$ 是归一化常数。连续状态下求和换成积分,这正是贝叶斯滤波(卡尔曼滤波是其高斯特例)。本章把这套更新搬到**符号层**——状态是命题组合、观测是传感动作的结果。 **Q3**: 原始状态 $s$ 看不清(部分可观测),但**信念** $b$(关于 $s$ 的概率分布)是可以精确维护和更新的(Q2 的公式)。如果我们把 $b$ 本身当作"新状态",那么"在 $b$ 上选动作 → 转移到新 $b'$"就是一个**完全可观测的 MDP**——因为我们总是确切知道当前的 $b$。这就是"belief 是充分统计量"的含义:$b$ 浓缩了全部历史(动作-观测序列)里与决策相关的信息。代价是状态空间从离散的 $s$ 变成连续的概率单纯形,维度爆炸——所以理论可解、实际要近似(§8)。 **Q4**: Stream 是把几何能力(IK、碰撞检测、运动规划)封装成符号搜索能按需调用的采样器。`sample-ik` 输入一个目标位姿和抓取,输出一个可达的关节构型 $q$,并**认证**一个符号事实如 `Kin(p,g,q)`——这条事实告诉符号规划器"存在一个可达构型 $q$ 使抓取几何可行"。这样连续量 $q$ 就以"被某条认证事实引用"的方式进入了符号世界。本章 §9 会把 Stream 扩展到**采样信念**(如采样一个满足某可观测性条件的观察位姿)。 **Q5**: (a) **任务层**——"杯子在桌上还是水槽里"是一个**离散命题的真假未知**(`On(cup,table)` vs `On(cup,sink)`),且"先去看再决定"是一个**信息收集的离散决策**,这是任务层信念规划(contingent planning,§5)的典型问题。(b) **运动层**——±2cm 是一个**连续量的高斯噪声**,由运动层的 belief-space 运动规划 / 机会约束处理(U 线 U3/U4),任务层不该去管厘米级误差。(c) **任务层**——"门锁没锁"又是一个离散命题真假未知,且"开之前不知道、试了才知道"需要带感知分支的策略(contingent,§5)。这三个例子精确划出了本章 §2 要讲的**任务层 vs 运动层不确定性分工**:任务层管"命题真假未知 + 离散信息决策",运动层管"连续量噪声"。

1. 本章目标

学完本章后,你应当能够:

  1. 辨析任务层不确定性的来源(状态不确定、效果不确定、感知不确定),并说清它与运动层不确定性(连续量噪声)的分工——什么该在符号层处理、什么该留给运动层(接 U 线)。
  2. 解释信念空间规划的核心思想:把规划的状态从"一个确定的世界"换成"世界的概率分布(信念)",并写出信念在动作与观测下的更新;理解"belief 是充分统计量、信念空间 MDP"如何把部分可观测问题重新变成可解形式。
  3. 区分三类经典的不确定性规划——conformant(无感知、要对所有可能初始世界都成功)、contingent(有感知、按观测分支的策略树)、probabilistic(带概率的 MDP/POMDP)——并判断一个任务该用哪一类。
  4. 使用 determinization + replanning(以 FF-Replan 为代表)这条"用确定化绕开概率"的工程捷径,理解它为什么常常出奇地有效、又在哪类问题("概率即灾难"、需主动信息收集)上必然失败。
  5. 阅读并编写概率规划语言:PPDDL 的 probabilistic 效果、RDDL 的 DBN/factored 表示,知道它们各自适合什么、为什么 IPPC 从 PPDDL 演进到 RDDL。
  6. 描述 POMDP 在 TAMP 里的用法与三类近似(QMDP/最大似然确定化、在线 belief-tree 搜索、宏动作/技能抽象),理解为什么纯 POMDP 在长时域操作上不可扩展、TAMP 如何用符号结构压缩它。
  7. 设计一个感知不确定下的 pick-place 信念空间 TAMP:把"看一眼""再决定"作为一等动作纳入规划,把 PDDLStream 的 Stream 扩展到采样信念与观察位姿,并把它接到 T1 的 Mini-TAMP 累积项目上。
  8. 打通任务层信念规划与运动层 belief-space 的接口:说清"符号层决定看哪、抓哪""几何层算厘米级的 belief 传播与机会约束"如何分层协作(接 30_不确定性规划/ 的 U4/U3)。

本章知识导航

本章只做一件事,但做得彻底:把前五章"世界完全可知、动作必然成功"的地基撤掉,看任务层如何在"看不全、看不准、做不准"的世界里规划。 整章围绕一条主线展开——从"信念"这个核心对象出发,看它如何催生三类规划范式(conformant / contingent / probabilistic),如何被工程捷径(determinization)绕开,如何用语言(PPDDL/RDDL)表达,如何借 POMDP 求解又被 TAMP 压缩,最后落到一个完整的感知不确定 pick-place 系统并接回运动层。

                根问题:世界看不全、看不准、动作做不准时,任务层如何规划?
            ┌───────────────────────────┼───────────────────────────┐
            │                           │                           │
       【不确定从哪来】              【核心范式】                 【落地与接口】
            │                           │                           │
   §2 任务层不确定性来源         §3 信念空间规划(主干)          §9 感知不确定 pick-place
   ├─ 状态/效果/感知三类         ├─ 状态→信念的跃迁              ├─ "看一眼"作为一等动作
   ├─ vs 运动层(连续噪声)        ├─ 信念更新=预测+校正          ├─ Stream 采样信念/观察位姿
   └─ §2.4 分工判据             └─ 信念空间 MDP                ├─ 接 Mini-TAMP 累积项目
            │                           │                     └─ §9.5 仿真到真机
   ┌────────┴────────┐         §4 Conformant(无感知)               │
   │  为什么不能              ├─ 对所有可能世界都成功         §10 与运动层接口 + 对比
   │  沿用确定性 TAMP         └─ Conformant-FF                ├─ 任务层信念 ↔ 运动层belief
   └─ §2.3 三道崩溃          §5 Contingent(有感知)            ├─ 分层:符号选/几何算
                            ├─ 按观测分支的策略树            ├─ vs U线POMDP(运动层)
                            └─ Contingent-FF                 └─ §10.4 局限与前沿
                            §6 Determinization + FF-Replan
                            ├─ all-outcomes / most-likely
                            └─ 何时灵 / 何时必败(信息收集)
                            §7 概率语言:PPDDL / RDDL
                            ├─ probabilistic 效果
                            └─ DBN/factored 表示
                            §8 POMDP in TAMP + 近似
                            ├─ QMDP/最大似然/在线belief树
                            └─ 宏动作/技能压缩长时域

怎么读这张图:左列建立"为什么确定性 TAMP 不够"(§2);中列是本章硬核——信念空间这个核心对象(§3)长出 conformant(§4)、contingent(§5)两类无概率/有概率的范式,以及绕开它的工程捷径(§6)、表达它的语言(§7)、求解它的机器(§8 POMDP);右列落地——一个完整的感知不确定 pick-place(§9)和与运动层的接口(§10)。⭐⭐⭐ 的 §3(信念空间)、§5(contingent)、§6(determinization)是必掌握主干;⭐⭐⭐⭐ 的 §8(POMDP 近似)与 §10(接口与前沿)是进阶。

主干与分支:第一遍务必拿下 §2.4(任务层 vs 运动层分工判据)、§3(信念与信念空间,全章的核心对象)、§5(contingent planning,最贴近真实机器人的范式)、§6(FF-Replan,最实用的工程捷径)、§9(完整案例)。§4(conformant)、§7(语言细节)、§8(POMDP 近似理论)、§10.4(前沿)可第二遍深入。

前置知识桥接

本章站在三块基石上,各用几行重新激活。

回顾 TAMP_T1-T3:确定性 TAMP 的隐含假设。 前五章我们默认世界完全可知(规划开始就知道每个命题真假、每个物体精确位姿)、动作效果确定pick 必成、place 必稳)。在这套假设下,规划就是在确定的状态图上搜一条到目标的路径(T1 的 FF/PDDL),几何可行性由 Stream 采样保证(T3)。本章把这两条假设同时撤掉——这不是给 TAMP "打补丁",而是换了一个根本不同的问题:规划的对象从"状态"变成"信念"

回顾 U 线 U4(30_不确定性规划/50):POMDP 与 belief。 U4 已经把"看不清世界时如何决策"讲透了——POMDP 七元组、belief 的贝叶斯更新、"belief 是充分统计量"、α-vector/PWLC 值函数、点基方法(SARSOP)、在线搜索(DESPOT)。那一章站在运动/决策层:状态是连续的(车的位姿、他车意图),求解是数值的(值迭代、belief 树 MCTS)。本章把同一套 belief 思想搬到任务层:状态是离散命题组合,"动作"是带前提-效果的符号算子,求解借助符号规划器(Conformant-FF/Contingent-FF)或符号-几何集成(belief-space TAMP)。U4 给了"信念决策的数学机器",本章给"这套机器如何嵌进符号任务规划、如何与几何耦合"。

回顾概率与贝叶斯滤波。 信念更新(§0 Q2)就是一次贝叶斯滤波——预测(按转移推一步)+ 校正(按观测似然加权)。如果你学过卡尔曼滤波(连续高斯)或 SLAM 里的滤波(U4 §U4.1 点明"SLAM 工程师你已经会一半了"),本章的信念更新就是同一件事在离散符号状态上的版本。差别只在:这里的"状态"是 {On(cup,table), Locked(door), ...} 这样的命题组合,"观测"是传感动作(看一眼、摸一下)的离散结果。

本质洞察:U4 和本章是同一枚硬币的两面——U4 是"belief 规划的运动层 / 数值实现",本章是"belief 规划的任务层 / 符号实现"。一个机器人要在不确定世界里干长时域的活,两层都需要:任务层用信念决定"该先去看哪、该先抓哪个"(离散信息决策),运动层用 belief 算"这一抓厘米级会不会偏、这条路 99% 安全吗"(连续噪声传播)。本章 §10 会把两层正式接起来。读本章时,请始终带着"我现在讲的是符号层的不确定性,运动层那套(U4)是它的下游伙伴"这个定位——这能帮你避免把两层的方法张冠李戴。

如果跳过本章会怎样

  • 场景一(只学了确定性 TAMP,T1-T4):你能在仿真里解出漂亮的 pick-place 计划,但一搬到真机就频繁失败——因为真机的感知给的是"杯子大概在这,±3cm,也可能根本看错了",你的规划器却当成"杯子精确在 \((0.3,0.2,0.1)\)"。你不知道该用信念表示这种不确定,也不知道"先看一眼确认再抓"应该作为一个规划动作而不是写死的预处理脚本。缺了 §3/§5,你会把不确定性当成"工程噪声"用 try-catch 硬扛,而不是当成规划问题正面求解。
  • 场景二(想做主动感知 / 信息收集):你的机器人需要"打开柜门看看东西在不在里面""挪开挡视线的盒子再判断"。你发现确定性规划器根本表达不了"这个动作的价值在于它能消除不确定性"——因为确定性世界里没有不确定性可消除。缺了 §5(contingent planning)和 §8(POMDP 的信息价值),你不知道如何让规划器主动选择信息收集动作,只能手工写死"先看后抓"的固定脚本,换个任务就得重写。
  • 场景三(用了 FF-Replan 但莫名其妙失败):你听说"确定化 + 重规划"很好用,于是把概率动作的"最可能效果"拿出来当确定性规划,跑得飞快。但在某些任务上它彻底失败——比如"必须先按按钮才知道哪扇门能开",FF-Replan 永远规划"假装门开了直接走",撞墙、重规划、再撞、死循环。缺了 §6.4,你不知道这是 determinization 的固有盲区(它看不见"信息收集"的价值),会误以为是代码 bug 而浪费大量时间。
  • 场景四(把任务层和运动层不确定性搅在一起):你想用一个大 POMDP 把"杯子在哪个房间(离散)"和"抓取偏差几厘米(连续)"一起求解,结果状态空间爆炸、求解器跑不动。缺了 §2.4 和 §10 的分层思想,你不知道这两类不确定性应该分层处理——任务层管离散命题的信念,运动层管连续量的噪声,各用各的机器,通过接口协作。

预计阅读时间

模式 覆盖范围 预计时间
精读 全部小节 + 信念更新推导 + §9 完整案例复现 + 接入 Mini-TAMP + 练习 16-20 小时
速读 §2.4 分工 + §3 信念空间 + §5 contingent + §6 FF-Replan + §9 案例骨架,跳过 §7 语言细节与 §8 POMDP 理论 6-7 小时
实战 §3 信念更新 + §5 策略树 + §6 determinization 取舍 + §9 设计工作流 + §10 接口 + 故障排查 8-10 小时
速查 知识导航 + §3 信念更新公式 + §4/§5/§6 三范式对照 + §10.3 任务层↔运动层接口表 + 各节小结 2 小时

针对不同目标:想理解原理走精读/速读;想为真实机器人做信念规划走实战路径(重点 §5/§6/§9);想快速查范式选型走速查(§2.4 判据 + 三范式对照表)。


2. 任务层的不确定性从哪来 ⭐⭐

2.1 动机:一个在真机上崩掉的"完美计划"

回到 TAMP 线那个贯穿场景:带机械臂的移动机器人收拾房间。在 T1-T3 里,我们让它解一个 pick-place:把杯子从桌上放到架子上。规划器输出一串漂亮的动作——move(base→table)pick(cup)move(base→shelf)place(cup, shelf)——仿真里一气呵成。

现在把它搬到真机。第一帧相机图像传来,感知模块报告:"桌面区域检测到一个疑似杯子的物体,置信度 0.7,位姿估计 \((0.31, 0.19, 0.74)\),协方差对应约 ±3cm。"问题立刻浮现:

  • 它真的是杯子吗? 置信度 0.7 意味着有 30% 的概率那是别的东西(一个倒扣的碗、一个圆罐)。确定性规划器的世界里只有 On(cup, table) 这条命题非真即假,它无法表达"0.7 概率是杯子"
  • 杯子精确在哪? ±3cm 的不确定,对"抓取"这个动作是致命的——夹爪宽度可能就 8cm,偏 3cm 就抓空。
  • 架子上有没有别的东西挡着? 相机有遮挡,架子深处看不清。规划器假设"架子是空的",但这只是它没看见,不等于真的空。
  • 抓取会不会失败? 真实夹爪有滑脱概率,pick(cup) 执行后 Holding(cup) 不是必然为真。

这四个问题,没有一个能在确定性 TAMP 的框架里正面回答。最朴素的应对是"出错了再说"——抓空了用传感器检测、检测到失败就重试。这能扛过一部分情况,但有一类问题它根本扛不住:当"该做什么"本身取决于"你还不知道的事"时。 比如杯子可能在桌上也可能在水槽里——机器人该往哪走?"出错了再说"在这里失效,因为走错方向不是"出错",而是"信息不足下的盲目下注"。

本质洞察:确定性 TAMP 的崩溃,根子不在"动作会失败"(那个还能靠重试缓解),而在"决策依赖于未知"。当机器人必须在"不知道杯子在哪"的前提下决定"先去哪",问题的性质就从"执行一个计划"变成了"在不确定性下做序贯决策"——这正是信念空间规划(§3)要解决的,也是本章与前五章的根本分野。请记住这条分野:会失败 ≠ 需要信念规划;决策依赖未知 = 需要信念规划。 §6 会看到,只"会失败"的问题用 FF-Replan 重试就够了,只有"决策依赖未知"才真正需要 §3-§5 的重武器。

2.2 任务层不确定性的三类来源

把任务层会遇到的不确定性系统地分一下类。注意我们刻意用符号层的语言描述(命题、动作算子),以区别于 U 线 U0 §2 那个面向运动层的"认知/偶然/模型/环境"四分类——两者视角不同,下面 §2.4 会对齐。

来源 符号层的样子 真机例子 本章对应
状态不确定(initial-state / current-state uncertainty) 初始时某些命题的真假未知:\(P(\texttt{On(cup,table)})=0.7\) 杯子在桌上还是水槽里?门锁没锁?盒子里有没有东西? §3 信念、§5 contingent
效果不确定(action-outcome uncertainty) 动作执行后效果是随机的:pick 以 0.9 成功、0.1 滑脱 抓取可能滑脱、推门可能没推开、放置可能倒 §6 determinization、§7 概率语言
感知不确定(observation uncertainty) 传感动作给的观测有噪声/会误报:look 返回 cup 但似然 \(P(o=\texttt{cup}\mid s)<1\) 视觉误检、置信度低、遮挡导致看不全 §5 contingent、§8 POMDP

这三类不是互斥的——一个真实任务往往三者都有。但区分它们有用,因为不同来源呼唤不同的方法

  • 只有状态不确定、且没有传感能力(不能中途观察)→ conformant planning(§4):要找一个不管初始世界是哪种都能成功的序列。
  • 状态/感知不确定、且能传感(可以中途看一眼再决定)→ contingent planning(§5):要找一棵按观测分支的策略树。
  • 主要是效果不确定、概率明确、可重规划 → determinization + replanning(§6)或概率规划(§7)。
  • 三者都重、且需要权衡"信息收集 vs 任务推进" → POMDP 视角(§8)。

本质洞察:这三类来源对应"我不知道世界现在是什么样"(状态)、"我不知道我的动作会把世界变成什么样"(效果)、"我不知道我看到的是不是真的"(感知)。它们恰好覆盖了一个 agent 与世界交互的三个环节——感知世界、对世界建模、改变世界——每个环节都可能漏进不确定性。把不确定性按"它从哪个环节漏进来"分类,比笼统地说"这个任务有不确定性"有用得多:它直接告诉你该调哪一类方法。

2.3 为什么不能沿用确定性 TAMP:三道崩溃

有人会想:能不能给确定性 TAMP 打补丁就好——比如每次用"最可能的世界"去规划,错了再重来?这个朴素想法(其实就是 §6 的 FF-Replan 的雏形)在很多情况下确实够用,但有三道坎它迈不过去,正是这三道坎逼出了信念空间规划。

崩溃一:最可能世界 ≠ 安全世界。 假设杯子有 0.7 概率在桌上、0.3 在水槽。"最可能世界"是桌上,于是规划"去桌边抓"。但若真相是水槽,机器人到了桌边扑空——更糟的是,如果"去桌边"路上会锁死某个状态(比如关上了通往水槽的门),这个错误就不可逆了。确定性规划只赌一个世界,赌错的代价它算不到。

崩溃二:看不见"信息收集"的价值。 真正致命的是这种任务:"先去走廊尽头看一眼,才知道杯子在 A 房还是 B 房。"确定性规划器的世界里杯子有个确定位置(哪怕是猜的),所以它永远不会主动去"看"——在它眼里"看"这个动作不改变任何命题、纯属浪费。于是它直接奔向猜测的房间,一半概率扑空。主动感知的价值,在确定性框架里根本无法表达——因为那个框架里没有"不确定性"这个可被消除的东西。这是确定性 TAMP 最深的盲区,§5(contingent)和 §8(POMDP 信息价值)专门补它。

崩溃三:重试 ≠ 收敛。 "错了再重规划"隐含假设每次重试都在取得进展。但如果动作本身不提供新信息,重试就是原地打转。例:门可能上锁,确定性规划"假装没锁、去开",失败,重规划——还是"假装没锁、去开",因为它的模型里门的状态没变、最可能仍是"没锁"。于是无限重试同一个失败动作。要打破死循环,必须让"开门失败"这件事更新对门的信念("看来更可能锁了"),并据此改变后续决策——这正是信念更新(§3)干的事。

本质洞察:这三道崩溃有一个共同根源——确定性 TAMP 把"不确定性"从世界模型里抹掉了,于是任何"与不确定性打交道"的智能行为(权衡风险、主动求知、从失败中学习)都无从谈起。 信念空间规划的全部价值,就是把不确定性作为一等公民重新放回世界模型:状态不再是"一个世界"而是"世界的分布"(信念),动作不仅改变世界还改变信念(包括"看一眼"这种只改变信念的动作)。一旦不确定性在模型里显式存在,"该冒险还是该求稳""该先探还是该先做"这些决策才第一次变得可计算。这是本章所有方法的共同出发点。

2.4 任务层 vs 运动层:不确定性该在哪一层处理

这是本章最重要的一条工程判据,也是本章与 U 线 30_不确定性规划/ 划清边界的关键。同样是"不确定性",有的该在任务层(符号)处理,有的该在运动层(几何)处理,用错层会让问题无谓地爆炸。

判据很简单:看不确定的东西是"离散命题的真假"还是"连续量的数值噪声"。

维度 任务层不确定性(本章) 运动层不确定性(U 线 U3/U4)
不确定的对象 离散命题真假:杯子在桌上吗?门锁了吗? 连续量数值:位姿偏几厘米?速度多少?
信念长什么样 离散分布 / 命题集合上的概率 连续分布(高斯、粒子)
决策的性质 离散选择:先去看哪?先抓哪个?走哪个分支? 连续路径:轨迹怎么走才 99% 安全
典型方法 conformant/contingent 规划、belief-space TAMP、POMDP(离散) belief-space 运动规划、机会约束、POMDP(连续状态)
典型工具 Contingent-FF、PPDDL/RDDL、SS-Replan 卡尔曼/粒子滤波、CC-RRT、SARSOP/DESPOT
本大纲位置 本章 T6 30_不确定性规划/ U3(机会约束) / U4(POMDP)

举三个例子走一遍(呼应 §0 Q5):

  • "杯子在桌上还是水槽里,要先看再决定" → 任务层。这是离散命题(两个 On 命题谁真)的不确定,决策是离散的(去哪看、去哪拿)。用 contingent planning(§5)。
  • "抓取时末端有 ±2cm 高斯误差" → 运动层。这是连续量(末端位姿)的噪声,决策是连续的(怎么调整抓取轨迹让它鲁棒)。用 belief-space 运动规划(U4)或机会约束(U3)。任务层不该去管这 2cm——它只需要知道"pick 动作有个成功概率"这个汇总数字。
  • "门可能锁了" → 任务层。离散命题真假未知。

两层如何协作? 不是二选一,而是分层:任务层把运动层的连续不确定性汇总成一个符号层的数字(如"这次抓取的成功概率 = 0.9",这个 0.9 由运动层的 belief 传播算出),然后任务层在符号层面用这个数字做离散决策。反过来,任务层决定"去看 A 房"后,"怎么走到 A 房且 belief 不发散"是运动层的事。§10 会把这个接口讲透。

本质洞察:把不确定性分到正确的层,是不确定 TAMP 工程化的第一原则,违反它的代价是指数级的。若你硬要用一个大 POMDP 同时建模"杯子在哪个房间(离散,3 种)"和"抓取偏差(连续,无穷)",连续维度会让 belief 空间无法离散求解;反过来,若你想用符号 contingent 规划去处理"±2cm 抓取误差",你得把厘米级位姿离散成成千上万个命题,符号搜索瞬间爆炸。正确的做法永远是分层:离散的不确定性留给符号任务层(少数命题、少数分支,可符号搜索),连续的不确定性留给几何运动层(高斯/粒子滤波,可数值传播),两层通过"成功概率""可达性"这类汇总量握手。这条"按不确定性的离散/连续性质分层"的原则,是理解整个不确定 TAMP 体系(本章 + U 线)的总纲——本章讲上半层,U 线讲下半层。

⚠️ 常见陷阱

陷阱一(概念误区):把"动作会失败"等同于"需要信念规划"。 - 错误描述:一看到"抓取可能滑脱"就上 contingent/POMDP 重武器。 - 现象/后果:为一个本可以"重试就解决"的问题付出巨大的建模和求解代价,规划器跑不动。 - 根本原因:混淆了"效果不确定(可重试)"和"决策依赖未知(需信念)"。前者动作失败了重做一遍即可(FF-Replan,§6 足矣);后者是"不先获取信息就无法正确决策",才真正需要信念规划。 - 正确做法:先问"失败后重试能取得进展吗?"——能(如抓滑了再抓),用 determinization+replan;不能(如不先看就不知道往哪走),才用 contingent(§5)。§6.4 给了精确判据。

陷阱二(概念误区):把运动层的连续噪声塞进符号任务层。 - 错误描述:在 PDDL 里用大量命题(PoseInCell_3_7PoseInCell_3_8…)去离散化连续位姿不确定性。 - 现象/后果:命题数与符号搜索的分支因子爆炸,规划器无法在合理时间内求解。 - 根本原因:违反 §2.4 的分层原则——连续量的噪声本该由运动层用滤波/机会约束数值地处理。 - 正确做法:任务层只保留汇总符号量(成功概率、可达性布尔),连续噪声交给运动层(U3/U4),两层通过接口(§10)握手。

陷阱三(思维陷阱):用"最可能世界"规划,却忘了它可能不安全也不可逆。 - 错误描述:永远拿 belief 里概率最大的那个世界去做确定性规划。 - 现象/后果:在"最可能 ≠ 安全"或动作不可逆的任务上酿成无法挽回的失败(§2.3 崩溃一)。 - 根本原因:最大似然确定化(QMDP 式)丢掉了分布的"尾巴",而风险恰恰藏在尾巴里。 - 正确做法:评估"赌错的代价"——代价低且可逆,最可能世界规划够用(§6、§8 的 QMDP 近似);代价高或不可逆,必须显式地在信念上规划、留出信息收集或保守余量(§5、§10 接 U 线 CVaR/机会约束)。

练习

  1. (⭐⭐,辨析) 下列任务各属于状态/效果/感知不确定的哪一类(可多选),并判断它该用 conformant、contingent、还是 determinization+replan:(a) 仓库里某货架补货,但不知道货架当前是满是空,无传感器;(b) 拧螺丝可能拧滑(10% 概率),拧滑了再拧一次即可;(c) 抽屉里可能有钥匙也可能没有,可以拉开看。
  2. (⭐⭐,分层) 一个移动操作任务同时包含:"目标物体在三个房间之一(离散)"和"机械臂基座定位有 ±5cm 漂移(连续)"。请按 §2.4 把这两类不确定性分到任务层/运动层,并说明两层通过什么汇总量握手(提示:可达性、成功概率)。
  3. (⭐⭐⭐,反例构造) 构造一个具体任务,使得"用最可能世界做确定性规划 + 失败重试"陷入 §2.3 崩溃三的无限死循环。要求写出动作、初始信念、为什么重试不更新信念。再说明:要打破死循环,缺的是哪一步(提示:§3 信念更新)。

3. 信念空间规划:把"状态"换成"信念" ⭐⭐⭐

这是本章的核心对象。前两节论证了"确定性 TAMP 不够",本节给出替代品:不在世界状态上规划,而在世界状态的概率分布——信念——上规划。一旦你接受了这个视角转换,conformant(§4)、contingent(§5)、POMDP(§8)都只是它的不同特例。

3.1 动机:从"一个世界"到"一片可能世界"

确定性规划里,规划器在任一时刻确切知道世界处于哪个状态 \(s\)。它的搜索是在状态图上找一条 \(s_0 \to s_{\text{goal}}\) 的路径。

不确定性进来后,规划器不再知道世界到底是哪个 \(s\),它只知道"世界可能\(s_1\)(概率 0.7)、可能\(s_2\)(概率 0.3)……"。这个"对世界状态的概率分布",就叫信念(belief),记作 \(b\)

\[ b(s) = P(\text{世界真实状态} = s \mid \text{至今的全部动作与观测历史}) \]

它是一个定义在状态空间 \(\mathcal{S}\) 上的概率分布:\(\sum_{s\in\mathcal{S}} b(s) = 1\)\(b(s)\ge 0\)

多视角类比:确定性规划像在一张地图上走,你始终知道自己站在哪个格子。信念空间规划像在浓雾中走——你不知道自己确切在哪,但你心里有一张"我可能在这些格子、各自多大概率"的概率热力图。你的每一步(动作)会让热力图整体平移、扩散(更不确定),每一次睁眼看(观测)会让热力图收缩、聚焦(更确定)。规划,就是在这张不断变形的热力图上,决定怎么走才能既到达目标、又在关键时刻把雾驱散到足够看清路。

关键的认识转换是:信念本身就是一种"状态"——只不过是"知识状态"而非"世界状态"。 机器人也许不知道杯子在哪,但它确切知道自己的信念("我认为 0.7 在桌上")。规划如果以信念为对象,机器人就又回到了"确切知道当前状态(信念)"的舒适区——这正是 §3.3 "信念空间 MDP"的精髓。

3.2 信念更新:动作让信念漂移,观测让信念聚焦

信念不是静止的,它随机器人与世界的交互而演化。演化分两种,对应两类动作。

第一类:物理动作(改变世界)→ 预测更新(prediction)。 机器人执行一个会改变世界的动作 \(a\)(如 movepick)。世界状态按转移模型 \(P(s'\mid s,a)\) 随机变化,于是信念也要推一步:

\[ \bar b(s') = \sum_{s\in\mathcal{S}} P(s'\mid s, a)\, b(s) \]

这一步通常让信念更分散(更不确定)——因为动作有随机效果,原本集中的信念被"摊开"了。例:pick(cup) 以 0.9 成功,那么即便原来 100% 确信杯子在桌上,执行后信念也变成"0.9 在手里、0.1 还在桌上(抓滑了)"。

第二类:传感动作(获取信息)→ 校正更新(correction / Bayesian update)。 机器人执行一个传感动作(如 looktouch),收到观测 \(o\)。观测按似然模型 \(P(o\mid s')\) 与真实状态相关,于是用贝叶斯法则把观测信息融进信念:

\[ b'(s') = \frac{P(o\mid s')\,\bar b(s')}{\sum_{s''\in\mathcal{S}} P(o\mid s'')\,\bar b(s'')} = \eta\, P(o\mid s')\,\bar b(s') \]

其中 \(\eta = \big[\sum_{s''} P(o\mid s'')\bar b(s'')\big]^{-1}\) 是归一化常数。这一步通常让信念更集中(更确定)——观测把"与观测不符的世界"的概率压低了。例:look 返回"看到杯子",且这个传感器很准(\(P(o=\text{见杯}\mid \text{杯在}) = 0.95\)\(P(o=\text{见杯}\mid \text{杯不在})=0.05\)),那么观测后"杯在"的概率会大幅上升。

把两步合起来,就是一次完整的信念-MDP 转移:从 \(b\) 出发,执行 \(a\),收到 \(o\),到达新信念 \(b' = \tau(b, a, o)\)。这个 \(\tau\) 就是 §0 Q2 的贝叶斯滤波,也是 U4 讲的 belief 更新——只不过这里的 \(s\) 是离散命题组合,不是连续向量

本质洞察:信念更新的两步——动作让信念漂移/扩散、观测让信念聚焦/收缩——是整个不确定性决策的物理引擎。它解释了为什么"主动感知"有价值:传感动作不改变世界(物理上"白做"),但它通过校正更新收缩信念,让后续决策更准。它也解释了为什么"长链动作不靠观测会越来越盲":纯物理动作链只有预测更新,信念一路扩散,到链尾几乎一无所知——这正是 §4 conformant planning 的根本困难(它禁用观测,只能靠"对所有可能世界都成立"硬扛扩散)。记住这一对此消彼长(动作增熵、观测减熵),你就握住了理解后续所有范式的钥匙。

下面用代码把这套更新在符号状态上实现一遍。我们用"命题集合到概率"的字典表示离散信念。

Step 1: 先讲为什么这样表示。

为什么用 dict{frozenset(命题) : 概率} 表示符号信念,而不是连续向量?

因为任务层的"状态"是离散命题的组合,如 {On(cup,table), Empty(hand)}。
一个信念就是"哪几种命题组合各占多大概率"——天然是一个从
"命题集合"到"概率"的映射。用 frozenset 装命题(可哈希、可做 dict 键),
用 dict 的值存概率,是最直接的表示。

规模警告:n 个独立布尔命题理论上有 2^n 种世界。所以这种"显式枚举所有
可能世界"的表示只适合 n 不大(命题不确定的维度低)的情况——这恰好是
任务层不确定性的常态(不确定的命题往往就几个:杯子在哪、门锁没锁)。
高维连续不确定性绝不能这么表示(§2.4 分层原则),那是运动层滤波的活。

Step 2: 给出正确写法。

from collections import defaultdict

# 符号信念:frozenset(命题字符串) -> 概率。所有概率之和为 1。
Belief = dict  # 类型别名,仅作可读性

def predict(belief: Belief, transition) -> Belief:
    """预测更新:执行一个物理动作后推进信念。
    transition(s) -> {s': p}  给出从世界 s 出发、各结果世界 s' 的概率。"""
    new_b = defaultdict(float)
    for s, b_s in belief.items():
        for s_next, p in transition(s).items():
            new_b[s_next] += p * b_s          # ∑_s P(s'|s,a) b(s)
    return normalize(dict(new_b))             # 数值稳健起见显式归一化

def correct(belief: Belief, obs, likelihood) -> Belief:
    """校正更新:收到观测 obs 后用贝叶斯法则收缩信念。
    likelihood(obs, s) -> P(obs | s)。"""
    new_b = {}
    for s, b_s in belief.items():
        w = likelihood(obs, s) * b_s          # P(o|s) · b̄(s),尚未归一化
        if w > 0:
            new_b[s] = w
    return normalize(new_b)                    # 除以 η⁻¹ = ∑ P(o|s) b̄(s)

def normalize(belief: Belief) -> Belief:
    z = sum(belief.values())
    if z == 0:
        raise ValueError("信念归一化失败:所有世界概率为 0 —— 观测与信念完全矛盾,"
                         "通常是似然模型把真实观测判成了不可能(见陷阱二)")
    return {s: p / z for s, p in belief.items()}

Step 3: 给出错误写法并解释为什么错。

# ❌ 错误 1:校正后忘了归一化
def correct_wrong(belief, obs, likelihood):
    return {s: likelihood(obs, s) * b_s for s, b_s in belief.items()}
# 问题:贝叶斯更新的分母 η 不能省。不归一化,∑b'(s) ≠ 1,
#      它不再是概率分布。几步之后概率会趋于 0 或爆炸,所有后续决策失效。

# ❌ 错误 2:似然模型给某个真实可能的状态分配了 0 概率
#   likelihood("见杯", s) = 1.0 if "杯在" in s else 0.0   # 把传感器当完美
# 问题:真实传感器会误报。若传感器其实会以 5% 概率"在杯不在时也报见杯",
#      你却建模成 0,那么一旦真实世界是"杯不在"但传感器误报"见杯",
#      correct 会把所有概率清零 → normalize 抛异常 / 信念崩溃。
#      永远给"反常但可能"的观测留一点概率质量(见陷阱二)。

# ❌ 错误 3:用浮点 set 而非 frozenset 当字典键
#   belief = { {"On(cup,table)"}: 0.7, ... }   # set 不可哈希,TypeError
# 问题:可变 set 不能作 dict 键。必须用 frozenset,否则连构造信念都会报错。

Step 4: 不同表示方式对比。

# === 三种符号信念表示,按"不确定维度"选 ===
# | 表示                         | 适用                         | 规模       |
# |------------------------------|------------------------------|-----------|
# | A. 显式枚举 dict{world:p}     | 不确定命题少(≤~15维)、要精确  | O(2^n) 上界|
# | B. 因子化(每命题独立的边缘概率)| 命题间近似独立时,省内存       | O(n)      |
# | C. 粒子集合(采样若干 world)   | 不确定维度高、容忍近似        | O(#粒子)  |
#
# 本章主线用 A(任务层不确定维度通常很低,精确且直观);
# §8/§9 真实系统不确定维度上去后,转向 C(粒子,与运动层滤波一脉相承)。
# B 在命题强相关时会丢相关性(如"门锁了"和"钥匙在锁孔"高度相关),慎用。

3.3 信念空间 MDP:把部分可观测问题"扳回"完全可观测

现在到了信念空间规划最深刻的一步认识。原始问题是部分可观测的——机器人看不清世界状态 \(s\),这让经典 MDP/规划方法(都假设状态可观测)失效。但有一个漂亮的转换能"扳回"可观测性:

把信念 \(b\) 本身当作状态。

理由:机器人虽然不知道 \(s\),但它总是确切知道当前的 \(b\)(它自己维护的)。所以如果我们定义一个新问题,其状态空间是"所有可能的信念"(概率单纯形 \(\Delta(\mathcal{S})\)),那么在这个新问题里,状态(信念)是完全可观测的。这个新问题就是一个普通的 MDP,叫信念空间 MDP(belief-MDP)

原始 POMDP(部分可观测) 诱导的 belief-MDP(完全可观测)
状态 \(s\in\mathcal{S}\)(看不清) 状态 \(b\in\Delta(\mathcal{S})\)(自己维护,可观测)
动作 \(a\) 同样的动作 \(a\)
转移 \(P(s'\mid s,a)\) + 观测 \(P(o\mid s')\) 转移 \(\tau(b,a,o)\)(§3.2 的更新)+ 观测概率 \(P(o\mid b,a)\)
奖励 \(R(s,a)\) 期望奖励 \(\rho(b,a) = \sum_s b(s) R(s,a)\)

本质洞察:这就是 U4 反复强调的那句话——"belief 是充分统计量,POMDP = belief 空间上的 MDP"——在任务层的版本。它的威力在于:一旦扳回 MDP,所有为 MDP/确定性规划开发的机器(值迭代、启发式搜索、A*)原则上都能用,只是搜索空间从离散状态变成了连续信念。它的代价也在这里:信念空间是连续的、维度等于状态数,直接在上面规划会遇到"维度灾难"\(|\mathcal{S}|\) 维连续空间)。本章后续方法(conformant/contingent/POMDP 近似)本质上都是在回答同一个问题:如何不显式遍历整个连续信念空间,就在它上面找到好的策略? 不同范式给了不同的"偷工减料"方式——conformant 干脆禁用观测把策略压成一条线(§4),contingent 只展开实际可能的观测分支(§5),POMDP 近似只在可达信念上备份(§8)。理解了"信念空间 MDP 是理想、维度灾难是障碍、各范式是不同的绕障方式",你就有了俯瞰全章的制高点。

3.4 任务层信念规划与 U 线 POMDP 的分工(先立此存照)

读到这里你可能会问:这不就是 U4 的 POMDP 吗?本章和它到底差在哪? 这是个好问题,先在此立个清晰的分工,§8、§10 再展开。

U 线 U4(30_不确定性规划/50 本章 T6
状态 \(s\) 连续(车位姿、他车意图)或小规模离散(Tiger) 离散命题组合(OnLockedHolding…),可能很多命题
关注 belief 更新的数值实现、值函数(α-vector/PWLC)、点基/在线求解器 把 belief 规划嵌进符号任务规划:动作有 PDDL 式前提-效果、用符号规划器搜策略、与几何 Stream 耦合
"动作" 抽象的 \(a\)(少数几个) 带参数的符号算子 pick(?obj)look(?region),可与几何采样耦合(§9)
求解主力 SARSOP、DESPOT、POMCP(通用 POMDP 求解器) Conformant-FF / Contingent-FF(符号规划器)、SS-Replan(符号+几何+重规划)
长时域 靠折扣 + 在线搜索深度有限 符号结构(动作的因子化前提-效果)天然压缩,宏动作/HTN 进一步抽象

本质洞察:U4 把 POMDP 当作一个通用的序贯决策数学问题来求解(不管状态是什么,只要给我转移/观测/奖励,我用 α-vector 或 belief 树搜)。本章把不确定性当作符号任务规划问题的一个属性来处理——它在乎"动作有结构化的前提和效果""目标是逻辑公式""可以和几何采样耦合"。同一个 belief-MDP,U4 用"无结构的通用求解器"硬解(适合状态少、结构弱的问题如 Tiger、交互驾驶),本章用"利用符号结构的专用规划器"巧解(适合命题多、动作结构强的长时域操作)。这不是重复,而是同一思想在两个抽象层、面向两类问题的两种落地——这也正是总论 T0 把 T6 与 U4 都列出、并标注"T6 接 U 线"的原因。

⚠️ 常见陷阱

陷阱一(概念误区):把信念当成"加权平均的状态",在平均状态上规划。 - 错误描述:把信念 \(b\) 坍缩成一个"期望世界"(如各物体位姿取均值)再做确定性规划。 - 现象/后果:在双峰信念(杯子要么在桌上要么在水槽,期望是"半空中"——一个根本不存在的世界)上酿成荒谬决策。 - 根本原因:信念是分布,不是一个点。期望/平均会制造出概率为 0 的"幻影世界"。 - 正确做法:在信念(整个分布)上规划,或至少在分布的若干代表性世界上分别考虑(contingent 分支,§5)。只有单峰、低方差时,平均世界近似才相对安全。

陷阱二(编程陷阱):似然模型给真实可能的观测分配 0 概率,导致信念崩溃。 - 错误描述:把传感器建模成完美的(P(误报) = 0),或漏掉某个观测结果。 - 现象/后果:一旦真实世界产生了被建模为"不可能"的观测,校正更新把所有概率清零,normalize 除零崩溃(§3.2 错误 2)。 - 根本原因:贝叶斯更新中 \(P(o\mid s)=0\) 会彻底杀死状态 \(s\),无法复活。 - 正确做法:永远给"反常但可能"的观测留一点概率质量(如最小 \(\epsilon\) 似然)。这等价于承认"传感器会犯错",是数值稳健的必需。

陷阱三(思维陷阱):以为"扳回 MDP"就万事大吉,忽视维度灾难。 - 错误描述:听到"POMDP = belief 空间 MDP"就以为可以直接套用 A*/值迭代在信念上规划。 - 现象/后果:信念空间是 \(|\mathcal{S}|\) 维连续空间,直接遍历瞬间爆炸,规划器跑不动。 - 根本原因:"扳回 MDP"是理论上的可解性,不是实践上的可计算性。 - 正确做法:理解后续所有范式(§4-§8)都是"不显式遍历信念空间"的近似手段,按问题特性选其一。

练习

  1. (⭐⭐,手算) 初始信念 \(b(\text{杯在桌}) = 0.7\)\(b(\text{杯在水槽}) = 0.3\)。机器人执行 look(table),传感器似然为 \(P(\text{见杯}\mid\text{杯在桌})=0.9\)\(P(\text{见杯}\mid\text{杯在水槽})=0.1\)。若观测到"见杯",用 §3.2 的校正公式手算更新后的信念。再问:若观测到"没见杯",更新后信念是多少?
  2. (⭐⭐⭐,实现) 用 §3.2 的 predict/correct 框架,实现"门可能上锁"任务的一次信念演化:初始 \(b(\text{锁})=b(\text{没锁})=0.5\);动作 try_open 的转移为"没锁→开(成功),锁→仍锁(失败)";执行后通过观测"门是否开了"做校正。写出 try_open 失败(门没开)后的信念,并解释它如何打破 §2.3 崩溃三的死循环。
  3. (⭐⭐⭐,概念) 解释为什么"纯物理动作长链 + 不观测"会让信念单调发散(熵不减)。结合 §3.2 的预测/校正,说明 conformant planning(§4,禁用观测)为什么是信念规划里"最难"的特例——它只有增熵的预测、没有减熵的校正。

4. Conformant Planning:无感知下也要稳的序列 ⭐⭐⭐

信念空间规划的第一个、也是最"硬"的特例:机器人对初始世界有不确定,但执行过程中完全没有传感能力(或选择不用)。它要找的是一个固定的动作序列,使得不管初始世界是哪一种,执行完都能达成目标。这叫 conformant planning(保形/一致性规划)。

4.1 动机:有些场合你根本看不了

为什么要研究"不许观察"这种看似自缚手脚的设定?因为真实世界里它真实存在:

  • 盲操作:在黑暗中、传感器失灵时、或物体被完全遮挡时,机器人只能"闭着眼"按预案动作。
  • 开环可靠性:有些安全关键动作不能依赖运行时传感(传感可能被攻击/失效),要求序列本身对所有情况鲁棒——这正是 conformant 的精神。
  • 理论地基:conformant 是信念规划的"最小内核"——它只有 §3.2 的预测更新(动作推进信念),没有校正更新(观测收缩信念)。理解了最难的无观测情形,contingent(有观测)只是在它上面加分支。

经典例子(来自规划文献):一个机器人要把若干个朝向未知的零件全部拨到朝上。它没有传感器看零件当前朝向。怎么办?答案是一个 conformant 序列:对每个零件,执行"翻到朝上"这个幂等动作——不管它原来朝上还是朝下,翻完都朝上。这个序列对所有初始朝向组合都成功,是一个 conformant plan。

4.2 形式化:在信念(可能世界集合)上规划,目标是"信念整体达标"

conformant planning 的状态是信念,但因为没有观测,信念只受预测更新驱动。又因为很多 conformant 问题里动作是确定的(只是初始状态不确定),信念可以简化为一个可能世界的集合 \(B \subseteq \mathcal{S}\)(不带概率,只关心"哪些世界还可能")。

  • 初始信念 \(B_0\):所有与初始知识相容的世界。如"3 个零件朝向未知"→ \(B_0\)\(2^3=8\) 个世界。
  • 动作的信念转移:执行 \(a\) 后,\(B' = \{\, \text{apply}(a, s) : s \in B \,\}\)——把动作作用到集合里每一个世界上。
  • 目标:要求集合里每一个世界都满足目标公式 \(g\),即 \(\forall s \in B,\ s \models g\)。注意是 \(\forall\) 不是 \(\exists\)——这是 conformant"对所有可能世界都成功"的数学表达。
\[ \text{找序列 } \pi = \langle a_1,\dots,a_k\rangle \ \text{ s.t. }\ \forall s_0 \in B_0,\ \ \text{apply}(\pi, s_0) \models g \]

本质洞察:conformant 的核心难点是那个 \(\forall\) ——目标必须对集合里每一个世界都成立。这比经典规划(只需让一个确定的世界到达目标)难一个数量级:经典规划的状态是一个世界,conformant 的状态是一个世界集合(信念),而集合的数量是世界数的指数。直接表示和搜索这个指数大的集合不可行——所以 conformant planning 的全部技巧,在于如何不显式枚举集合就推理它。Conformant-FF 的关键贡献(§4.3)正是用命题逻辑公式(CNF)隐式表示信念集合,把"这个动作序列后目标对所有世界成立吗"变成一个可满足性/蕴含判定,从而避免枚举指数个世界。

4.3 Conformant-FF:用 CNF 隐式表示信念,把"对所有世界成立"变成蕴含判定

Hoffmann 与 Brafman 在 2006 年(Artificial Intelligence)提出的 Conformant-FF,是 conformant planning 最有影响力的求解器,它把经典的 FF 规划器(T1 §3 讲过的删除松弛启发式)扩展到了初始状态不确定的情形。其核心思想有两条:

思想一:不枚举世界,用 CNF 公式表示"当前可能的世界集合"。 与其列出 \(B\) 里所有世界,不如用一个命题逻辑公式 \(\varphi\) 描述它们——满足 \(\varphi\) 的赋值恰好是 \(B\) 里的世界。初始不确定("零件 1 朝向未知")写成 CNF 子句,动作序列对信念的作用,转化为对公式的推理。

思想二:用蕴含判定代替"对所有世界检查"。 "动作序列后命题 \(p\) 在所有可能世界都成立吗?"等价于逻辑蕴含 \(\varphi_{\text{after}} \models p\)——而这可以用 SAT 求解器或针对性的推理高效判定,无需枚举。Conformant-FF 用一套基于命题公式的推理(implication tests on CNF capturing the action-sequence semantics)来回答这类查询,从而把指数的世界枚举压成可处理的逻辑推理。

它还把 FF 的删除松弛启发式扩展到 conformant 设定:通过把"相关的条件式 / 不确定性"也做松弛,估计"还要多少步能让目标对所有世界成立",引导前向搜索。这让它在许多 benchmark 上比"显式 belief-state 搜索"快几个数量级。

下面用伪代码刻画 conformant 前向搜索的骨架(用显式世界集合,便于理解;Conformant-FF 用 CNF 把这套逻辑做得更省)。

Step 1: 先讲为什么这样搜。

为什么 conformant 搜索的"节点"是世界集合,目标判定用 all() 而非 any()?

因为 conformant 要的计划对"所有可能初始世界"都成功。所以:
 - 搜索节点 = 当前可能世界的集合 B(一个信念,无观测所以是确定的集合演化);
 - 动作转移 = 把动作作用到 B 里每个世界,得到新集合 B';
 - 目标判定 = B 里每个世界都满足目标(all),而不是存在一个满足(any)。
把 any 误写成 all 的对偶(只要求一个世界达标)会得到"碰巧能成"的脆弱计划,
违背 conformant 的全部意义——它要的恰恰是"无论如何都能成"。

Step 2: 给出正确写法。

from itertools import product

def conformant_bfs(B0, actions, goal, max_depth=20):
    """conformant 前向搜索(显式世界集合版,教学用)。
    B0: 初始可能世界集合(frozenset of frozenset(命题));
    actions: [(name, applicable(s)->bool, apply(s)->s')];
    goal(s)->bool: 单个世界是否满足目标。"""
    from collections import deque
    start = frozenset(B0)
    frontier = deque([(start, [])])
    seen = {start}
    while frontier:
        B, plan = frontier.popleft()
        # 目标判定:B 里每个世界都达标(∀),这才是 conformant 解
        if all(goal(s) for s in B):
            return plan
        if len(plan) >= max_depth:
            continue
        for (name, applicable, apply_) in actions:
            # 动作必须在 B 的所有世界都可执行(否则该序列对某些世界非法)
            if not all(applicable(s) for s in B):
                continue
            B_next = frozenset(apply_(s) for s in B)   # B' = {apply(a,s) : s∈B}
            if B_next not in seen:
                seen.add(B_next)
                frontier.append((B_next, plan + [name]))
    return None   # 无 conformant 解:不存在对所有世界都成功的固定序列

Step 3: 给出错误写法并解释为什么错。

# ❌ 错误 1:目标判定用 any(只要有一个世界达标就算成功)
#   if any(goal(s) for s in B): return plan
# 问题:这求的是"乐观计划"——存在某个初始世界能成功。但 conformant 要的是
#      "无论哪个初始世界都成功"。any 给出的计划在其他世界会失败,完全错位。

# ❌ 错误 2:动作可执行性只检查"某个世界"而非"所有世界"
#   if any(applicable(s) for s in B):  ...
# 问题:若某动作只在 B 的部分世界可执行,把它放进固定序列,对其余世界就是非法操作
#      (前提不满足)。conformant 序列必须在所有可能世界都合法可执行。

# ❌ 错误 3:忘记 conformant 可能无解,不设深度上限 / 不返回 None
# 问题:有些问题根本不存在"对所有世界都成功的固定序列"(比如必须先观察才能区分
#      的世界)。这类问题 conformant 无解,应转 contingent(§5)。不处理无解会死循环。

Step 4: conformant 与经典/contingent 的对比。

# === 三种规划的"状态"和"解"对比 ===
# | 范式        | 搜索节点(状态) | 解的形态        | 目标判定 | 能用观测? |
# |-------------|---------------|----------------|---------|----------|
# | 经典规划     | 单个世界 s     | 动作序列(线)    | 一个世界 | —(确定)  |
# | conformant  | 世界集合 B     | 动作序列(线)    | ∀世界    | 否        |
# | contingent  | 信念(带分支)   | 策略树(分支)    | ∀分支叶  | 是(§5)   |
#
# 关键:conformant 的解仍是"一条线"(固定序列),但状态是"一片世界";
# contingent 的解是"一棵树"(按观测分支),因为它能观察并据此走不同分支。

4.4 conformant 的能力边界:什么时候它无解、必须上 contingent

conformant 强在"不依赖任何运行时传感、开环可靠",但它有一个硬边界:当不同的初始世界必须用不同的动作才能达成目标、而你又无法在执行前区分它们时,conformant 无解。

经典例子:杯子在 A 房或 B 房(各 50%),目标是把杯子拿到门口。conformant 要找一个固定序列,对"杯在 A"和"杯在 B"都成功。但"去 A 房拿"对"杯在 B"失败,"去 B 房拿"对"杯在 A"失败,没有任何固定序列能同时搞定两者——除非允许先去看一眼再决定。这个"看一眼再分支"超出了 conformant(它禁用观测),必须升级到 contingent(§5)。

本质洞察:conformant 与 contingent 的分界,恰好是 §3.2 那对更新的分界——conformant 只有预测更新(动作增熵),contingent 加了校正更新(观测减熵)。conformant 无解的根源,是它的信念只会扩散不会收缩,于是当"必须先收缩信念(搞清世界是哪种)才能正确行动"时,它无能为力。这给了一条清晰的方法选择链:先问"不观察行不行"——行(有对所有世界都成功的固定序列)就用 conformant(更简单、开环可靠);不行(必须先获取信息)就升级到 contingent。 这条链也呼应 §2.3 崩溃二:"看不见信息收集价值"的问题,conformant 同样束手无策——它和确定性规划共享"无观测"这个根本局限,只是 conformant 至少诚实地承认了状态不确定。

⚠️ 常见陷阱

陷阱一(概念误区):把 conformant 的"对所有世界成功"误解为"对最可能世界成功"。 - 错误描述:以为 conformant 是"挑个最可能的初始世界规划"。 - 现象/后果:得到的计划在小概率初始世界上失败,丢掉了 conformant 唯一的卖点(开环可靠)。 - 根本原因:混淆了 \(\forall\)(conformant)与"最大似然"(determinization,§6)。 - 正确做法:conformant 的目标判定永远是"集合里每个世界都达标"。若你只想顾最可能世界,那是 §6 的 determinization,不是 conformant。

陷阱二(思维陷阱):明明能传感,却硬用 conformant,付出不必要的保守代价。 - 错误描述:在可以"看一眼"的场合也坚持找无观测的固定序列。 - 现象/后果:要么无解(§4.4),要么找到的序列过度保守(为兼顾所有世界绕远路)。 - 根本原因:没意识到观测能收缩信念、大幅简化问题。 - 正确做法:能传感就上 contingent(§5);只有真的不能传感(盲操作、安全关键开环)才用 conformant。

陷阱三(编程陷阱):用显式世界集合表示高维不确定,集合大小指数爆炸。 - 错误描述:\(n\) 个不确定命题就枚举 \(2^n\) 个世界放进集合搜索。 - 现象/后果:\(n\) 稍大(如 20)集合就上百万,内存和时间都扛不住。 - 根本原因:显式枚举信念集合的固有指数复杂度。 - 正确做法:用 Conformant-FF 的 CNF 隐式表示 + 蕴含判定(§4.3),避免枚举;或确认不确定维度确实很低才用显式集合。

练习

  1. (⭐⭐,建模) 把 §4.1 的"翻零件"任务形式化:3 个零件朝向未知(朝上/朝下),动作 flip_up(i) 把零件 \(i\) 翻到朝上(幂等,不管原朝向)。写出 \(B_0\)(含几个世界)、目标公式、以及一个 conformant 解,并论证它对所有 8 个初始世界都成功。
  2. (⭐⭐⭐,判定) 给定任务:"开关可能在开或关,灯泡可能好或坏(共 4 种世界),目标是让灯亮。"动作只有 toggle_switch(翻转开关),无传感。这个任务有 conformant 解吗?若无,最少需要哪一类传感动作才能用 contingent 解?说明理由。
  3. (⭐⭐⭐,实现+调试) 运行 §4.3 的 conformant_bfs 解练习 1 的翻零件任务。然后把目标判定的 all 改成 any,观察它给出什么"计划",并解释为什么那个计划在真机上会失败——这正是陷阱一的代码版。

5. Contingent Planning:带感知分支的策略树 ⭐⭐⭐

这是本章最贴近真实机器人的范式。conformant 禁用观测、解是一条线;contingent planning 允许观测,解是一棵按观测结果分支的策略树。"先去看一眼柜子,看到钥匙就拿、没看到就去别处找"——这种"边走边看、看了再定"的智能,正是 contingent planning 的产物。

5.1 动机:真实机器人是"边做边看"的

§4.4 已经点明 conformant 的死穴:当不同世界需要不同动作、又无法事先区分时,固定序列无解。现实中机器人几乎总是有传感能力的——它有相机、有力觉,能在执行中获取信息。浪费这个能力(强行用 conformant)既保守又常常无解。

contingent planning 把传感动作(lookprobeopen-and-check)纳入规划,并允许计划根据观测结果走不同分支。它的解不再是动作序列,而是一棵策略树(contingent plan / policy tree)

                    look(cupboard)            ← 传感动作,会产生观测
                   /            \
          见钥匙(o=yes)      没见钥匙(o=no)    ← 按观测分支
              │                   │
        pick(key)            look(drawer)      ← 不同分支走不同后续
              │                /        \
        goto(door)      见钥匙        没见钥匙
              │            │             │
            [成功]      pick(key)      [报告找不到]
                       goto(door) ...

树的内部分支点是观测动作(条件取决于观测结果),叶子是达成目标(或确认失败)的终止。执行时,机器人沿树而下:到分支点就执行观测、看结果选分支、继续,直到叶子。

本质洞察:contingent plan 是一棵树而非一条线,这个形态差异背后是 §3.2 的校正更新在起作用——观测收缩信念,且不同观测把信念收缩到不同区域,于是后续最优动作也不同,计划必须分叉。 你可以把策略树看成"把信念空间 MDP 的最优策略,沿着实际可能发生的观测序列展开成的树"。这也立刻解释了 contingent 的主要复杂度来源:树的分支随观测点的增多而指数膨胀(每个观测点 ×|观测结果数|)。所以 contingent planning 的核心技巧,是只展开实际可能、且与目标相关的观测分支,而非盲目展开所有——这与 U 线 U1(分支/场景规划)"为多个离散未来同时准备策略"、U4(DESPOT)"belief 树就是被引导的 contingency 树"是同一思想在不同抽象层的体现(§10 详述)。

5.2 形式化:AND/OR 搜索,目标是"每条分支都达标"

contingent planning 在信念空间上做 AND/OR 搜索

  • OR 节点(动作选择):在当前信念 \(b\),机器人一个动作——这是"或",因为只需选一个好动作。物理动作和传感动作都在这里候选。
  • AND 节点(观测分叉):执行了传感动作后,观测结果是机器人不能控制的——所有可能的观测都得应对,这是"与",因为计划必须对每个可能观测都有后续且都达标。

一个 contingent 解(策略树)合法,当且仅当:从根信念出发,每个 OR 节点选定一个动作,每个 AND 节点(观测分叉)对每一个可能观测都有子树,且每一条根到叶的路径最终都满足目标。形式上,策略 \(\sigma: b \mapsto a\) 要使得:

\[ \forall\, \text{可达信念 } b \text{ under } \sigma,\quad \text{要么 } b \models g\ (\text{叶}),\ \text{要么 } \sigma(b) \text{ 定义且其所有观测后继都被 } \sigma \text{ 覆盖} \]

本质洞察:AND/OR 结构精确刻画了 contingent planning 的本质——机器人控制动作(OR:我选),但不控制观测结果(AND:老天给,我都得接)。这与博弈树惊人地相似:OR 节点像"我方走子"(选最优),AND 节点像"对手走子"(要对所有应对都不败)——只不过这里的"对手"是不确定的世界/传感器。这个视角的实用价值是:contingent 求解可以借用 AND/OR 搜索、博弈树搜索的成熟技术(如 AO* 算法、剪枝)。理解了"动作是 OR、观测是 AND",你就明白为什么 contingent 比 conformant(纯 OR,因为无观测、无 AND 分叉)难:多出来的 AND 分叉是复杂度的主要来源,也是"会看"换来的能力的代价。

5.3 Contingent-FF:把启发式前向搜索扩展到部分可观测

Hoffmann 与 Brafman 在 2005 年(ICAPS)提出的 Contingent-FF,把他们的 Conformant-FF(§4.3)进一步扩展到部分可观测——即允许观测动作。它延续了两个关键设计:

用"隐式信念状态"表示部分可观测下的知识。 与 conformant 一样,它不显式枚举可能世界,而是用命题公式紧凑表示"当前可能的世界 + 已知的观测约束"。观测动作执行后,对每个可能观测结果分裂出一个更新后的隐式信念状态。

用松弛启发式引导 AND/OR 搜索。 Contingent-FF 把 FF 的删除松弛思想推广到部分可观测:它的关键技巧是把"松弛后的 contingent 问题"进一步映射回一个松弛的 conformant 问题来估代价(targeted use of an additional relaxation, mapping the relaxed contingent problem into a relaxed conformant problem)。直觉是:先乐观地假设观测能完美区分世界,把问题简化成"无需分支的 conformant",用 conformant 启发式估算还要多少步。这个启发式引导前向搜索高效地构造策略树。它还包含对一类简单非确定效果的初步处理。

下面用伪代码刻画 AND/OR 递归搜索的骨架(构造策略树)。

Step 1: 先讲为什么这样递归。

为什么 contingent 搜索是 AND/OR 递归,物理动作和观测动作处理方式不同?

因为两类动作对"信念→后续"的影响结构不同:
 - 物理动作 a:信念按预测更新得到唯一的 b',后续是"一条"子计划(OR 内部,选它);
 - 观测动作 o:信念按观测结果分裂成多个 b'_o(每个观测结果一个),后续必须
   对"每个"可能观测都有子计划,且都要成功(AND,全覆盖)。
所以递归在观测动作处分叉成多个子问题、且要求全部成功(all);
在物理动作处不分叉、只推进信念。把这两者混为一谈(比如观测后只规划一个分支)
会得到"只在某个观测结果下成功"的残缺策略,执行时遇到别的观测就崩。

Step 2: 给出正确写法(策略树构造)。

def plan_contingent(belief, goal_holds, phys_actions, sense_actions,
                    depth=0, max_depth=12):
    """AND/OR 搜索构造 contingent 策略树(教学版,显式信念)。
    返回策略树节点 dict,或 None(此信念下无解)。"""
    if goal_holds(belief):
        return {"type": "leaf", "status": "goal"}          # 叶:目标达成
    if depth >= max_depth:
        return None

    # ---- OR:尝试每个物理动作(不分叉,推进信念后递归)----
    for a in phys_actions:
        if a.applicable(belief):
            b_next = a.predict(belief)                      # 预测更新(§3.2)
            sub = plan_contingent(b_next, goal_holds, phys_actions,
                                  sense_actions, depth + 1, max_depth)
            if sub is not None:
                return {"type": "action", "act": a.name, "child": sub}

    # ---- OR over 观测动作;每个观测动作内部是 AND(覆盖所有观测结果)----
    for s in sense_actions:
        if not s.applicable(belief):
            continue
        outcomes = s.possible_observations(belief)         # 此信念下可能的观测
        branches, ok = {}, True
        for o in outcomes:
            b_o = s.correct(belief, o)                      # 校正更新(§3.2)
            if not b_o:                                     # 该观测在此信念下概率 0,跳过
                continue
            sub = plan_contingent(b_o, goal_holds, phys_actions,
                                  sense_actions, depth + 1, max_depth)
            if sub is None:                                 # 有一个观测分支无解 → 整个观测动作不可用
                ok = False
                break
            branches[o] = sub
        if ok and branches:
            return {"type": "observe", "act": s.name, "branches": branches}  # AND 分叉点

    return None                                             # 物理/观测动作都试过仍无解

Step 3: 给出错误写法并解释为什么错。

# ❌ 错误 1:观测后只规划"最可能的那个观测结果"的分支
#   o_star = argmax_o P(o); return {... "child": plan(correct(belief,o_star))}
# 问题:这把 AND(覆盖所有观测)偷换成"赌一个观测"。执行时若真实观测是别的结果,
#      策略树没有对应分支 → 机器人不知所措。contingent 必须覆盖所有可能观测。

# ❌ 错误 2:AND 分支用 "有一个成功就行"(any)而非"全部成功"(all)
#   if any(plan(correct(belief,o)) for o in outcomes): ...
# 问题:和错误 1 同类。观测结果不由机器人控制,必须对每个都有成功后续,
#      "有一个分支能成"远远不够 —— 那是把 AND 当 OR。

# ❌ 错误 3:不剪掉"观测不会带来新信息"的无用传感动作
# 问题:若某观测动作在当前信念下所有结果的似然都相同(不改变信念分布),
#      它纯属浪费且会无限加深树。应检测"观测后信念是否真的分裂/收缩",
#      否则剪枝(呼应 §6 的信息增益判据)。否则搜索会被无信息观测灌爆。

Step 4: 策略树执行器(规划产物怎么跑)。

# === 把上面规划出的策略树,在真机/仿真上执行 ===
def execute(tree, world, sense_fn, act_fn):
    """tree: plan_contingent 的产物; world: 真实(隐藏)世界;
    sense_fn(name,world)->o 真实传感; act_fn(name,world)->world 真实执行。"""
    node = tree
    while node["type"] != "leaf":
        if node["type"] == "action":
            world = act_fn(node["act"], world)            # 执行物理动作
            node = node["child"]
        elif node["type"] == "observe":
            o = sense_fn(node["act"], world)              # 执行传感,拿真实观测
            if o not in node["branches"]:                 # 真实观测超出预案分支
                raise RuntimeError(f"观测 {o} 无对应分支 —— 似然模型漏了某结果(陷阱)")
            node = node["branches"][o]                    # 按真实观测走对应分支
    return node["status"]   # "goal" 表示成功
# 关键:执行器是"解释器"——它沿树而下,在 observe 节点用真实观测选分支。
# 这正是 contingent plan "边做边看"的运行时体现。

5.4 与 T5 行为树、U 线分支规划的关系(避免混淆)

contingent 策略树容易和两个相邻概念混淆,这里厘清。

与 T5 行为树(执行层)的关系。 策略树(contingent plan)是规划产物——规划器在规划时构造出来的、对所有预期观测都有应对的树。T5 的行为树是执行框架——它管 tick、监控、失败恢复。两者互补:contingent planning 生成应对不确定性的策略,行为树承载并稳健执行它(observe 节点天然映射为行为树的条件分支,物理动作映射为执行叶)。前沿做法正是"规划器在线生成行为树"(plan-to-BT),contingent plan 是其中一种可被编译成 BT 的策略表示。简言之:contingent 答"该准备哪些分支",行为树答"怎么稳健地按分支执行、执行中又出意外怎么办"。

与 U 线 U1 分支/场景规划、U4 DESPOT 的关系。 U1(30_不确定性规划/20)的"分支规划/MPDM/EUDM"和本节是同一思想(为多个离散未来准备分支策略)在不同抽象层:U1 在运动/交互层分支(他车的几种语义策略、闭环前向仿真),本节在任务/符号层分支(命题真假的几种可能、符号动作)。U4 的 DESPOT 更点破了这层联系——"belief 树就是被引导的 contingency 树"。它们的数学骨架都是 AND/OR / belief 树,差别在节点里装的是符号命题(本章)还是连续状态/轨迹(U 线)。§10 会把这条"同骨架、不同层"的关系正式接起来。

本质洞察:contingent 策略树是一个"枢纽概念"——它向下接执行(T5 行为树承载它)、向旁接运动层不确定(U1/U4 是它在连续层的孪生)、向上接 POMDP(它是 POMDP 最优策略沿可达观测展开的树,§8)。把这四者(contingent / 行为树 / U 线分支 / POMDP)放在一起看,你会发现它们共享一个深层结构:在"我能选动作、但不能选观测/扰动"的世界里,把决策组织成一棵对所有不可控分支都有应对的树。 这个结构是机器人不确定性决策的通用语言。本章在符号层讲它,T5 讲它的执行,U 线讲它的连续版——理解了通用结构,跨章的知识就串成了一张网。

⚠️ 常见陷阱

陷阱一(概念误区):把 contingent plan 当成"一条带 if 的序列",只准备最可能分支。 - 错误描述:以为"先看一眼,如果看到 X 就……"只需写最可能的那一支。 - 现象/后果:真实观测落到没准备的分支时,机器人无应对(§5.3 错误 1/2)。 - 根本原因:把 AND(覆盖所有观测)误当 OR(赌一个观测)。 - 正确做法:每个观测点必须对所有可能观测结果都有子计划。这是 contingent 与"乐观确定化"的本质区别。

陷阱二(思维陷阱):滥加传感动作,让策略树被无信息观测灌爆。 - 错误描述:在每一步都插入各种 look,以为"多看总没错"。 - 现象/后果:策略树指数膨胀,规划超时;很多观测其实不改变信念(无信息)。 - 根本原因:没区分"有信息的观测"(改变信念分布)和"无信息的观测"(不改变)。 - 正确做法:只在"观测能收缩信念、且收缩与决策相关"时分支(§5.3 错误 3 的剪枝)。这呼应 §8 的信息价值(VoI)——观测要值得做。

陷阱三(编程陷阱):策略树执行器遇到预案外观测直接崩溃,无兜底。 - 错误描述:execute 在 observe 节点假设真实观测必在 branches 里。 - 现象/后果:真机传感器给出建模时没列的观测(噪声、新情况),执行器抛异常、任务中断。 - 根本原因:开环假设"规划时枚举的观测 = 运行时所有可能观测",真机会打破它。 - 正确做法:执行器对预案外观测要有兜底——触发重规划(§6 的 replanning 思想)、或退到一个安全默认分支。这正是为什么真实系统常把 contingent planning 与 replanning 结合(§6、§9 的 SS-Replan)。

练习

  1. (⭐⭐,画树) 任务:"钥匙在抽屉或柜子里(各 50%),目标是拿到钥匙到门口。"可用动作:look(drawer)look(cupboard)pick(key)(需先看到钥匙所在)、goto(door)。画出一棵完整的 contingent 策略树,标出每个 observe 节点的分支和叶子。
  2. (⭐⭐⭐,实现) 用 §5.3 的 plan_contingent 框架实现练习 1 的任务(定义信念、物理动作、传感动作及其 possible_observations/correct),跑出策略树,再用 execute 在"钥匙真实在柜子"和"真实在抽屉"两种世界各执行一遍,验证两种世界都成功。
  3. (⭐⭐⭐,对比) 同一个"钥匙在抽屉或柜子"任务,分别用 conformant(§4)和 contingent(§5)求解。说明 conformant 为什么无解、contingent 为什么有解,并指出二者的解在形态上(线 vs 树)和执行上(开环 vs 边看边走)的根本差异。

6. Determinization 与 FF-Replan:用"假装确定"绕开概率 ⭐⭐⭐

前面三节(信念、conformant、contingent)都是"正面硬刚"不确定性——把它建模进信念、在信念空间上规划。本节讲一条截然不同的工程捷径假装世界是确定的,用快得多的确定性规划器求解,错了再重规划。 这条捷径以 FF-Replan 为代表,它简单到近乎"作弊",却在概率规划竞赛上击败了精心设计的概率规划器——理解它为什么有效、又在哪里必然失败,是不确定性 TAMP 工程直觉的关键一课。

6.1 动机:在信念上规划太贵,能不能绕开?

§3.3 说过,信念空间是 \(|\mathcal{S}|\) 维连续空间,直接规划遭遇维度灾难。conformant/contingent 用符号技巧缓解,但仍比确定性规划慢得多。有没有办法复用成熟、飞快的确定性规划器(T1 的 FF/FastDownward)来对付不确定性?

有。核心观察是:很多任务的不确定性,重试就能化解——动作偶尔失败,但失败了重做一遍(或换条路)就好,不需要事先把所有可能都规划进一棵树。对这类任务,与其费力做 contingent,不如:

  1. 确定化(determinize):把概率动作变成确定动作(扔掉概率),得到一个普通的确定性规划问题。
  2. 规划:用飞快的确定性规划器求一条到目标的路径。
  3. 执行 + 监控:执行计划,同时监控实际结果。
  4. 重规划(replan):一旦实际结果偏离了确定化的假设(动作失败、世界与预期不符),从当前真实状态重新确定化 + 规划。

这就是 determinization + replanning 范式。它把"应对不确定性"从"规划时一次性想全"挪到了"执行时遇到再说"——用重规划的次数换规划的复杂度。

6.2 两种确定化:all-outcomes 与 most-likely

把概率动作变确定动作,有两种主流做法,区别在于"怎么处理一个动作的多个可能结果"。

most-likely-outcome(最可能效果)确定化。 每个概率动作只保留概率最大的那个效果,扔掉其余。例:pick 有 0.9 成功、0.1 滑脱,确定化后就是"pick 必成功"。 - 优点:动作数不变,规划问题最小。 - 缺点:完全忽略小概率分支。若小概率分支恰恰重要(如那 0.1 的滑脱会导致不可逆灾难),它看不见。

all-outcomes(全效果)确定化。 把每个概率动作拆成多个确定动作,每个对应一个可能效果。例:pick 拆成 pick-success(→ Holding)和 pick-slip(→ 杯落地)两个确定动作,规划器可以自由选用任一个。 - 优点:保留了所有可能效果,规划器能找到"利用某个效果"的计划(包括利用小概率好效果)。 - 缺点:动作数膨胀(每个概率动作 ×效果数);且规划器会"乐观地"假设自己能选中想要的效果——而真机不能选效果(效果是随机的),这正是它需要靠重规划来兜底的原因。

FF-Replan 主要用 all-outcomes(也可用 most-likely)。下面把 all-outcomes 确定化 + 重规划循环用代码写出来。

Step 1: 先讲为什么这样确定化 + 循环。

为什么 all-outcomes 把一个概率动作拆成多个确定动作,再靠重规划兜底?

概率动作 pick: 0.9→Holding(cup), 0.1→OnFloor(cup)
确定化(all-outcomes)拆成两个确定动作:
   pick-success: 前提同 pick, 效果 = Holding(cup)
   pick-slip:    前提同 pick, 效果 = OnFloor(cup)
确定性规划器把这两个当普通动作,会"挑"对自己有利的(通常挑 pick-success),
求出一条乐观路径。但真机执行 pick 时,结果是随机的——可能真滑了(OnFloor)。
这时实际状态偏离了规划假设(规划假设 Holding,实际 OnFloor),触发重规划:
从真实状态(OnFloor)重新确定化+规划(这次会先规划把杯子从地上捡起)。
"规划乐观、执行兜底、偏离重来"——这就是 FF-Replan 的全部精髓。

Step 2: 给出正确写法。

def determinize_all_outcomes(prob_actions):
    """把概率动作集合做 all-outcomes 确定化。
    每个概率动作 (name, precond, [(p, effect), ...]) 拆成多个确定动作。"""
    det_actions = []
    for name, precond, outcomes in prob_actions:
        for i, (p, effect) in enumerate(outcomes):
            det_actions.append((f"{name}__o{i}", precond, effect))  # 一个效果一个确定动作
    return det_actions

def ff_replan(initial_state, goal, prob_actions, det_planner,
              execute_action, max_replans=100):
    """determinization + replanning 主循环(FF-Replan 思想)。
    det_planner(state, goal, det_actions) -> 确定性计划(动作名序列) 或 None。"""
    det_actions = determinize_all_outcomes(prob_actions)
    state = observe_current_state()                  # 从真机/仿真读当前真实状态
    replans = 0
    while not goal(state):
        plan = det_planner(state, goal, det_actions) # 用飞快的确定性规划器
        if plan is None:
            raise RuntimeError("确定化问题都无解 —— 目标在乐观假设下都到不了,应换范式")
        for det_act_name in plan:
            base = det_act_name.split("__o")[0]       # 取回原始概率动作名
            outcome = execute_action(base)            # 真机执行,结果是随机的!
            state = observe_current_state()           # 重新观测真实状态
            if not consistent(state, det_act_name):   # 实际结果≠确定化假设的效果
                replans += 1
                if replans > max_replans:
                    raise RuntimeError("重规划次数超限 —— 疑似'概率即灾难'盲区(§6.4)")
                break                                 # 跳出执行循环 → 外层重新规划
    return "goal reached"

Step 3: 给出错误写法并解释为什么错。

# ❌ 错误 1:执行时假设"挑中的效果一定发生",不监控、不重规划
#   for det_act in plan: execute_action(det_act.split("__o")[0])  # 一路执行到底
# 问题:确定性规划器挑了 pick-success,但真机 pick 可能滑脱。不监控就发现不了偏离,
#      后续动作全建立在错误假设上(以为 Holding,其实 OnFloor),整条计划崩塌。
#      determinization 的正确性完全依赖"执行后监控 + 偏离即重规划"。

# ❌ 错误 2:每步都无条件重规划(哪怕结果符合预期)
#   for det_act in plan: execute(...); plan = det_planner(...)  # 每步都重算
# 问题:浪费。只在"实际结果偏离确定化假设"时才需要重规划。结果符合预期就继续执行
#      剩余计划。无条件重规划把 FF-Replan 的速度优势(规划一次跑多步)丢光了。

# ❌ 错误 3:most-likely 确定化丢了一个"不可逆灾难"的小概率分支
#   只保留 pick 的 0.9 成功分支,忽略 0.1 "滑脱砸坏易碎品"
# 问题:若那 0.1 是不可逆的(砸坏了无法恢复),重规划也救不回来。determinization
#      隐含假设"失败可恢复"。不可逆的小概率灾难必须用信念规划(§5)预防,不能靠重试。

Step 4: 两种确定化对比。

# === most-likely vs all-outcomes 确定化对比 ===
# | 维度          | most-likely(最可能)      | all-outcomes(全效果)        |
# |---------------|--------------------------|-----------------------------|
# | 动作数        | 不变                     | ×效果数(膨胀)               |
# | 看得见小概率? | 否(只留最可能)           | 是(每个效果都是可选动作)    |
# | 规划器倾向    | 走最可能路径             | 乐观:挑对自己有利的效果     |
# | 适合          | 效果高度集中、失败少      | 想利用某些(小概率)好效果    |
# | 共同盲区      | 都靠重规划兜底,都看不见"信息收集价值"(§6.4) |

6.3 为什么这么"作弊"的方法却很强:FF-Replan 的竞赛传奇

Yoon、Fern 与 Givan 在 2007 年(ICAPS)提出 FF-Replan,本意只是给概率规划竞赛(IPPC)做一个朴素基线——确定化 + 用 FF 规划 + 重规划。结果它赢了 2004 年首届 IPPC,并在 2006 年的域上也表现强劲(虽非正式参赛)。一个"假装确定、错了重来"的基线,击败了一众精心设计的概率规划器,这个结果在领域内引起了深刻反思。

它为什么强?

  • 确定性规划器极其成熟、极快。 FF 的删除松弛启发式(T1 §3)让它能在毫秒级解大规划问题。determinization 直接嫁接了这份算力。
  • 很多 benchmark 的不确定性是"良性"的。 动作偶尔失败,但失败可恢复、重规划能取得进展。对这类问题,"事先想全所有分支"(contingent/POMDP)是杀鸡用牛刀——重试就够了。
  • 重规划自带反馈。 每次重规划都从真实当前状态出发,相当于隐式地利用了执行中获得的信息(虽然它不主动求信息)。

本质洞察:FF-Replan 的传奇给了一条极重要的工程教训——不要为不确定性付出超过必要的代价。如果一个问题的不确定性能靠"重试+重规划"化解,就别上 contingent/POMDP 的重武器。这呼应了 §2.1 那条分野:"会失败"用 FF-Replan,"决策依赖未知"才用信念规划。 FF-Replan 之所以能赢,正是因为早期 IPPC 的很多域属于前者。它也树立了一个所有不确定性方法都该对标的基线:你的复杂方法,真的比"确定化+重规划"强吗?强在哪个具体的不确定性结构上? 答不出这个问题,复杂方法就没有正当性。这种"先问最简单的基线行不行"的思维,是工程上对抗过度设计的利器。

6.4 FF-Replan 的死穴:"概率即灾难"与信息收集盲区

FF-Replan 的强大有明确边界。它在两类问题上必然失败,理解这两类是本节的核心。

死穴一:probabilistically interesting / "概率即灾难"问题。 当某些动作有小概率导致不可逆的灾难(avoidable dead-ends),而避免灾难需要主动绕开(而非事后补救)时,determinization 失败。因为确定化(尤其 most-likely)把那个小概率灾难分支抹掉了,规划器看不见危险、不会去避,于是一头撞上去——而灾难不可逆,重规划也救不回来。Little 与 Thiébaux(2007,与 FF-Replan 同会)正是用这类"probabilistically interesting"问题指出了 replanning 范式的根本局限。

死穴二:信息收集盲区(§2.3 崩溃二的回归)。 determinization 的世界里没有不确定性(被假装掉了),所以它永远不会主动去观察。对"必须先看才知道往哪走"的任务(杯子在 A 房或 B 房、门锁没锁要先试),FF-Replan 会一路乐观假设、撞错、重规划、再撞——因为它的模型里没有"看一眼能消除不确定"这回事。这类需要主动感知的任务,是 determinization 的绝对禁区,必须用 contingent(§5)或 POMDP(§8)。

本质洞察:FF-Replan 的两个死穴,本质是同一个缺陷的两面——它把不确定性从模型里抹掉了,于是任何"需要正视不确定性"的智能(规避不可逆风险、主动求知)都无从产生。这和 §2.3 确定性 TAMP 的崩溃同源,只是 FF-Replan 多了重规划这层缓冲,能扛住"良性、可恢复"的不确定。判据由此清晰:(1) 失败可恢复吗?不可恢复(不可逆灾难)→ 不能用 FF-Replan,要用信念规划预防;(2) 不观察能正确决策吗?不能(决策依赖未知)→ 不能用 FF-Replan,要用 contingent。两个"能"都成立,FF-Replan 往往是最高效的选择。 把这条判据刻进脑子,你就能在"简单重试"和"信念规划重武器"之间做出正确的工程取舍——这是不确定性 TAMP 最实用的决策。

6.5 一个能算的反例:独木桥上 FF-Replan 为何"自信地"失败

死穴一抽象讲完,用一个能算成功率的例子把它钉死(这也是 §6 练习 2 的脚手架)。独木桥任务:要从桥这头走到对岸,桥长 \(N\) 步。每走一步 step:以 0.9 前进一格,以 0.1 掉下桥fallen,不可逆死局,掉了就再也回不来)。目标:到达对岸(走完 \(N\) 步且未掉落)。

FF-Replan 看到的世界(确定化后)。 most-likely 确定化把 step 的 0.1 掉落分支抹掉,只留"0.9 前进"→ 变成"step 必定前进一格"的确定动作。于是 FF 规划出 \([\texttt{step}\times N]\)——"直接走过去",规划器自信满满(它的世界里根本没有掉落这回事)。all-outcomes 也好不到哪去:它虽保留了 fallen 分支,但因为 fallen 是死局(无后继、不可达目标),FF 不会主动选它,规划仍是"全程 step 前进"——同样看不见累积风险。

真机执行的真实成功率。 每步独立 0.9 存活,走完 \(N\) 步全部存活的概率是:

\[ P(\text{成功}) = 0.9^{N} \]

\(N=5\)\(0.9^5\approx 0.59\)\(N=10\)\(0.9^{10}\approx 0.35\)\(N=20\)\(0.9^{20}\approx 0.12\)成功率随桥长指数衰减,而 FF-Replan 在规划时始终"100% 自信能过"——这个"规划自信度恒为 1、真实成功率指数趋 0"的鸿沟,正是死穴一的量化面孔。

为什么重规划救不了? FF-Replan 的重规划在"偏离预期"时触发。但这里偏离 = 掉下桥 = fallen 死局——重规划从 fallen 状态出发,目标不可达(死局无路回对岸),重规划返回"无解",任务彻底失败。重规划的前提(失败可恢复)在不可逆死局上崩塌,这正是死穴一的机理。

FF-Replan 在独木桥上的执行轨迹(N=5 的一次典型失败):
  规划: [step, step, step, step, step]   ← 确定化世界:自信能过
  执行: step(进1) step(进2) step(掉!)    ← 真机:第3步触发0.1掉落
  观测: fallen (死局)
  重规划: FF.plan(从 fallen 到 对岸) → 【无解】(死局不可达目标)
  结果: 失败。且这是【不可恢复】的失败,不是"重试一下"能救的。
─────────────────────────────────────────────────────────
对照:若把 step 的掉落分支【保留并重罚】(或用信念规划§5/§8 显式建模死局),
规划器才会"看见"累积风险 → 可能选择更安全的动作(如先架护栏/绕路),
或至少在风险过高时拒绝执行。这正是 TAMPURA(§8.6)"风险感知"要补的能力。

对比性思维(反事实):如果把这座桥的掉落改成可恢复的(掉下去能爬回原格,只是多花几步),FF-Replan 立刻变得完全够用——每次掉落就重规划"爬回来再走",期望多走几步但终能过桥,且它仍然飞快。同一个任务,仅仅把"不可逆"改成"可逆",FF-Replan 就从"必然失败"变成"高效够用"。 这个反事实精准锁定了死穴一的真正触发条件——不是"有小概率坏事",而是"小概率坏事不可逆"。所以判断要不要弃用 FF-Replan,关键一问不是"动作会不会失败",而是"失败了能不能爬回来":能爬回来,重试就行;爬不回来(掉下桥、打碎杯子、锁死门),才必须上信念/风险规划提前规避。把这一刀切准,你就不会在良性问题上过度设计、也不会在不可逆问题上埋雷。

⚠️ 常见陷阱

陷阱一(思维陷阱):在"概率即灾难"问题上用 FF-Replan,被不可逆失败反复打击。 - 错误描述:对含不可逆 dead-end 的任务也用确定化+重规划。 - 现象/后果:规划器撞上被抹掉的灾难分支,不可逆,重规划救不回,任务彻底失败(§6.4 死穴一)。 - 根本原因:确定化丢掉了小概率灾难分支,规划器看不见、不规避。 - 正确做法:先判断失败是否可逆。不可逆 → 用信念规划(§5)显式规避,或在确定化中保留灾难分支并惩罚它。

陷阱二(概念误区):以为重规划能替代主动感知。 - 错误描述:对"必须先看才知道往哪走"的任务,指望"撞错了重规划"最终能成。 - 现象/后果:无限撞错-重规划循环,因为重规划本身不主动获取信息(§6.4 死穴二、§2.3 崩溃三)。 - 根本原因:determinization 的模型里没有不确定性可消除,故不会规划观测动作。 - 正确做法:需要主动感知的任务用 contingent(§5),把 look 作为一等规划动作。

陷阱三(编程陷阱):all-outcomes 确定化后忘记执行时映射回原始动作 / 不监控偏离。 - 错误描述:直接把 pick__o0pick__o1 当真机能执行的动作,或执行后不检查实际结果。 - 现象/后果:真机没有"pick-success"这个可选动作(它只能 pick,结果随机),且不监控就发现不了滑脱(§6.2 错误 1)。 - 根本原因:确定化是规划时的虚构,真机执行的是原始概率动作、结果不可控。 - 正确做法:执行时把 name__oK 映射回原始 name 执行,执行后观测真实状态,偏离确定化假设就重规划。

练习

  1. (⭐⭐,确定化) 给定概率动作 unlock:前提 HasKey,效果 0.8→Unlocked、0.2→KeyStuck(钥匙卡住,需 extract-key 恢复)。写出它的 most-likely 和 all-outcomes 两种确定化结果。讨论:哪种确定化能让规划器"预先准备好钥匙卡住的应对"?
  2. (⭐⭐⭐,判据应用) 对下列任务判断该用 FF-Replan 还是信念规划,并说明理由:(a) 扫地机器人偶尔卡在地毯边(卡住可后退脱困);(b) 拆弹机器人剪线,剪错线(小概率)即引爆(不可逆);(c) 快递机器人要先扫码才知道包裹该送哪层。
  3. (⭐⭐⭐⭐,实现+复现盲区) 用 §6.2 的 ff_replan 实现一个"门可能锁了"任务(open 成功率取决于隐藏的 Locked 状态)。观察它陷入"假装没锁→开→失败→重规划→再假装没锁"的死循环(§6.4 死穴二),并解释要打破它必须引入什么(提示:把"门是否锁了"建成信念 + try 动作更新信念,转 §5 contingent)。

7. 概率 PDDL:PPDDL 与 RDDL ⭐⭐⭐

前面讲的 conformant/contingent/FF-Replan 都需要一个输入:带概率的动作模型。这一节讲怎么它——两种标准的概率规划语言:PPDDL(PDDL 的概率扩展,效果导向)和 RDDL(基于动态贝叶斯网络,状态转移导向)。它们是国际概率规划竞赛(IPPC)的标准输入语言,理解它们能让你读懂文献里的 benchmark、也能为自己的不确定任务建模。

7.1 为什么需要专门的概率语言:T1 的 PDDL 不够用

T1 教的经典 PDDL 动作长这样(确定效果):

(:action pick
  :parameters (?o - object)
  :precondition (and (on-table ?o) (hand-empty))
  :effect (and (holding ?o) (not (on-table ?o)) (not (hand-empty))))

它的 :effect确定的——执行后这些命题必然如此。但真实的 pick 会滑脱,我们需要表达"0.9 概率成功、0.1 概率滑脱"。经典 PDDL 没有任何语法表达"概率效果"。于是有了 PPDDL——在 PDDL 上加一个 probabilistic 关键字。

本质洞察:概率语言要解决的核心表达问题,是"一个动作执行后,世界会以不同概率进入不同的后继状态"。PPDDL 和 RDDL 给了两种回答这个问题的范式——PPDDL 以动作/效果为中心("这个动作有这些带概率的效果",是经典 PDDL 的自然延伸),RDDL 以状态变量/转移为中心("每个状态变量下一时刻的值,由一个条件概率分布决定",更像动态贝叶斯网络)。这个"效果导向 vs 转移导向"的分野,决定了它们各自擅长的领域(§7.4),也反映了规划界两种建模哲学的并存。

一点历史(为什么这两种语言会先后出现)。 概率规划语言的演进,是被国际概率规划竞赛(IPPC, International Probabilistic Planning Competition) 的需求一步步推出来的,这条历史能帮你理解"为什么是这两种、为什么从 PPDDL 转向 RDDL":

2004  PPDDL (Younes & Littman, 技术报告 CMU-CS-04-167)
  │   给 PDDL 加 probabilistic 效果;作为 IPC-4(2004) 概率赛道的标准语言。
  │   局限: 只能表达"少数动作各自有少量概率效果"的【完全可观测 MDP】;
  │         很多变量并发演化时要枚举效果组合,笨拙;无观测变量,表达不了 POMDP。
2006/2008  IPPC 沿用 PPDDL
  │   FF-Replan(§6, Yoon-Fern-Givan 2007)正是在这几届用"确定化+重规划"夺冠,
  │   反而暴露了"很多 benchmark 不够 probabilistically interesting"的问题
  │   (Little & Thiébaux 2007)——竞赛需要更能逼出真概率推理的、更真实的域。
2010  RDDL (Sanner, "RDDL: Language Description")
  │   改用 DBN/CPF 视角:每个状态变量一个条件概率函数,天然支持并发变量、
  │   连续量、以及【观测变量(→POMDP)】。表达力远超 PPDDL。
2011  IPPC 起改用 RDDL 为官方语言
      因为竞赛想纳入"大量变量并发""部分可观测""连续状态"这些更贴近真实
      机器人/资源调度的结构,PPDDL 的效果列表视角不够用了。

这条线索点破了一个常被忽略的事实:语言不是凭空设计的,而是被"想求解什么问题、想公平比较什么方法"反向塑造的。PPDDL 够用时没人换;当竞赛的雄心从"离散、动作稀疏、完全可观测"扩展到"并发、连续、部分可观测",PPDDL 的表达天花板撞到了,RDDL 才应运而生。理解这条演进,你选语言时就不会盲目跟新——而是问"我的问题结构落在 PPDDL 够用的那一档,还是非 RDDL 不可的那一档"(§7.4)。

7.2 PPDDL:给 PDDL 加 probabilistic 效果

Younes 与 Littman 在 2004 年(CMU 技术报告 CMU-CS-04-167)定义了 PPDDL 1.0,作为 IPC-4 概率赛道的输入语言。核心扩展是一个 probabilistic 效果构造:

;; PPDDL:带概率效果的 pick 动作
(:action pick
  :parameters (?o - object)
  :precondition (and (on-table ?o) (hand-empty))
  :effect (probabilistic
            0.9 (and (holding ?o) (not (on-table ?o)) (not (hand-empty)))  ;; 成功
            0.1 (and (on-floor ?o) (not (on-table ?o)))))                  ;; 滑脱落地

语义清晰:执行 pick 后,以 0.9 概率应用第一组效果、0.1 概率应用第二组。概率之和应 \(\le 1\)(不足 1 的部分表示"什么都不发生")。PPDDL 还支持:

  • 嵌套probabilistic 可与 when(条件效果)任意嵌套,表达"在某条件下,效果是概率的"。
  • 奖励:用 (increase (reward) k) 给 MDP 加奖励/代价,于是 PPDDL 问题语义上是一个 MDP(Younes 与 Littman 明确给出了 MDP 语义)。
  • 目标 vs 奖励:既可用经典的目标命题(goal-oriented MDP),也可用奖励最大化(reward-oriented)。

下面把 PPDDL 动作在内存里表示出来,给前面 §6/§7 的算法当输入。

Step 1: 先讲为什么这样表示。

为什么把 PPDDL 概率动作表示成 (precond, [(prob, effect_set), ...])?

因为 PPDDL 的 probabilistic 效果本质是"一组(概率, 效果)对"——执行后按概率
抽一组效果应用。把它表示成"前提 + 带概率的效果列表",正好对应这个语义,
也正好是 §6 determinize / §3 predict 需要的输入形态:
  - determinize(all-outcomes) 遍历效果列表,每个 (p, eff) 拆成一个确定动作;
  - predict(信念更新) 遍历效果列表,按 p 把概率质量分配到各后继世界。
所以这个表示是连接"语言(PPDDL)"和"算法(§3/§6)"的桥。

Step 2: 给出正确写法。

from dataclasses import dataclass
from typing import Callable

@dataclass
class ProbAction:
    """PPDDL 概率动作的内存表示。"""
    name: str
    precond: Callable           # precond(state) -> bool
    outcomes: list              # [(prob, effect_fn), ...]; effect_fn(state)->new_state
    # 不变式:sum(p for p,_ in outcomes) <= 1.0;不足 1 的余量表示"无变化"

    def applicable(self, state):
        return self.precond(state)

    def predict(self, belief):
        """把 PPDDL 概率效果接到 §3.2 的预测更新。"""
        from collections import defaultdict
        nb = defaultdict(float)
        for s, b_s in belief.items():
            if not self.precond(s):
                nb[s] += b_s                     # 前提不满足:动作无效,世界不变
                continue
            residual = 1.0 - sum(p for p, _ in self.outcomes)
            if residual > 1e-9:
                nb[s] += residual * b_s          # "什么都不发生"的余量
            for p, eff in self.outcomes:
                nb[eff(s)] += p * b_s            # 按概率分配到各后继世界
        z = sum(nb.values())
        return {s: v / z for s, v in nb.items()}

Step 3: 给出错误写法并解释为什么错。

# ❌ 错误 1:probabilistic 概率之和 > 1
#   outcomes = [(0.9, succ), (0.3, slip)]   # 0.9+0.3 = 1.2 > 1
# 问题:违反概率公理,predict 后信念不再是合法分布。PPDDL 规定概率和 ≤ 1,
#      等于 1 时无"无变化"余量,小于 1 时余量是"动作没产生任何效果"。

# ❌ 错误 2:忽略"不足 1 的余量"= 什么都不发生
#   只遍历 outcomes 分配概率,sum=0.9 时丢了 0.1 的概率质量
# 问题:0.1 的"动作无效果"分支被吞掉,归一化后会错误地把这 0.1 摊到成功/滑脱上,
#      高估了动作的成功率。必须显式处理 residual = 1 - ∑p。

# ❌ 错误 3:用确定性 PDDL 的 :effect 硬写概率(写成两条 effect)
#   :effect (and (holding ?o) (on-floor ?o))   # 想表达"可能这样可能那样"
# 问题:这表达的是"两个效果同时发生"(又拿着又掉地上,矛盾),不是"二选一概率"。
#      概率的"或"必须用 probabilistic 关键字,不能用 and 堆叠。

Step 4: PPDDL 概率动作 → 三种算法入口的对接。

# === 同一个 PPDDL 概率动作,喂给本章三类算法 ===
# act = ProbAction("pick", precond, [(0.9, succ_eff), (0.1, slip_eff)])
#
# | 算法                    | 怎么用 act                                      |
# |-------------------------|-------------------------------------------------|
# | §3 信念规划/预测更新     | act.predict(belief)  按概率分配到后继世界        |
# | §6 determinize(all-out) | 遍历 act.outcomes, 每个(p,eff)→一个确定动作      |
# | §7 RDDL 对照(下文)       | 同一动作可改写为 RDDL 的 CPF(状态变量转移)       |
# 关键:PPDDL 是"效果列表"视角,下面的 RDDL 是"状态变量转移"视角,二者可互译。

7.3 RDDL:用动态贝叶斯网络描述转移

PPDDL 有个表达瓶颈:当很多状态变量同时、相关地变化(如交通网里每个路口的信号、传染病模型里每个个体的状态)时,用"动作的概率效果列表"描述会非常笨拙——你得为效果的每种组合列一项,组合数爆炸。Sanner 在 2010 年提出的 RDDL(Relational Dynamic Influence Diagram Language) 换了个视角:

不描述"动作有哪些概率效果",而描述"每个状态变量下一时刻的值,服从什么条件概率分布"——即一个动态贝叶斯网络(DBN)。

RDDL 的核心是为每个状态流(state fluent)写一个条件概率函数(CPF),给出它在下一时刻 '(prime)的分布,条件是当前时刻的状态变量和动作:

// RDDL 风格(示意):每个状态变量的下一时刻分布由 CPF 给出
cpfs {
    // 杯子下一时刻是否被持有,取决于当前是否在抓、抓取是否成功
    holding-cup' = if (pick-cup ^ on-table-cup)
                   then Bernoulli(0.9)          // 抓:90% 成功
                   else holding-cup;            // 不抓:保持原值

    on-floor-cup' = if (pick-cup ^ on-table-cup)
                    then Bernoulli(0.1)         // 抓:10% 滑落
                    else on-floor-cup;
};
reward = -1;   // 每步代价

RDDL 的关键能力:

  • factored 转移(DBN):每个变量独立声明转移,天然支持"很多变量并发变化",无需枚举组合——这是它相对 PPDDL 的最大优势。
  • 同时支持 MDP 与 POMDP:RDDL 能声明 observ(观测变量)及其 CPF,于是可以描述部分可观测问题(POMDP),而 PPDDL 1.0 只面向完全可观测的 MDP。这是 IPPC 从 PPDDL 转向 RDDL 的核心动因之一。
  • 连续变量、复杂分布:支持连续状态、Bernoulli/Normal/Poisson 等多种分布,表达力远超 PPDDL。
  • 关系型/参数化:用对象和量词紧凑描述大规模结构化域(如 \(N\) 个路口的交通网)。

本质洞察:从 PPDDL 到 RDDL 的演进,是规划界"表达力 vs 简单性"钟摆的一次摆动。PPDDL 简单、是经典 PDDL 的自然延伸,但只能表达"少数动作各自有少量概率效果"的 MDP;当竞赛想纳入"很多变量并发演化""部分可观测""连续量"这些更真实的结构时,PPDDL 的效果列表视角就捉襟见肘,于是转向 RDDL 的 DBN 视角。这条演进给建模者的启示是:选语言要匹配问题的结构——少数动作、离散、完全可观测、效果稀疏,用 PPDDL(简单够用);大量变量并发、需要部分可观测或连续量,用 RDDL(表达力强但更复杂)。 这与 §6 "不要为不确定性付出超过必要代价"是同一种工程审美:用恰好够用的工具。

7.4 PPDDL vs RDDL:怎么选

维度 PPDDL RDDL
视角 动作的概率效果(PDDL 延伸) 状态变量的转移(DBN/CPF)
可观测性 仅 MDP(完全可观测) MDP POMDP(可声明观测变量)
并发变量变化 笨拙(要枚举效果组合) 自然(每变量独立 CPF)
连续/复杂分布 无(仅离散概率效果) 有(Normal/Poisson/连续状态)
学习曲线 平缓(会 PDDL 就上手) 较陡(要懂 DBN)
IPPC 时代 IPC-4 (2004)、IPPC-2006/2008 IPPC-2011 起
适合 离散、动作稀疏、完全可观测的经典概率规划 大规模结构化、部分可观测、连续的真实域

对机器人 TAMP 的实践建议:单纯描述"抓取/放置有成功率"这类离散、动作中心的不确定,PPDDL 简单够用;要描述"传感器观测(部分可观测)""连续位姿不确定""多物体状态并发演化",RDDL 更合适。但要注意——真实机器人 TAMP 往往不直接用这两种语言求解,而是把它们当建模/benchmark 接口:用 PPDDL/RDDL 描述问题,再交给专门的求解器(或本章 §8 的 POMDP 近似、§9 的 belief-space TAMP)。语言负责"说清问题",求解负责"解决问题",两者分离。

⚠️ 常见陷阱

陷阱一(编程陷阱):PPDDL 的 probabilistic 概率和超过 1 或忽略"无效果"余量。 - 错误描述:效果列表概率之和 > 1,或 < 1 时不处理"什么都不发生"的余量。 - 现象/后果:信念更新后不是合法分布,或高估动作成功率(§7.2 错误 1/2)。 - 根本原因:误解 PPDDL 语义——概率和 \(\le 1\),余量 \(1-\sum p\) 是"动作无效果"。 - 正确做法:建模时确保概率和 \(\le 1\);实现预测更新时显式处理 residual 余量。

陷阱二(概念误区):用 PDDL 的 and 堆叠效果来"表达概率二选一"。 - 错误描述:把"可能 A 可能 B"写成 :effect (and A B)。 - 现象/后果:表达成了"A 和 B 同时发生"(常自相矛盾),而非概率二选一。 - 根本原因:混淆逻辑合取(and,同时)与概率选择(probabilistic,按概率取其一)。 - 正确做法:概率的"或"必须用 probabilistic 关键字,每个分支一个概率。

陷阱三(概念误区):以为 PPDDL 能描述部分可观测(POMDP)。 - 错误描述:试图用 PPDDL 表达"传感器观测有噪声"的 POMDP 问题。 - 现象/后果:PPDDL 1.0 只有完全可观测的 MDP 语义,无观测变量,表达不了。 - 根本原因:PPDDL 面向 MDP,部分可观测需要 RDDL 的 observ 变量。 - 正确做法:需要部分可观测就用 RDDL;或在机器人 TAMP 里直接用 belief-space 表示(§3/§9)。

练习

  1. (⭐⭐,建模) 用 PPDDL 写一个 place 动作:前提 holding ?o,效果 0.85→放稳(on ?o ?surfacehand-empty)、0.15→放倒(toppled ?ohand-empty)。确保概率语义正确。
  2. (⭐⭐⭐,互译) 把练习 1 的 PPDDL place 动作改写成 RDDL 风格的 CPF(为 on'toppled'hand-empty' 各写一个条件概率函数)。对比两种写法,说明在"只有这一个动作"时哪种更简洁、在"100 个物体并发放置"时哪种更简洁。
  3. (⭐⭐⭐,选型) 下列建模需求各该用 PPDDL 还是 RDDL:(a) 仓库 50 个货位的库存每步随机消耗(并发、结构化);(b) 单机械臂抓放,抓取有成功率(离散、动作稀疏);(c) 移动机器人带噪声相机找物体(部分可观测)。逐一说明理由。

8. POMDP 在 TAMP 里的用法与近似 ⭐⭐⭐⭐

§6 的 determinization 绕开了概率,§7 的 PPDDL/RDDL 把概率"说清楚了"但没说"怎么解"。本节回到最一般、最强的武器:把不确定 TAMP 当作一个 POMDP 来正经求解。这是 §3.3"信念空间 MDP"理想的兑现,也是它代价的兑现——纯 POMDP 在长时域操作上不可扩展。本节的主线因此是:POMDP 给了什么、为什么直接用它会爆炸、TAMP 用三类近似与符号结构如何驯服它。这是本章理论上最深的一节(⭐⭐⭐⭐),但只要抓住"信念空间太大、想办法别遍历它"这条线,就不难跟上。

8.1 动机:为什么任务层最终绕不开 POMDP

前面的范式各有"舒适区",但都有它们处理不了的硬骨头:

  • conformant(§4)无观测,处理不了"必须看才能决定"。
  • contingent(§5)有观测分支,但通常不带概率权衡(它要求每条分支都达标,是布尔的"覆盖所有观测",不回答"这个观测有多值得做、要不要为 5% 的可能性付出代价")。
  • determinization(§6)抹掉概率,处理不了不可逆死局与信息价值。

当一个任务同时有"状态不确定 + 效果不确定 + 感知不确定",且需要在"信息收集 vs 任务推进""冒险 vs 求稳"之间做定量权衡时,前面的范式都不够,只有 POMDP 的完整机器能精确表达这种权衡。回顾 U4(30_不确定性规划/50):POMDP 是七元组 \(\langle \mathcal{S}, \mathcal{A}, \mathcal{T}, \mathcal{R}, \Omega, \mathcal{O}, \gamma\rangle\)——状态、动作、转移 \(\mathcal{T}=P(s'\mid s,a)\)、奖励 \(\mathcal{R}\)、观测集 \(\Omega\)、观测模型 \(\mathcal{O}=P(o\mid s',a)\)、折扣 \(\gamma\)。它在信念空间上求一个策略 \(\pi: \Delta(\mathcal{S}) \to \mathcal{A}\),最大化期望折扣回报。这套机器自动地、定量地权衡信息价值——因为"看一眼"会收缩信念、让后续奖励更高,最优策略会在收益大于代价时自发选择它。这是前面所有范式都没有的能力。

对比性思维(不是 X 而是 Y):TAMP 用 POMDP,不是因为 POMDP 比 contingent/FF-Replan"更高级所以更好",而是因为只有它能定量回答"这个信息值不值得去取"。contingent 只能说"我为这个观测准备了分支",FF-Replan 根本看不见观测;只有 POMDP 能算出"为了消除这点不确定性,我愿意多走三步去看一眼,因为看错的代价 × 概率 > 多走三步的代价"。这个信息的定价能力(value of information, VoI) 是 POMDP 不可替代的核心——也是它昂贵的根源(要在信念空间上求值函数)。所以选 POMDP 的判据不是"想不想要最优",而是"问题里有没有需要定价的信息权衡"。没有,用轻量范式;有,才值得为 POMDP 的代价买单。

8.2 为什么纯 POMDP 在 TAMP 上必然爆炸:三重维度灾难

把 §3.3 的"维度灾难"在 TAMP 语境下拆细,会看到 POMDP 用于长时域操作面对的不是一重、而是三重爆炸,三者相乘:

爆炸一:状态空间。 TAMP 的状态是命题组合 + 物体位姿。\(n\) 个布尔命题就有 \(2^n\) 个离散状态;再叠加连续位姿,状态空间是混合的、巨大的。POMDP 求解器要在这之上维护值函数。

爆炸二:信念空间(在状态空间之上再升一维)。 POMDP 的真正搜索空间不是状态空间,而是其上的概率单纯形 \(\Delta(\mathcal{S})\)——一个 \(|\mathcal{S}|-1\) 维的连续空间。状态已经 \(2^n\),信念空间就是 \(2^n - 1\) 维连续体。

爆炸三:时域(history/观测树的分支)。 长时域操作动辄几十步。在线 belief 树搜索每步要展开"动作 × 观测"分支,深度 \(H\) 的树有 \((|\mathcal{A}||\Omega|)^H\) 个节点。操作任务的 \(H\) 一大,这棵树指数爆炸。

\[ \underbrace{|\mathcal{S}| \sim 2^n}_{\text{状态}} \ \times\ \underbrace{\Delta(\mathcal{S})\ \text{是}\ (2^n{-}1)\text{维连续}}_{\text{信念}} \ \times\ \underbrace{(|\mathcal{A}||\Omega|)^H}_{\text{时域树}} \]

本质洞察:纯 POMDP 求解器(SARSOP、POMCP、DESPOT)在 U4 里能解 Tiger、RockSample、交互驾驶,是因为那些问题状态少、时域短或可折扣截断。TAMP 的长时域操作三重爆炸全占,纯 POMDP 必然跑不动。但这里有一个关键转机——TAMP 的状态不是无结构的,它是因子化的(命题 + 物体),动作有结构化的前提-效果。这个结构是 TAMP 相对一般 POMDP 的额外信息,正是驯服三重爆炸的钥匙:用符号规划压缩状态/时域(动作的因子化前提-效果天然剪枝)、用确定化/最大似然压缩信念、用宏动作/技能抽象压缩时域。本节后面的三类近似,本质都是"用 TAMP 的结构换 POMDP 的可扩展性"——这是 §3.4 立的分工"本章用利用符号结构的专用规划器巧解"的具体兑现。

8.3 近似一:QMDP 与最大似然确定化(最便宜)

最便宜的近似是假装不确定性下一步就消失

QMDP:先把底层 MDP(假设状态完全可观测)解出来,得到状态值函数 \(Q_{\text{MDP}}(s,a)\);然后在信念 \(b\) 下取期望选动作:

\[ \pi_{\text{QMDP}}(b) = \arg\max_a \sum_{s} b(s)\, Q_{\text{MDP}}(s, a) \]

它等价于假设"这一步动作后,所有不确定性立刻被揭示"(因为它用的是完全可观测的 \(Q_{\text{MDP}}\))。后果:QMDP 永远不会主动选信息收集动作——因为它假设信息反正下一步白送,何必花代价去取。这恰好是 §2.3 崩溃二、§6.4 盲区二的 POMDP 版本。

最大似然确定化(most-likely-state, MLS):更粗暴——直接取信念里概率最大的状态 \(s^* = \arg\max_s b(s)\),对它做确定性/MDP 规划。这就是 §6 FF-Replan 的 most-likely 确定化在 POMDP 框架里的名字,缺陷一样:丢掉分布的尾巴,在双峰信念上制造幻影世界(§3 陷阱一)。

近似 假设 优点 致命缺陷
QMDP 不确定性下一步消失 快,只需解底层 MDP 不主动收集信息
MLS/最大似然 世界就是最可能那个 最快 双峰信念上荒谬、忽视风险尾巴

这两个近似的共同价值:当信息会自然到来(不需主动去取)、且信念较集中(单峰低方差)时,它们又快又够好。SS-Replan(§9)的"确定性 cost-sensitive 规划"本质就是这一族——它在大多数良性步骤上用最大似然式的确定化求快,只在真需要时才显式处理信念。

8.4 近似二:在线 belief 树搜索(POMCP / DESPOT 思想)

第二类近似不预先求整个值函数,而是从当前信念出发,只向前搜有限深度的 belief 树,选眼下最好的动作,执行一步,再从新信念重搜。这正是 U4 讲的 POMCP(蒙特卡洛树搜索 + 粒子信念)和 DESPOT(确定性稀疏化 belief 树)的思想。

核心技巧(都为对抗 §8.2 爆炸三):

  • 粒子表示信念:不显式存 \(2^n\) 维分布,而用一组采样的世界(粒子)近似——与运动层粒子滤波一脉相承(§3.2 表示 C)。
  • 蒙特卡洛展开:用 rollout(默认策略模拟到底)估计叶节点价值,避免精确备份。
  • 观测稀疏化(DESPOT):只采样 \(K\) 个观测场景而非所有观测,把 \((|\mathcal{A}||\Omega|)^H\) 压成 \((|\mathcal{A}|K)^H\)
  • UCT 引导:用上置信界把搜索预算花在有希望的动作上(POMCP)。

在 TAMP 里,纯 POMCP/DESPOT 仍受限于操作任务的长时域和大动作空间。关键的 TAMP 改造是缩小动作空间:不让搜索在所有原子动作上盲目展开,而是用符号规划器先生成少数几个"有意义的候选动作/子目标",belief 树只在这些候选上分支。这就把"在线 belief 树"和"符号任务规划"缝在了一起——符号层提议候选,belief 树在候选上定量权衡。

多视角类比:在线 belief 树搜索像下棋时只往前精算几步、而非穷举整盘。棋手(规划器)从当前局面(信念)出发,只深入计算几个有希望的着法(动作)及对手的几种主要回应(观测),选眼下最好的一步走,走完看对手实际怎么应再重算。它和"预先解出完整值函数"(离线 POMDP,像背完整个开局库到残局库)相比:相似处是都为选好动作;不同处是在线搜索只算当前局面需要的(省,但每步都要现算)、且深度有限(看不了太远,长时域要靠宏动作 §8.5 补)。这个"只精算当前需要的几步"正是它对抗时域爆炸的方式——但也正是它在超长时域上力不从心、必须叠加技能抽象的原因。

8.5 近似三:宏动作与技能抽象(压缩长时域)

前两类近似压的是信念和观测分支,但时域本身(几十上百步)仍是 belief 树的天敌。第三类近似从根上砍时域:用宏动作(macro-action)/ 技能(skill / option)把一长串原子动作打包成一个"高层动作",让 POMDP 在高层动作上规划,时域 \(H\) 直接缩小一个数量级。

  • option / 半 MDP(SMDP):一个技能是一个带终止条件的子策略(如"导航到桌前"内部是几十步运动,对外是一个动作)。POMDP 在 option 层规划,每个 option 跨越多个原子时间步。
  • HTN + POMDP:用 HTN(T1 提过的分层任务网络)的配方把任务分解成子任务,每层规模可控,不确定性在合适的层处理。
  • belief-space option / 参数化技能:技能本身可以是"信念条件触发"的——如"看一眼直到置信度 > 0.9"是一个会收缩信念的宏动作。§9 的 SS-Replan、"Seeing is Believing"(Zhao 等,2025,arXiv:2504.03245,用 VLM 做不确定性估计 + 参数化技能库 + belief-space 规划)正是这条路线的代表:用参数化技能库做高层动作、在符号信念上规划、把信息收集(看、移开遮挡)作为一等技能。

这条近似与 TAMP 的契合最深:TAMP 本来就有"任务层(离散、少数高层动作)/ 运动层(连续、长串底层动作)"的天然分层,宏动作抽象不过是把这个分层用于压缩 POMDP 的时域。

本质洞察:三类近似可以叠加,且各打一个爆炸维度——最大似然/QMDP 压信念维(爆炸二),belief 树 + 观测稀疏化压观测分支(爆炸三的宽度),宏动作/技能抽象压时域深度(爆炸三的深度)。真实的 belief-space TAMP 系统(SS-Replan、TAMPURA、Seeing-is-Believing)几乎都是这三者的某种组合:用技能库把时域压短、用符号规划提议候选动作、用确定化/采样处理信念、只在关键决策点(信息价值高处)做较精细的信念权衡。没有任何单一近似能独力驯服三重爆炸;可扩展的不确定 TAMP 永远是"用 TAMP 结构 + 多种近似的组合拳"。 这也是为什么本章反复强调"分层"和"利用符号结构"——它们不是美学偏好,而是对抗维度灾难的唯一可行路径。

8.6 TAMPURA:把"抽象信念 + 风险感知"做进 TAMP

值得专门点出一个把上述思想系统化的近期工作:TAMPURA(Curtis, Matheos, Gothoskar, Mansinghka, Tenenbaum, Lozano-Pérez & Kaelbling, "Partially Observable Task and Motion Planning with Uncertainty and Risk Awareness", RSS 2024, arXiv:2403.10454)。它的核心做法:

  • 抽象信念空间:把连续的概率信念划分成离散的抽象信念状态,每个抽象状态配一组带"可能效果描述"的算子(算子内部封装底层控制器)。于是 POMDP 的连续信念被压成可符号搜索的离散抽象信念——直接对抗 §8.2 爆炸二。
  • 风险感知:显式建模并规避"不良且不可逆"的结果(呼应 §6.4 盲区一)——这正是 determinization 看不见、纯 QMDP 也忽视的死局风险。
  • 双层不确定性推理:在抽象任务层(符号)和连续控制器层(几何)两层分别推理不确定性,通过算子的"可能效果"接口握手——这就是 §2.4 分层原则、§10 接口的一个完整落地。
  • 实验结论:在需要信息收集、风险敏感、对不确定性鲁棒的任务上,这种"学到的动作效果概率 + 随机 belief-space 规划"显著优于强化学习与 MCTS 基线。

TAMPURA 几乎是本章前八节思想的集大成:信念空间(§3)+ 抽象压缩(§8.5)+ 风险/死局规避(§6.4)+ 任务-运动分层(§2.4)。把它作为"信念空间 TAMP 现代范本"记住。

8.7 用代码看 QMDP 与在线 belief 树骨架

把最便宜的 QMDP 和在线 belief 树的核心写出来,对照看"信息收集为什么 QMDP 选不出来、belief 树能"。

Step 1: 先讲为什么这样写。

为什么 QMDP 用"完全可观测 Q 值在信念下取期望",就必然选不出信息收集动作?

因为 Q_MDP(s,a) 是在【假设状态可观测】下算的——它默认"反正马上就知道
在哪个 s 了"。于是一个纯信息收集动作(如 look,不改变世界、只收缩信念)在
每个 s 下的 Q_MDP 都不会因为"它能减少不确定"而加分(MDP 里没有不确定可减)。
取期望后 look 的价值 ≈ 它的即时代价(负),永远竞争不过推进任务的动作。
要让"看"有价值,必须在【信念】上评估未来(belief 树/POMDP 值函数),
让"看之后信念收缩→后续决策更优"这条收益被算进来。

Step 2: 给出正确写法(QMDP + 在线 belief 树骨架)。

def qmdp_action(belief, Q_mdp, actions):
    """QMDP:用完全可观测的 Q 值在信念下取期望选动作。
    belief: {s: p}; Q_mdp: {(s,a): value} 预先解底层 MDP 得到。"""
    def q_belief(a):
        return sum(p * Q_mdp[(s, a)] for s, p in belief.items())
    return max(actions, key=q_belief)   # 注意:信息收集动作在此几乎不会胜出

def belief_tree_value(belief, depth, actions, tau, obs_model, reward, gamma=0.95):
    """在线 belief 树:从 belief 前看 depth 步,返回最优(动作, 价值)。
    tau(b,a,o)->b'  信念转移(§3.2); obs_model(b,a)->{o: P(o|b,a)};
    reward(b,a)->float  期望即时奖励 ρ(b,a)=Σ b(s)R(s,a)。"""
    if depth == 0:
        return (None, 0.0)
    best_a, best_v = None, float("-inf")
    for a in actions:
        # 即时奖励 + 对所有可能观测求期望的未来价值(这一步让"看"的收益显形)
        v = reward(belief, a)
        for o, p_o in obs_model(belief, a).items():
            if p_o <= 0:
                continue
            b_next = tau(belief, a, o)                       # 观测 o 后的新信念
            _, v_future = belief_tree_value(b_next, depth - 1,
                                            actions, tau, obs_model, reward, gamma)
            v += gamma * p_o * v_future                      # 按观测概率加权
        if v > best_v:
            best_a, best_v = a, v
    return best_a, best_v   # 信息收集动作因"收缩信念→未来价值高"可能在此胜出

Step 3: 给出错误写法并解释为什么错。

# ❌ 错误 1:在 belief 树里对观测取 max 而非按概率取期望
#   v += gamma * max(v_future over o)      # 只看最好观测
# 问题:观测【不可控】(你不能选看到什么),必须对所有可能观测【按概率加权求期望】。
#      取 max = 假设你能选到最有利的观测 = 过度乐观(类似 §6.2 all-outcomes 的病)。
#      AND/OR 语义里观测是 AND 节点(要对所有分支负责),不是 OR(挑一个)。

# ❌ 错误 2:用 QMDP 期望在需要信息收集的任务上规划
#   a = qmdp_action(belief, Q_mdp, actions)   # 期望它会选 look
# 问题:§8.3。QMDP 假设不确定性下一步消失,结构上就不会选纯信息收集动作。
#      "先看才能决定"的任务上 QMDP 会直奔猜测目标、忽略 look,和 §2.3 崩溃二同病。
#      需要信息价值 → 必须 belief 树/POMDP,不能 QMDP。

# ❌ 错误 3:belief 树不限深度、不剪枝、动作空间不缩减
#   belief_tree_value(b, depth=50, all_atomic_actions, ...)  # 长时域+大动作空间
# 问题:§8.2 三重爆炸。深度 50 × 全原子动作 × 全观测 = (|A||Ω|)^50 节点,跑不动。
#      TAMP 必须:用宏动作/技能缩动作空间(§8.5)、限深度+rollout 估叶(§8.4)、
#      观测稀疏化(DESPOT)。直接深搜原子动作 = 把 POMDP 的爆炸原样扛在身上。

Step 4: 三类近似对比选型。

# === POMDP-in-TAMP 三类近似,按"问题特性"选 ===
# | 近似            | 压哪个爆炸维   | 何时够用                  | 何时不够              |
# |-----------------|----------------|---------------------------|-----------------------|
# | QMDP/最大似然   | 信念维(爆炸二) | 信息自然到来、信念单峰    | 需主动收集信息→失效   |
# | 在线 belief 树  | 观测分支(三宽) | 需信息价值、时域中等      | 超长时域→深度不够     |
# | 宏动作/技能抽象 | 时域深度(三深) | 长时域、有自然技能分层    | 单独用仍需配合上两者  |
# 真实系统(SS-Replan/TAMPURA/Seeing-is-Believing)= 三者组合 + 符号结构剪枝。
# 选型铁律:先问"有没有需要定价的信息权衡"(§8.1)——没有,退 §6 determinize;
# 有,再按"时域多长/信念多散"在上面三类近似里组合。

8.8 一个能手算的对照:Tiger 上 QMDP 为何不 listen、belief 树为何 listen

抽象讲了三遍"QMDP 不选信息收集、belief 树会选",这里用最小的 Tiger 问题把数字算出来,让这个差异从直觉变成可验证的算术。这也是 §8 练习 1-2 的解题脚手架。

问题设定(标准 Tiger)。 两扇门,老虎藏其一(状态 \(s\in\{\texttt{TL},\texttt{TR}\}\),老虎在左/右)。动作:open-leftopen-rightlisten。开到有虎的门:奖励 \(-100\)(被吃);开到无虎的门:\(+10\)listen:代价 \(-1\),返回一个有噪声的观测(左/右各以 0.85 准确度听到虎吼)。初始信念 \(b_0=(0.5,0.5)\)

先解底层 MDP(完全可观测)得 \(Q_{\text{MDP}}\) 若状态可观测(知道虎在哪),最优动作显然是"开无虎的门"得 \(+10\)。于是:

\[ Q_{\text{MDP}}(\texttt{TL}, \texttt{open-right}) = +10,\quad Q_{\text{MDP}}(\texttt{TL}, \texttt{open-left}) = -100,\quad Q_{\text{MDP}}(\texttt{TL}, \texttt{listen}) = -1 + 10 = +9 \]

listen 在已知状态下纯属多花 \(-1\) 再开对门,故 \(+9\);对称地 \(\texttt{TR}\) 同理。)

QMDP 在 \(b_0=(0.5,0.5)\) 选什么? 按 §8.3 公式 \(\sum_s b(s)Q_{\text{MDP}}(s,a)\)

\[ \begin{aligned} Q_{\text{QMDP}}(b_0,\texttt{open-left}) &= 0.5\cdot(-100) + 0.5\cdot(+10) = -45\\ Q_{\text{QMDP}}(b_0,\texttt{open-right}) &= 0.5\cdot(+10) + 0.5\cdot(-100) = -45\\ Q_{\text{QMDP}}(b_0,\texttt{listen}) &= 0.5\cdot(+9) + 0.5\cdot(+9) = +9 \end{aligned} \]

咦——这一步 QMDP 确实选了 listen\(+9 > -45\))!但关键在下一步:QMDP 用的 \(Q_{\text{MDP}}\) 假设"listen 之后状态就完全已知了"(因为底层 MDP 是完全可观测的)。所以在 QMDP 眼里,listen 的价值 \(+9\) 来自"听完就确定知道虎在哪、稳开对门"——它高估了一次 listen 的功效(真实一次 listen 只把信念推到 \(0.85\),远没到确定)。更要命的是:听完一次后信念变成 \((0.85,0.15)\),QMDP 此时算 \(Q_{\text{QMDP}}=0.85\cdot10+0.15\cdot(-100)=-6.5\)(开门)对比 \(0.85\cdot9+0.15\cdot9=+9\)(listen),又选 listen……但它每次都以为"这次 listen 完就确定了",于是要么过度自信开门、要么因为高估 listen 而行为不稳定。QMDP 的病根:它用"不确定性下一步消失"的 \(Q_{\text{MDP}}\) 评估,无法正确累积多次观测的价值,也无法表达"还不够确定、需要再听一次"的精细权衡。

belief 树(§8.7)在 \(b_0\) 选什么? belief 树假设不确定性下一步消失——它显式展开"listen → 观测(左吼/右吼)→ 信念更新 → 再决策"。从 \(b_0=(0.5,0.5)\) 出发:

  • open-left/open-right:即时期望 \(-45\),无后续可挽救。
  • listen:即时 \(-1\);之后以约 0.5 概率听到"左吼"(信念更新到 \((0.85,0.15)\))、0.5 概率"右吼"(更新到 \((0.15,0.85)\))。在 \((0.85,0.15)\) 上,再展开一层会发现"再 listen 一次能把信念推到约 \(0.97\),然后稳开对门得接近 \(+10\)"。把这些按观测概率加权的未来价值回填,listen 的 belief-树价值会显著高于 \(-45\),于是 belief 树选 listen——而且因为它能往前看多层,它会自然地决定"听到信念足够确定(如 >0.95)才开门",这正是 Tiger 的最优策略形态。

本质洞察:QMDP 和 belief 树在 Tiger 第一步碰巧都选了 listen,但原因截然不同、后果也截然不同——QMDP 选它是因为高估了"一次 listen 就揭示真相"(错误的理由,导致后续不稳定、信念稍偏就贸然开门),belief 树选它是因为正确算出"多听几次把信念推到足够确定再开门"的期望最优(正确的理由,导致稳健的"听够再开"策略)。这个对照点破了 §8.3 的要害:QMDP 的错不一定表现为"第一步选错动作",而常表现为"用错误的理由选对/选错、且无法正确权衡‘还要不要再收集一次信息’"。 当传感器噪声更大(如准确度降到 0.6,需要听很多次才够确定)时,QMDP 的"一步揭示"假设错得更离谱,与最优策略的差距急剧拉大——这就是 §8 练习 2 让你调传感器精度去观察的现象。信息的价值是要在多步信念演化里累积评估的,这正是 belief 树有、QMDP 没有的能力。

⚠️ 常见陷阱

陷阱一(概念误区):以为 QMDP/最大似然只是"精度差一点"的 POMDP 近似。 - 错误描述:把 QMDP 当成"略不精确但方向对"的 POMDP。 - 现象/后果:在需信息收集的任务上,QMDP 不是"差一点"而是结构性地错——永远不选 look。 - 根本原因:QMDP 假设不确定性下一步消失,从原理上排除了信息收集动作的价值(§8.3)。 - 正确做法:判断任务是否需要主动感知。需要 → 必须 belief 树/完整 POMDP;不需要(信息自然到来)→ QMDP 才是合理近似。

陷阱二(思维陷阱):在 belief 树里把"动作"和"观测"都当成自己能选的。 - 错误描述:搜索时对动作取 max、对观测也取 max。 - 现象/后果:得到一个"指望看到最有利观测"的过度乐观策略,真机上观测不配合就崩。 - 根本原因:动作可控(取 max 合理),观测不可控(必须按概率取期望)——这是 AND/OR / belief 树的本质(§5.2、§8.7 错误 1)。 - 正确做法:动作层 max(选最优动作),观测层期望(对所有观测按概率加权)。

陷阱三(编程陷阱):直接对原子动作、长时域跑 belief 树,不做任何 TAMP 压缩。 - 错误描述:把操作任务的几十步原子动作原样喂给 POMDP 求解器。 - 现象/后果:三重爆炸(§8.2),求解器内存/时间爆炸,跑不出结果。 - 根本原因:没利用 TAMP 的符号结构与分层去压缩状态/动作/时域。 - 正确做法:用技能/宏动作缩时域、用符号规划提议候选动作缩动作空间、用粒子/稀疏化处理信念——三类近似组合(§8.5 本质洞察)。

练习

  1. (⭐⭐⭐,手算+辨析) Tiger 问题(两扇门,老虎在其一,可 listen 收缩信念或 open 一扇门)。说明为什么 QMDP 在初始均匀信念 \(b=(0.5,0.5)\) 下不会选 listen(用 §8.3 公式论证 listen 的 QMDP 价值),而完整 POMDP/belief 树会先 listen 几次再开门。这与 §2.3 崩溃二是什么关系?
  2. (⭐⭐⭐⭐,实现) 用 §8.7 的 belief_tree_value 实现一个最小 Tiger,验证:depth=1 时退化得像 QMDP(看不出 listen 价值),depth\(\ge 2\) 时 listen 因"收缩信念→后续开对门概率大增"而胜出。改变 listen 的传感器精度,观察 listen 被选的阈值如何移动(联系 VoI)。
  3. (⭐⭐⭐⭐,设计) 给一个 20 步的移动操作任务(找物体 + 抓 + 放,物体在 3 个房间之一),说明你会如何用 §8.5 的三类近似组合把它变得可解:哪些原子动作打包成技能?符号层提议哪些候选?信息收集(看房间)在哪一层、用什么近似定价?画出整体架构(提示:对照 §8.6 TAMPURA 与 §9 SS-Replan)。

9. 感知不确定下的 pick-place:信念空间 TAMP 全流程 ⭐⭐⭐

前八节给了零件:信念(§3)、范式(§4-§6)、语言(§7)、求解机器(§8)。本节把它们组装成一个完整、可落地的系统——回到 §2.1 那个在真机上崩掉的 pick-place,这次把它正确地做出来。这是本章的实战主干(⭐⭐⭐),也是 T1 Mini-TAMP 累积项目的"不确定性"模块。我们以 SS-Replan(Garrett, Paxton, Lozano-Pérez, Kaelbling & Fox, "Online Replanning in Belief Space for Partially Observable Task and Motion Problems", ICRA 2020, arXiv:1911.04577)为工程范本,因为它正好把"PDDLStream 的 Stream(T3)+ 信念 + 重规划"缝成一个跑在真机上的系统。

9.1 问题设定:把 §2.1 的四个不确定性正面接住

回到收拾房间的机器人,把杯子放到架子上。§2.1 列了四个在真机上冒出的不确定性,这次逐一安排好它落在哪一层、用什么接:

§2.1 的不确定性 性质 落在哪一层 本节怎么接
它真的是杯子吗(置信度 0.7) 离散命题真假 任务层 信念 \(b(\texttt{IsCup})\) + look 收缩(§9.2)
杯子精确在哪(±3cm) 连续位姿噪声 运动层 几何 belief 传播 / 抓取成功概率汇总(§9.4 接口)
架子深处有没有东西挡着 离散命题真假(未观测 \(\neq\) 空) 任务层 "未见区域可能非空"建模 + 主动 look(§9.2)
抓取会不会滑脱 效果不确定(可重试) 任务层(汇总概率)+ 执行 pick 成功概率 + 偏离重规划(§9.3)

这张表本身就是 §2.4 分工原则的实操:离散命题真假 → 任务层信念;连续噪声 → 运动层;可重试效果 → 重规划。 每一类用它该用的工具,不混层。

9.2 把"看一眼"做成一等规划动作

确定性 TAMP 最深的盲区是看不见"看"的价值(§2.3 崩溃二)。本节系统的核心改造,就是把传感动作 look 升格为带前提-效果的一等符号算子,让规划器能像调度 pick/move 一样调度它。

look 的符号刻画(PDDL 风格 + 信念语义):

(:sensor-action look
  :parameters (?region ?obj)
  :precondition (and (Visible ?region ?conf)        ; 从当前构型能看到该区域
                     (UncertainAbout ?obj))         ; 对该物体还不确定(否则白看)
  :observation (Detected ?obj ?region)              ; 观测结果(随机:见/不见)
  :belief-effect 校正更新 b'(s)=η·P(o|s)·b(s))      ; §3.2 校正:收缩信念
)

关键设计点:

  • look 不改变世界,只改变信念(纯信息收集)。它的"效果"不是某个命题翻真,而是对信念做一次 §3.2 的校正更新(收缩)。
  • 前提 UncertainAbout 防止无信息观测(§5 陷阱二):只在"还不确定、且看了能收缩"时才允许 look,避免策略树被白看灌爆。
  • 观测是随机的look 可能"见"可能"不见",似然 \(P(o\mid s)<1\)(传感器会误检)。这把 §3 陷阱二(别给真实观测 0 概率)落到实处——似然模型永远留 \(\epsilon\) 余量。

本质洞察:把 look 做成一等动作,是本章所有理论在工程上的"临门一脚"。一旦 look 有了前提(什么时候能看、值得看)和效果(看了信念怎么变),规划器就能自动在"先看再抓"和"直接抓"之间权衡——它会在"不看就抓的失败代价 × 概率 > 看一眼的代价"时自发插入 look(这正是 §8.1 的信息定价 VoI)。对比确定性 TAMP:那里 look 没有效果(不改变任何命题)、纯属浪费,规划器永不调用它。 一字之差(效果是"改变信念"而非"改变世界"),把"主动感知"从不可能变成了规划器的自发行为。这就是为什么"信念"必须是一等对象——只有信念在模型里,"收缩信念"才能成为一个有价值的、可被规划的效果。

9.3 把 PDDLStream 的 Stream 扩展到采样信念与观察位姿

T3 的 PDDLStream 用 Stream(采样器)把几何能力喂给符号搜索(§0 Q4)。本节把这套机制扩展到信念:新增两类 Stream,让规划器能按需采样"怎么看"和"看了的信念后果"。

新 Stream 一:sample-observation-pose(采样观察位姿)。 输入一个待观察区域,输出一个能看清它的机器人构型/相机位姿,并认证 Visible(region, conf)。这和 T3 的 sample-ik(采样抓取构型)同构——只不过认证的不是"可达抓取"而是"可观察"。

新 Stream 二:predict-observation(预测观测的信念后果)。 输入"当前信念 + 一个 look 动作",输出"各可能观测结果及其概率,以及每个结果对应的更新后信念",认证一组 BeliefAfter(b, look, o, b')。这把 §3.2 的校正更新封装成 Stream,让符号搜索能"展开观测分支"而不必自己算贝叶斯。

T3 原 Stream(几何)              本节新增 Stream(信念)
─────────────────────         ──────────────────────────
sample-grasp  → Grasp          sample-observation-pose → Visible
sample-ik     → Kin            predict-observation     → BeliefAfter
plan-motion   → Motion         (校正更新封装为可采样的认证事实)

多视角类比:把 Stream 扩展到信念,像给一个只会算"手能不能够到"的助手,新教它算"眼睛能不能看清"和"看了之后我会知道什么"。原来的 Stream(T3)回答几何可行性问题(够得到吗、撞不撞、走得通吗);新 Stream 回答信息可行性问题(看得清吗、看了信念变多少)。相似处是机制完全一样——都是"采样器产出值 + 认证符号事实喂回搜索"(§0 Q4);不同处是认证的事实从"几何约束"变成了"可观察性 / 信念转移"。这个统一是 PDDLStream 架构优雅的体现:同一个"采样器即接口"的抽象,既能装几何能力,也能装信息/信念能力——不确定性没有破坏 T3 的架构,而是顺着它的接口长了出来。

9.4 与运动层的接口:连续 belief 怎么汇总成符号概率

§9.1 表里"杯子精确在哪(±3cm)"被分给了运动层。但任务层的 pick 动作需要一个"成功概率"才能做信念更新——这个概率从哪来?从运动层的连续 belief 传播汇总而来。 这是 §2.4 "两层通过汇总量握手"的具体机制,也是 §10 接口的预演:

  • 运动层维护物体位姿的连续信念(高斯/粒子,来自感知滤波,U 线 U4)。
  • 给定一个候选抓取,运动层做一次 belief 传播 / 机会约束评估(U 线 U3):在 ±3cm 的位姿不确定下,这个抓取夹爪能套住物体的概率是多少?得到一个标量,如 \(p_{\text{grasp}} = 0.9\)
  • 这个 \(0.9\) 作为 pick 动作的成功概率回传给任务层,任务层据此做 §3.2 的预测更新(0.9 在手、0.1 还在原处)。
\[ \underbrace{\text{连续位姿信念 } \mathcal{N}(\hat p, \Sigma)}_{\text{运动层(U4)}} \xrightarrow[\text{机会约束(U3)}]{\text{belief 传播}} \underbrace{p_{\text{grasp}}=P(\text{抓中})}_{\text{标量}} \xrightarrow{\text{回传}} \underbrace{\text{符号 pick 的成功概率}}_{\text{任务层(本章)}} \]

反向,任务层决定"去看 A 区"后,"怎么走到能看清 A 区的位姿、且路上 belief 不发散"是运动层(sample-observation-pose 给出目标位姿,运动层规划安全轨迹)。两层就这样一来一回:任务层出离散决策(看哪、抓哪),运动层出连续评估(成功概率、可达性、安全轨迹),用标量汇总量握手。

9.5 完整控制循环与仿真到真机

把 §9.2-§9.4 拼成一个完整循环(SS-Replan 式:信念空间确定性 cost-sensitive 规划 + 执行 + 重估信念 + 重规划):

感知不确定 pick-place 主循环(SS-Replan 式):
1. 初始化信念 b(物体类别/位置的离散信念 + 运动层连续位姿信念)。
2. loop:
3.    若 b 下目标必然达成: 成功。
4.    在【信念空间】做确定性 cost-sensitive 规划:
        - 候选动作含物理动作(pick/move/place)与传感动作(look);
        - look 的"收益"来自它收缩信念(§9.2),代价来自移动/时间;
        - 用最大似然式确定化求快(§8.3),但 look 的信息价值被显式计入。
5.    取计划第一个动作 a 执行(pick/look/move/place)。
6.    观测真实结果 o(感知模块给的检测/位姿估计)。
7.    用 o 更新信念 b:
        - 物理动作→预测更新(§3.2);传感动作→校正更新(§3.2);
        - 连续位姿→运动层滤波(U4),汇总出新的成功概率(§9.4)。
8.    若实际结果偏离计划预期(抓滑了、看到没料到的东西): 回 4 重规划(§6)。
9.    否则: 沿计划继续。

这个循环把全章串起来:信念表示(§3)→ 在信念上规划且 look 是一等动作(§9.2)→ Stream 采样观察位姿与信念后果(§9.3)→ 运动层汇总成功概率(§9.4)→ 偏离重规划(§6)→ 最大似然/信息价值权衡(§8)。

仿真到真机的关键差异(呼应 §5 陷阱三):

  • 似然模型校准:仿真里 look\(P(o\mid s)\) 是你设的;真机要用真实感知模块的混淆矩阵/检测 PR 曲线标定,否则信念更新失真。
  • 预案外观测兜底:真机传感器会给出建模时没列的观测(新物体、强遮挡)。执行器必须有兜底——触发重规划或退到安全分支,绝不能假设"真实观测一定在预案里"。
  • 连续-离散接口的数值健壮\(p_{\text{grasp}}\) 从运动层来,若运动层 belief 退化(粒子枯竭、协方差爆炸),回传的概率不可信——要做合理性检查,必要时退到"先 look 重新定位"。

9.6 累积项目:给 Mini-TAMP 加"不确定性"模块

把本章成果接到 T1 起就在搭的 Mini-TAMP 累积项目上。前几章项目假设世界完全可知;本章新增一个 belief_tamp/ 模块,把它升级成感知不确定版。

Step 1: 先讲为什么这样组织。

为什么把"不确定性"做成 Mini-TAMP 的一个【可插拔模块】,而非重写整个项目?

因为确定性 TAMP 的内核(符号搜索 T1、Stream 采样 T3)可以【复用】——本章不是
推翻它们,而是在外面包一层"信念 + 重规划"(§9.5 循环)。具体:
 - 复用 T3 的 Stream 框架,只【新增】两类信念 Stream(§9.3);
 - 复用 T1 的符号规划器,只把状态从"世界"换成"最大似然世界/抽象信念"(§8.3);
 - 在最外层套 §9.5 的"执行-观测-更新信念-重规划"循环。
这正是 §8.5/§8.6"用确定性 TAMP 内核 + 信念外壳"的工程范式——可插拔、可回退。

Step 2: 给出模块骨架(正确写法)。

# belief_tamp/ —— Mini-TAMP 的不确定性模块(接 T1/T3 内核)
from mini_tamp.streams import sample_grasp, sample_ik, plan_motion  # 复用 T3
from mini_tamp.symbolic import ff_plan                              # 复用 T1

class BeliefTAMP:
    def __init__(self, det_domain, belief0, perception, motion_layer):
        self.det_domain   = det_domain        # 确定化后的符号域(§8.3 最大似然)
        self.belief       = belief0           # 离散信念 + 运动层连续信念句柄
        self.perception   = perception        # 真实/仿真感知模块: ()->observation
        self.motion       = motion_layer      # 运动层: 抓取成功概率 / 安全轨迹(§9.4)

    def new_belief_streams(self):
        """§9.3 新增的两类信念 Stream,与 T3 的几何 Stream 并列注册。"""
        return [
            ("sample-observation-pose", self._sample_obs_pose),  # →Visible
            ("predict-observation",     self._predict_obs),      # →BeliefAfter
        ]

    def step(self, goal):
        """§9.5 主循环的一步:规划→执行首动作→观测→更新信念→判定是否重规划。"""
        s_ml = self.belief.most_likely_world()          # 最大似然确定化(§8.3)
        # 成功概率由运动层汇总后写进确定化域(§9.4 接口)
        self.det_domain = self.motion.annotate_success_probs(self.det_domain, self.belief)
        plan = ff_plan(self.det_domain, s_ml, goal)     # 复用 T1 符号规划器
        if not plan:
            return "look_to_localize"                    # 退到主动感知重定位(兜底)
        a = plan[0]
        o = self.execute_and_observe(a)                  # 执行首动作并取真实观测
        deviated = self.belief.update(a, o, self.motion) # 物理→预测/传感→校正(§3.2)
        return "replan" if deviated else "continue"      # 偏离→重规划(§6)

Step 3: 给出错误写法并解释为什么错。

# ❌ 错误 1:每步重新从零规划整棵 contingent 策略树
#   tree = plan_contingent(self.belief, ...)   # 每步全展开所有观测分支
# 问题:§8.2 时域爆炸 + 重复劳动。真实系统用"确定化求一条线 + 偏离重规划"(§9.5),
#      不预先展开所有分支。只在【当前】信念下规划当前要走的一步,错了才重算。
#      预先建整树 = 把 contingent 的指数代价每步付一遍。

# ❌ 错误 2:look 的信息价值不计入规划,只按"代价最低"选动作
#   plan = ff_plan(det_domain_without_look_value, ...)  # look 仅有代价无收益
# 问题:§9.2/§8.3。若不把"look 收缩信念→后续成功率提升"计入,确定化规划会
#      把 look 当纯负代价动作永不选 → 退回 §2.3 崩溃二。必须让 look 的收益(VoI)
#      进入 cost-sensitive 目标,它才会在该看时被选。

# ❌ 错误 3:把运动层 ±3cm 位姿不确定离散成命题塞进符号域
#   det_domain += [f"PoseCell_{i}_{j}" for i,j in grid]   # 厘米级离散化
# 问题:§2.4 分层铁律 + §2 陷阱二。连续噪声该由运动层滤波数值处理,汇总成
#      一个 p_grasp 标量回传(§9.4),不该爆成成千上万命题塞进符号搜索。
#      违反 = 符号分支因子爆炸,规划器瘫痪。

Step 4: 确定性 Mini-TAMP vs 信念 Mini-TAMP,对比。

# === Mini-TAMP 两个版本的差异一览 ===
# | 维度        | 确定性版(T1-T3)     | 信念版(本章 belief_tamp)        |
# |-------------|---------------------|---------------------------------|
# | 状态        | 已知世界 s          | 信念 b(离散)+ 运动层连续信念    |
# | 动作集      | pick/move/place     | + look(传感,改变信念)           |
# | Stream      | grasp/ik/motion     | + obs-pose/predict-obs(§9.3)    |
# | 执行后      | 假设按计划走        | 观测→更新信念→偏离重规划(§9.5)  |
# | 失败处理    | 无/报错             | 重规划 + look 重定位兜底        |
# | 内核        | —                   | 【完全复用】T1 符号 + T3 Stream |
# 关键:信念版 = 确定性版【内核】+ 信念外壳,可插拔、可回退到确定性版(无不确定时)。

⚠️ 常见陷阱

陷阱一(思维陷阱):把"先看后抓"写死成固定脚本,而非让规划器决定。 - 错误描述:在代码里硬编码"总是先 lookpick"。 - 现象/后果:换个任务(信念已经很确定、不需要看)就浪费一次观测;或需要看两次的场景只看一次。 - 根本原因:把信息收集当预处理脚本,而非可规划的决策(违背 §9.2 的"look 是一等动作")。 - 正确做法:让 look 带前提-效果进规划,规划器按信息价值(§8.1 VoI)自动决定看不看、看几次。无不确定时它自然不看。

陷阱二(概念误区):用一个大 POMDP 同时建模离散类别不确定和连续位姿不确定。 - 错误描述:把"是不是杯子(离散)"和"位姿 ±3cm(连续)"塞进同一个 POMDP 求解。 - 现象/后果:连续维度让 belief 空间无法离散求解,状态爆炸(§2.4 本质洞察)。 - 根本原因:违反分层——离散归任务层信念、连续归运动层滤波。 - 正确做法:分层(§9.4)。任务层管离散类别/位置信念,运动层管连续位姿,用 \(p_{\text{grasp}}\) 标量握手。

陷阱三(编程陷阱):执行器假设真实观测必在规划枚举的观测集里。 - 错误描述:look 返回的观测直接用来索引预案分支,无兜底。 - 现象/后果:真机给出建模外观测(新物体、强遮挡),执行器崩溃或行为未定义(§5 陷阱三)。 - 根本原因:开环假设"规划期观测集 = 运行期观测集",真机打破它。 - 正确做法:预案外观测触发重规划或退安全分支(§9.5 兜底),永不假设观测必在预案内。

练习

  1. (⭐⭐⭐,设计) 为"杯子可能在桌上(0.7)或水槽(0.3)、相机有遮挡、抓取可能滑脱"的任务,写出 §9.5 主循环会生成的前几步动作序列(含 look),并标注每步后信念如何变化(用 §3.2 预测/校正)。指出哪一步是规划器自发插入的信息收集、为什么它在这里有价值。
  2. (⭐⭐⭐⭐,实现/扩展) 在 §9.6 的 BeliefTAMP 骨架上实现 _predict_obs(§9.3 的 predict-observation Stream):给定信念和一个 look,产出各观测结果概率及更新后信念。接到 §3.2 的 correct 上,验证它能正确展开"见/不见"两个分支。
  3. (⭐⭐⭐⭐,跨章综合) 综合 T1(符号规划)、T3(Stream)、本章(信念 + 重规划):手工组装一个最小感知不确定 pick-place 端到端流程——T1 的符号域 + T3 的 grasp/ik Stream + 本章的 look 动作和信念 Stream + §9.5 循环。说明数据如何在三章的组件间流动(符号搜索↔Stream↔信念更新↔运动层概率)。

10. 与运动层 belief-space 的接口,横向对比与局限 ⭐⭐⭐⭐

全章最后一节收口三件事:(1) 把贯穿全章的"任务层信念 ↔ 运动层 belief"接口正式讲透(§9.4 只给了一个例子,这里给通法);(2) 把本章五类范式与 U 线横向对比成一张大图,建立选型直觉;(3) 诚实地交代局限与前沿。这是 ⭐⭐⭐⭐ 的收尾节,难度在"把全章 + U 线放在一张图上俯瞰",但只要抓住 §2.4 的分层主线,就能把所有碎片归位。

10.1 接口通法:两层各管什么、怎么握手

§2.4 立了分层原则、§9.4 给了一个 pick 的例子。这里给出通用接口——任意不确定 TAMP 系统里,任务层(本章)和运动层(U 线 U3/U4)的职责划分与握手协议。

接口维度 任务层(本章 T6)出 运动层(U 线 U3/U4)出 握手的汇总量
动作可行性 "我想执行 pick(cup)" 在当前位姿信念下能否抓中 成功概率 \(p_{\text{succ}}\in[0,1]\)
可达性 "我想去看 A 区" 能否规划到观察位姿的安全轨迹 布尔可达 + 轨迹
安全性 "这条任务路线" 沿途碰撞/越界概率 风险 \(\le \delta\)(机会约束,U3)
信息收益 "看 A 区值不值" 看后连续位姿信念收缩多少 信息增益(熵减)汇总
belief 维护 离散命题信念(§3) 连续位姿信念(高斯/粒子,U4) 各维护各的,按需汇总

握手协议的本质:任务层提出离散意图(看哪、抓哪、走哪条任务路线),运动层返回连续评估(概率、可达、风险、信息增益),任务层用这些标量做离散决策。 两层的 belief 不合并——离散信念在任务层、连续信念在运动层,各用各的机器(符号搜索 vs 滤波),只在接口处交换标量。

本质洞察:不确定 TAMP 的接口设计,本质是一次抽象边界的划定——把"连续、高维、数值"的不确定性封进运动层,向上只暴露"离散、低维、符号"的汇总量。这与软件工程的"信息隐藏"是同一种智慧:上层(任务层)不该知道下层(运动层)±3cm 协方差的细节,只需要一个 \(p_{\text{succ}}=0.9\);下层不该知道上层的逻辑目标,只需要"评估这个抓取"。这个边界划得好不好,直接决定系统能否扩展——划好了,两层各自用最适合的机器、独立演化;划坏了(如把连续噪声塞进符号层,§2 陷阱二),两层的复杂度相乘,系统爆炸。所以"任务层信念 vs 运动层 belief"不是两套互不相干的方法,而是一个分层系统的上下两半,接口是它们的契约——这正是总论 T0 把 T6 标注"接 U 线"、本章从头到尾强调分层的根本原因。

10.2 与 U 线的横向对比:同一个 belief,两个抽象层

把本章(任务层 belief)和 U 线(运动层 belief)放在一张表上,彻底厘清"它们是什么关系、各管什么、何时调谁"。

本章 T6(任务层 belief) U 线 U4(运动层 belief,30_不确定性规划/50
belief 是什么 离散命题组合上的分布 连续状态(位姿/意图)上的分布
表示 dict/CNF/粒子(离散世界) 高斯/粒子滤波
不确定的对象 杯子在桌上吗、门锁了吗 位姿偏几厘米、他车意图
"动作" 符号算子 pick/look(带前提-效果) 控制量 / 轨迹
求解 Conformant-FF/Contingent-FF/SS-Replan/TAMPURA SARSOP/DESPOT/POMCP/CC-RRT
长时域 靠符号结构 + 宏动作压缩 靠折扣 + 在线搜索深度
何时是它的主场 离散信息决策(看哪、抓哪、走哪支) 连续噪声传播(这一抓偏不偏、这条路安全吗)

再把本章内部五类范式 + U 线方法做一张选型决策表,作为全章方法地图的总索引:

问题特征 推荐范式 本章节
状态不确定、传感、要开环保证 conformant §4
状态/感知不确定、传感、要分支策略 contingent §5
效果不确定、可恢复完全可观测 determinization + replan §6
需定量信息权衡(VoI)、有风险/死局 POMDP + 近似(QMDP/belief 树/技能) §8
长时域操作、感知不确定、要落地 belief-space TAMP(SS-Replan/TAMPURA) §9
连续位姿噪声、轨迹级安全 → 交给运动层(机会约束/belief 运动规划) U 线 U3/U4
风险尾部敏感(不只均值) → 接 U 线 CVaR 30/60

对比性思维(不是 X 而是 Y):本章和 U 线不是"两个讲 belief 的重复章节",而是同一个 belief-MDP 思想在符号层和几何层的两次落地。判断一个不确定性该调哪一章,永远回到 §2.4 的判据——离散命题真假 → 本章;连续量噪声 → U 线。一个真实的长时域移动操作任务,几乎总是两章都要:本章决定"先去 A 房看杯子(离散决策)",U 线算"怎么走到 A 房且定位不发散、这一抓 ±3cm 下成功率多少(连续评估)"。把它们当对立或重复,是初学者最常见的误区;把它们当一个分层系统的上下两半,才是正确的心智模型。

把上面的选型表画成一棵决策树,作为遇到新任务时的"该用哪个范式"导航(与总论 T0 §6 的方法选型树同构,这里专注不确定性维度):

                    一个不确定性下的任务,该用本章哪个范式?
              ┌─────────────────────┴─────────────────────┐
        不确定的是"离散命题真假"?                    不确定的是"连续量噪声"?
              │ 是(任务层,本章)                            │ 是
              ▼                                            ▼
   ┌──────────┴──────────┐                    交给运动层(U线 U3/U4):
 能在执行中"看"吗?                              机会约束/belief运动规划/CVaR
   │                  │                         (不在本章,见 30_不确定性规划/)
 否(无传感)         是(能传感)
   │                  │
   ▼                  ▼
conformant(§4)   ┌────┴────────────────────┐
对所有可能      失败可恢复 & 完全可观测?    需要定量信息权衡(VoI)
初始世界       │ 是                          或有不可逆死局?
都成功         ▼                            │ 是
            determinization              ┌──┴───────────────┐
            +FF-Replan(§6)             时域短/中?          时域很长?
            假装确定,错了重算           │ 是                │ 是
            (注意两盲区§6.4)            ▼                   ▼
                                  contingent(§5)       belief-space TAMP(§9)
                                  或 belief树(§8.4)    SS-Replan/TAMPURA:
                                  按观测分支的策略树    技能抽象压时域(§8.5)
                                                       +符号提议候选+确定化

怎么用这棵树:从根问"不确定的是离散命题还是连续量"(§2.4 判据,第一刀),离散进本章、连续去 U 线;本章内再问"能不能看"(分出 conformant/有感知),有感知再问"失败可恢复且可观测吗"(分出 FF-Replan/需信念),最后按"是否需信息定价 + 时域长短"落到 contingent / belief 树 / belief-space TAMP。这棵树把全章十节压成一条可执行的决策路径——遇到新任务,沿树走一遍就知道该读哪一节、用哪个工具。

最后用同一个任务把 conformant 和 contingent 的形态差异并排看清(呼应 §4/§5 练习)。任务:"钥匙在抽屉或柜子(各 50%),拿到钥匙去门口。"

conformant(§4)──无观测,要一条对两种世界都成功的【线】:
  若存在"不看也能拿钥匙"的动作(如同时翻倒抽屉和柜子让钥匙掉出)→ 有线性解;
  本任务无此动作 → conformant 【无解】(不看就无法知道去哪拿)。

contingent(§5)──有观测,按观测分支的【树】:
        look(drawer)
        ├─ 见钥匙 → pick(key) → goto(door)            ✓
        └─ 没见   → look(cupboard) → pick(key) → goto(door)  ✓
  两条分支都达标(∀叶) → contingent 【有解】。
  形态:线 vs 树;执行:开环 vs 边看边走;这就是"能否观测"带来的根本差异。

本质洞察:这个并排例子浓缩了 §4-§5 的全部分野——conformant 无解、contingent 有解,差的恰恰是"观测"这一个能力。观测之所以是分水岭,是因为它提供了 §3.2 的校正更新(收缩信念),而本任务的不确定性只能靠观测消除(没有"不看也能归位"的动作)。这把抽象的"预测增熵、校正减熵"落到了最具体的决策后果上:当不确定性只能靠观测消除时,禁用观测(conformant)就等于判了死刑,必须用 contingent 让计划长成一棵能对每个观测结果都有应对的树。 把这条规律记牢,你拿到任何新任务,先问一句"这里的不确定性能靠动作本身消除、还是只能靠看"——答案直接决定 conformant 行不行、要不要上 contingent。

10.3 局限与前沿

诚实交代本章方法的边界,以及近五年学界在往哪走。

局限一:信念表示的可扩展性。 离散显式信念 \(O(2^n)\) 只在不确定命题少时可行(§3.2)。命题一多(几十个物体、各自类别/位置不确定),即使 CNF/粒子也吃力。前沿:用学习的紧凑信念表示(神经网络编码信念)、用factored/结构化信念利用命题独立性。

局限二:似然/转移模型从哪来。 全章假设 \(P(o\mid s)\)\(P(s'\mid s,a)\) 已知。真机上它们要么手工标定(费力、易错)、要么学习(需数据)。前沿:从交互数据学习动作效果概率与观测模型(TAMPURA 的"learned action effect probabilities"正是此路)、用基础模型/VLM 当感知不确定性估计器——"Seeing is Believing"(Zhao 等, 2025, arXiv:2504.03245)用 VLM 直接估计符号命题的不确定性,绕开手工标定似然,是这条线最新的代表。

局限三:连续-离散接口的紧耦合难题。 §10.1 的"标量握手"在多数情况够用,但有些任务里离散决策和连续评估强耦合("抓哪个角"既是离散选择又依赖连续可抓性的精细分布),简单标量汇总会丢信息。前沿:联合的 hybrid belief 表示(SS-Replan 的 "hybrid belief states" 就是混合离散-连续信念)、把几何不确定更细地反馈给符号层。

局限四:长时域 + 强不确定的根本张力未解。 时域越长、不确定越强,三重爆炸(§8.2)越凶。当前所有方法都是"近似 + 利用结构"的权宜,没有银弹。前沿:LLM/基础模型提供高层结构先验(用语言模型常识缩小搜索、提议合理子目标,再用信念规划在子目标内精算)——这是 §80(大模型任务规划)与本章的交叉点,也是当前最活跃的方向之一。

本质洞察:本章方法的所有局限,最终都指向同一个根本张力——不确定性的精确表示/求解是指数的,而真实任务又长又不确定。过去二十年的进展(Conformant-FF 的 CNF、SS-Replan 的重规划、TAMPURA 的抽象信念、Seeing-is-Believing 的 VLM)本质都是同一招的变奏:找一个"足够好的结构"来代替"精确但指数的信念表示/求解"——逻辑公式、最大似然、抽象划分、语言模型先验,都是这个"结构"的不同形态。这条线还远未走完:怎样的结构既紧凑又不丢关键不确定性、既能学习又能保证安全,是这个领域的开放前沿。理解了"用结构对抗指数"这条贯穿全章的暗线,你就不只是学了几个方法,而是握住了整个不确定 TAMP 领域的演进逻辑——也就能判断下一篇新论文是在这条线的哪个位置、解决了哪一段。

⚠️ 常见陷阱

陷阱一(概念误区):把任务层信念和运动层 belief 合并成一个大 belief 求解。 - 错误描述:试图用统一的 hybrid POMDP 同时精确求解离散命题信念和连续位姿信念。 - 现象/后果:连续维度让求解爆炸,失去分层带来的可扩展性(§2.4、§9 陷阱二)。 - 根本原因:违反抽象边界——两层该各用各的机器、接口处交换标量(§10.1)。 - 正确做法:分层 + 标量握手(§10.1)。只在确实强耦合时才用受控的 hybrid belief(§10.3 局限三),且仍尽量保持分层。

陷阱二(思维陷阱):接口处汇总量选得太粗,丢掉决策关键信息。 - 错误描述:运动层只回传一个"可达/不可达"布尔,丢掉了成功概率分布。 - 现象/后果:任务层无法做风险权衡(不知道是 0.51 还是 0.99 的"可达"),在风险敏感任务上误判。 - 根本原因:汇总量的粒度要匹配上层决策的需要——风险敏感任务需要概率而非布尔。 - 正确做法:按上层决策需要选汇总量粒度(布尔可达 / 成功概率 / 风险分位数 / 信息增益),风险敏感时回传概率甚至分布摘要(接 U 线 CVaR)。

陷阱三(概念误区):以为有了 LLM/基础模型就不需要信念规划了。 - 错误描述:用 LLM 直接生成动作序列,跳过信念表示与信息价值推理。 - 现象/后果:LLM 给的计划在需要主动感知/风险权衡时同样会犯 §2.3 的崩溃(它也可能"假装知道杯子在哪")。 - 根本原因:LLM 提供的是高层结构先验/常识,不替代"对不确定性的定量推理"(VoI、风险)。 - 正确做法:LLM 缩小搜索/提议子目标,信念规划在其框架内做定量不确定性推理——两者互补(§10.3 局限四、§80 交叉)。

练习

  1. (⭐⭐⭐,接口设计) 为"机器人去货架取一个可能缺货的零件"设计任务层↔运动层接口:列出任务层提出哪些意图、运动层回传哪些汇总量、用什么粒度(布尔/概率/分布)。说明若这是风险敏感任务(取错代价极高),汇总量粒度该如何调整(提示:§10.2 接 CVaR)。
  2. (⭐⭐⭐⭐,选型综合) 给四个任务:(a) 盲拧一批朝向未知的螺丝;(b) 钥匙在抽屉或柜子、可拉开看;(c) 积木码放、偶尔滑落可重码;(d) 核环境里取样、看一眼代价极高且有不可逆污染风险。用 §10.2 的选型表为每个选范式(§4-§9)并说明理由,指出哪些还需要 U 线配合、配合什么。
  3. (⭐⭐⭐⭐,前沿思辨) 选 §10.3 的一个局限,结合一篇近五年论文(如 TAMPURA 2024、Seeing-is-Believing 2025),论述它"用什么结构代替精确指数信念"、解决了哪一段、又留下了什么新问题。这道题没有标准答案,目的是练"把新论文放进全章演进逻辑"的能力。

本章常见误解汇总

误解 正确理解 出处
"动作会失败"就需要信念规划 会失败 \(\neq\) 需信念规划;只"会失败且可恢复"用重试/FF-Replan 即可,只有"决策依赖未知"才需信念规划 §2.1、§6.4
把连续位姿噪声(±cm)放进符号任务层处理 连续噪声归运动层滤波,任务层只收"成功概率"等汇总标量;混层会指数爆炸 §2.4、§9.4
用"最可能世界"规划总是安全的 最大似然丢掉分布尾巴,在双峰信念/不可逆动作上会酿成不可挽回的错误 §2.3、§3 陷阱一、§8.3
信念是"加权平均的状态",可在平均状态上规划 信念是分布不是点;平均会造出概率为 0 的幻影世界(杯子"在半空中") §3 陷阱一
把似然模型里传感器当完美(误报概率 = 0) 必须给"反常但可能"的观测留 \(\epsilon\) 概率,否则真实观测一来信念崩溃、归一化除零 §3 陷阱二
"POMDP = belief 空间 MDP"所以可直接套 A*/值迭代 那是理论可解性;信念空间 \(\lvert\mathcal S\rvert\) 维连续,实践上维度灾难,必须近似 §3.3、§3 陷阱三
conformant = 对最坏情况规划 conformant 要对每一个可能初始状态都达标(布尔合取),不是只对最坏的一个 §4 陷阱一
contingent plan 是"一条带 if 的序列",只准备最可能分支 每个观测点须对所有可能观测有子计划(AND,覆盖全部),不是赌一个观测(OR) §5 陷阱一
FF-Replan 夺过竞赛冠军,能替代概率规划 冠军是在"可恢复 + 可观测"的良性 benchmark 上拿的;不可逆/需感知问题上它结构性失效 §6.4 陷阱一
QMDP/最大似然只是"精度差一点"的 POMDP 在需信息收集的任务上它结构性地错——永远不选 look,不是"差一点" §8.3、§8 陷阱一
belief 树里动作和观测都可以取 max 动作可控(取 max),观测不可控(按概率取期望);都 max 是过度乐观 §8.7、§8 陷阱二
"先看后抓"应写死成固定脚本 look 该带前提-效果进规划,规划器按信息价值(VoI)自动决定看不看 §9.2、§9 陷阱一
有了 LLM/基础模型就不需要信念规划 LLM 提供高层结构先验/常识,不替代对不确定性的定量推理(VoI、风险);两者互补 §10.3、§10 陷阱三
任务层信念和运动层 belief 是两个互不相干的方法 是同一个 belief-MDP 思想在符号层/几何层的两次落地,一个分层系统的上下两半 §3.4、§10.2

本章小结

本章把前五章"世界完全可知、动作必然成功"的地基撤掉,系统地讲了任务层如何在"看不全、看不准、做不准"的世界里规划。一条主线贯穿始终:不确定性的精确表示与求解是指数的,而真实任务又长又不确定——所有方法本质都是"用一个足够好的结构(逻辑公式、最大似然、抽象划分、技能、语言先验)代替精确但指数的信念"。

核心脉络回顾:不确定性从三个环节漏进任务层(状态/效果/感知,§2),逼出"信念"这个核心对象(§3,状态→分布,动作增熵、观测减熵,belief-MDP 把部分可观测扳回可观测)。信念长出无观测的 conformant(§4,对所有可能世界同时成立)、有观测的 contingent(§5,AND/OR 策略树)两类范式,被工程捷径 determinization+FF-Replan(§6,假装确定、错了重算,良性问题够用但有不可逆/需感知两盲区)绕开,被 PPDDL/RDDL(§7,效果视角 vs DBN 视角)表达,被 POMDP(§8,唯一能给信息定价,但三重爆炸,靠 QMDP/belief 树/技能三类近似驯服)求解。最后落到完整的感知不确定 pick-place(§9,look 作一等动作、Stream 扩到信念、SS-Replan 循环、接 Mini-TAMP)与运动层接口(§10,离散信念归任务层、连续 belief 归运动层、标量握手)。

术语速查表

术语(中 / 英) 一句话定义
信念(belief, \(b\) 对世界真实状态的概率分布;任务层是命题组合上的离散分布
信念空间 MDP(belief-MDP) 把信念当状态的 MDP;使部分可观测问题在信念上变完全可观测
预测更新(prediction) 物理动作后按转移推进信念 \(\bar b(s')=\sum_s P(s'\mid s,a)b(s)\);通常增熵
校正更新(correction) 观测后按贝叶斯收缩信念 \(b'(s')=\eta P(o\mid s')\bar b(s')\);通常减熵
conformant planning 无观测下,对所有可能初始状态都成功的固定动作序列
contingent planning 有观测下,按观测结果分支的策略树(AND/OR)
determinization(确定化) 把概率动作塌缩成确定动作;most-likely(留最可能)/ all-outcomes(拆每效果)
FF-Replan all-outcomes 确定化 + 偏离即重规划;概率规划的强基线
PPDDL PDDL 的概率扩展,probabilistic 效果列表;仅 MDP
RDDL 用 DBN/CPF 描述转移;支持 MDP/POMDP、并发变量、连续量
QMDP 用完全可观测 Q 值在信念下取期望;快但永不主动收集信息
信息价值(VoI) 一次观测带来的决策收益;POMDP 能定量给它定价
宏动作 / 技能(option) 把一长串原子动作打包成带终止条件的高层动作,压缩时域
hybrid belief 混合离散命题 + 连续位姿的信念表示(SS-Replan)
抽象信念(abstract belief) 把连续信念划分成离散抽象状态以便符号搜索(TAMPURA)

知识点总表

# 知识点 核心要点 对应节 难度
1 任务层不确定性来源 状态/效果/感知三类,对应"世界是什么/动作把它变成什么/看到的是否真" §2.2 ⭐⭐
2 任务层 vs 运动层分工 离散命题真假归任务层,连续量噪声归运动层;用错层指数爆炸 §2.4 ⭐⭐
3 信念与信念更新 状态→分布;动作增熵(预测)、观测减熵(校正) §3.1-§3.2 ⭐⭐⭐
4 信念空间 MDP belief 是充分统计量,把部分可观测扳回完全可观测;代价是维度灾难 §3.3 ⭐⭐⭐
5 conformant planning 对所有可能初始世界同时成立;Conformant-FF 用 CNF + SAT 蕴含避免枚举 §4 ⭐⭐⭐
6 contingent planning AND/OR 策略树,每个观测点覆盖所有观测;Contingent-FF §5 ⭐⭐⭐
7 determinization + FF-Replan 假装确定、错了重算;良性够用,不可逆/需感知必败 §6 ⭐⭐⭐
8 概率语言 PPDDL/RDDL 效果列表 vs DBN/CPF;MDP vs MDP+POMDP §7 ⭐⭐⭐
9 POMDP 在 TAMP + 近似 唯一能给信息定价;三重爆炸;QMDP/belief 树/技能三类近似 §8 ⭐⭐⭐⭐
10 感知不确定 pick-place look 作一等动作、Stream 扩到信念、SS-Replan 循环、接 Mini-TAMP §9 ⭐⭐⭐
11 任务层↔运动层接口 分层 + 标量握手(成功概率/可达/风险/信息增益) §10.1 ⭐⭐⭐⭐
12 横向对比与选型 五范式 + U 线一张选型表;同一 belief 思想两个抽象层 §10.2 ⭐⭐⭐⭐

延伸阅读

按主题分类,标注难度(⭐ 入门 / ⭐⭐ 核心 / ⭐⭐⭐ 进阶 / ⭐⭐⭐⭐ 研究级)。年份与发表处已核实。

信念空间 TAMP 奠基(先读) - Kaelbling & Lozano-Pérez, "Integrated Task and Motion Planning in Belief Space", International Journal of Robotics Research (IJRR), 2013. ⭐⭐⭐⭐ —— 本章母文,把 TAMP 正式搬进信念空间,HPN 分层 + 回归。 - Garrett, Paxton, Lozano-Pérez, Kaelbling & Fox, "Online Replanning in Belief Space for Partially Observable Task and Motion Problems", ICRA, 2020(arXiv:1911.04577,代码 SS-Replan)。⭐⭐⭐ —— §9 工程范本:hybrid belief + 确定性 cost-sensitive 规划 + 重规划。

conformant / contingent 规划(§4-§5) - Hoffmann & Brafman, "Conformant planning via heuristic forward search: A new approach", Artificial Intelligence, vol. 170, 2006, pp. 507–541(Conformant-FF)。⭐⭐⭐ —— CNF 隐式信念 + SAT 蕴含。 - Hoffmann & Brafman, "Contingent Planning via Heuristic Forward Search with Implicit Belief States", ICAPS, 2005(Contingent-FF)。⭐⭐⭐ —— 把 FF 启发式扩到部分可观测。 - Bryce & Kambhampati, "A Tutorial on Planning Graph-Based Reachability Heuristics", AI Magazine, 2007. ⭐⭐⭐ —— conformant/contingent 启发式综述。

determinization 与重规划(§6) - Yoon, Fern & Givan, "FF-Replan: A Baseline for Probabilistic Planning", ICAPS, 2007. ⭐⭐ —— 经典 all-outcomes 确定化基线。 - Little & Thiébaux, "Probabilistic Planning vs. Replanning", ICAPS Workshop on IPC, 2007. ⭐⭐⭐ —— 何时确定化必败("probabilistically interesting")。

概率规划语言(§7) - Younes & Littman, "PPDDL1.0: An Extension to PDDL for Expressing Planning Domains with Probabilistic Effects", 技术报告 CMU-CS-04-167, 2004. ⭐⭐ —— PPDDL 定义。 - Sanner, "Relational Dynamic Influence Diagram Language (RDDL): Language Description", 2010(IPPC-2011 官方语言)。⭐⭐⭐ —— RDDL 与 DBN 视角。

POMDP 求解与近似(§8,多数已在 U 线 U4 展开) - Kaelbling, Littman & Cassandra, "Planning and Acting in Partially Observable Stochastic Domains", Artificial Intelligence, vol. 101, 1998. ⭐⭐⭐⭐ —— POMDP 奠基。 - Kurniawati, Hsu & Lee, "SARSOP: Efficient Point-Based POMDP Planning by Approximating Optimally Reachable Belief Spaces", RSS, 2008. ⭐⭐⭐⭐ —— 点基离线求解(U4 详讲)。 - Silver & Veness, "Monte-Carlo Planning in Large POMDPs"(POMCP), NeurIPS, 2010;Ye, Somani, Hsu & Lee, "DESPOT: Online POMDP Planning with Regularization", JAIR, 2017. ⭐⭐⭐⭐ —— 在线 belief 树(U4 详讲)。

近五年前沿(研究级,§8-§10) - Curtis, Matheos, Gothoskar, Mansinghka, Tenenbaum, Lozano-Pérez & Kaelbling, "Partially Observable Task and Motion Planning with Uncertainty and Risk Awareness"(TAMPURA), RSS, 2024(arXiv:2403.10454)。⭐⭐⭐⭐ —— 抽象信念 + 风险/死局规避 + 双层不确定性推理,本章现代范本。 - Zhao, McClinton, Curtis, Kumar, Silver, Kaelbling & Wong, "Seeing is Believing: Belief-Space Planning with Foundation Models as Uncertainty Estimators", 2025(arXiv:2504.03245)。⭐⭐⭐⭐ —— 用 VLM 估计符号命题不确定性 + 参数化技能 + belief-space 规划,绕开手工标定似然。

教科书 / 综述 - Garrett, Chitnis, Holladay, Kim, Silver, Kaelbling & Lozano-Pérez, "Integrated Task and Motion Planning", Annual Review of Control, Robotics, and Autonomous Systems, 2021. ⭐⭐⭐ —— TAMP 总览,含不确定性一节,定位本章于全局。 - Geffner & Bonet, A Concise Introduction to Models and Methods for Automated Planning, Morgan & Claypool, 2013. ⭐⭐⭐ —— conformant/contingent/概率规划的统一模型视角。


本章与后续章节的关系

后续/相关章节 关系 本章为它铺垫了什么
T7 大模型任务规划(§80,下一章) LLM 提供高层结构先验,本章提供不确定性的定量推理——两者互补 §10.3 局限四点明"LLM 缩小搜索、信念规划在其框架内精算";LLM 也会犯 §2.3 崩溃,需信念兜底
T5 行为树与执行监控(§60) 执行层承载本章生成的策略 §5.4:contingent plan 可编译成 BT;observe 节点→BT 条件分支;预案外观测→触发重规划
U 线 U4 POMDP 与 Belief 规划(30/50 同一 belief 思想的运动层/数值实现,本章的下游伙伴 §3.4、§10.2:本章出离散决策,U4 出连续评估;§9.4/§10.1 给出握手接口
U 线 U3 机会约束(30/40 运动层把连续噪声汇总成"成功概率/风险 \(\le \delta\)"回传任务层 §9.4、§10.1:抓取成功概率、安全轨迹风险的来源
U 线 CVaR 风险敏感(30/60 风险敏感任务下接口汇总量从均值升级到分位数 §10.2、§10 陷阱二:风险敏感时回传概率/分布摘要而非布尔
T3 PDDLStream(§40) 本章把 Stream 机制扩展到采样信念与观察位姿 §9.3:sample-observation-posepredict-observation 与 T3 的 sample-ik 同构
T1 TAMP 基础 / Mini-TAMP(§20) 本章给累积项目加"不确定性"模块 §9.6:belief_tamp/ 复用 T1 符号内核 + T3 Stream,外套信念+重规划

🔧 故障排查手册

不确定性 TAMP 的故障常常"看起来像 bug、其实是方法选错"。下面五个高频场景,按"症状→可能原因→排查步骤→相关章节"组织。

场景一:规划器永远不主动"看",直奔猜测目标然后频繁扑空

内容
症状 机器人从不执行 look/感知动作,总是直接去猜测的位置抓/取,约一半概率扑空;重规划后还是直奔(换个猜测目标)。
可能原因 (1) 用了确定性 TAMP 或 FF-Replan(完全可观测假设,看不见信息价值);(2) 用了 QMDP(假设不确定性下一步消失,结构上不选 look);(3) look 建模成纯代价动作,信息收益没进规划目标。
排查步骤 ① 确认任务是否真的"决策依赖未观测信息"(§2.1 判据)——是,则不该用 FF-Replan/确定性;② 检查求解器:QMDP?换 belief 树/完整 POMDP(§8.4);③ 检查 look 是否带"收缩信念"的效果、其 VoI 是否计入 cost-sensitive 目标(§9.2);④ 验证 look 前提 UncertainAbout 没把所有 look 都剪掉。
相关章节 §2.3 崩溃二、§6.4 盲区二、§8.3、§9.2

场景二:执行几步后信念归一化报错 / 信念突然全为 0

内容
症状 normalize 抛"所有世界概率为 0"异常,或某次观测后信念整个崩溃、后续决策全失效。
可能原因 (1) 似然模型把传感器当完美(\(P(\text{误报})=0\)),真实出现了被建模为"不可能"的观测;(2) 似然模型漏列了某个观测结果;(3) 校正后忘了归一化,概率累乘趋 0。
排查步骤 ① 检查似然 \(P(o\mid s)\) 是否对所有 \((o,s)\) 留了 \(\epsilon\) 余量(§3 陷阱二);② 打印崩溃前一步信念与刚收到的观测,看是哪个 \(s\)\(P(o\mid s)=0\) 清零;③ 确认 correct 后调了 normalize(§3.2 错误 1);④ 真机上用感知模块的混淆矩阵重新标定似然(§9.5)。
相关章节 §3.2、§3 陷阱二、§9.5

场景三:FF-Replan 在仿真飞快、一上真机就偶发"灾难性"不可恢复失败

内容
症状 确定化 + 重规划在仿真和大多数真机试验里又快又好,但偶尔触发某个低概率结果后彻底卡死/损坏,无法恢复。
可能原因 问题含不可逆死局(掉落、打碎、锁死),determinization 抹掉了该结果的小概率,规划器"自信能过"(§6.4 盲区一)。
排查步骤 ① 列出所有动作的低概率效果,标出哪些不可逆(§6.4 表);② 若存在不可逆灾难,停用纯 FF-Replan;③ 改用风险感知方法:显式建模死局(TAMPURA,§8.6)或接 U 线机会约束/CVaR 留安全余量(§10.2);④ 在确定化目标里给低概率危险动作加重惩罚作为过渡缓解。
相关章节 §6.4 盲区一、§8.6、§10.2、§10.3 局限四

场景四:把 ±cm 位姿不确定塞进符号层后,规划器超时/内存爆炸

内容
症状 加入位姿不确定建模后,PDDL 命题数暴涨(PoseCell_*)、符号搜索分支因子爆炸,规划器跑不出解或 OOM。
可能原因 违反分层——把连续量的噪声离散成大量命题塞进任务层(§2 陷阱二、§9 陷阱二)。
排查步骤 ① 检查符号域里是否有位姿/距离的细粒度离散命题;② 把连续位姿不确定移回运动层用滤波处理(U4);③ 运动层只回传 \(p_{\text{grasp}}\)/可达布尔等汇总标量给任务层(§9.4、§10.1);④ 确认任务层信念只含离散命题(类别/位置/锁否),维度低。
相关章节 §2.4、§9.4、§9 陷阱二、§10.1

场景五:策略树/执行器遇到"没料到的观测"直接崩溃

内容
症状 真机传感器返回一个建模时没枚举的观测(新物体、强遮挡、奇异检测),执行器抛异常或行为未定义,任务中断。
可能原因 开环假设"规划期枚举的观测集 = 运行期所有可能观测",真机打破它(§5 陷阱三、§9 陷阱三)。
排查步骤 ① 检查 observe 节点是否假设真实观测必在 branches 里;② 加兜底分支:预案外观测→触发重规划(§6/§9.5)或退到安全默认动作;③ 把 contingent planning 与 replanning 结合(SS-Replan 模式,§9.5);④ 给似然/观测集留"其他"类,吸收未建模观测。
相关章节 §5 陷阱三、§9.5、§9 陷阱三

API 速查表

本章涉及的核心函数/接口签名与说明(教学实现,对应正文代码)。

接口 签名 说明 出处
预测更新 predict(belief, transition) -> Belief 物理动作后推进信念 \(\bar b(s')=\sum_s P(s'\mid s,a)b(s)\) §3.2
校正更新 correct(belief, obs, likelihood) -> Belief 观测后贝叶斯收缩 \(b'=\eta P(o\mid s)\bar b\) §3.2
归一化 normalize(belief) -> Belief 除以 \(\sum\);全 0 时报错(似然与信念矛盾) §3.2
conformant 转移 apply_action_to_belief(belief, action) -> Belief \(B'=\bigcup_{s\in B}\text{effects}(a,s)\);前提须全 \(B\) 成立 §4.5
conformant 目标 goal_satisfied(belief, goal) -> bool \(\forall s\in B,\ s\models g\)all 不是 any §4.5
conformant 搜索 conformant_bfs(B0, actions, goal) -> plan 信念(世界集合)空间 BFS §4.5
contingent 规划 plan_contingent(belief, ...) -> tree AND/OR 搜索,产出策略树 §5.3
策略树执行 execute(tree, world) observe 节点按真实观测选支;预案外要兜底 §5.3
all-outcomes 确定化 all_outcomes_determinize(prob_action) -> [DetAction] 每概率效果拆一个确定动作 §6.2
FF-Replan 循环 ff_replan(prob_domain, init, goal, ...) -> status 确定化+执行首动作+偏离重规划 §6.2
QMDP 选动作 qmdp_action(belief, Q_mdp, actions) -> action \(\arg\max_a\sum_s b(s)Q_{\text{MDP}}(s,a)\);不选信息收集 §8.7
在线 belief 树 belief_tree_value(belief, depth, ...) -> (action, value) 动作 max、观测按概率期望 §8.7
观察位姿 Stream sample-observation-pose → 认证 Visible 采样能看清某区域的构型(仿 sample-ik §9.3
观测预测 Stream predict-observation → 认证 BeliefAfter 封装校正更新为可采样事实 §9.3
运动层概率汇总 motion.annotate_success_probs(domain, belief) -> domain \(p_{\text{grasp}}\) 写进确定化域 §9.4、§9.6
信念 TAMP 步 BeliefTAMP.step(goal) -> {'continue'/'replan'/...} §9.5 主循环一步 §9.6

研究实践建议

分层次给出建议,帮你把本章用到研究或工程里。

入门(先建立正确直觉,避免最常见错误) - 永远先用 §2.4 判据把不确定性分层:离散命题真假 → 任务层,连续量噪声 → 运动层。这一步错了,后面全错。 - 永远先问 §6.4 两问题:失败能恢复吗?决策依赖未观测信息吗?两个"否"就用 determinization+replan,别一上来就上 POMDP 重武器。 - 写信念更新时,似然模型永远给"反常但可能"的观测留 \(\epsilon\)——这是数值健壮的第一道防线(§3 陷阱二)。

进阶(做一个能跑的不确定 TAMP 系统) - 复用确定性内核 + 信念外壳(§9.6):别推翻 T1/T3,在外面套"信念 + 重规划"。可插拔、可回退、易调试。 - 把 look 做成带前提-效果的一等动作(§9.2),让规划器自动决定看不看,而不是写死脚本。 - 接口处汇总量的粒度匹配上层决策需要(§10 陷阱二):风险敏感任务回传概率/分位数而非布尔。 - 真机部署前用感知模块的混淆矩阵标定似然、给执行器加预案外观测兜底(§9.5、场景五)。

研究级(推进领域前沿) - 选一个 §10.3 的局限切入:紧凑信念表示、学习似然/转移模型、hybrid belief 紧耦合、长时域×强不确定的张力。 - 读 TAMPURA(2024)与 Seeing-is-Believing(2025),用"它用什么结构代替精确指数信念、解决哪一段、留下什么新问题"的框架解剖它们(§10 练习 3)——这是把握领域演进的核心能力。 - LLM × 信念规划是当前最活跃的交叉点(§10.3 局限四、§80):让语言模型提供高层结构先验、信念规划在其框架内做定量不确定性推理,是值得投入的方向。 - 始终带着全章暗线判断新工作的位置:它在"用结构对抗指数信念"这条线的哪一段? 这能帮你快速定位任意新论文的贡献与局限。


下一章预告: TAMP_T7 大模型任务规划(LLM Task Planning,§80)。本章把不确定性作为一等公民放回任务层,但始终假设"动作的前提-效果、似然/转移模型"由人写好。下一章换一个维度的不确定性来源——任务本身用自然语言模糊地给出("把房间收拾干净"该分解成哪些子目标?),看大语言模型如何用它的常识把模糊指令翻译成可规划的符号目标与动作序列。两章在 §10.3 局限四处交汇:LLM 提供高层结构先验(缩小搜索、提议合理子目标),本章提供不确定性的定量推理(信息价值、风险权衡)——一个负责"大概该做什么",一个负责"在看不清的世界里稳稳地做成"。读 T7 时请带着本章的警觉:LLM 也会"假装知道杯子在哪",它给的计划在需要主动感知/风险权衡时同样会犯 §2.3 的崩溃,仍需本章的信念规划兜底。两者互补,缺一不可。


版本信息速查

本章涉及的工具、求解器与语言的关键版本/出处信息(便于复现与查阅)。

名称 类型 出处 / 版本 用途(本章节)
Conformant-FF 求解器 Hoffmann & Brafman, AIJ 2006 conformant 规划(§4)
Contingent-FF 求解器 Hoffmann & Brafman, ICAPS 2005 contingent 规划(§5)
FF-Replan 算法/基线 Yoon, Fern & Givan, ICAPS 2007 determinization + replan(§6)
PPDDL 语言 Younes & Littman, 2004(IPC-4 概率赛道) 概率效果建模(§7)
RDDL / rddlsim 语言 / 模拟器 Sanner, 2010(IPPC-2011 官方语言) DBN/POMDP 建模(§7)
SARSOP POMDP 求解器 Kurniawati, Hsu & Lee, RSS 2008(APPL 工具包) 点基离线求解(§8,U4 详)
DESPOT / POMCP POMDP 求解器 Ye 等 JAIR 2017 / Silver & Veness NeurIPS 2010 在线 belief 树(§8,U4 详)
SS-Replan 系统 / 代码 Garrett 等, ICRA 2020(github: caelan/SS-Replan) belief-space TAMP 范本(§9)
TAMPURA 系统 Curtis 等, RSS 2024(arXiv:2403.10454) 抽象信念 + 风险感知(§8.6)
Seeing-is-Believing 系统 Zhao 等, 2025(arXiv:2504.03245) VLM 估计不确定性 + belief 规划(§8.5/§10.3)
PDDLStream 框架 Garrett 等, ICAPS 2020(github: caelan/pddlstream) Stream 扩展到信念(§9.3,T3 详)

说明:本章的教学代码(§3/§4/§6/§8/§9 的 predict/correct/conformant_bfs/ff_replan/belief_tree_value/BeliefTAMP 等)为自包含的最小实现,用于讲清语义,不依赖上述具体求解器;真实系统请使用上表的成熟工具(如 SS-Replan/PDDLStream 做 belief-space TAMP、SARSOP/DESPOT 做 POMDP 求解)。版本与接口可能随上游更新而变化,以各自官方仓库/论文为准。