Working calibration

This commit is contained in:
cristhian aguilera
2026-01-30 16:40:06 -03:00
parent 610c43e16d
commit 61bc384826
17 changed files with 1717 additions and 6 deletions

View File

@@ -0,0 +1,74 @@
#!/usr/bin/env python3
"""Analyze saved observations for issues."""
import argparse
import numpy as np
from scipy.spatial.transform import Rotation
def main():
parser = argparse.ArgumentParser(description="Analyze hand-eye observations for issues.")
parser.add_argument("observations", nargs="?", default="calibration_observations.npz",
help="Path to observations .npz file")
args = parser.parse_args()
# Load dora observations
dora_obs = np.load(args.observations, allow_pickle=True)
print("=== OBSERVATIONS ANALYSIS ===")
print(f"File: {args.observations}")
print(f"Keys: {list(dora_obs.keys())}")
R_gripper2base = dora_obs['R_gripper2base']
t_gripper2base = dora_obs['t_gripper2base']
R_target2cam = dora_obs['R_target2cam']
t_target2cam = dora_obs['t_target2cam']
n = len(R_gripper2base)
print(f"Count: {n}")
print("\n=== GRIPPER POSES (base_T_gripper) ===")
for i in range(n):
R = R_gripper2base[i]
t = t_gripper2base[i].flatten()
# Check rotation matrix validity
det = np.linalg.det(R)
orth = np.allclose(R @ R.T, np.eye(3), atol=1e-6)
rpy = Rotation.from_matrix(R).as_euler('xyz', degrees=True)
print(f"\nObs {i+1}:")
print(f" det(R)={det:.6f}, orthogonal={orth}")
print(f" t(mm)=[{t[0]*1000:.1f}, {t[1]*1000:.1f}, {t[2]*1000:.1f}]")
print(f" RPY(deg)=[{rpy[0]:.1f}, {rpy[1]:.1f}, {rpy[2]:.1f}]")
if not orth:
print(" WARNING: Rotation matrix not orthogonal!")
if abs(det - 1.0) > 1e-6:
print(f" WARNING: Rotation matrix determinant is {det}, expected 1.0!")
print("\n=== TARGET POSES (cam_T_target) ===")
for i in range(n):
R = R_target2cam[i]
t = t_target2cam[i].flatten()
det = np.linalg.det(R)
orth = np.allclose(R @ R.T, np.eye(3), atol=1e-6)
print(f"\nObs {i+1}:")
print(f" det(R)={det:.6f}, orthogonal={orth}")
print(f" t(m)=[{t[0]:.4f}, {t[1]:.4f}, {t[2]:.4f}]")
print(f" distance from camera: {np.linalg.norm(t)*1000:.1f}mm")
# Check for pose diversity (important for calibration)
print("\n=== POSE DIVERSITY CHECK ===")
positions = np.array([t_gripper2base[i].flatten() for i in range(n)])
pos_range = positions.max(axis=0) - positions.min(axis=0)
print(f"Position range (mm): X={pos_range[0]*1000:.1f}, Y={pos_range[1]*1000:.1f}, Z={pos_range[2]*1000:.1f}")
rotations = np.array([Rotation.from_matrix(R_gripper2base[i]).as_euler('xyz', degrees=True) for i in range(n)])
rot_range = rotations.max(axis=0) - rotations.min(axis=0)
print(f"Rotation range (deg): Roll={rot_range[0]:.1f}, Pitch={rot_range[1]:.1f}, Yaw={rot_range[2]:.1f}")
if __name__ == "__main__":
main()