
    *iC                        U d Z ddlZddlZddlmZ ddlmZmZmZmZ ddl	Z	ddl
ZddlmZ ddlmZmZmZ ddlmZ ddlmZmZmZmZ dd	lmZ dd
lmZ ddlmZm Z  da!ee         e"d<   deej#                 deej#                 deeej#        ej#        f                  deeej#        ej#        f                  dededej#        fdZ$da%eej#                 e"d<   	 ddej#        de&dej#        fdZ' G d d          Z(dS )z1Orchestrates the full camera calibration workflow    N)datetime)DictListOptionalTuple)
Kinematics)CALIBRATION_FILECALIBRATION_POSES_FILECAMERA_CONFIG)get_yam_4310_linear_xml_path)CameraCalibratorChArUcoBoardConfigload_calibration_posessave_calibration_results)CameraConfig)Camera)RobotControllersmooth_move_joints_kinematics_cacheleft_arm_posesright_arm_posesleft_board_posesright_board_posesleft_hand_eye_resultright_hand_eye_resultreturnc                     t          |           dk     st          |          dk     rt          d          t          |          dk     st          |          dk     rt          d          ddlm  t	          t          |           t          |          t          |          t          |                    }t          d| d           t          j        d          }t          j        |d	                   |d
dd
df<   t          j        |d                   |d
ddf<   t          j        d          }t          j        |d	                   |d
dd
df<   t          j        |d                   |d
ddf<   t          j	        
                    |d
dd
df                   }	t          j	        
                    |d
dd
df                   }
t          |	dz
            dk    st          |
dz
            dk    rt          d|	dd|
dd           g }t          |          D ]1}| |         }||         }||         \  }}t          j        |          \  }}t          j        d          }||d
dd
df<   |                                |d
ddf<   ||         \  }}t          j        |          \  }}t          j        d          }||d
dd
df<   |                                |d
ddf<   ||z  |z  }||z  |z  }|t          j	                            |          z  }t          j	                            |          }|                    |           3 fd|D             }d |D             }                     |                                          }t          j        |d          }t          j        d          }|                                |d
dd
df<   ||d
ddf<   t          d|d
ddf                     |S )aD  Compute transform from right arm base to left arm base after hand-eye calibrations

    Uses hand-eye calibration results for both arms:
    1. For each pose, compute board position from left arm: left_base -> left_ee -> left_cam -> board
    2. For each pose, compute board position from right arm: right_base -> right_ee -> right_cam -> board
    3. Since board is fixed, both should point to same location in world
    4. Compute offset between bases and average across poses

    Args:
        left_arm_poses: List of T_left_base_to_left_ee transforms
        right_arm_poses: List of T_right_base_to_right_ee transforms (in right base frame)
        left_board_poses: List of (rvec, tvec) board observations from left camera
        right_board_poses: List of (rvec, tvec) board observations from right camera
        left_hand_eye_result: Hand-eye calibration result for left wrist (T_left_cam_to_left_ee)
        right_hand_eye_result: Hand-eye calibration result for right wrist (T_right_cam_to_right_ee)

    Returns:
        T_right_base_to_left_base: 4x4 transformation matrix
       z#Need at least 1 pose from both armsz3Need at least 1 board observation from both camerasr   RotationzD    Using hand-eye calibrations to compute bimanual base transform (z
 poses)...   rotation_matrixN   translation_vector      ?g{Gz?z<    Warning: Rotation matrices are not orthogonal (det_left=z.4fz, det_right=)c                 R    g | ]#}                     |d dd df                   $S Nr#   from_matrix.0Tr    s     7/home/robot-lab/raiden_cmu/raiden/calibration/runner.py
