44 lines
1.5 KiB
C++
44 lines
1.5 KiB
C++
#include "fgc/SettleRule.h"
|
|
|
|
#include <cmath>
|
|
|
|
namespace fgc {
|
|
|
|
SettleRule::Verdict SettleRule::add(const FrameStats& f) {
|
|
if (f.brightness < 0) {
|
|
window_.clear();
|
|
return Verdict::Waiting;
|
|
}
|
|
window_.push_back(f);
|
|
const size_t n = p_.frames < 1 ? 1 : static_cast<size_t>(p_.frames);
|
|
while (window_.size() > n) window_.pop_front();
|
|
if (window_.size() < n || !steady()) return Verdict::Waiting;
|
|
|
|
bool in_band = true;
|
|
for (const auto& w : window_)
|
|
in_band = in_band && w.brightness >= bandLow() && w.brightness <= bandHigh();
|
|
if (in_band) return Verdict::Settled;
|
|
return atLimit() ? Verdict::AtLimit : Verdict::Waiting;
|
|
}
|
|
|
|
bool SettleRule::steady() const {
|
|
for (size_t i = 1; i < window_.size(); ++i) {
|
|
const double a = window_[i - 1].brightness, b = window_[i].brightness;
|
|
if (std::fabs(b - a) > p_.steady * std::fmax(a, 1.0)) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool SettleRule::atLimit() const {
|
|
const FrameStats& f = window_.back();
|
|
if (f.exposure_us < 0 || f.gain_db < 0) return false;
|
|
// A hair of slack: the camera reports quantised exposure and gain.
|
|
if (f.brightness < bandLow() && p_.exposure_max_us > 0 && p_.gain_max_db >= 0)
|
|
return f.exposure_us >= p_.exposure_max_us * 0.99 && f.gain_db >= p_.gain_max_db - 0.1;
|
|
if (f.brightness > bandHigh() && p_.exposure_min_us > 0 && p_.gain_min_db >= 0)
|
|
return f.exposure_us <= p_.exposure_min_us * 1.01 && f.gain_db <= p_.gain_min_db + 0.1;
|
|
return false;
|
|
}
|
|
|
|
} // namespace fgc
|