跳转至

PhysHSI Refiner 当前进展交接 2026-06-12

这份文档记录当前 src/refiner/ 里已经打通的 MVP 链路、可复现实验路径、可视化方式、已知问题和下一步计划。这里的 Kimodo 指当前使用的 motion generation 模块,口头讨论里有时会说成 KeyModel。

1. 当前目标

我们现在不是在做完整研究版 refiner,而是在打通一个可迭代的 physics-aware refinement 框架:

  1. 用 Kimodo 生成或读取 human-object interaction motion。
  2. 把 Kimodo motion 转成 ProtoMotions tracker 可用的 tracker_motion.motion
  3. 用 ProtoMotions / Isaac Lab 的 pretrained tracker 作为 base checkpoint 跑 tracking。
  4. 后续在 tracker 结果上训练一个 residual policy,让 policy 在物理场景里修正 reference motion 或 tracking 行为。
  5. 每个 case 都能产出左右拼接可视化:左边 Kimodo reference,右边 ProtoMotions tracking result。

目前代码已经打通的是 MVP 框架和若干 smoke / diagnostic case。真正的 physics residual training 还没有开始。

2. 主要代码路径

核心代码都在:

src/refiner/

主要模块:

src/refiner/convert.py
src/refiner/tracker.py
src/refiner/physics_scene.py
src/refiner/pipeline.py
src/refiner/legacy/
tools/refiner/visualize_mesh_compare.py
tools/refiner/legacy_visualize_mesh_compare.py

辅助 tracking / replay 代码:

utils/tracking_adapters/protomotions/run_isaaclab_tracking.py
utils/tracking_adapters/common/render_isaacsim_trace.py
utils/tracking_adapters/phcx/render_isaacsim_replay.py

本次新增或重点使用的能力:

  • convert.py:把 HSI SMPLX-22 motion 转成 ProtoMotions tracker motion。
  • tracker.py:直接跑 ProtoMotions / Isaac Lab tracking。
  • physics_scene.py:从 HSI motion + SAGE layout 构建 physics scene proxy,并做坐标残差 sanity check。
  • pipeline.py:单次 tracking 数据流:motion -> tracker motion -> physics scene -> rollout。
  • src/refiner/legacy/:旧 refiner case、prior dataset、offline debug training / rollout。
  • visualize_mesh_compare.py:direct motion/trace 左右拼接 mesh 可视化。
  • legacy_visualize_mesh_compare.py:旧 case/manifest 可视化入口。
  • render_isaacsim_replay.py:新增 camera-direction-source=source_heading,让右侧 tracker replay 使用 Kimodo global_root_heading 对齐左侧 Kimodo camera。

3. Body Format 和 Converter 设计

现在 converter 是显式按 body format 配置的,后面换 SMPLX / SOMA 不需要改 data loader 或 train 入口。

当前支持:

source_skeleton=soma77  -> tracker_backend=soma23
source_skeleton=smplx22 -> tracker_backend=smpl

预留但未实现:

source_skeleton=smplx52 -> tracker_backend=smplx

对应代码在 src/refiner/convert.py

  • Soma77ToSoma23Converter
  • Smplx22ToSmplConverter
  • Smplx52ToSmplxConverter 目前是 placeholder,会直接 NotImplementedError

注意事项:

  • 不允许把历史 22-joint debug seed motion 当作 canonical SOMA motion。
  • SOMA 路径必须重新生成 Kimodo-SOMA77 motion,再转成 ProtoMotions soma23。
  • SMPLX22 路径目前是把 Kimodo body-only 22-joint SMPLX motion 转成 ProtoMotions SMPL tracker motion。
  • 代码里没有 subprocess fallback 去调用 ProtoMotions converter;优先路径是直接 import submodule 里的 ProtoMotions / Kimodo converter 代码。

4. 数据根目录

SOMA 12-case MVP:

data/refiner/prior/
data/refiner/prior/cases/case_sit_mvp_0001
...
data/refiner/prior/cases/case_sit_mvp_0012

SMPLX22 -> SMPL 的 12-case 版本:

data/refiner/prior_smpl/
data/refiner/prior_smpl/cases/case_sit_mvp_0001
...
data/refiner/prior_smpl/cases/case_sit_mvp_0012

