2222import numpy as np
2323
2424from dotbot .logger import LOGGER
25- from dotbot .models import DotBotCalibrationStateModel , DotBotLH2Position
26- from dotbot .protocol import PayloadLh2RawData
25+ from dotbot .models import DotBotCalibrationStateModel
26+ from dotbot .protocol import PayloadLh2CalibrationHomography , PayloadLh2RawData
2727
2828if sys .platform == "win32" :
2929 LIB_EXT = "dll"
@@ -121,7 +121,7 @@ def __init__(self):
121121 self .reference_points = REFERENCE_POINTS_DEFAULT
122122 Path .mkdir (CALIBRATION_DIR , exist_ok = True )
123123 self .calibration_output_path = CALIBRATION_DIR / "calibration.out"
124- self .calibration_data = self ._load_calibration ()
124+ self .calibration : PayloadLh2CalibrationHomography = self ._load_calibration ()
125125 self .calibration_points = np .zeros (
126126 (2 , len (self .reference_points ), 2 ), dtype = np .float64
127127 )
@@ -140,18 +140,14 @@ def state_model(self) -> DotBotCalibrationStateModel:
140140 return DotBotCalibrationStateModel (state = "done" )
141141 return DotBotCalibrationStateModel (state = "unknown" )
142142
143- def _load_calibration (self ) -> Optional [CalibrationData ]:
143+ def _load_calibration (self ) -> Optional [PayloadLh2CalibrationHomography ]:
144144 if not os .path .exists (self .calibration_output_path ):
145145 self .logger .info ("No calibration file found" )
146146 return None
147147 with open (self .calibration_output_path , "rb" ) as calibration_file :
148148 calibration = pickle .load (calibration_file )
149- # for compatibility with existing calibration data type, cast
150- # homography matrix to float32
151- calibration .m = calibration .m .astype (np .float32 )
152149 self .logger .info ("Lighthouse calibration loaded" )
153150 self .state = LighthouseManagerState .Calibrated
154-
155151 return calibration
156152
157153 def add_calibration_point (self , index ):
@@ -260,42 +256,23 @@ def compute_calibration(self): # pylint: disable=too-many-locals
260256 ransacReprojThreshold = 0.001 ,
261257 )
262258
263- self .calibration_data = CalibrationData (zeta , random_rodriguez , n , M )
259+ calibration_data = CalibrationData (zeta , random_rodriguez , n , M )
260+ matrix_bytes = bytearray ()
261+ for bytes_block in [
262+ int (n * 1e6 ).to_bytes (4 , "little" , signed = True )
263+ for n in calibration_data .m .ravel ()
264+ ]:
265+ matrix_bytes += bytes_block
266+
267+ # Prepare homography matrix and send it to the robot
268+ self .calibration = PayloadLh2CalibrationHomography (
269+ index = 0 ,
270+ homography_matrix = matrix_bytes ,
271+ )
264272
273+ # Store calibration data as pickle for later reload
265274 with open (self .calibration_output_path , "wb" ) as output_file :
266- pickle .dump (self .calibration_data , output_file )
275+ pickle .dump (self .calibration , output_file )
267276
268277 self .state = LighthouseManagerState .Calibrated
269- self .logger .info ("Calibration done" , data = self .calibration_data )
270-
271- def compute_position (
272- self , raw_data : PayloadLh2RawData
273- ) -> Optional [DotBotLH2Position ]:
274- """Compute the position coordinates from LH2 raw data and available calibration."""
275- if self .state != LighthouseManagerState .Calibrated :
276- return None
277-
278- if any (raw_data .locations [index ].bits == 0 for index in range (2 )):
279- return None
280-
281- counts = lh2_raw_data_to_counts (raw_data )
282- camera_points = np .asarray (
283- [
284- calculate_camera_point (
285- counts [0 ], counts [1 ], raw_data .locations [0 ].polynomial_index
286- ),
287- calculate_camera_point (
288- counts [0 ], counts [1 ], raw_data .locations [1 ].polynomial_index
289- ),
290- ],
291- dtype = np .float64 ,
292- )
293-
294- pts_cam_new = np .hstack ((camera_points , np .ones ((len (camera_points ), 1 ))))
295- reprojected_points = np .matmul (self .calibration_data .m , pts_cam_new [0 ].T )
296-
297- return DotBotLH2Position (
298- x = reprojected_points [0 ] / reprojected_points [2 ],
299- y = 1 - reprojected_points [1 ] / reprojected_points [2 ],
300- z = 0.0 ,
301- )
278+ self .logger .info ("Calibration done" , data = self .calibration )
0 commit comments