From e5b25d23e52ef5714a6a3cc0003fbddb5e4d297c Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Tue, 10 Nov 2026 07:25:40 -0600 Subject: [PATCH] fix autotracking movement time prediction and recorded move times Movement time prediction multiplied the fitted intercept by the saved zero-step calibration time instead of 1, so predictions didn't match the regression. In absolute zoom mode, a pan/tilt followed by a zoom recorded the zoom's timestamps against the pan/tilt distance, because _zoom_absolute resets the PTZ start and stop times. The pan/tilt times are now captured before the zoom runs. --- frigate/ptz/autotrack.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/frigate/ptz/autotrack.py b/frigate/ptz/autotrack.py index 6b9a85a1ad..0c63e3394d 100644 --- a/frigate/ptz/autotrack.py +++ b/frigate/ptz/autotrack.py @@ -585,7 +585,7 @@ class PtzAutoTracker(threading.Thread): def _predict_movement_time(self, camera, pan, tilt): combined_movement = abs(pan) + abs(tilt) - input_data = np.array([self.intercept[camera], combined_movement]) + input_data = np.array([1, combined_movement]) return np.dot(self.move_coefficients[camera], input_data) @@ -744,6 +744,8 @@ class PtzAutoTracker(threading.Thread): continue else: + pan_tilt_times = None + if ( camera_config.onvif.autotracking.zooming == ZoomingModeEnum.relative @@ -755,17 +757,28 @@ class PtzAutoTracker(threading.Thread): await self._wait_until_stopped(camera, metrics) + # _zoom_absolute resets the metrics timestamps + pan_tilt_times = ( + metrics.start_time.value, + metrics.stop_time.value, + ) + if zoom > 0 and metrics.zoom_level.value != zoom: await self.onvif._zoom_absolute(camera, zoom, 1) await self._wait_until_stopped(camera, metrics) + start_time, stop_time = pan_tilt_times or ( + metrics.start_time.value, + metrics.stop_time.value, + ) + if camera_config.onvif.autotracking.movement_weights: logger.debug( f"{camera}: Predicted movement time: {self._predict_movement_time(camera, pan, tilt)}" ) logger.debug( - f"{camera}: Actual movement time: {metrics.stop_time.value - metrics.start_time.value}" + f"{camera}: Actual movement time: {stop_time - start_time}" ) # save metrics for better estimate calculations @@ -781,8 +794,8 @@ class PtzAutoTracker(threading.Thread): { "pan": pan, "tilt": tilt, - "start_timestamp": metrics.start_time.value, - "end_timestamp": metrics.stop_time.value, + "start_timestamp": start_time, + "end_timestamp": stop_time, } )