Tray best diagnostic case:

data/refiner/tray_best_smpl/cases/case_tray_best_20260605

Tray case 的原始 Kimodo best motion 来自:

output/auto_experiments/20260605_kimodo_hand_generalization_rot050_cw2/hoi_889a0ed0_tight_pick_place__default/motion_augmented_hands.npz

Tray case 是为了调试 bending / pick-place / physics tracking,不是当前 train loader 的标准 12-case 数据集。它的 object.pkl 是动态物体轨迹风格,和 sit-MVP loader 要求的静态 quat_w schema 不完全一致。

5. 常用环境

仓库根目录:

cd /mnt/data/PhysHSI

ProtoMotions / Isaac Lab tracking 和 Isaac replay 默认使用:

/mnt/data/PhysHSI/env_protomotions_isaaclab/bin/python

关键 submodule:

submodules/ProtoMotions
submodules/kimodo

Kimodo / offline render 有时需要显式设置:

export PYTHONPATH=/mnt/data/PhysHSI/submodules/kimodo:/mnt/data/PhysHSI:$PYTHONPATH

如果需要跑 Kimodo generation,可以通过 --kimodo-command 指定 Kimodo 所在 Python,例如 conda 的 isaac-sim 环境。具体命令按机器环境调整。

GPU / Isaac Lab 命令通常需要在有 GPU 可见的环境里运行;在 Codex sandbox 里可能看不到 GPU,需要用非 sandbox / approved GPU execution。

6. 生成和转换 Case

SOMA 12-case MVP 的目标命令形态:

/mnt/data/PhysHSI/env_protomotions_isaaclab/bin/python -m src.refiner.legacy.convert_prior \
  --preset sit_mvp_12 \
  --source-skeleton soma77 \
  --backend soma23 \
  --generate-soma \
  --out data/refiner/prior \
  --target-fps 30 \
  --skip-existing-complete

SMPLX22 -> SMPL 的 12-case 转换:

/mnt/data/PhysHSI/env_protomotions_isaaclab/bin/python -m src.refiner.legacy.convert_prior \
  --preset sit_mvp_12 \
  --source-skeleton smplx22 \
  --backend smpl \
  --out data/refiner/prior_smpl \
  --target-fps 30 \
  --skip-existing-complete

每个 case 目录核心产物:

manifest.json
motion.npz
tracker_motion.motion
object.pkl
contact.npy
task_plan.json
task_validation.json
scene_context.json

motion.npz 是 Kimodo canonical motion;tracker_motion.motion 是 ProtoMotions tracker reference。

7. Data Loader Smoke

SOMA 12-case:

python -m src.refiner.legacy.data --data-root data/refiner/prior --split train

当前通过,输出示例:

{
  "num_cases": 12,
  "max_T": 413
}

SMPLX 12-case:

python -m src.refiner.legacy.data --data-root data/refiner/prior_smpl --split train

当前通过,输出示例:

{
  "num_cases": 12,
  "max_T": 304
}

8. Tracking

统一入口:

/mnt/data/PhysHSI/env_protomotions_isaaclab/bin/python -m src.refiner.legacy.tracker_case \
  --data-root data/refiner/prior_smpl \
  --case-id case_sit_mvp_0010 \
  --scene-mode none \
  --out output/refiner_tracking_debug/case_sit_mvp_0010_none

旧 case runner 带 physics scene:

/mnt/data/PhysHSI/env_protomotions_isaaclab/bin/python -m src.refiner.legacy.tracker_case \
  --data-root data/refiner/prior_smpl \
  --case-id case_sit_mvp_0010 \
  --scene-mode physics \
  --physics-object-source all \
  --out output/refiner_tracking_debug/case_sit_mvp_0010_physics

--scene-mode none 表示不加载 physics objects,只测试 tracker 本身。

这里的 --physics-object-source 是 legacy case runner 参数;新的 direct 入口 tools/run_refiner_tracking.py 不暴露这个开关。

--scene-mode physics 会通过 legacy case runner 调用新的直接 physics scene API 生成:

physics_scene/scene.pt
physics_scene/scene.json

