LabUtopia EBench

Teaching Note · USD Physics · DryingBox

为什么一个门会让 open_door 变难

这篇页面给产品经理和评测侧解释:USD articulation 不是普通模型导入,它同时包含层级、刚体、关节、驱动、材质和运行期状态。我们遇到的 DryingBox 问题,本质是“一个看起来像门的资产,进入 Isaac runtime 后没有成为一个稳定、可读、可评的门”。

Articulation Root: obj_obj_DryingBox_01
Joint: RevoluteJoint
Handle path: /handle

一句话结论

Before

旧门不是稳定任务对象

旧图只看到黑箱角,门板、把手、铰链和动作点不可读;运行期还出现过 joint position ~= 1.573e13 这类异常状态。

Root Cause

USD 层级和 PhysX articulation 不干净

门是 articulated object,不是普通 mesh。ArticulationRootAPIRigidBodyAPIJointbody0/body1scalehandle 层级都要同时正确。

P1 Baseline

用 sanitized surrogate 先锁定链路

P1 先用稳定的 DryingBox sanitized_surrogate 做对照基线:固定底座、只保留一个 RevoluteJoint、把门回放到 [0.0]、把手保留在内部 /handle 路径。这证明 EBench 读图和关节读数链路能跑,但还不等于原生复杂资产已经调通。

硬约束:最终必须调通 LabUtopia 原生复杂 DryingBox

这次不是继续把 cube-based surrogate 打磨得更像,而是让 LabUtopia native complex DryingBox_01 本体进入 EBench:保留原生 mesh、材质、层级身份和内部 /handle,只在必要时用 additive physics override 补齐 Isaac runtime 需要的稳定物理属性。2026-06-24 P2 已完成 Franka POC gate:native visual/hierarchy/handle 保留,EBench readback 可见,native_complex_dryingbox_ready=true

层级 必须保留 允许覆盖 不允许
Native visual 原生 DryingBox 的门板、框架、把手、真实 mesh 和 material identity。 少量 displayColor 或 material binding 只用于 eval readback 可读性。 不把干燥箱替换成 Cube 拼出来的假箱体作为最终资产。
Native hierarchy /World/DryingBox_01 的内部树和 nested /handle 语义。 在 EBench wrapper 下增加诊断 metadata、object map 和 bbox contract。 不把 handle 拆成 top-level duplicate object。
Additive physics override 原生资产仍然是任务对象和视觉对象。 mass/inertia、修 body0/body1、固定 base、校正 reset target、隔离非任务 DOF。 不把物理稳定性问题通过换简化几何体绕过去。
Eval camera 使用 evaluator readback 作为证据路径。 任务相机、任务级隐藏和对比度增强可调整。 不把展示图、viewer 截图或漂亮图说成 baseline 成绩。
PM 版一句话:不是“换个假箱子”,而是“把原箱子搬进 EBench,再给它补上评测需要的稳定合页、复位规则和状态读回”。
Current Evidence
native_complex_dryingbox_ready=true
P2 native readback
Native Gate
task_render_accepted=true
Franka POC passed
Still False
official_baseline_evaluable=false
Lift2 gate pending
Native evidence Path SHA256
asset audit saved/diagnostics/native_dryingbox_audit_20260624_091136/audit.json e6eab4a6fc6a6b3ddddbabc2717a674c606c83255467db8b97bfbdac085aad4d
native-only smoke saved/diagnostics/native_dryingbox_smoke_20260624_091152/smoke.json fdab719564440d8528623785b55662acb38b74cf607d249dce963885082664a4
EBench readback saved/diagnostics/native_dryingbox_open_door_eval_explicit_20260624_093156/diagnostics.json f28451fe121e43ac48c2e4b25ce28dfe395ee09e570318017c45cdfb2257225e

先把基础讲清楚:什么是 USD articulation

USD 不是单个模型文件

USD 更像一个“可组合的场景数据库”。一个最终场景通常由很多 layerreferencepayload 和 override 合成。产品上看到的是一个门,工程上看到的是一棵 prim hierarchy 加很多属性。

这也是为什么“资产加载成功”不等于“评测可用”:mesh 可能出现了,但坐标、材质、物理、关节、相机读取任一环节不对,任务图就可能不可读。

Articulation 是带关节的刚体系统

