
    *iTH                     b   d Z ddlZddlZddlZddlZddlmZmZ ddlmZ ddl	m
Z
 ddlmZmZmZ ddlmZ ddlZddlZddlmZmZ dd	lmZ dd
lmZ ddlmZ ddlmZ e G d d                      Ze G d d                      Z  G d d          Z!deedfdede"de#de#dee         f
dZ$dS )z4Interactive recording of robot poses for calibration    N)asdict	dataclass)datetime)Path)DictListOptional)quote)CALIBRATION_POSES_FILECAMERA_CONFIG)CameraConfig)Camera)TeleopInterface)RobotControllerc                   `    e Zd ZU dZdZeed<   dZeed<   dZe	ed<   dZ
e	ed<   d	Zeed
<   d ZdS )ChArUcoBoardConfigz+Configuration for ChArUco calibration board	   	squares_x	squares_ygQ?square_lengthgZd;O?marker_lengthDICT_6X6_250
dictionaryc                      t          |           S N)r   selfs    9/home/robot-lab/raiden_cmu/raiden/calibration/recorder.pyto_dictzChArUcoBoardConfig.to_dict!   s    d||    N)__name__
__module____qualname____doc__r   int__annotations__r   r   floatr   r   strr    r    r   r   r      s{         55IsIsM5 M5   $J$$$    r    r   c                       e Zd ZU dZeed<   eed<   dZee	e
                  ed<   dZee	e
                  ed<   dZeed<   dZeed	<   d
 ZdS )CalibrationPosez4A single calibration pose with robot joint positionsidnameN
follower_r
follower_l 	timestampnotesc                     | j         | j        | j        | j        d}| j        
| j        |d<   | j        
| j        |d<   |S )Nr,   r-   r1   r2   r.   r/   )r,   r-   r1   r2   r.   r/   )r   results     r   r   zCalibrationPose.to_dict0   sQ    'IZ	
 
 ?&#'?F< ?&#'?F< r    )r!   r"   r#   r$   r%   r&   r(   r.   r	   r   r'   r/   r1   r2   r   r)   r    r   r+   r+   %   s         >>GGG
III(,Je%,,,(,Je%,,,IsE3OOO    r    r+   c            
           e Zd ZdZeedfdedededee	         fdZ
d Zdd
edefdZdefdZd ZdefdZd ZddeddfdZddZddZddZddefdZdS )CalibrationPoseRecorderz*Records robot poses for camera calibrationN	interfaceoutput_filecamera_config_filecharuco_configc                 ,   || _         t          |          | _        | j        j                            dd           || _        |pt                      | _        g | _        d | _	        g | _
        i | _        i | _        t          j                    | _        d S )NT)parentsexist_ok)r8   r   r9   parentmkdirr:   r   r;   posesrobot_controllercalibration_targetscameras_camera_roles	threadingEvent_rerun_stop_event)r   r8   r9   r:   r;   s        r   __init__z CalibrationPoseRecorder.__init__A   s     #,,%%dT%BBB"4,D0B0D0D,.
;?.0 *,79!*!2!2r    c                    t          | j                  }|                    d          du}|                    d          du}|r/|                    d          }| j                            |           |r/|                    d          }| j                            |           |                    d          D ]%}|| j        vr| j                            |           &t          | j        j        o|| j        j        o|||          | _	        | j	        
                                 | j                            | j	                   | j                            | j	                   dS )zBInitialize robots based on which wrist cameras are in camera.json.right_wristN
left_wristscene)use_right_leaderuse_left_leaderuse_right_followeruse_left_follower)r   r:   get_camera_by_rolerC   appendget_cameras_by_roler   r8   uses_leadersrB   setup_for_teleop_recordingsetupstart)r   cfg	has_righthas_leftcams        r   initialize_robotsz)CalibrationPoseRecorder.initialize_robotsW   ss   4233**=99E	)),77tC  	1((77C$++C000 	1((66C$++C000 **733 	5 	5C$222(//444 /!^8FY N7DH(&	!
 !
 !
 	88:::T2333T233333r    r0   r2   returnc                    t          | j                  }t          j                                                    }t          |d| ||          }| j                                        }d|v r|d                                         |_	        d|v r|d                                         |_
        | j                            |           |S )zRecord the current robot posepose_r4   r.   r/   )lenrA   r   now	isoformatr+   rB   get_joint_positionstolistr.   r/   rS   )r   r2   pose_idr1   posejoint_positionss         r   record_current_posez+CalibrationPoseRecorder.record_current_posex   s    dj//LNN,,..	"""	
 
 
 /CCEE?**-l;BBDDDO?**-l;BBDDDO
$r    c                     | j         r:| j                                         }t          d|j         d|j                    dS t          d           dS )z&Delete the most recently recorded poseu   ✓ Deleted pose : TzNo poses to deleteF)rA   popprintr,   r-   )r   deleteds     r   delete_last_posez(CalibrationPoseRecorder.delete_last_pose   sY    : 	jnn&&GBgjBBGLBBCCC4&'''5r    c           	         | j         st          d           dS t          dt          | j                    d           | j         D ]G}t          d|j         d|j         d|j                    |j        rt          d|j                    HdS )	zPrint all recorded poseszNo poses recorded yetNz

Recorded z	 pose(s):z  rk   z - z     Notes: )rA   rm   ra   r,   r-   r1   r2   )r   rg   s     r   
list_posesz"CalibrationPoseRecorder.list_poses   s    z 	)***F6C
OO666777J 	3 	3D@tw@@$)@@@@AAAz 31TZ11222	3 	3r    c                 <    | j                                         }|duS )zCheck if any leader button was pressed

        Returns:
            True if a button was pressed (rising edge), False otherwise
        N)rB   check_button_press)r   pressed_leaders     r   rs   z*CalibrationPoseRecorder.check_button_press   s#     .AACCT))r    c                    d| j                                         d | j        D             | j        dt	          j                                                    t	          j                                                    d}t          | j        d          5 }t          j
        ||d           ddd           n# 1 swxY w Y   t          d	t          | j                   d
| j                    dS )z Save recorded poses to JSON filez1.0c                 6    g | ]}|                                 S r)   )r   ).0rg   s     r   
<listcomp>z6CalibrationPoseRecorder.save_poses.<locals>.<listcomp>   s     <<<dllnn<<<r    fixed)versionr;   rA   rC   board_mountcreatedlast_modifiedw   )indentNu   
✓ Saved z
 poses to )r;   r   rA   rC   r   rb   rc   openr9   jsondumprm   ra   )r   datafs      r   
save_posesz"CalibrationPoseRecorder.save_poses   s    "199;;<<<<<#'#;"|~~//11%\^^5577
 
 $"C(( 	)AIdAa((((	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	JS__JJ8HJJKKKKKs   B55B9<B9
   warmup_framesc                 6   t          | j                  }|                                D ]}	 |                    |          }|                                 || j        |<   |                    |          | j        |<   T# t          $ r}t          d| d|            Y d}~xd}~ww xY w| j        rgt          dt          | j                   d           t          |          D ]4}| j                                        D ]}|                                 3dS dS )z:Open all cameras from config for live Rerun visualization.z"  Warning: could not open camera 'z': Nz  Warming up z camera(s)...)r   r:   list_camera_namescreate_camerar   rD   get_rolerE   	Exceptionrm   ra   rangevaluesgrab)r   r   rY   r-   r\   e_s          r   _open_camerasz%CalibrationPoseRecorder._open_cameras   sX   4233))++ 	I 	IDI''--


%(T"+.<<+=+="4(( I I IG4GGAGGHHHHHHHHI< 	B#dl"3"3BBBCCC=))  <..00  CHHJJJJ	 	 s   AA==
B&B!!B&c                    t          j        d           d}d}t          j        |          }t          j        |d           d| dt	          |d	
           }t          d|            t          d| d| d| d| d	           t                       d}| j                                        s)| j        	                                D ]\  }}	 |
                                r|                                }|j        }	| j                            |          dk    rt          j        |	t          j                  }	|	d d d d d d df         }
t          j        d|           t          j        d| t          j        |
                     # t*          $ r Y w xY w|dz  }| j                            d           | j                                        'd S d S )Nraiden_calibrationi&  i&  )	grpc_portF)web_portopen_browserzhttp://localhost:z?url=r0   )safez
Rerun viewer:    zSSH tunnel:      ssh -L z:localhost:z -L z <host>r   rK   frame)sequencezcameras/   g      ?)rrinit
serve_grpcserve_web_viewerr
   rm   rH   is_setrD   itemsr   	get_framecolorrE   getcv2rotate
ROTATE_180set_timelogImager   wait)r   r   r   
server_uri
viewer_url	frame_idxr-   r\   r   r   img_rgbs              r   _rerun_streamz%CalibrationPoseRecorder._rerun_stream   s   
$%%%	]Y777

XEBBBBTTTjr8R8R8RTT
0J00111rxrrHrr)rr`irrr	
 	
 	
 		(//11 	-!\//11  	c
xxzz E # %-11$77=HH$'Jucn$E$EE"'111ddd
"3Gi@@@@0$00"(72C2CDDD    DNI"'',,, (//11 	- 	- 	- 	- 	-s   B>F
FFc                    | j         sd S | j                                         t          j        | j        d          | _        | j                                         t          dt          | j                    d           d S )NT)targetdaemonu     ✓ Rerun stream started (z camera(s)))
rD   rH   clearrF   Threadr   _rerun_threadrX   rm   ra   r   s    r   _start_rerun_streamz+CalibrationPoseRecorder._start_rerun_stream   s    | 	F$$&&&&-T5GPTUUU  """KS->->KKKLLLLLr    c                     | j                                          t          | d          r| j                            d           | j                                        D ]}|                                 | j                                         d S )Nr   g       @)timeout)	rH   sethasattrr   joinrD   r   closer   )r   r\   s     r   _stop_rerun_streamz*CalibrationPoseRecorder._stop_rerun_stream   s    ""$$$4)) 	1##C#000<&&(( 	 	CIIKKKKr       	min_posesc                     ddl }ddl}ddl}ddl}t	          d           t	          d           t	          d           t	          d                                                                                                                  j        	                                  fd}|                    |j
        |           t	          d            j        D ]}t	          d	|            t	          d
           t	          d j        j         d j        j         d           t	          d j        j        dz  dd           t	          d j        j        dz  dd           t	          d j        j                    t	          d           t	          d            j        j        rt	          d           nt	          d           t	          d            j        j        rt	          d           nt	          d           t	          d| d           t	          d           t	          d           t	          d           t	          d            t	          d!           t	          d"            j        j        p j        j        }|rt	          d#           t	          d$           t	          d           t	          d%           d}	t.          j                                        r|                    t.          j                  }		 	 t7           j                  }
d'|
 }|
|k     r
|d(| d)z  }n|d*z  }t	          |           t	          d+d,d&-           d}| j                             j                  r't	          d.           t=          j        d/           d0}nPt.          j                                        r|	r|                     t.          j        gg g d1          d         r|                     t.          j        !                                           t.          j        "                    d2          }|#                    t.          j        |j$        |	           |d3k    rtJ          |d4k    s|d5k    rEt	          d6d,d&-           tM                      '                                (                                }n1|d7v r|}t	          d8|            nnt=          j        d/           ||d0k    r )                                }t	          d9|j*         d:|j+                     j        j,        r2|j,        r+|j,        dd;         }t	          d<d= |D                          j        j-        r2|j-        r+|j-        dd;         }t	          d>d? |D                         n|d@k    r .                                 n|dAk    r /                                 n|dBk    r|
|k     rt	          dC|
 dD| dE           t	          dFd,d&-           |	r&|#                    t.          j        |j$        |	           tM                      '                                (                                }|dGk    rt	          dH            0                                 t	          dI            j        1                                 n|dJk    rt	          d           t	          d           t	          d           t	          d            t	          d!           t	          d"           |r* j        j        rt	          d#           t	          dK           n!t	          dL|            t	          dM           kn:# tJ          $ r t	          dN           |	r&|#                    t.          j        |j$        |	            j        r^t	          dOd,d&-           tM                      '                                (                                }|dPk    r 0                                  j        1                                 Y nytd          $ rm}t	          dQ|            ddl3}|4                                  j        r2 j        5                                r j        6                                 Y d}~nd}~ww xY w j        7                                  8                                  j        r j        9                                 dS dS #  j        7                                  8                                  j        r j        9                                 w w xY w)Rz&Run interactive pose recording sessionr   NzG
======================================================================z,  Raiden - Camera Calibration Pose RecordingzF======================================================================z*
Opening cameras for live visualization...c                 :    j                                          d S r   )rB   emergency_stop)signumr   r   s     r   signal_handlerzICalibrationPoseRecorder.run_interactive_recording.<locals>.signal_handler  s    !0022222r    z
Target Cameras:z  - z
ChArUco Board Configuration:z  - Grid size: xz squaresz  - Checker size: i  z.1fz mmz  - Marker size: z  - Dictionary: z
Instructions:z3  1. Position the ChArUco board in a fixed locationz?  2. Move the LEADER arms - followers will automatically followz/  2. Move the robot arms using the input devicez@  3. Position so the board is clearly visible from the camera(s)z>  4. Press button on any leader arm OR type 'r' to record posez  4. Type 'r' to record posez  5. Record at least z( diverse poses (vary distance and angle)z

Commands:z  r - Record current posez  d - Delete last posez  l - List recorded posesz  q - Quit and savez  h - Show helpz
Button Input:z9  - Press button on any leader arm to record current posez
Ready to record poses!Tz
Poses recorded: z / z
 (minimum)u    ✓ (minimum reached)z/
Waiting for input (button press or command)...r0   )endflushz#

Input received! Recording pose...g?rg?r   
z
Command [r/d/l/q/h]: )r   dlqhz
Command: u   ✓ Recorded pose rk      z,  Right follower position (first 3 joints): c                     g | ]}|d S z.3fr)   rw   ps     r   rx   zECalibrationPoseRecorder.run_interactive_recording.<locals>.<listcomp>  s    KdKdKd[\qJJKdKdKdr    z+  Left follower position (first 3 joints): c                     g | ]}|d S r   r)   r   s     r   rx   zECalibrationPoseRecorder.run_interactive_recording.<locals>.<listcomp>  s    JcJcJcZ[a::JcJcJcr    r   r   r   z
Warning: Only z poses recorded (minimum: z).zContinue anyway? [y/N]: yzContinuing recording...z%
Calibration pose recording complete!r   z,  - Press button on any leader arm to recordzUnknown command: zType 'h' for helpz

Interrupted by userz+Save recorded poses before exiting? [Y/n]: nz
Error: ):selectsignaltermiosttyrm   r   r   r]   r8   r   SIGTERMrC   r;   r   r   r   r   r   rU   waits_for_button_startrB   leader_rleader_lsysstdinisatty	tcgetattrra   rA   polltimesleepsetrawfilenoread	tcsetattr	TCSADRAINKeyboardInterruptinputstriplowerri   r,   r-   r.   r/   ro   rq   r   shutdownr   	traceback	print_exc
has_robotsr   r   r   cleanup)r   r   r   r   r   r   r   r   has_leadersold_settingsposes_countstatuscommandcharrg   posconfirmsaver   r   s   `                   r   run_interactive_recordingz1CalibrationPoseRecorder.run_interactive_recording   s5
   


o<===h 	;<<<  """ 	   	3 	3 	3 	3 	3 	fnn555!""". 	# 	#F///"""".///ed1;eed>Q>[eee	
 	
 	
 	T4#6#Dt#KTTTTUUUS$"5"Cd"JSSSSTTTA!4!?AABBB   CDDD>& 	ESTTTTCDDDPQQQ>0 	2RSSSS0111WIWWW	
 	
 	
 	m)***&''')***#$$$   +4V8M8V 	O#$$$MNNNo())) 9 	8",,SY77LM	0p/!$*oo;k;;**9I9999FF66FfF    o~**4+@AA EFFF
3"% y'')) (l (!==#)b"dCCAF &JJsy'7'7'9'9:::#&9>>!#4#4D#-- #	7+<l    $v~~&7 7!% %&ArQU V V V V*/''--//*?*?*A*A %!%)B!B!B*. %&?g&?&? @ @ @ % 
3C oF c>>3355DEtwEE$)EEFFF,7 DO "obqb1fKdKd`cKdKdKdff   ,7 DO "obqb1eJcJc_bJcJcJcee   ^^))++++^^OO%%%%^^"Y..c{ccV_ccc   8bMMMM' #-- #	7+<l   #(''--//"7"7"9"9"c>>!";<<<$OO%%%BCCC )22444^^-(((566623335666/000+,,," Nt~'L N/000LMMM 7g77888-...ap/B " ! 	- 	- 	-+,,, N!!#)W->MMMz &CSWXXXXww}},,..3;;OO%%% !**,,,,, 	7 	7 	7/a//"""!!! $ 7)>)I)I)K)K 7%44666	7 N  """##%%%$ 0%--/////0 0 N  """##%%%$ 0%--////0s@   Q,]9 7d 9B?b08d :	b0A#b+&d +b00d Ae)r0   )r   )r^   N)r   )r!   r"   r#   r$   r   r   r   r(   r	   r   rI   r]   r+   ri   boolro   rq   rs   r   r%   r   r   r   r   r  r)   r    r   r7   r7   >   s       44
 2"/7;3 3"3 3  	3
 !!343 3 3 3,4 4 4B  o    .$    
3 
3 
3*D * * * *L L L" 3     "- - - -<M M M M   X0 X03 X0 X0 X0 X0 X0 X0r    r7   r   r8   r   r9   r:   r;   c                 X    t          | |||          }|                    |           dS )z/Main entry point for calibration pose recording)r8   r9   r:   r;   )r   N)r7   r  )r8   r   r9   r:   r;   recorders         r   run_calibration_pose_recordingr    sC     '-%	  H &&&;;;;;r    )%r$   r   r   rF   r   dataclassesr   r   r   pathlibr   typingr   r   r	   urllib.parser
   r   rerunr   raiden._configr   r   raiden.camera_configr   raiden.cameras.baser   raiden.controlr   raiden.robot.controllerr   r   r+   r7   r%   r(   r  r)   r    r   <module>r     s   : :  



      ) ) ) ) ) ) ) )             ' ' ' ' ' ' ' ' ' '       



     @ @ @ @ @ @ @ @ - - - - - - & & & & & & * * * * * * 3 3 3 3 3 3 
 
 
 
 
 
 
 
        0X0 X0 X0 X0 X0 X0 X0 X0z -+37< <<< < 	<
 /0< < < < < <r    