Solver-driven auto-exposure feeds solution.diagnostics.Matches to the PID controller (python/PiFinder/camera_interface.py:436). Matches is the count of stars tetra3 matched — it is zero both when the frame is genuinely too dark and when the frame is fine but the solver rejected it for some other reason.
SolveDiagnostics (python/PiFinder/types/positioning.py:241) carries no centroid count:
Matches: int = 0
RMSE: Optional[float] = None
Prob: Optional[float] = None
FOV: Optional[float] = None
T_solve: Optional[float] = None
T_extract: Optional[float] = None
So the controller cannot distinguish "no stars in the image" from "plenty of stars, but the solve failed". A frame full of good centroids that tetra3 discards reads to auto-exposure exactly like a black frame, and the controller walks the exposure in a direction that cannot help.
This is not new — defocus has always done this — but ADR 0027 gave it a second trigger. A mis-stated lens puts every frame outside the FOV gate, so tetra3 prunes perfectly good centroids before verification and Matches is zero on every frame. See the "Consequences" section of docs/adr/0027-fov-gate-derived-from-optical-train.md.
What to explore
Drive the controller from centroids detected rather than Matches. Centroid count measures what auto-exposure actually cares about — whether the frame has usable signal — and is independent of whether the solve succeeded.
Prerequisite: add a Centroids field to SolveDiagnostics. The count is already available in the solver at the point the diagnostics are built.
Worth deciding as part of this: whether centroid count replaces Matches as the control signal or supplements it (e.g. centroids for the exposure decision, Matches for a separate "are we solving?" signal).
Related: #611 gates zero-match recovery on the same new field — worth landing Centroids once and building both on it.
Found while implementing #609 / ADR 0027.
Solver-driven auto-exposure feeds
solution.diagnostics.Matchesto the PID controller (python/PiFinder/camera_interface.py:436).Matchesis the count of stars tetra3 matched — it is zero both when the frame is genuinely too dark and when the frame is fine but the solver rejected it for some other reason.SolveDiagnostics(python/PiFinder/types/positioning.py:241) carries no centroid count:So the controller cannot distinguish "no stars in the image" from "plenty of stars, but the solve failed". A frame full of good centroids that tetra3 discards reads to auto-exposure exactly like a black frame, and the controller walks the exposure in a direction that cannot help.
This is not new — defocus has always done this — but ADR 0027 gave it a second trigger. A mis-stated lens puts every frame outside the FOV gate, so tetra3 prunes perfectly good centroids before verification and
Matchesis zero on every frame. See the "Consequences" section ofdocs/adr/0027-fov-gate-derived-from-optical-train.md.What to explore
Drive the controller from centroids detected rather than
Matches. Centroid count measures what auto-exposure actually cares about — whether the frame has usable signal — and is independent of whether the solve succeeded.Prerequisite: add a
Centroidsfield toSolveDiagnostics. The count is already available in the solver at the point the diagnostics are built.Worth deciding as part of this: whether centroid count replaces
Matchesas the control signal or supplements it (e.g. centroids for the exposure decision,Matchesfor a separate "are we solving?" signal).Related: #611 gates zero-match recovery on the same new field — worth landing
Centroidsonce and building both on it.Found while implementing #609 / ADR 0027.