UsdPhysics / PhysX 里,articulation 由多个 rigid links 和 joints 组成。joint position 是每个 DOF 的状态;如果是旋转轴,它就是弧度角。

门最小可用结构可以理解成:箱体是固定 base,门板是一个 link,门板和箱体之间有一个 RevoluteJoint,把手应该挂在门板上。

Root
ArticulationRootAPI
Base
PhysicsFixedJoint
Door DOF
RevoluteJoint
Reset Target
[0.0]
对产品经理的比喻:普通 mesh 像一块静态道具;USD articulation 像一个带合页、门轴、限位、质量和物理状态的舞台机关。道具放进场景只要位置对;机关还必须能稳定转、能复位、能被相机看清。

互动:切换失败模式,看门为什么会坏

下面这个小动画不是 Isaac 渲染结果,而是用于教学的结构示意。切换按钮可以看到我们这次实际排查过的几类风险。

Root scale: [1,1,1]
Joint state: 0.0 rad
Nested handle: /World/.../obj_obj_DryingBox_01/handle
Baseline

P1 对照基线:稳定、可读、可验证

当前正式诊断里,surrogate DryingBox 只暴露 RevoluteJointjoint_positions=[0.0]runtime_physics_stable=true。门板、框架和细橙色把手都在同一张 camera2 readback 图里。这是 native 接入的对照组,不是 native 完成证明。

门角度演示 28 deg

七步走:原生复杂 DryingBox 应该怎么调通

下面是实施路线和当前进度。前五步已经有 evidence:asset audit、native-only Isaac smoke、EBench wrapper、additive physics overrideopen_door eval readback 都已通过;第六步是把证据写进教程和周报;第七步才进入 Lift2 baseline gate。不能把本地 POC PASS 当作官方 Lift2 baseline PASS。

Gate 1

Asset audit:先看清原生资产到底长什么样

只读打开 LabUtopia 原始 /World/DryingBox_01,导出 prim tree、ArticulationRootAPI、所有 RigidBodyAPI、所有 Jointbody0/body1、root scalemass/inertiacenterOfMassprincipalAxes、handle path 和 material binding。

通过标准:拿到 JSON 报告和 USD hash,能明确 native 风险点,而不是靠猜。

我们这次遇到的门问题

问题 产品侧表现 工程侧原因 风险
旧图只看到黑箱角 看不出门在哪里,也看不出要抓哪个把手。 camera2 构图、任务对象显隐、LabUtopia 坐标归一都还没收敛。 PM 无法判断任务是否成立,评测侧也无法把它当作有效视觉证据。
joint position 爆值 门状态不可解释,reset 后可能不是可评的关闭态。 原始 DryingBox 的 USD physics topology 对 Isaac runtime 不稳定,出现过 1.573e13 量级关节读数和 PhysX transform warning 策略还没开始评,场景状态已经不可信。
把手像独立物体 把手位置异常,或者中间版本变成一大片橙色面板。 把手原本应该是 DryingBox 内部子路径 /handle,但导入/封装时曾出现 top-level duplicate 或过大 display marker。 动作点不可读,视觉 QA 会把图判为 WARN 或 FAIL。
原生材质/结构不等于 eval 可读 原生视角可能更像 LabUtopia,但不一定能让任务目标清楚。 P1 目标是 eval-path evidence,所以用了任务专用 camera2、任务级隐藏和高对比 displayColor 如果混淆“展示图”和“评测图”,会误判当前 readiness。

P1 已做什么:从爆值风险到稳定 sanitized_surrogate 对照组

/World/labutopia_level1_poc/obj_obj_DryingBox_01
PhysicsArticulationRootAPI, root scale [1,1,1]
Root
body_link
fixed base, mass and inertia are finite
Base
door_link
connected by RevoluteJoint, reset target [0.0]
Door
/handle
nested under DryingBox, fixed to door_link, scale [0.045,0.075,0.25]
Handle

关键策略

  • P1 先不让不稳定的原始复杂 articulation 直接进入正式评测,而是生成 DryingBox sanitized_surrogate 做可控对照组。
  • BaseFixedJoint 把箱体固定住,避免整个干燥箱在物理里漂移。
  • 只保留一个明确的 RevoluteJoint,让门的状态可以用一个角度解释。
  • 在 reset 后回放 target_positions=[0.0],保证任务从关闭态开始。
  • handle 保持为 DryingBox 内部子部件,而不是 top-level object。
  • 给门板、门缝、把手加 displayColor 和 material binding,让 camera2 读图可解释。

