跳转至

Physics Studio:实现与接口

当前验证状态:整体尚未验证。

Physics Studio 的目标是在同一条重建出的 articulated HOI 任务上比较物理方法。它只统一 任务输入、完整的 articulated scene、最终评测与可视化;每个 baseline 仍运行作者自己的 task、network、trainer、buffer、PPO/GAE、reset/curriculum 与 player。

flowchart LR
  I["case.json + result.pt + 接触标签"] --> S["共享准备"]
  S --> A["全关节 articulated scene"]
  S --> H["本 case 人体 XML"]

  A --> C["CoDA 适配器"]
  A --> M["InterMimic 适配器"]
  A --> R["RePHO 适配器"]
  A --> P["PHC-X 适配器"]
  H --> C
  H --> M
  H --> R
  H --> P

  C --> CT["作者 CoDA trainer / player"]
  M --> MT["作者 InterMimic trainer / player"]
  R --> RT["作者 RePHO coordinator / trainer / player"]
  P --> PT["作者 PHC-X player"]

  CT --> O["common_rollout.npz"]
  MT --> O
  RT --> O
  PT --> O
  O --> E["统一 Success / Fail 评测"]
  O --> V["统一 renderer / Viser"]

Studio 不存在通用 trainer、通用 policy loop,或某个方法专属的 renderer / evaluator。

两条执行路径

路径 输入与资产 算法 可以得出的结论
Official reproduction 作者原生输入、资产与 checkpoint 作者代码不改 原作者提供的方法可以复现
Studio benchmark 统一的 case.json + result.pt 与完整全关节场景 作者 trainer/player 加上显式 articulated 适配 各方法在同一任务协议下可比较

Official reproduction 的输出绝不进入 Studio 汇总;作者 demo 的 XML、motion file 或 checkpoint 不能成为 Studio 的隐藏输入。

Baseline 算法保真约束

Studio 只能适配 canonical 输入边界、完整 articulated scene、articulated observation/reward 输入和 common recorder。它不能替换 baseline 的 network、trainer、buffer、 PPO/GAE、optimizer、normalizer、curriculum、reset/termination 语义或 player。任何超出这些 范围的改变,都是必须单独披露的 adaptation,不能再称为“保留作者算法的 baseline”。

所有 baseline 运行在同一套 rl-games 1.6.1 环境中。为适应该上游 API 的机械兼容补丁可以 保留:它只能修正 import、参数名或等价的数据容器访问,且必须保持同一输入、PPO 日程、buffer 字段、checkpoint 布局与 player 行为。它不属于 articulated adaptation,也绝不能借机改写训练 算法;其逐项等价性由 author-fidelity 计划中的 captured comparison 验证。

Canonical 输入

公开输入刻意只保留:

case.json
result.pt

case.json 保存静态任务信息:资产身份、support plane/static boxes、人体 gender、active joint 名称和 contact reference 路径。result.pt 保存动态 reference:SMPL-X pose/betas、 object root pose、全部 object joint 的 values/names/types 以及 FPS。接触标签仍是 reconstruction preprocess 的已审核输出,并由 case.json 直接引用。

唯一的公开读取函数是:

task, result, contact_labels = load_physics_input(case_json_path, result_path)

它直接读取固定字段,并拒绝 shape 无效、非有限数、未知 joint 或时间轴不一致的输入;不会猜测 旧路径、推断 contact,或兼容旧 runtime 格式。

共享的场景与人体准备

articulated_scene.py 为 Isaac backend 准备本 case 的完整 articulated object。每个 URDF joint 都会被加载、可碰撞并保持物理自由。reference 也包含全部 joint、object-root state、 link state、contact-region geometry 与静态 support geometry。

若 active supervision 覆盖多个 child link,contact preparation 必须为每个 link 至少保留一个 标注点;当 contact_region_max_points 小于 link 数时直接失败。continuous joint 在进入 reference、速度与评测前沿时间轴 unwrap,避免跨 \(\pm\pi\) 被误判为一次大幅反向运动。

physics.active_joint_names 只表达任务监督:它选择 reference motion 和 success condition, 绝不会锁住、驱动或移除其他 joint。非 active 的门被撞开是允许发生的物理现象;其 drift 只作为 诊断显示,不单独决定 Success / Fail。

