057f4c2cf6
原因:记录 L20 USD 初步校验、严格浮动覆盖层、受限动力学回放及 HDF5 交付契约,包版本更新为 0.1.1。 验证:68 项 CPU/USD 回归测试通过,Ruff/format 与暂存 diff 检查通过;已核验单环境 small 2x480、合成 HDF5 2x960 步明确 PASS。独立暂存审查未发现问题。完整 pre-commit 因模块缺失未执行,干净环境安装未验证。 兼容性:Cartpole 及任务 ID 不变,原始 USD/URDF 未改;旧 prepared 覆盖层需重新生成。仅合成轨迹初步校验,不代表真实专家回放、训练或硬件验收。
92 lines
3.4 KiB
Python
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()
|