<listcomp>zDcompute_bimanual_base_transform_from_calibration.<locals>.<listcomp>   s7    EEEQ%%aBQBi00EEE    c                 &    g | ]}|d ddf         S r(    r,   r-   s     r.   r/   zDcompute_bimanual_base_transform_from_calibration.<locals>.<listcomp>   s$    111Abqb!eH111r0   axisz@    Bimanual transform (T_right_base_to_left_base) translation: )len
ValueErrorscipy.spatial.transformr    minprintnpeyearraylinalgdetabsrangecv2	Rodriguesflatteninvappendconcatenatemean	as_matrix)!r   r   r   r   r   r   	num_posesT_left_cam_to_left_eeT_right_cam_to_right_eedet_left	det_right
transformsiT_left_base_to_left_eeT_right_base_to_right_eervec_ltvec_lR_l_T_board_to_left_camrvec_rtvec_rR_rT_board_to_right_camT_left_base_to_boardT_right_base_to_boardT_left_base_to_right_baseT_right_base_to_left_base	rotationstranslationsavg_rotationavg_translationr    s!                                   @r.   0compute_bimanual_base_transform_from_calibrationrd      s   6 >Q#o"6"6":":>???
q  C(9$:$:Q$>$>NOOO000000NO	 I 
dyddd  
 F1II$&H-ABS-T$U$U"1"bqb&!#%8,@AU,V#W#W"1"a%  fQii&(h/DEV/W&X&XBQBF#%'X23& &BQBE"
 y}}22A2rr6:;;H	5bqb"1"f=>>I
8c>T!!SS%9%9D%@%@u8uuuenuuuu	
 	
 	

 J9 *5 *5!/!2#21#5  *!,v&&Q fQii&)BQBF#%+^^%5%5BQBE"*1-v&&Q!vayy'*RaR!V$&,nn&6&6RaRU# #%::=PP 	
 %'>>AUU 	 %929==!<
 <
 %
!
 %'IMM2K$L$L!34444 FEEE*EEEI11j111L''	227799Lgl333O "q		(4(>(>(@(@bqb"1"f%'6bqb!e$	mKdegfgegijejKkmm   %$r0   T_RIGHT_BASE_TO_LEFT_BASEleftjoint_positionsarmc                    t           t          t                      d          a t          |           dk    sJ dt          |                        t	          j        d          }| |dd<   t                               |          }|dk    r?t          t          d          t          j	        
                    t                    }||z  S |S )	aa  Compute forward kinematics for YAM robot arm using i2rt library

    Args:
        joint_positions: 6 joint positions (without gripper)
        arm: Which arm ("left" or "right")

    Returns:
        4x4 transformation matrix from left arm base to end-effector (grasp_site)
        All transforms are expressed relative to the left arm base frame.
    N
grasp_site	site_name   z Expected 6 joint positions, got    rightzeBimanual transform not available. Calibrate both left and right wrist cameras together to compute it.)r   r   _get_combined_xml_pathr6   r;   zerosfkre   r7   r>   rE   )rg   rh   qT_arm_base_to_eer^   s        r.   compute_forward_kinematicsru      s       &'='?'?<XXX 1$$$A3+?+?AA %$$
 	AAbqbE )++A.. g~~$,V   %'IMM2K$L$L!(+;;; r0   c                   H   e Zd ZdZeeedfdedededee	         fdZ
d Zd	ed
efdZd"dee         defdZdedededefdZdedededefdZdededededee         f
dZdeeeeef         f         fdZ	 	 	 d#dee         dee         d eee                  defd!ZdS )$CalibrationRunnerz&Runs the complete calibration workflowNcamera_config_file
poses_fileoutput_filecharuco_configc                     || _         || _        || _        || _        d | _        d | _        d | _        d | _        d | _        i | _	        t          j                    | _        d S N)rx   ry   rz   _charuco_config_overridecamera_config
poses_databoard_config
calibratorrobot_controllercameras	threadingEvent_move_stop_event)selfrx   ry   rz   r{   s        r.   __init__zCalibrationRunner.__init__   sf     #5$&(6%59*.:>6:;?*, ) 1 1r0   c                    t          d           t          | j                  | _        t	          | j                                                  }t          d| d           t          | j                  | _        t	          | j        d                   }t          d| d           | j	        | j	        | _
        n$t          j        | j        d                   | _
        t          d	           t          | j
                  | _        dS )
