fwt_software/src/core/SettleRule.cpp

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