Skip to content

Hand-Eye Roundtrip

SUMMARY

hand_eye_roundtrip() recovers a single base_T_board from all frames, then reprojects board points through it and compares to detections, the core metric behind run()'s hand_eye_roundtrip_error.

SUPPORTED TARGETS

Available only on CharucoTarget, it consumes a camera_T_target_list produced by ChArUco detection.

UNITS

Input images are BGR ndarrays. robot_poses and tcp_T_camera are (4, 4) SE(3) matrices with translation in meters. Returns the round-trip error as a float in pixels.

The Skill

python
error = bench.hand_eye_roundtrip(
    images, robot_poses, tcp_T_camera, intrinsic_matrix, distortion_coefficients,
    target, camera_T_target_list,
)
SkillReturnsDescription
hand_eye_roundtrip(images, robot_poses, tcp_T_camera, intrinsic_matrix, distortion_coefficients, target, camera_T_target_list)floatRecovers a single base_T_board from all frames, then reprojects board points through it and compares to detections.
ParameterTypeDescription
imageslist[ndarray]BGR frames, aligned with robot_poses.
robot_poseslist[(4, 4) ndarray]Per-frame robot base to TCP transforms.
tcp_T_camera(4, 4) ndarrayHand-eye transform under test.
intrinsic_matrix(3, 3) ndarrayCamera matrix.
distortion_coefficientsndarrayDistortion coefficients.
targetCharucoTargetCalibration target the board points come from.
camera_T_target_listlist[(4, 4) ndarray]Per-frame target poses, aligned with images.

The Code

python
from telekinesis.axon import CalibrationBenchmark, EyeInHandCalibrator
from telekinesis.axon.targets import CharucoTarget

target = CharucoTarget(squares_x=6, squares_y=9, square_length=0.012, marker_length=0.009)

calibrator = EyeInHandCalibrator(target)
result = calibrator.calibrate(robot_T_tcp_list, image_list)

bench = CalibrationBenchmark()
error = bench.hand_eye_roundtrip(
    image_list, robot_T_tcp_list, result.tcp_T_camera,
    result.intrinsic_matrix, result.distortion_coefficients,
    target, result.camera_T_target_list,
)

BEST PRACTICE

Re-run hand_eye_roundtrip after any change to the intrinsics or the target definition, it depends on both, and a stale tcp_T_camera benchmarked against updated intrinsics will report a misleading error.