z(Load camera config and calibration posesz
Loading configuration...u   ✓ Camera config loaded: z camera(s) configuredposesu   ✓ Calibration poses loaded: z pose(s)Nr{   u   ✓ ChArUco board config loaded)r:   r   rx   r   r6   list_camerasr   ry   r   r~   r   r   	from_dictr   r   )r   num_camerasrJ   s      r.   load_configurationz$CalibrationRunner.load_configuration   s    *+++ *$*ABB$,99;;<<M;MMMNNN 1AA011	ByBBBCCC (4 $ =D 2 < 01! !D 	/000 +4+<==r0   
left_wristright_wristc                    t          dd||          | _        t          d           | j                                         t          d           | j                            d           | j                            d           dS )	z5Initialize robots based on which cameras to calibrateF)use_right_leaderuse_left_leaderuse_right_followeruse_left_followerz
Checking CAN interfaces...z
Initializing robots...)gravity_comp_modeTsimultaneousN)r   r   r:   check_can_interfacesinitialize_robotsmove_to_home_positions)r   r   r   s      r.   r   z#CalibrationRunner.initialize_robots  s     !0"!*(	!
 !
 !
 	,---22444 	()))//%/HHH 	44$4GGGGGr0   
   camera_nameswarmup_framesc           
      *   t          d           |D ]}| j                            |          }| j                            |          }|t	          d| d          t          d| d| d| d           | j                            |          }|                                 || j        |<   t          d	| d
           t          |          D ]2}| j        	                                D ]}|
                                 3t          d           dS )z4Initialize cameras by name using the camera factory.z
Initializing cameras...NzCamera 'z' not found in configz  - Initializing  (z
, serial: z)...z  Warming up cameras (z frames)...u   ✓ Cameras initialized)r:   r   get_camera_typeget_serial_by_namer7   create_cameraopenr   rA   valuesgrab)r   r   r   namecam_typeserialcamerarV   s           r.   initialize_camerasz$CalibrationRunner.initialize_cameras  sB   )***  		( 		(D)99$??H'::4@@F~ !GD!G!G!GHHHNdNNhNN&NNNOOO'55d;;FKKMMM!'DL 	A}AAABBB}%% 	 	A,--//   	'(((((r0   camera_dataleft_camera_idright_camera_idr   c                 z   t          d           |                    |          }|                    |          }|r|st          d           dS |d         r|d         st          d           dS t          d           | j                            |          }| j                            |          }|r|st          d           dS |                                \  }}	}
|                                \  }}}t          d|d	         d
d|d         d
           t          d|d	         d
