"""Explicit offline smoothing ablation, preserving calibration and moving wrist.""" import json,shutil import numpy as np import mujoco from scipy.ndimage import gaussian_filter1d from scipy.spatial.transform import Rotation from l20_calibrated import ROOT,Calibration base=ROOT/'output/l20_2047635068/jitter_audit';out=base/'temporal';out.mkdir(exist_ok=True) m=dict(np.load(base/'corrected/motion.npz'));cal=Calibration();names=list(m['joint_names']) sigma=2.5 a=gaussian_filter1d(m['active_qpos'],sigma,axis=0) q=[] for row in a: d=dict(zip(cal.active,row)) for n in cal.passive:d[n]=cal.passive_value(n,d[cal.curves[n][0]])[0] q.append([d[n] for n in names]) m['qpos']=np.array(q);m['active_qpos']=a m['wrist_pos_unsmoothed']=m['wrist_pos'].copy();m['wrist_quat_unsmoothed_wxyz']=m['wrist_quat_wxyz'].copy() m['wrist_pos']=gaussian_filter1d(m['wrist_pos'],sigma,axis=0) rot=Rotation.from_quat(m['wrist_quat_wxyz'][:,[1,2,3,0]]) relative=(rot[0].inv()*rot).as_rotvec();assert np.linalg.norm(relative,axis=1).max()limits[:,1]+1e-8))), boundary='Offline hand-only smoothing ablation, not contact or hardware validation') (out/'validation.json').write_text(json.dumps(r,indent=2));print(json.dumps(r,indent=2))