代码层证据

root: /World/labutopia_level1_poc/obj_obj_DryingBox_01
joint: RevoluteJoint
target_positions: [0.0]
handle: /World/labutopia_level1_poc/obj_obj_DryingBox_01/handle
runtime_joint_positions: [0.0]
runtime_physics_stable: true
task_render_accepted: true
official_baseline_evaluable: false

可读性结果

P1 图不是为了还原 LabUtopia 原生 viewer,而是为了证明 evaluator 能看到任务:门板、框架、细橙色把手在同一张图里;render_validation 能检测到 obj_DryingBox_01obj_DryingBox_01_handle 的 bbox 尺寸达标。

P2 已用 native complex DryingBox_01 重新跑过 asset audit、Isaac smoke 和 EBench readback gate。当前边界是:native_complex_dryingbox_ready=truetask_render_accepted=true,但 official_baseline_evaluable=false

Claim Boundary:三件事不能混在一起

Claim 现在可以说 现在不能说
Task render Franka POC 三任务 eval readback 非黑,P1 surrogate baseline 中 render_validation.passed=truetask_render_accepted=true;P2 native DryingBox readback 同样通过任务证据门禁。 不能说策略已经求解成功;当前 smoke 默认动作分数仍是 0.0
Native asset 可以说 LabUtopia native complex DryingBox_01 已通过 Franka POC native gate:mesh、材质、层级和 nested handle 保留,只做必要的 additive physics override 不能说 P2 readback 就是 LabUtopia viewer 原生视角,也不能把它说成官方 Lift2 baseline 成绩。
Official Lift2 baseline 后续需要验证 Lift2 复合资产根目录和官方 runner gate。 不能说官方 Lift2 baseline 已经可评、已执行或已有官方成绩。

旧图和最终图怎么读

Old open door failed render
旧图:只看到黑色箱体角,门板、把手、铰链和动作点都不明确。
Current open door evaluator readback
P1 eval readback:正面可见 DryingBox frame、door panel 和 thin orange handle;正式诊断里 render_validation.passed=true。这张图是 surrogate baseline 证据,不是 native complex DryingBox 调通证据。
Native complex DryingBox evaluator readback
P2 native readback:回到 LabUtopia native complex DryingBox_01,原生箱体和 nested handle 在 EBench evaluator camera 中可见;正式诊断里 native_complex_dryingbox_ready=truetask_render_accepted=true

资料来源和我们如何使用

中文解释是面向 PM 的二次整理;英文术语保留原样,便于工程和论文阅读时对齐官方文档。

OpenUSD Introduction 用于解释 USD compositionlayerreference 和 scene graph 不是单个模型文件。
UsdPhysics Schema 用于说明 UsdPhysics 是 USD 中表达 physics simulation representation 的 schema 集合。
UsdPhysicsArticulationRootAPI 用于解释 ArticulationRootAPI 标记 reduced-coordinate articulation subtree,以及 fixed-base root 的放置规则。
UsdPhysicsJoint 用于解释 Joint 如何约束两个 rigid bodies,或约束 rigid body 与 world。
Omni Physics Articulations 用于对齐 Isaac/Omniverse 对 USD hierarchy、fixed-base articulation 和 root API 的实践要求。
PhysX Articulations 用于解释 reduced-coordinate articulation 维护 joint positions / velocities / accelerations,旋转轴 joint position 是 radians。
NVIDIA OpenUSD for Developers 用于 PM 口径解释 OpenUSD 是建模、分类、组合多数据源的生态,不只是文件格式。
AOUSD Explainer: What Is OpenUSD? 用于补充 layeringcomposition 和协作式资产组织的非官方解读。

项目证据来自 saved/diagnostics/labutopia_p1_gate_open_door_formal_20260624_0002/diagnostics.jsonsaved/diagnostics/native_dryingbox_open_door_eval_explicit_20260624_093156/diagnostics.jsonstandalone_tools/labutopia_poc/build_asset_overlay.py 和周报 evidence manifest。