humanoid.py 是本 case 人体 XML 的唯一共享来源。它只根据 canonical 的 betas/gender 生成 人体。backend 可以请求各自原生所需的 axis/control contract,但不能再实现第二份 beta/SMPL-X generator。

原生临时输入只写在 backend 的 temporary directory。完成后只发布 common rollout、evaluation JSON、匹配的人体 XML、可选视频和 run_record.json

先看懂:Studio 对各方法到底做了什么

可以把 Studio 理解成“给作者算法换同一份题目和同一张答题纸”,而不是另写一套算法。

方法 作者原版仍负责什么 Studio 只新增什么 最终交付
CoDA CommonAgent、model、PPO/GAE、buffer、checkpoint、player 从 canonical input 写 CoDA 原生 reference;加载完整 URDF;记录 common rollout articulated manipulation rollout
InterMimic InterMimicAgent、network、PPO/GAE、buffer、curriculum、player InterMimicArticulated task:完整 URDF、articulated obs/reward、recorder articulated manipulation rollout
RePHO 两个作者 worker、forward/backward coordinator、exchange、repair、player 与 InterMimic 相同的 scene/input 边界 articulated manipulation rollout
PHC-X 作者 human-tracking policy 与 player canonical human motion 转换、完整物体状态和 recorder human-tracking diagnostic,不是 manipulation baseline

控制接口对照:主路径与仓库内其他接口

这张表刻意将“策略输出什么”和“输出怎样成为关节目标”拆开。它区分“默认主路径”和作者 仓库内的其他接口;不代表所有方法都已进入 Studio benchmark。\(x_t\) 是当前人体物理状态, \(r_t\) 是人体 reference,\(o_t,\hat o_t\) 是当前/参考物体状态,\(a_t\) 是 joint action, \(z_t\) 是 motion latent,\(c_t\) 是 contact / interaction-window 信息。\(q_0\) 是机器人/人形的 默认关节姿态,\(s\) 是该后端的动作标尺。

先看懂四个 q

符号 大白话 会随帧变化吗?
\(q_{\rm mid}\) 关节允许范围的中点 不会
\(q_0\) 作者指定的默认站姿 不会
\(q_{\rm offset}\) 作者对 action map 额外改过后的固定中心 不会
\(q_t^{ref}\) \(t\) 帧希望模仿到的参考关节角度

前三者只是不同作者给“action = 0 时的目标姿态”起的不同名字;它们不会随 reference 播放而改变。只有 \(q_t^{ref}\) 是 motion 的逐帧内容。故普通 action map 写成 \(q^{PD}=q_{\rm mid/0/offset}+s\odot a\),而 reference-centered residual 才写成 \(q_t^{PD}=q_t^{ref}+s\odot\Delta a\)