然后把这个 scene 交给 ProtoMotions / Isaac Lab tracker。这个模式才是真正会发生物理交互和碰撞影响的模式。

默认 checkpoint 在:

submodules/ProtoMotions/data/pretrained_models/motion_tracker/soma-bones/last.ckpt
submodules/ProtoMotions/data/pretrained_models/motion_tracker/smpl/last.ckpt

9. Residual Policy 框架

当前已经搭了最小训练和 rollout 框架,但还没有做真正 physics-in-the-loop residual training。

当前 train.py 是 offline debug proxy,只用于检查 loader、policy、reward、optimizer plumbing:

python -m src.refiner.legacy.train \
  --data-root data/refiner/prior \
  --scene-mode none \
  --out output/refiner_debug_train \
  --steps 16 \
  --batch-size 32

重要限制:

train.py --scene-mode physics

目前会直接 NotImplementedError。这是故意的,避免误以为已经在 Isaac Lab 里训练 residual policy。

reward.py 目前包括这些最小项:

  • tracking root error
  • contact hint / object distance
  • floor penalty
  • fall penalty
  • residual regularization

这些 reward 都只是 MVP 起点,后面需要根据真实 physics training 调。

rollout exporter:

python -m src.refiner.legacy.rollout \
  --data-root data/refiner/prior \
  --ckpt output/refiner_debug_train/checkpoints/latest.pt \
  --out output/refiner_debug_rollout \
  --overwrite

当前 rollout 是把 offline residual 加回 root_positions 并导出,不等价于真实 physics rollout。

10. 可视化

Direct tracking + render 入口:

PYTHONPATH=/mnt/data/PhysHSI /mnt/data/PhysHSI/env_protomotions_isaaclab/bin/python tools/run_refiner_tracking.py \
  --motion output/auto_experiments/20260710_hsi_generation_handoff_left_rerun/motion.npz \
  --layout-json data/selected_SAGE10k/e2e_test_scenes/2cdc81db/layout_2cdc81db.json \
  --out-dir output/refiner_tracking_direct_example \
  --render \
  --force

Direct 左右拼接 mesh 可视化入口:

PYTHONPATH=/mnt/data/PhysHSI /mnt/data/PhysHSI/env_protomotions_isaaclab/bin/python tools/refiner/visualize_mesh_compare.py \
  --source-motion output/auto_experiments/20260710_hsi_generation_handoff_left_rerun/motion.npz \
  --kinematic-video output/auto_experiments/20260710_hsi_generation_handoff_left_rerun/kinematic_video.mp4 \
  --trace output/refiner_tracking_direct_example/rollout_trace.npz \
  --layout-json data/selected_SAGE10k/e2e_test_scenes/2cdc81db/layout_2cdc81db.json \
  --scene-origin-xy 1.0 1.9 \
  --out-dir output/refiner_tracking_direct_example/visual \
  --with-scene \
  --force

旧 case/manifest 可视化仍在 tools/refiner/legacy_visualize_mesh_compare.py,但不属于新的 direct tracking 流程;新验证默认只用上面的 direct 入口。

输出含义:

  • kinematic_video.mp4:HSI generation 生成的运动学视频。
  • tracked_video.mp4:ProtoMotions / Isaac replay 后的 tracking 视频。
  • tracking_comparison.mp4:左侧 kinematic_video.mp4,右侧 tracked_video.mp4
  • --with-scene:tracking 视频叠 SAGE scene;scene 默认 opaque,显示完整 objects。

Camera 对齐注意:

  • 右侧 tracker replay 不应该用 reference trajectory direction,否则 camera 会跟着轨迹方向乱转。
  • direct 可视化默认读取 Kimodo motion.npz:global_root_heading,并按 body format 转到 tracker 坐标系。
  • SMPLX22 当前使用 smplx22_to_tracker,SOMA 使用 soma77_to_tracker

旧 tray 视频只作为历史诊断记录,不作为当前 direct tracking 命名规范。

11. Tray Best Diagnostic 结果

Tray best case:

case_tray_best_20260605

Tracking 输出:

output/refiner_tray_best_smpl_tracking_none/case_tray_best_20260605
output/refiner_tray_best_smpl_tracking_physics/case_tray_best_20260605

