Files
chenlin 057f4c2cf6 chore(release): v0.1.1 USD文件初步校验
原因:记录 L20 USD 初步校验、严格浮动覆盖层、受限动力学回放及 HDF5 交付契约,包版本更新为 0.1.1。

验证:68 项 CPU/USD 回归测试通过,Ruff/format 与暂存 diff 检查通过;已核验单环境 small 2x480、合成 HDF5 2x960 步明确 PASS。独立暂存审查未发现问题。完整 pre-commit 因模块缺失未执行,干净环境安装未验证。

兼容性:Cartpole 及任务 ID 不变,原始 USD/URDF 未改;旧 prepared 覆盖层需重新生成。仅合成轨迹初步校验,不代表真实专家回放、训练或硬件验收。
2026-09-11 15:12:39 +08:00

92 lines
3.4 KiB
Python

"""Isaac Lab scene-loading diagnostic ONLY: no physics steps, actuators, or replay.
Run headless with an external timeout. This legacy topology diagnostic deliberately
performs no dynamic experiment (see track_l20.py for the experimental path). Create a disposable
floating overlay first; this script never edits/saves USD layers or existing scenes.
"""
import argparse
import json
import random
import traceback
from pathlib import Path
def main():
from isaaclab.app import AppLauncher
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("asset", type=Path, help="Diagnostic floating overlay, not the fixed preview")
AppLauncher.add_app_launcher_args(parser)
parser.set_defaults(headless=True)
args = parser.parse_args()
asset = args.asset.resolve(strict=True)
# USD inspection imports pxr: defer it until Kit has initialized its libraries.
launcher = AppLauncher(args)
app = launcher.app
exit_code = 0
try:
import numpy as np
import torch
from dex_workbench_tracking.asset import inspect
manifest = inspect(asset)
if manifest["world_fixed_joints"] or manifest["articulation_roots"] != [manifest["root_body_path"]]:
parser.error("Expected a floating diagnostic overlay; use dex_workbench_tracking.asset first")
from pxr import UsdGeom, UsdPhysics
import isaaclab.sim as sim_utils
random.seed(42)
np.random.seed(42)
torch.manual_seed(42)
sim = sim_utils.SimulationContext(sim_utils.SimulationCfg(dt=1 / 240, device=args.device))
spawn = sim_utils.UsdFileCfg(usd_path=str(asset))
spawn.func("/World/Hand", spawn)
stage = sim.stage
roots, joint_names = [], []
for prim in stage.Traverse():
if not str(prim.GetPath()).startswith("/World/Hand/"):
continue
if prim.HasAPI(UsdPhysics.ArticulationRootAPI):
roots.append(str(prim.GetPath()))
if prim.IsA(UsdPhysics.RevoluteJoint):
joint_names.append(prim.GetName())
if prim.HasAPI(UsdPhysics.RigidBodyAPI):
matrix = UsdGeom.XformCache().GetLocalToWorldTransform(prim)
if not np.isfinite(np.asarray(matrix)).all():
raise AssertionError(f"Nonfinite initial body transform: {prim.GetPath()}")
expected = "/World/Hand" + manifest["root_body_path"][len(manifest["default_prim"]) :]
assert roots == [expected], (roots, expected)
assert sorted(joint_names) == [joint["name"] for joint in manifest["joints"]]
assert not stage.GetCompositionErrors(), stage.GetCompositionErrors()
print(
json.dumps(
{
"status": "PASS",
"check": "Isaac_Lab_scene_loading_only",
"seed": 42,
"num_envs": 1,
"physics_steps": 0,
"root": expected,
"joints": len(joint_names),
"dynamic_replay": "BLOCKED",
"reset_and_tracking_metrics": "NOT_RUN",
}
),
flush=True,
)
except BaseException:
exit_code = 1
traceback.print_exc()
raise
finally:
# No SimulationContext.reset()/step(): even passive dynamics are unvalidated.
app.close(exit_code=exit_code)
if __name__ == "__main__":
main()