方法 策略输出(action 公式) 最终 PD target 公式 reference 的角色
第一类:直接完整 joint action 策略一次输出全身 action;reference 进入 observation / reward,但不直接成为 PD target 中心 可执行主路径:直接 imitation,但策略需同时学自然 motion 与接触修正
PHC-X \(a_t=\pi_{\mathrm{PNN}}(x_t,r_{t:t+K})\) \(q_t^{PD}=q_{\rm mid}+s\odot a_t\) 输入给 PNN tracker;不直接写进 PD target
CoDA \(a_t=\pi_{\mathrm{MimicArti}}(x_t,r_{t:t+K},o_t,\hat o_t)\) \(q_t^{PD}=q_{\rm mid}+s\odot a_t\) humanoid_ref 将 body/DOF/future reference 写入 observation;policy 输出完整 joint action
CoDA* \(a_t=\pi_\theta(x_t)\) \(q_t^{PD}=q_{\rm mid}+s\odot a_t+q_t^{ref}\) 紧邻 CoDA 仅为展示 hand_ref.py未接通注释草稿;不属于任何可执行类别,不能训练或报告为 CoDA 结果
InterMimic / RePHO \(a_t=\pi_{\mathrm{method}}(x_t,r_{t:t+K},o_t,\hat o_t)\) \(q_t^{PD}=q_{\rm offset}+s\odot a_t\) 人体与物体 reference 都进入 observation,且共用同一 absolute-PD 映射;仅作者训练流程不同:InterMimic 是 teacher/student curriculum,RePHO 是双向 worker、exchange 与 repair
第二类:以 reference action 为中心的 residual \(a_t=a_t^{ref}+\Delta a_t\) \(q_t^{PD}=q_t^{ref}+s\odot\Delta a_t\) reference 本身就是逐帧 PD-target 中心;policy 只预测相对该帧 reference 的修正
PHC-X* \(\Delta a_t=\pi_{\mathrm{PNN}}(x_t,r_{t:t+K})\) \(q_t^{PD}=q_t^{ref}+s\odot\Delta a_t\) reference 同时作为 tracker 输入与 PD-target 中心
OmniGrasp* \(\Delta a_t=\pi_{\mathrm{HumanoidIm}}(x_t,r_{t:t+K})\) \(q_t^{PD}=q_t^{ref}+s\odot\Delta a_t\) PHC-style human tracking interface;需明确以此 task/config 运行,不能标作默认 OmniGrasp-Z
HDMI \(\tilde a_t^{ref}=(q_t^{ref}-q_0)/s\)\(a_t=\tilde a_t^{ref}+\Delta a_t\) \(q_t^{PD}=q_0+s\odot a_t=q_t^{ref}+s\odot\Delta a_t\) 真正的 reference-centered joint-action residual;训练器还使用 residual-action distillation
第三类:以 tracker action 为中心的 residual \(a_t=a_t^{base}+\Delta a_t\)\(a_t^{base}=\pi_{\rm tracker}(x_t,r_{t:t+K})\) 各方法沿用自己的固定 action map reference 先经闭环 tracker 变成 action;residual 修正的是 tracker 已考虑当前物理状态后的输出
ResMimic \(a_t=a_t^{GMT}+\Delta a_t^{Res}\) \(q_t^{PD}=q_0+s\odot a_t\) GMT 先提供全身 action;object/contact 条件的 residual 在 joint-action 空间相加
Ours \(a_t=\pi_{\rm tracker}(x_t,r_t)+\pi_{\rm contact}(x_t,r_t,o_t,\hat o_t,c_t)\) \(q_t^{PD}=q_{\rm mid}+s\odot a_t\) 推荐设计,尚未实施:采用 joint-range action map;tracker 保住全身 motion,contact policy 只补交互所需的 action 修正。物体所有 joint 仍是被动、自由、可碰撞
第四类:latent residual / motion decoder 策略先修正低维 motion latent,再由冻结或预训练 decoder 生成 joint action action 维度更低,但前提是已有与 embodiment 严格匹配的 motion prior
GRAIL \(z_t=\mathcal E(r_t)\)\((\Delta z_t,u_t)=\pi_\phi(x_t,o_t)\)\(a_t^{body}=\mathcal G(z_t+0.1\Delta z_t)\),手部由 \(u_t\) 映射 \(q_t^{PD}=q_0+s\odot[ a_t^{body},H(u_t)]\) reference 先编码为 SONIC token;策略只修正 latent,并输出双手抓握 primitive
OmniGrasp \(z_t=\mu_{\mathrm{prior}}(x_t)+\Delta z_t\)\(a_t=D(x_t,z_t)\) \(q_t^{PD}=q_{\rm mid}+s\odot a_t\) 主要使用物体轨迹、接触与 shape;不是 paired human-reference tracker

\(s\) 统一表示“逐关节 action 标尺”:PHC/CoDA 中它通常由关节 range 的一半得到, ResMimic/GRAIL 中它来自作者的 action_scale 配置。\(H\) 只是把 GRAIL 的每只手一个 open/close primitive 展开为该手的多个手指 joint action。PHC-X*、OmniGrasp* 与 HDMI 才会直接以 \(q_t^{ref}\) 为 PD target 的中心。

对 Ours,第二行的 policy 不是新的 PD controller,也不是物体 action。它只是把“跟踪人体参考”与 “修正手—物接触”分开;两项 action 相加后仍走同一个 humanoid actuator map。第一版不额外引入 tanh、手工 clip 或 latent tokenizer;关节限位仍由已有 actuator map 统一处理。

星号(*)表示“同一作者仓库内额外存在的接口”,而不是主方法的默认控制语义。 其中 CoDA* 是未接通 prototype;PHC-X* 和 OmniGrasp* 是可显式选择的原生 HumanoidIm residual-PD 接口。任何实验记录都必须写明实际 task、config 和 checkpoint,不能只写方法名。

