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 保存静态任务信息:资产身份、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 直接引用。
唯一的公开读取函数是:
它直接读取固定字段,并拒绝 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 与原版到底差什么¶
InterMimicArticulated 是 InterMimic 的一个 task 子类,不是新算法、不是新 trainer,也不是
Studio 自己写的 policy。它的目的很窄:让原本的 InterMimic 训练器能够在统一的 articulated
object 上运行。
一次运行发生什么¶
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。articulated_scene.py从该 case 的 URDF 建立物体、地面与 static boxes。物体的每个 joint 都真实存在、可碰撞、可被误撞开;不会因为它不是 active joint 就被锁死。backends/intermimic.py向作者intermimic.run传入上面两份输入,并指定 task 名称InterMimicArticulated。训练仍由作者InterMimicAgent完成。- 测试时仍调用作者 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 q、qvel、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¶
- canonical reference 先重采样到 common FPS,再转为 CoDA 原生 control FPS;
- adapter 写全关节 scene、CoDA 所需 fingertip/contact layout 与本 case XML;
- 原始 CoDA
CommonAgent、model、PPO/GAE、buffer、checkpoint 和 player 不变; - 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¶
- 复用 OMOMO human conversion 和共享全关节 scene;
backends/repho.py启动作者的 forward/backward coordinator,而不是另写 trainer;- Studio 只使两个作者 worker 读取 canonical human input 与完整物体 scene;
- 新的 forward 或 backward 作者 player 导出最终 common rollout。
PHC-X¶
phcx_motion.py把 canonical SMPL-X 转为 PHC-X 原生 tracking motion 与 local-axis XML;phcx_input.py准备完整物体 reference/contact,并把 PHC 原生 rollout 转为 common rollout;- 它可以走同一份评测、视频和 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.json、common_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.json 和
result.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/
两台机器都从下列目录启动:
共享运行遵守以下固定规则:
- 两台机器使用各自本地的 Conda 环境。
TORCH_EXTENSIONS_DIR、Python cache 和 adapter 临时目录写入各自机器的/tmp,不能写入共享项目根。- 两台机器可以写同一个 experiment root,但分配的 case 必须互不重叠。
- 每个 case 同一时刻只能由一台机器领取,避免覆盖 checkpoint、日志或最终输出。
- 一轮正式实验启动后冻结 Git commit;队列运行期间不能修改代码,否则后续 case 会使用不同实现。
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,不放在本实现页。