d|d         d
           |                     ||                                |	                                          }|                     ||                                |                                          }|                     |d         |d         ||          }|st          d           dS t          dt          |d                    d           t          d           | j        	                    |d         |d                   }|d         s(t          d|                    dd                      dS t          d|d          d           t          d           | j        	                    |d         |d                   }|d         s(t          d|                    dd                      dS t          d |d          d           t          d!           t          |d         |d         |d         |d         ||          at          d"t          |d                    d#           t          j                            t                    fd$|d         D             |d<   t          d%           d&S )'a  Compute bimanual transform from hand-eye calibration results

        Strategy:
        1. Compute left hand-eye calibration (in left arm base frame)
        2. Compute right hand-eye calibration (in right arm base frame)
        3. Use both hand-eye results to compute bimanual base transform
        4. Update right arm poses to left base frame

        Args:
            camera_data: Dictionary with calibration data for all cameras
            left_camera_id: Name of left wrist camera
            right_camera_id: Name of right wrist camera

        Returns:
            True if transform was successfully computed, False otherwise
        z@
Computing bimanual base transform from hand-eye calibrations...u     ✗ Missing camera dataFcornersu     ✗ No board detections foundz/  Step 1: Getting camera intrinsics from SDK...u     ✗ Camera objects not foundu       ✓ Left camera: fx=r   r   .1f, fy=r   r   u       ✓ Right camera: fx=robot_posesu     ✗ No valid pose pairs foundz+  Step 2: Computing hand-eye calibrations (
left_robotz pose pairs)...z0    Computing left wrist hand-eye calibration...
left_boardsuccessu,         ✗ Left hand-eye calibration failed: errorUnknown erroru6         ✓ Left hand-eye calibration complete (method: methodr&   z1    Computing right wrist hand-eye calibration...right_robotright_boardu-         ✗ Right hand-eye calibration failed: u7         ✓ Right hand-eye calibration complete (method: zD  Step 3: Computing bimanual base transform from hand-eye results...u)       ✓ Bimanual transform computed from z pose pair(s)c                 "    g | ]}||z  nd S r}   r2   )r,   poser^   s     r.   r/   zKCalibrationRunner._compute_and_apply_bimanual_transform.<locals>.<listcomp>  s9     %
 %
 %
 150@%,,d%
 %
 %
r0   u4     ✓ Right arm poses transformed to left base frameT)r:   getr   get_intrinsics_estimate_board_posestolist_match_valid_posesr6   r   calibrate_hand_eyerd   re   r;   r>   rE   )r   r   r   r   	left_data
right_dataleft_cameraright_cameraleft_cam_matrixleft_dist_coeffsleft_img_sizeright_cam_matrixright_dist_coeffsright_img_sizer   r   valid_posesr   r   r^   s                      @r.   %_compute_and_apply_bimanual_transformz7CalibrationRunner._compute_and_apply_bimanual_transform2  s   * 	QRRROON33	 ___55
  	
 	-...5# 	:i+@ 	34445 	?@@@l&&~66|''88 	, 	23335;F;U;U;W;W8)='')) 	<+^ 	bt'<bbbW[G\bbb	
 	
 	
 	e(8(>eeeIYZ^I_eee	
 	
 	

  55""$$##%%
 

 !66##%%$$&&
 
 --m$}%	
 
  	34445i#k,>W:X:Xiii	
 	
 	

 	@AAA#AA%{<'@ 
  
 $I. 	s?S?W?WX_ap?q?qss   5fEYZbEcfff	
 	
 	

 	ABBB $ B B&M(B!
 !
 %Y/ 	u@U@Y@YZacr@s@suu   5hF[\dFehhh	
 	
 	

 	TUUU$T%&%& !%
 %
! 	eK<U8V8Veee	
 	
 	

 %'IMM2K$L$L!%
 %
 %
 %
"=1%
 %
 %

=! 	DEEEtr0   camera_matrixdistortion_coeffsc                    t          j        |          }t          j        |          }g }t          |d         |d                   D ]C\  }}| j        j                            ||||          \  }	}
|	|                    |	|
f           D|S )z+Estimate board poses from corner detectionsr   ids)r;   r=   zipr   detectorestimate_poserF   )r   r   r   r   camera_matrix_npdist_coeffs_npboard_posesr   r   rvectvecs              r.   r   z'CalibrationRunner._estimate_board_poses  s     8M22"344I 6E8JKK 	1 	1LGS1??. JD$ ""D$<000r0   left_robot_posesright_robot_posesr   r   c                    g }g }g }g }t          t          |          t          |          t          |          t          |                    }	t          |	          D ]~}
||
         t||
         l|                    ||
                    |                    ||
                    |                    ||
                    |                    ||
                    |sdS ||||dS )z%Match valid pose pairs from both armsN)r   r   r   r   )r9   r6   rA   rF   )r   r   r   r   r   valid_left_robotvalid_right_robotvalid_left_boardvalid_right_boardmin_lenrP   s              r.   r   z$CalibrationRunner._match_valid_poses  s     !!!"" !!!""	
 
 w 	? 	?A".3DQ3G3S ''(8(;<<<!(():1)=>>> ''(8(;<<<!(():1)=>>> 	4 +,*,	
 
 	
r0   c           
      N
   t          d           t          d           t          d           t                       d | j                                        D             }| j        d         }t	          |          D ]\  }}t          d|dz    dt          |           d	|d
                     | j        r\g }| j        j        rad|v r]t          j	        |d                   }|
                    t          j        t          | j        j        |fd| j        id                     | j        j        rad|v r]t          j	        |d                   }|
                    t          j        t          | j        j        |fd| j        id                     |rZt          dt          |          dk    rdnd d           |D ]}|                                 |D ]}|                                 t          d           t%          j        d           nt%          j        d           t          d           | j                                        D ]\  }	}
	 |
                                st-          d|	           |
                                j        }t          j        |t          j                  }||	         d         
                    |           | j        j                            |          \  }}|t          |          dk    r||	         d         
                    |           ||	         d         
                    |           t          d|	 d t          |           d!           d"|	v rI| j        rAd}d#|	v r| j        j        r| j        j        }nd$|	v r| j        j        r| j        j        }np	 |                                }||	         d%         
                    |           t>          tA          tC                      d&'          at          j"        d(          }|dd)         |dd)<   t>          #                    |          }||	         d*         
                    |           n^# tH          $ r=}t          d+|            ||	         d*         
                    d           Y d}~nd}~ww xY wnt          d,|	 d-           # tH          $ r }t          d,|	 d.|            Y d}~d}~ww xY wt          d/           t          d0           |S )1a  Move through poses and collect calibration data.

        Returns:
            Dictionary mapping camera names to their calibration data.
            Each value is a dict with keys ``images``, ``corners``, ``ids``,
            and ``robot_poses`` (for hand-eye calibration).
        z!
