ae28d55f81
Source: RGB-D -> Dyn-HaMR -> L20 retargeting -> FoundationPose -> reference repair -> SPIDER, documented in docs/PIPELINE_LATEST.md and docs/SETUP_AND_WEIGHTS.md. Adds FoundationPose and nvdiffrast upstream snapshots, requirements/pipeline_venv.txt and the FoundationPose weight manifest/downloader. Assets (Git LFS): weights/ (WiLoR detector, HandFlow denoiser, UniDepth-L), FoundationPose checkpoints, HaMeR checkpoint, Dyn-HaMR HMP model and BMC constraints, L20 URDF/meshes, the 20260915_171525 D405 recording and the two box CADs. MANO models are not redistributed (third_party/hamer/_DATA/data/mano/README.txt). Environments, caches and run outputs excluded. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
35 lines
1.9 KiB
Python
35 lines
1.9 KiB
Python
"""Audit filtered/projected reference for table and hand-object penetration."""
|
|
from pathlib import Path
|
|
import json
|
|
import numpy as np
|
|
import mujoco
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
O = ROOT / "output/desktop_smooth_fix_20260915"
|
|
z = np.load(O / "reference_video_rate.npz")
|
|
m = mujoco.MjModel.from_xml_path(str(O / "scene_act.xml")); d = mujoco.MjData(m)
|
|
floor = next(i for i in range(m.ngeom) if "_floor" in (m.geom(i).name or ""))
|
|
floor_z = float(m.geom_pos[floor][2])
|
|
result = {"frames": len(z["qpos"]), "floor_z_m": floor_z, "max_table_penetration_mm": 0.0,
|
|
"max_hand_object_penetration_mm": 0.0, "frames_table_over_0_5mm": 0,
|
|
"frames_hand_object_over_0_5mm": 0}
|
|
for row in z["qpos"]:
|
|
d.qpos[:] = row; mujoco.mj_forward(m, d)
|
|
floor_min = {"right": 1.0, "left": 1.0}
|
|
for g in range(m.ngeom):
|
|
n = m.geom(g).name or ""
|
|
if not n.startswith(("right_", "left_")) or m.geom_dataid[g] < 0:
|
|
continue
|
|
side = n.split("_")[0]; mid = int(m.geom_dataid[g]); a = int(m.mesh_vertadr[mid]); b = a + int(m.mesh_vertnum[mid])
|
|
v = m.mesh_vert[a:b: max(1, (b-a)//128)]
|
|
world = v @ d.geom_xmat[g].reshape(3,3).T + d.geom_xpos[g]
|
|
floor_min[side] = min(floor_min[side], float(world[:,2].min()-floor_z))
|
|
tp = max(0.0, -min(floor_min.values())) * 1000
|
|
hp = 0.0
|
|
for c in d.contact:
|
|
a,b = int(c.geom[0]), int(c.geom[1]); ta,tb = int(m.geom_contype[a]),int(m.geom_contype[b])
|
|
if {ta,tb} == {1,2}: hp = max(hp, max(0.0,-float(c.dist))*1000)
|
|
result["max_table_penetration_mm"] = max(result["max_table_penetration_mm"],tp); result["max_hand_object_penetration_mm"] = max(result["max_hand_object_penetration_mm"],hp)
|
|
result["frames_table_over_0_5mm"] += tp > .5; result["frames_hand_object_over_0_5mm"] += hp > .5
|
|
(O/"smoothing_table_validation.json").write_text(json.dumps(result,indent=2)); print(json.dumps(result,indent=2))
|