当前观察:

  • scene-mode none:tracking 还能跟住,mean body error 约 0.119m
  • scene-mode physics:humanoid 后面明显摔倒,mean body error 约 1.477m,max body error 约 3.43m

这说明摔倒不是可视化相机导致的,而是已经在 physics tracking trace 里发生了。重新渲相机只是把问题看清楚。

12. 已知问题

12.1 Kimodo motion 本身可能有穿模或不物理

如果 Kimodo reference 已经有 body-object penetration、脚底穿地、身体和椅子/床/桌面冲突,那么 scene-mode physics 下 tracker 很容易被 collision 推开,最后直接摔倒。

这类问题需要先检查 Kimodo kinematic motion 本身,而不是只调 tracker。

建议检查:

  • root height / body min height
  • hand/object penetration
  • pelvis/seat penetration
  • feet/floor contact
  • dynamic object 和 static scene 的初始对齐

12.2 弯腰捡物体 case 有突然转弯

Tray best case 里有一段 bend / pick / turn / carry 的 motion。现在看到的问题是:reference 里存在比较突然的转向或姿态变化,physics tracking 在这个阶段容易失稳,然后后续摔倒。

这个问题可能来自:

  • Kimodo root heading 或 root path 变化太激烈。
  • 参考轨迹和实际 scene collision 不兼容。
  • Tracker checkpoint 本身没有见过类似 bending + object carrying + narrow scene collision 的组合。

12.3 SOMA generation 仍需要继续排查

我们已经预留并打通了 SOMA77 -> ProtoMotions soma23 的代码路径,但之前遇到过 Kimodo-SOMA 生成质量不稳定的问题。尤其要注意:

  • 不能把 22-joint seed motion 当 canonical SOMA motion。
  • 必须检查生成出的 SOMA77 motion.npz 是否确实是 [T,77,...]
  • 需要先做 kinematic visualization,再做 tracker。
  • 如果 reference 本身已经倒地或高度异常,converter 会 fail fast,不应该生成半成品。

13. 下一步建议

短期建议:

  1. 继续用 SMPLX22 -> SMPL 路径做几条稳定 diagnostic case,因为这条线现在更容易和 ProtoMotions SMPL tracker 对上。
  2. 对 tray / pick-place case 做 reference quality audit,先定位 Kimodo motion 的 sudden turn、穿模、接触不连续在哪里发生。
  3. 对 none 和 physics tracking 同时输出 source-heading camera 的 side-by-side video,避免 camera 旋转误导判断。
  4. 重新尝试 SOMA generation,但每条先过 raw kinematic gate 和 mesh visualization,再转 soma23。

中期建议:

  1. train.py --scene-mode physics 接到真正 Isaac Lab / ProtoMotions environment,而不是当前 offline proxy。
  2. Reward 从当前 MVP 项扩展到:
  3. full-body tracking
  4. foot contact / slip
  5. object contact
  6. penetration penalty
  7. fall termination
  8. residual smoothness
  9. 为每个 case 固化一个标准 report:
  10. Kimodo source video
  11. tracker none video
  12. tracker physics video
  13. metrics json
  14. root/body height plot
  15. scene coordinate residual

长期建议:

  1. 比较 Kimodo-SMPLX22 -> ProtoMotions SMPLKimodo-SOMA77 -> ProtoMotions soma23 哪条更稳。
  2. 如果 SOMA tracker 在坐标、body model、contact 上更自然,可以把 SOMA 作为主线。
  3. 如果 SMPL tracker 更稳,则继续补 SMPLX hand/object 信息和 scene-aware correction。
  4. 真正 refiner policy 应该在 physics scene 中训练,而不是只对 kinematic root 做 residual。

14. 给合作者的快速理解

一句话版本:

我们现在已经把 Kimodo motion -> ProtoMotions tracker -> Isaac Lab tracking -> side-by-side visualization -> residual policy debug training 这条工程链路搭起来了。当前最重要的问题不是代码入口,而是 reference motion 和 physics scene 的物理一致性:一旦 Kimodo 轨迹本身穿模、突然转向或与物体对不齐,physics tracker 会被 collision 打飞。下一步应该先稳定 reference 质量和 body format,再接真正 physics residual training。