Starting calibration sequence...F======================================================================zLCoordinate frame: All transforms will be expressed relative to left arm basec           
      :    i | ]}|g g g g g d |v rd nd|v rdnddS )rf   ro   N)imagesr   r   r   rg   arm_typer2   )r,   r   s     r.   
<dictcomp>z>CalibrationRunner.collect_calibration_data.<locals>.<dictcomp>  sb     
 
 
  !#%T>> #F!(Dggd	 	
 
 
r0   r   z
Pose r   /z: r   
follower_r
stop_eventT)targetargskwargsdaemon
follower_lz	  Moving z	both armsrh   z simultaneously...z  Waiting for stabilization...r%         ?z  Capturing images...zgrab() failed for )dtyper   Nr   r   r   u       ✓ z: ChArUco board detected (z	 corners)wristro   rf   rg   rj   rk   rn   rm   r   z.    Warning: Failed to get actual robot pose: u       ✗ z: Board not detectedz
: Error - G
======================================================================zData collection complete!)%r:   r   keysr   	enumerater6   r   r   r;   r=   rF   r   Threadr   r   r   startjointimesleepitemsr   RuntimeError	get_framecolorascontiguousarrayuint8r   r   detectget_joint_posr   r   rp   rq   rr   	Exception)r   r   r   rP   r   threadstarget_rtarget_ltcamera_namer   imager   r   robotactual_joint_posrs   
robot_posees                      r.   collect_calibration_dataz*CalibrationRunner.collect_calibration_data  s    	2333hZ	
 	
 	
 	
 
 ))++
 
 
 ( '' w	A w	AGAt@AE@@CJJ@@$v,@@AAA $ % (3 	8L8L!x\(:;;HNN!(#5"&"7"BH!M$0$2G#H#'	     (3 	8L8L!x\(:;;HNN!(#5"&"7"BH!M$0$2G#H#'	      !b3w<<!3C3CKKbbb   % " "				$ ! ! 6777
3 
3 )***'+|'9'9';'; JA JA#VIA!;;== O*+M+M+MNNN",,..4E 0bhGGGE,X6==eDDD $(?#;#B#B5#I#ILGS*s7||a/?/?#K0;BB7KKK#K07>>sCCCe{eecRYlleee  
 #k11d6K1$(E '; 6 6$($9$D !7 )-(=(H &+ 5 5$($9$D !6 )-(=(H (U383F3F3H3H 0 !,K 89J K R R$4!" !" !" $5#<8B(>(@(@2>9& 9& 9&$5
 %'HQKK(8!(<"1"->-A-A!-D-D
 +K 8 G N N$.!" !" !" !" $- U U U %$XUV$X$X!" !" !" !,K 8 G N Nt T T T T T T T TU JJJJKKK  A A A?[??A??@@@@@@@@ASJAX 	o)***sD   E'S B7Q87S8
R?3R:5S:R??S
T"S==Tleft_wrist_camera_idright_wrist_camera_idscene_camera_idsc                 j  : 	 |                                   g }|du}|du}t          |          }|r|                    |           |r|                    |           |r|                    |           |r|st          t          d          t          d           |D ] }d|v rdnd}	t          d| d|	 d	           !|                     |           |s|r|                     ||           nt          d
           | 	                                }
d}|r |rt          | 
                    |
||          }t          d           t          d           dt          j                                                    d| j        j        i i d}|r(t          !t                                          ddd|d<   n't           t                                          ddd|d<   g }|r||v r|                    |           |D ]}||k    r|                    |           |D ]}t          d| d           |
|         }t#          |d                   dk     r't          dt#          |d                    d           ^| j                            |          pd}t          d| d           | j                            |          }|st          d           |                                \  }}}t          d |d!         d"d#|d$         d"d%|d&         d"d'|d(         d"           d|                                |                                d)}d|v rd*nd| j                            |          |d+         |d,         t1          |          | d-d.t#          |d                   d/}d|v r=t          d0           |d1         r|d1         d2         t          d3           nt3          j        |d+                   }t3          j        |d,                   }g }t7          |d         |d4                   D ]C\  }}| j        j                            ||||          \  }}||                    ||f           D| j                            |d1         |          }|d5         r ||d6<   t          d7|d8          d	           n3t          d9|                    d:d;                      nt          d<           t3          j        |d+                   }t3          j        |d,                   }g }t7          |d         |d4                   D ]C\  }}| j        j                            ||||          \  }}||                    ||f           D| j                             |          }|d5         r4|r|r
|
                    |          }|rd6|d=                             |i           v rt          d>           |d=         |         d6         }t3          j!        d?          } t3          j        |d@                   | ddddf<   t3          j        |dA                   | dddf<   | j                            |          }!|!                                \  }"}#}$g }%t7          |d         |d4                   D ]C\  }}| j        j                            |||"|#          \  }}||%                    ||f           D|%r|d1         rt          dBt#          |%           dC           g }&tE          |%          D ]\  }'\  }}|'t#          |d1                   k    s|d1         |'         0tG          j$        |          \  }(}$t3          j!        d?          })|(|)ddddf<   |%                                |)dddf<   |d1         |'         }*|*| z  |)z  }+|&                    |+           |&rd2dDl&m': :fdE|&D             },dF |&D             }-:(                    |,          )                                }.t3          j)        |-d2G          }/t3          j!        d?          }+|.*                                |+ddddf<   |/|+dddf<   t3          j!        d?          }0t3          j        |d@                   |0ddddf<   t3          j        |dA                   |0dddf<   |+|0z  }1|1dddf         }2t          dH|2            |1ddddf                                         |d@<   |1dddf                                         |dA<   tG          j$        |1ddddf                   \  }3}$|3%                                                                |dI<   d|dJ<   t          dK           n/t          dL           nt          dM           nt          dN           ||dO<   t          dP           nt          dQ           ||d=         |<   t#          | j+        dR                   }4tY          dS |