InterMimic:InterMimicArticulated 与原版到底差什么

InterMimicArticulatedInterMimic 的一个 task 子类,不是新算法、不是新 trainer,也不是 Studio 自己写的 policy。它的目的很窄:让原本的 InterMimic 训练器能够在统一的 articulated object 上运行。

一次运行发生什么

  1. omomo_input.py 把 canonical SMPL-X 转成 OMOMO 原生人体 motion:body-tree order、local rotation convention、upright frame、153 DoFs、FK body positions 和 contact slots;同时生成 本 case 的 humanoid XML。
  2. articulated_scene.py 从该 case 的 URDF 建立物体、地面与 static boxes。物体的每个 joint 都真实存在、可碰撞、可被误撞开;不会因为它不是 active joint 就被锁死。
  3. backends/intermimic.py 向作者 intermimic.run 传入上面两份输入,并指定 task 名称 InterMimicArticulated。训练仍由作者 InterMimicAgent 完成。
  4. 测试时仍调用作者 player;Studio 只要求使用 1 个环境、从 reference frame 0 开始,并把 连续有效帧录为 common_rollout.npz

与原版 InterMimic 的逐项对照

部分 原版 InterMimic Studio 的 InterMimicArticulated 为什么必须改
task 类 InterMimic InterMimicArticulated(InterMimic) 只在 task 层加入 articulated scene;作者 trainer 不变
物体资产 作者原生 target asset / rigid target 状态 case URDF 的全部 link 与 joint,另加 ground/static boxes 统一测试真实 articulated object,而不是把其余门/抽屉删掉或固定
物体 reset 原版 target reset Start 使用 case JSON 的全部 init q/零 qvel;作者的 Hybrid/Random/Traverse 采样使用同一 absolute reference frame 的全部 q/qvel 既保证最终评测从声明的物理初态开始,也不破坏作者 curriculum 中 human/object 的同步状态
observation 原版人体与 target 观测 原观测之外加入固定的 articulated_graph:当前/参考 link 几何与 active-joint 状态 policy 必须看见“门现在在哪里、参考门应该在哪里”;输入宽度与 checkpoint 严格校验
reward 原版 human/object/interaction/contact 项 保留原 reward,再加入 active-joint qqvel、link 对齐和 target-contact 项 这是唯一与 articulated 任务有关的学习信号;不是重写 PPO 或 human reward
非 active joint 原版没有统一的全关节约束 仍在 PhysX 中自由、可碰撞;只记录其 drift 不允许 Studio 偷偷固定未监督的门/抽屉
训练 作者 InterMimicAgent、PPO/GAE、buffer、optimizer、curriculum 完全不改 结果才可称为作者算法在统一任务上的运行
测试输出 作者原生状态/可视化 从作者 task state 录为 common rollout 所有方法才能用同一个 evaluator、renderer 与 Viser 比较

入口分别是:backends/intermimic.py(启动作者 entrypoint)、 intermimic_articulated.py(仅 task 层适配)和 intermimic_agent.py(作者 agent,不改)。

其他 adapter:一眼能看懂的版本

CoDA / PhysicalArtiObj

  1. canonical reference 先重采样到 common FPS,再转为 CoDA 原生 control FPS;
  2. adapter 写全关节 scene、CoDA 所需 fingertip/contact layout 与本 case XML;
  3. 原始 CoDA CommonAgent、model、PPO/GAE、buffer、checkpoint 和 player 不变;
  4. CoDA 作者 reward 当前只监督一个 target joint,因此 multi-active-joint task 会明确拒绝;但 其余 joint 仍被动物理模拟,绝不固定。

CoDA 的作者 criterion 将 player 的第一局作为 warm-up。因此 Studio eval 仍只使用一个环境, 但让作者 player 顺序运行两局:第一局不录制,第二局从 reference frame 0 写入唯一的 common rollout。它不改 player、criterion 或 termination 语义。

RePHO

  1. 复用 OMOMO human conversion 和共享全关节 scene;
  2. backends/repho.py 启动作者的 forward/backward coordinator,而不是另写 trainer;
  3. Studio 只使两个作者 worker 读取 canonical human input 与完整物体 scene;
  4. 新的 forward 或 backward 作者 player 导出最终 common rollout。

