Initial snapshot: hand motion pipeline (Dyn-HaMR + dex-retargeting + SPIDER)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
"""Independent narrow-phase contact, coupling, floor and pose verification."""
|
||||
import os
|
||||
os.environ.setdefault('MUJOCO_GL','osmesa')
|
||||
from pathlib import Path
|
||||
import json,xml.etree.ElementTree as E
|
||||
import numpy as np,mujoco
|
||||
OUT=Path(__file__).resolve().parents[1]/'output/l20_full_replay'
|
||||
x=np.load(OUT/'motion.npz');m=mujoco.MjModel.from_xml_path(str(OUT/'scene.xml'));d=mujoco.MjData(m)
|
||||
penetration=[];counts=[];floor_count=0;coupling=0.;limit=0.
|
||||
for row in x['qpos']:
|
||||
d.qpos[:]=row;mujoco.mj_forward(m,d)
|
||||
ds=[]
|
||||
for c in d.contact:
|
||||
types={int(m.geom_contype[c.geom1]),int(m.geom_contype[c.geom2])}
|
||||
if types=={1,2}:ds.append(float(c.dist))
|
||||
if 4 in types:floor_count+=1
|
||||
penetration.append(max(0,-min(ds,default=0)));counts.append(len(ds))
|
||||
for eq in range(m.neq):
|
||||
j1,j2=m.eq_obj1id[eq],m.eq_obj2id[eq];v=row[m.jnt_qposadr[j2]]
|
||||
expected=sum(m.eq_data[eq,k]*v**k for k in range(5))
|
||||
coupling=max(coupling,abs(row[m.jnt_qposadr[j1]]-expected))
|
||||
for j in range(m.njnt):
|
||||
if m.jnt_limited[j]:
|
||||
v=row[m.jnt_qposadr[j]];limit=max(limit,m.jnt_range[j,0]-v,v-m.jnt_range[j,1])
|
||||
r=json.loads((OUT/'validation.json').read_text());r['geom_distance_max_penetration_mm']=float(np.max(x['penetration_m'])*1000)
|
||||
r.update(max_all_penetration_mm=float(max(penetration)*1000),max_holding_penetration_mm=float(max(penetration[160:])*1000),holding_frames_with_contact=int(np.count_nonzero(counts[160:])),holding_frames=len(counts)-160,floor_contacts=floor_count,linear_mimic_max_error_rad=float(coupling),joint_limit_violation_rad=float(limit),contact_verification='mj_forward contact manifold independently checked every frame; geomDistance has isolated inconsistent spikes')
|
||||
(OUT/'validation.json').write_text(json.dumps(r,indent=2));np.savez_compressed(OUT/'contact_verification.npz',penetration_m=penetration,contact_count=counts)
|
||||
assert np.isfinite(x['qpos']).all() and coupling<1e-8 and limit<1e-8 and floor_count==0
|
||||
print(json.dumps(r,indent=2))
|
||||
Reference in New Issue
Block a user