-                                D                       }5t#          |d=                   d2k    |4|5|4d2k    r|5|4z  nd2dT|dU<   t          dV           t          dW           t          dX           t          dYt#          |d=                               t          dZ|5 d[|4            t          d\|dU         d]         d^z  d"d_           |rt          d`           nt          t          da           t]          || j/                   t          db| j/                    	 d2dcl0m1}6  |6            2                    || j/                   t          dd           n)# tf          $ r}7t          de|7            Y d}7~7nd}7~7ww xY wt          df           | j4        r| j4        5                    dg           t          dh           | j4        6                                 to          j8        di           | j4        9                                 to          j8        di           t          dj           t          dk           | j        -                                D ]}|:                                 t          dl           t          dm           |S # tv          $ rc t          dn           | j<        =                                 | j4        r2| j4        >                                r| j4        ?                                  tf          $ r}8t          do|8            d2dl@}9|9A                                 | j<        =                                 | j4        r2| j4        >                                r| j4        ?                                  d}8~8ww xY w)pag  Run the full calibration workflow

        Args:
            left_wrist_camera_id: Name of left wrist camera (e.g., "left_wrist")
            right_wrist_camera_id: Name of right wrist camera (e.g., "right_wrist")
            scene_camera_ids: Names of all scene cameras (multiple allowed)

        Returns:
            Calibration results dictionary
        NzCannot calibrate right wrist camera without bimanual transform.
