diff --git a/docs/docs/configuration/autotracking.md b/docs/docs/configuration/autotracking.md index 9545fa7d3..c053ef369 100644 --- a/docs/docs/configuration/autotracking.md +++ b/docs/docs/configuration/autotracking.md @@ -167,3 +167,7 @@ To maintain object tracking during PTZ moves, Frigate tracks the motion of your ### Calibration seems to have completed, but the camera is not actually moving to track my object. Why? Some cameras have firmware that reports that FOV RelativeMove, the ONVIF command that Frigate uses for autotracking, is supported. However, if the camera does not pan or tilt when an object comes into the required zone, your camera's firmware does not actually support FOV RelativeMove. One such camera is the Uniview IPC672LR-AX4DUPK. It actually moves its zoom motor instead of panning and tilting and does not follow the ONVIF standard whatsoever. + +### Frigate reports an error saying that calibration has failed. Why? + +Calibration measures the amount of time it takes for Frigate to make a series of movements with your PTZ. This error message is recorded in the log if these values are too high for Frigate to support calibrated autotracking. This is often the case when your camera's motor or network connection is too slow or your camera's firmware doesn't report the motor status in a timely manner. You can try running without calibration (just remove the `movement_weights` line from your config and restart), but if calibration fails, this often means that autotracking will behave unpredictably. diff --git a/frigate/config/camera/onvif.py b/frigate/config/camera/onvif.py index 0c7985454..ff34e2a10 100644 --- a/frigate/config/camera/onvif.py +++ b/frigate/config/camera/onvif.py @@ -64,7 +64,9 @@ class PtzAutotrackConfig(FrigateBaseModel): raise ValueError("Invalid type for movement_weights") if len(weights) != 5: - raise ValueError("movement_weights must have exactly 5 floats") + raise ValueError( + "movement_weights must have exactly 5 floats, remove this line from your config and run autotracking calibration" + ) return weights diff --git a/frigate/ptz/autotrack.py b/frigate/ptz/autotrack.py index fc6284f40..7295fbc6f 100644 --- a/frigate/ptz/autotrack.py +++ b/frigate/ptz/autotrack.py @@ -500,9 +500,28 @@ class PtzAutoTracker: # simple linear regression with intercept X_with_intercept = np.column_stack((np.ones(X.shape[0]), X)) - self.move_coefficients[camera] = np.linalg.lstsq( - X_with_intercept, y, rcond=None - )[0] + coefficients = np.linalg.lstsq(X_with_intercept, y, rcond=None)[0] + + intercept, slope = coefficients + + # Define reasonable bounds for PTZ movement times + MIN_MOVEMENT_TIME = 0.1 # Minimum time for any movement (100ms) + MAX_MOVEMENT_TIME = 10.0 # Maximum time for any movement + MAX_SLOPE = 2.0 # Maximum seconds per unit of movement + + coefficients_valid = ( + MIN_MOVEMENT_TIME <= intercept <= MAX_MOVEMENT_TIME + and 0 < slope <= MAX_SLOPE + ) + + if not coefficients_valid: + logger.warning( + f"{camera}: Autotracking calibration failed. See the Frigate documentation." + ) + return False + + # If coefficients are valid, proceed with updates + self.move_coefficients[camera] = coefficients # only assign a new intercept if we're calibrating if calibration: