Files

33 lines
2.4 KiB
Python

"""Validate full registered trajectory and decode both deliverable videos."""
import json, subprocess
import numpy as np
from l20_calibrated import Calibration, ROOT
out=ROOT/'output/l20_2047635068/bottle_grasp'
m=np.load(out/'registered_motion.npz'); c=Calibration()
names=list(m['joint_names']); q=m['qpos']
limits=np.array([c.urdf_limits[n] for n in names])
coupling=max(float(np.max(np.abs(q[:,names.index(n)]-np.interp(q[:,names.index(a)],x,y)))) for n,(a,x,y) in c.curves.items())
report=dict(frames=len(q),finite=all(bool(np.isfinite(m[k]).all()) for k in ['qpos','wrist_pos','wrist_quat_wxyz','bottle_pos','bottle_quat_wxyz']),
limit_violations=int(np.sum((q<limits[:,0]-1e-8)|(q>limits[:,1]+1e-8))),
max_passive_coupling_error_rad=coupling,
max_penetration_mm=float(m['penetration_m'].max()*1000),
frames_above_1_5_mm=int(np.sum(m['penetration_m']>.0015)),
wrist_axis_range_m=np.ptp(m['wrist_pos'],axis=0).tolist(),
max_joint_step_rad=float(np.abs(np.diff(q,axis=0)).max()),
frames_with_joint_step_above_0_2_rad=int(np.sum(np.max(np.abs(np.diff(q,axis=0)),axis=1)>.2)),
max_wrist_step_m=float(np.linalg.norm(np.diff(m['wrist_pos'],axis=0),axis=1).max()),
max_command_quantization_error_rad=float(np.max(np.abs(np.array([c.decode(cmd,names) for cmd in m['command_u8']])-q))),videos={})
for filename,expected in [('contact_registration.mp4',len(q)),('physics_test.mp4',len(np.load(out/'physics_motion.npz')['qpos']))]:
path=out/filename
probe=json.loads(subprocess.check_output(['ffprobe','-v','error','-count_frames','-select_streams','v:0','-show_entries','stream=width,height,nb_read_frames,r_frame_rate','-of','json',str(path)]))['streams'][0]
subprocess.run(['ffmpeg','-v','error','-i',str(path),'-f','null','-'],check=True)
assert int(probe['nb_read_frames'])==expected
report['videos'][filename]=dict(probe,full_decode_passed=True)
report['geometry_checks_passed']=report['finite'] and report['limit_violations']==0 and coupling<1e-8 and report['frames_above_1_5_mm']==0
report['physical_retention_passed']=json.loads((out/'physics_validation.json').read_text())['retained']
report['execution_ready']=False
report['execution_limitations']=['Local pose jumps remain; no joint velocity constrained optimization','Free object retention test failed','Object trajectory is an inferred registration target']
(out/'delivery_validation.json').write_text(json.dumps(report,indent=2))
print(json.dumps(report,indent=2))