Please calibrate both left and right wrist cameras together to compute the transform.z
Calibration targets:r   zhand-eyescenez  - r   r&   z:
No wrist cameras selected - skipping robot initializationFz
Computing calibrations...r   z1.0left_arm_base)version	timestampcoordinate_framer{   r   quality_metricsTz:Transform from right arm base frame to left arm base frame)right_base_to_left_basecomputed_from_calibrationdescriptionbimanual_transformzHTransform from right arm base frame to left arm base frame (from config)
:r   r#   u     ✗ Insufficient data (z views, need >= 3)unknownz  Getting intrinsics from z SDK (factory calibration)...u     ✗ Camera object not foundu       ✓ fx=r   r   r   r   z, cx=)r      z, cy=)r   r%  )r   r   r   hand_eyer   r   _sdk_factory_calibration)r   r   
image_sizesource)typeserial_number
intrinsicsnum_poses_usedz#  Computing hand-eye calibration...r   r   uH     ✗ Forward kinematics not implemented - skipping hand-eye calibrationr   r   hand_eye_calibrationu/       ✓ Hand-eye calibration complete (method: r   u#     ✗ Hand-eye calibration failed: r   r   z&  Computing scene camera extrinsics...r   z:    Converting scene camera pose to left arm base frame...r!   r"   r$   z*      Computing T_board_to_left_base from z left wrist observations...r   c                 R    g | ]#}                     |d dd df                   $S r(   r)   r+   s     r.   r/   z5CalibrationRunner.run_calibration.<locals>.<listcomp>  sG     5* 5* 5*01 -5,@,@2A2rr6,K,K5* 5* 5*r0   c                 &    g | ]}|d ddf         S r(   r2   r3   s     r.   r/   z5CalibrationRunner.run_calibration.<locals>.<listcomp>  s4     8* 8* 8*01 -.bqb!eH8* 8* 8*r0   r4   z*      Scene camera position in left base: rotation_vectorreference_frameu<         ✓ Scene camera pose converted to left arm base framezW      ! Warning: Could not convert to left arm base frame (no valid board observations)zR      ! Warning: Cannot convert to left arm base frame (left wrist not calibrated)zW      ! Warning: Scene camera extrinsics are in board frame (left wrist not calibrated)
extrinsicsu)       ✓ Scene camera calibration completeu%     ✗ Scene camera calibration failedr   c              3   @   K   | ]}t          |d                    V  dS )r   N)r6   )r,   datas     r.   	<genexpr>z4CalibrationRunner.run_calibration.<locals>.<genexpr>  s?       ( ()-DO$$( ( ( ( ( (r0   )overall_successposes_collectedposes_with_detectionsdetection_rater  r   zCalibration complete!z	
Summary:z  - Cameras calibrated: z  - Poses used: r   z  - Detection rate: r:  d   %u:     - Bimanual transform: Computed from calibration data ✓z6  - Bimanual transform: Loaded from configuration fileu   
✓ Results saved to: )get_dbu%   ✓ Calibration result recorded in DBz/  Warning: could not record calibration in DB: z
Cleaning up...r   z#  Stopping robot control threads...r   u!     ✓ Robot controller cleaned upzI  Note: Arms remain in current position - manually move to home if neededu     ✓ Cameras closedu   
✓ Cleanup completez!

Calibration interrupted by userz
Error during calibration: )Br   boolrF   extendre   r7   r:   r   r   r  r   r   now	isoformatr   __dict__r   r6   r   r   r   r   r   r   listr;   r=   r   r   r   r   r   calibrate_scene_camerar<   r   rB   rC   rD   r8   r    rG   rH   rI   r   maxr   r   rz   raiden.db.databaser=  add_calibration_resultr  r   r   stop_teleoperationr   r   cleanupcloseKeyboardInterruptr   set
has_robotsemergency_stop	traceback	print_exc);r   r  r  r  target_camerascalibrate_leftcalibrate_rightcalibrate_scener   camera_typer   bimanual_transform_computedresultscameras_to_processr  r5  r   
cam_matrixdist_coeffsr(  intrinsics_resultcamera_resultr   camera_posesr   r   r   r   hand_eye_resultscene_resultr   left_hand_eyerK   r   r   r   rV   r   board_to_left_base_transformsrP   RrW   rQ   T_board_to_left_baser`   ra   rb   rc   T_scene_cam_to_boardT_left_base_to_scene_camscene_cam_pos_in_left_baservec_newtotal_posesr9  r=  _db_errr  rO  r    s;                                                             @r.   run_calibrationz!CalibrationRunner.run_calibration  s    A	##%%%  N1=N34?O"#344O =%%&;<<< <%%&:;;; 8%%&6777
  & .5 l  
 *+++( 7 7,3v,=,=jj75V55{5556666 ##N333  U U&&~GGGGSTTT 7799K +0' / 6O6W>>#%9;P  , /000(OOO !%\^^5577$3"&"3"<#% G + /H/T/H/O/O/Q/Q15#_1 1,--
 +6/H/O/O/Q/Q16#m1 1,- "$# @(<(N(N"))*>???- ; ;"666&--k:::1 H@ H@);)))***";/tI''!++\CY4H4H\\\     -==kJJWiXXXX   ))+66 9:::6<6K6K6M6M3
K J*T"2  J  J  JZ=M  J  J  JXbcgXh  J  J  Js}  C  tD  J  J  J  
  $%/%6%6%8%8)4););)=)=% %! +2[*@*@JJg%)%7%J%J;%W%W):?)K->?R-S&*:&6&6%-"G"G"G	# # '*$y/&:&:
! 
! k))?@@@  . $}2Ea2H2Pf   
 )+1B?1S(T(T&(h/@AT/U&V&V'),/Ye,M,M B BLGS)-)A)O)O 'm[* *JD$  $/ , 3 3T4L A A A +//*L*L /+ + +95 DSM*@A! nRabjRk n n n    " uoFYFYZacrFsFs u u    BCCC %'H->-O$P$PM"$(+<=P+Q"R"RK#%L(+DOT%[(I(I > >%)_%=%K%K#S-& &
d  +(//t=== $(?#I#I,#W#WL#I. aG
 * W.B W(38L(M(MI( Q"-Cw )H!c"6;;.< .< !&$`!" !" !"
 18	0B$81""81: 9;q		 5@B$12C$DA" A" 5bqb"1"f = @Bx$12F$G@" @" 5bqb!e <
 /3l.>.>?S.T.T$/$>$>$@$@ !E1A1
 46 047$-i$8)E:J5" 5" !N !NLGS 261I1W1W(/oGW2& 2&JD$ (,'7(8(?(?t(M(M(M#3 i!*	-8P i!*$) )HUXYiUjUj  )H  )H  )H%& %& %& EG$A;DEU;V;V %* %*<D$,-Y}5M1N1N,N,N/8/G/J/R,4 03}T/B/B1>@fQii(;FG(;BQBF(CEI\\^^(;BQBE(B BK,9B**+B-(>
 -C.C-D.A-B )= )F(L(L,@)* )* )* )* (E G%*(T(T(T(T(T(T5* 5* 5* 5*5R5* 5* 5*	8* 8*5R8* 8* 8*
 8@7K7K,58* 8**.$&& )5 ;=',UV:W:W:W?Avayy(<,8,B,B,D,D )=RaR!V(D GV(<RaRU(C @Bvayy(<GIx,89J,KH* H*(<RaR!V(D GIh,89M,NG* G*(<RaRU(C -ACW,W )A
 -ERaRU,K )C ).,uYs,u,u)* )* )* -ERaR!V,L,S,S,U,U )55F(G -ERaRU,K,R,R,T,T )55I(J 7:m,DRaR!V,L7* 7*! -5,<,<,>,>,E,E,G,G )55F(G -< )55F(G ).,j)* )* )* )* ). -F)* )* )* !&$x!" !" !" !" " y   7Cl3IJJJJEFFF2?	";// dog677K$' ( (1<1C1C1E1E( ( ( % %!
 $'wy'9#:#:Q#>#.)>?? #8+"E"E* *G%& /""")***,FS1C-D-DFFGGGJ%:JJ[JJKKK`w/@'ABR'SVY'Y````   + PRSSSS*6NOOO %Wd.>????T-=??@@@S555555//9IJJJ=>>>> S S SQQQRRRRRRRRS $%%%$ %<<$<OOO ;<<<%88::: 
