35class CycleSlipDetector;
56 : _enabled(enabled), _windowSize(windowSize), _polyDegree(polyDegree) {}
66 if (!_enabled) {
return PolynomialCycleSlipDetectorResult::Disabled; }
67 if (!_detectors.contains(key))
69 addMeasurement(key, insTime, measurementDifference);
70 return PolynomialCycleSlipDetectorResult::LessDataThanWindowSize;
73 const auto& detector = _detectors.at(key);
74 if (!detector.polyReg.windowSizeReached())
76 addMeasurement(key, insTime, measurementDifference);
77 return PolynomialCycleSlipDetectorResult::LessDataThanWindowSize;
80 auto polynomial = detector.polyReg.calcPolynomial();
81 auto predictedValue = polynomial.f(calcRelativeTime(insTime, detector));
83 if (std::abs(measurementDifference - predictedValue) > threshold)
86 addMeasurement(key, insTime, measurementDifference);
87 return PolynomialCycleSlipDetectorResult::CycleSlip;
89 addMeasurement(key, insTime, measurementDifference);
90 return PolynomialCycleSlipDetectorResult::NoCycleSlip;
103 if (_detectors.contains(key))
105 _detectors.erase(key);
127 _windowSize = windowSize;
128 for (
auto& detector : _detectors)
130 detector.second.polyReg.setWindowSize(windowSize);
140 _polyDegree = polyDegree;
141 for (
auto& detector : _detectors)
143 detector.second.polyReg.setPolynomialDegree(polyDegree);
156 _strategy = strategy;
157 for (
auto& detector : _detectors)
159 detector.second.polyReg.setStrategy(strategy);
165 struct SignalDetector
172 SignalDetector(
InsTime startTime,
size_t windowSize,
size_t polyDegree,
Strategy strategy)
173 : startTime(startTime), polyReg(polyDegree, windowSize, strategy) {}
176 PolynomialRegressor<double> polyReg;
179 bool _enabled =
true;
181 size_t _polyDegree = 2;
182 Strategy _strategy = Strategy::HouseholderQR;
188 [[nodiscard]]
static double calcRelativeTime(
const InsTime& insTime,
const SignalDetector& detector)
190 return static_cast<double>((insTime - detector.startTime).count());
195 [[nodiscard]] std::optional<double> calcRelativeTime(
const Key& key,
const InsTime& insTime)
const
197 if (!_detectors.contains(key)) {
return {}; }
199 return calcRelativeTime(insTime, _detectors.at(key));
205 [[nodiscard]] std::optional<double> predictValue(
const Key& key,
const InsTime& insTime)
const
207 if (!_detectors.contains(key)) {
return {}; }
209 const auto& detector = _detectors.at(key);
211 auto polynomial = detector.polyReg.calcPolynomial();
212 return polynomial.f(calcRelativeTime(insTime, detector));
217 [[nodiscard]] std::optional<Polynomial<double>> calcPolynomial(
const Key& key)
const
219 if (!_detectors.contains(key)) {
return {}; }
221 return _detectors.at(key).polyReg.calcPolynomial();
228 void addMeasurement(
const Key& key, InsTime insTime,
double measurementDifference)
230 if (!_enabled) {
return; }
231 auto& detector = _detectors.insert({ key, SignalDetector(insTime, _windowSize, _polyDegree, _strategy) }).first->second;
233 detector.polyReg.push_back(calcRelativeTime(insTime, detector), measurementDifference);
236 friend class GnssAnalyzer;
237 friend class CycleSlipDetector;
244template<
typename Key>
247 bool changed =
false;
249 bool enabled = polynomialCycleSlipDetector.
isEnabled();
250 if (ImGui::Checkbox(fmt::format(
"Enabled##{}", label).c_str(), &enabled))
253 polynomialCycleSlipDetector.
setEnabled(enabled);
256 if (!enabled) { ImGui::BeginDisabled(); }
258 ImGui::SetNextItemWidth(width);
259 if (
int windowSize =
static_cast<int>(polynomialCycleSlipDetector.
getWindowSize());
260 ImGui::InputIntL(fmt::format(
"Window size##{}", label).c_str(), &windowSize,
264 polynomialCycleSlipDetector.
setWindowSize(
static_cast<size_t>(windowSize));
267 ImGui::SetNextItemWidth(width);
269 ImGui::InputIntL(fmt::format(
"Polynomial Degree##{}", label).c_str(), &polyDegree,
270 0, std::min(
static_cast<int>(polynomialCycleSlipDetector.
getWindowSize()) - 1, std::numeric_limits<int>::max())))
276 ImGui::SetNextItemWidth(width);
278 gui::widgets::EnumCombo(fmt::format(
"Strategy##{}", label).c_str(), strategy))
284 if (!enabled) { ImGui::EndDisabled(); }
292template<
typename Key>
305template<
typename Key>
308 if (j.contains(
"enabled"))
310 auto enabled = j.at(
"enabled").get<
bool>();
313 if (j.contains(
"windowSize"))
315 auto windowSize = j.at(
"windowSize").get<
size_t>();
318 if (j.contains(
"polynomialDegree"))
320 auto polynomialDegree = j.at(
"polynomialDegree").get<
size_t>();
323 if (j.contains(
"strategy"))
325 auto strategy = j.at(
"strategy").get<
size_t>();
Combo representing an enumeration.
nlohmann::json json
json namespace
Definition FlowManager.hpp:21
The class is responsible for all time-related tasks.
void from_json(const json &j, ImColor &color)
Converts the provided json object into a color.
void to_json(json &j, const ImColor &color)
Converts the provided color into a json object.
Utility functions for std::pair.
bool PolynomialCycleSlipDetectorGui(const char *label, PolynomialCycleSlipDetector< Key > &polynomialCycleSlipDetector, float width=0.0F)
Shows a GUI for advanced configuration of the PolynomialCycleSlipDetector.
Definition PolynomialCycleSlipDetector.hpp:245
PolynomialCycleSlipDetectorResult
Cycle-slip detection result type.
Definition PolynomialCycleSlipDetector.hpp:39
@ NoCycleSlip
No cycle-slip found.
@ LessDataThanWindowSize
Less data than the specified window size (cannot predict cycle-slip yet)
@ Disabled
The cycle-slip detector is disabled.
@ CycleSlip
Cycle-slip found.
Polynomial curve fitting.
Structs identifying a unique satellite.
ankerl::unordered_dense::map< Key, T > unordered_map
Unordered map type.
Definition Unordered_map.hpp:34
The class is responsible for all time-related tasks.
Definition InsTime.hpp:667
Cycle-slip detection.
Definition PolynomialCycleSlipDetector.hpp:49
size_t getPolynomialDegree() const
Get the degree of the polynomial which is used for fitting.
Definition PolynomialCycleSlipDetector.hpp:135
void setFitStrategy(Strategy strategy)
Sets the strategy used for fitting.
Definition PolynomialCycleSlipDetector.hpp:154
void setWindowSize(size_t windowSize)
Sets the amount of points used for the fit (sliding window)
Definition PolynomialCycleSlipDetector.hpp:125
void setEnabled(bool enabled)
Sets the enabled state.
Definition PolynomialCycleSlipDetector.hpp:116
PolynomialRegressor<>::Strategy Strategy
Strategies for fitting.
Definition PolynomialCycleSlipDetector.hpp:148
bool isEnabled() const
Is the cycle-slip detector enabled?
Definition PolynomialCycleSlipDetector.hpp:110
void setPolynomialDegree(size_t polyDegree)
Sets the degree of the polynomial which is used for fitting.
Definition PolynomialCycleSlipDetector.hpp:138
size_t getWindowSize() const
Get the window size for the polynomial fit.
Definition PolynomialCycleSlipDetector.hpp:122
PolynomialCycleSlipDetectorResult checkForCycleSlip(const Key &key, InsTime insTime, double measurementDifference, double threshold)
Checks for a cycle slip.
Definition PolynomialCycleSlipDetector.hpp:64
Strategy getFitStrategy() const
Get the strategy used for fitting.
Definition PolynomialCycleSlipDetector.hpp:151
void reset(const Key &key)
Reset the polynomial for the given combination.
Definition PolynomialCycleSlipDetector.hpp:101
PolynomialCycleSlipDetector(size_t windowSize, size_t polyDegree, bool enabled=true)
Constructor.
Definition PolynomialCycleSlipDetector.hpp:55
void clear()
Empties the collected polynomials.
Definition PolynomialCycleSlipDetector.hpp:94
Strategy
Possible Fit strategies.
Definition PolynomialRegressor.hpp:43