PHC-X

  1. phcx_motion.py 把 canonical SMPL-X 转为 PHC-X 原生 tracking motion 与 local-axis XML;
  2. phcx_input.py 准备完整物体 reference/contact,并把 PHC 原生 rollout 转为 common rollout;
  3. 它可以走同一份评测、视频和 Viser,但结论只说明人体 tracking,不能当作 articulated manipulation policy 的训练结果。

Common rollout、评测与可视化

common_rollout.npz 是唯一公开的动态结果,包含:

  • 52-body human root/DoF/body state;
  • object root 和每个 object joint 的 qpos;
  • 全部 joint 的 reference、names 与 types;
  • contact distances/forces 与 intended-contact labels;
  • FPS 与 valid_frame_count

recorder 只接受连续的 reference frames。若 episode 提前结束,它只记录有效前缀,并通过 valid_frame_count 标出剩余时间轴;绝不把一次 reset 当成连续 rollout。

evaluation.py 读取 case.jsoncommon_rollout.npz 和固定阈值。它检查 active-joint contact、post-contact progress、completion 与 early termination,最终只返回 success: true/false 和诊断 failure reason。inactive-joint drift 会报告,但绝不单独把结果 判成失败。

renderer 与 Viser 只从 common rollout 取得动态的人体/物体 transforms。case.jsonresult.pt 只用于定位不可变资产、scale、support geometry 和匹配的人体 XML;不会渲染 native pkl 或 backend-native rollout。

实现文件(按需展开)
pipeline/physics/
  input.py, timeline.py, contact.py
  articulated_scene.py, humanoid.py
  common_rollout.py, evaluation.py, render.py, run_record.py, run.py
  converters/   # ARCTIC GT、ParaHome GT、CoDA generated motion
  backends/     # coda、omomo_input、intermimic、repho、phcx_*
  vis/          # common rollout renderer 与 comparison viewer
pipeline/object_assets/physics/  # URDF packaging、collision caching、decomposition
scripts/physics/verification/    # source/checkpoint/tensor/多次运行检查

原生 coordinate/layout conversion 只在 backend 边界。backend 内不能保留 fallback loader、旧 runtime format、通用 policy 或通用 training loop。run_record.json 只记录 method、mode、case、 seed、输入输出、checkpoint 和 native counters。

共享双机项目根与运行约束

最终代码、数据、checkpoint 和实验输出收敛到同一个共享项目根;两台机器直接从该路径运行, 不维护第二套可执行工程:

/mnt/cvda_mnt/projects/arthoi4d/
  configs/
  data/
    arctic/
    d3dhoi/
    partnet/
  docs/
  output/
  pipeline/
  scripts/
  submodules/
  tests/

两台机器都从下列目录启动:

cd /mnt/cvda_mnt/projects/arthoi4d

共享运行遵守以下固定规则:

  1. 两台机器使用各自本地的 Conda 环境。
  2. TORCH_EXTENSIONS_DIR、Python cache 和 adapter 临时目录写入各自机器的 /tmp,不能写入共享项目根。
  3. 两台机器可以写同一个 experiment root,但分配的 case 必须互不重叠。
  4. 每个 case 同一时刻只能由一台机器领取,避免覆盖 checkpoint、日志或最终输出。
  5. 一轮正式实验启动后冻结 Git commit;队列运行期间不能修改代码,否则后续 case 会使用不同实现。
  6. git pull、切换 branch 和 submodule update 等会改变共享 checkout 的操作,同一时刻只能由一台机器执行。

共享项目根是唯一正式运行路径。xuyuan 的 PHC-X teacher + residual policy 最终合并为 Studio ours 的算法实现;其余 canonical input、full-J articulated scene、reset、common rollout、 evaluator 和 renderer 均复用 Studio,不继续维护独立数据准备或评测路径。

具体迁移时间盒、只读源路径、数值等价 Gate 和夜间 smoke test 见 Shared Studio 夜间迁移

当前范围

CoDA 和 InterMimic 是当前的 articulated Studio baseline。RePHO 只有功能层证据,后续训练暂缓。 PHC-X 仅用于 tracking/evaluation diagnostic。Ours 等训练协议冻结后再纳入;HDMI-SMPL-X 需要单独的 embodiment/simulator protocol,当前不纳入。精确的训练保真证据和实验状态在 Author-Fidelity Plan,不放在本实现页。