3 %--/// 
39:::_  
 ,--//  ()))*+++N  	 	 	7888!%%'''$ 7)>)I)I)K)K 7%44666 		 		 		444555!!!!%%'''$ 7)>)I)I)K)K 7%44666		sE   mr; 8n
 	r; 

n0n+&r; +n00D
r; ;A5v20A=v--v2)r   )NNN)__name__
__module____qualname____doc__r   r
   r	   strr   r   r   r   r>  r   r   intr   r   r   rC  r   r   r  rj  r2   r0   r.   rw   rw      s#       00 #00+7;2 22 2 	2
 !!342 2 2 2*> > >4HD Ht H H H H*) )tCy ) ) ) ) )0LL14LGJL	L L L L\04IM	   "#
#
  #
 	#

  #
 
$#
 #
 #
 #
J]	c4T	?"	#] ] ] ]B /3/304	Q Q&smQ  (}Q #49-	Q
 
Q Q Q Q Q Qr0   rw   )rf   ))rn  r   r   r   typingr   r   r   r   rB   numpyr;   i2rt.robots.kinematicsr   raiden._configr	   r
   r   raiden._xml_pathsr   rp   raiden.calibration.corer   r   r   r   raiden.camera_configr   raiden.cameras.baser   raiden.robot.controllerr   r   r   __annotations__ndarrayrd   re   ro  ru   rw   r2   r0   r.   <module>r|     sm   7 7 7            . . . . . . . . . . . . 



     . - - - - - R R R R R R R R R R T T T T T T            . - - - - - & & & & & & G G G G G G G G +/ 8J' . . .%$%"*%% 5RZ!789% E"*bj"89:	%
 %  % Z% % % %F 37 8BJ/ 6 6 6 -3, ,Z,&),Z, , , ,^S S S S S S S S S Sr0   