INSTINCT Code Coverage Report


Directory: src/
File: Navigation/GNSS/Ambiguity/AmbiguityResolution.cpp
Date: 2025-11-25 23:34:18
Exec Total Coverage
Lines: 10 119 8.4%
Functions: 1 8 12.5%
Branches: 8 95 8.4%

Line Branch Exec Source
1 // This file is part of INSTINCT, the INS Toolkit for Integrated
2 // Navigation Concepts and Training by the Institute of Navigation of
3 // the University of Stuttgart, Germany.
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9 /// @file AmbiguityResolution.cpp
10 /// @brief Ambiguity resolution algorithms
11 /// @author T. Topp (topp@ins.uni-stuttgart.de)
12 /// @date 2023-09-20
13
14 #include "AmbiguityResolution.hpp"
15 #include <imgui.h>
16
17 #include "internal/gui/widgets/imgui_ex.hpp"
18 #include "internal/gui/widgets/EnumCombo.hpp"
19 #include "internal/gui/widgets/EnumComboWithAbbreviation.hpp"
20 #include "internal/gui/widgets/HelpMarker.hpp"
21
22 namespace NAV
23 {
24
25 const char* to_string(AmbiguityResolutionStrategy ambiguityResolutionStrategy)
26 {
27 switch (ambiguityResolutionStrategy)
28 {
29 case AmbiguityResolutionStrategy::Continuous:
30 return "Continuous";
31 case AmbiguityResolutionStrategy::FixAndHold:
32 return "Fix and Hold";
33 case AmbiguityResolutionStrategy::COUNT:
34 break;
35 }
36 return "";
37 }
38
39 const char* to_string(AmbiguityResolutionParameters::DecorrelationAlgorithm decorrelationAlgorithm)
40 {
41 switch (decorrelationAlgorithm)
42 {
43 case AmbiguityResolutionParameters::DecorrelationAlgorithm::None:
44 return "None";
45 case AmbiguityResolutionParameters::DecorrelationAlgorithm::Z_Transformation:
46 return "Z-Transformation";
47 case AmbiguityResolutionParameters::DecorrelationAlgorithm::COUNT:
48 break;
49 }
50 return "";
51 }
52
53 const char* to_string(AmbiguityResolutionParameters::SearchAlgorithm searchAlgorithm)
54 {
55 switch (searchAlgorithm)
56 {
57 case AmbiguityResolutionParameters::SearchAlgorithm::None:
58 return "None";
59 case AmbiguityResolutionParameters::SearchAlgorithm::IntegerRounding:
60 return "Integer Rounding (IR)";
61 case AmbiguityResolutionParameters::SearchAlgorithm::IntegerBootstrapping:
62 return "Integer Bootstrapping (IB)";
63 case AmbiguityResolutionParameters::SearchAlgorithm::IntegerLeastSquaresSearch:
64 return "Integer least-squares (ILS) Search (LAMBDA)";
65 case AmbiguityResolutionParameters::SearchAlgorithm::IntegerLeastSquaresSearchAndShrink:
66 return "Integer least-squares (ILS) Search-And-Shrink (MLAMBDA)";
67 case AmbiguityResolutionParameters::SearchAlgorithm::COUNT:
68 break;
69 }
70 return "";
71 }
72
73 const char* to_string_short(AmbiguityResolutionParameters::SearchAlgorithm searchAlgorithm)
74 {
75 switch (searchAlgorithm)
76 {
77 case AmbiguityResolutionParameters::SearchAlgorithm::None:
78 return "None";
79 case AmbiguityResolutionParameters::SearchAlgorithm::IntegerRounding:
80 return "Integer Rounding (IR)";
81 case AmbiguityResolutionParameters::SearchAlgorithm::IntegerBootstrapping:
82 return "Integer Bootstrapping (IB)";
83 case AmbiguityResolutionParameters::SearchAlgorithm::IntegerLeastSquaresSearch:
84 return "ILS Search (LAMBDA)";
85 case AmbiguityResolutionParameters::SearchAlgorithm::IntegerLeastSquaresSearchAndShrink:
86 return "ILS Search-And-Shrink (MLAMBDA)";
87 case AmbiguityResolutionParameters::SearchAlgorithm::COUNT:
88 break;
89 }
90 return "";
91 }
92
93 const char* to_string(AmbiguityResolutionParameters::ValidationAlgorithm validationAlgorithm)
94 {
95 switch (validationAlgorithm)
96 {
97 case AmbiguityResolutionParameters::ValidationAlgorithm::None:
98 return "None";
99 case AmbiguityResolutionParameters::ValidationAlgorithm::DifferenceTest:
100 return "Difference Test";
101 case AmbiguityResolutionParameters::ValidationAlgorithm::ProjectorTest:
102 return "Projector Test";
103 case AmbiguityResolutionParameters::ValidationAlgorithm::RatioTestCriticalValue:
104 return "Ratio Test (critical value)";
105 case AmbiguityResolutionParameters::ValidationAlgorithm::RatioTestFailureRate:
106 return "Ratio Test (failure rate)";
107 case AmbiguityResolutionParameters::ValidationAlgorithm::COUNT:
108 break;
109 }
110 return "";
111 }
112
113 bool GuiAmbiguityResolution(const char* id, AmbiguityResolutionParameters& params, float width)
114 {
115 bool changed = false;
116
117 if (params.searchAlgorithm == AmbiguityResolutionParameters::SearchAlgorithm::None) { ImGui::BeginDisabled(); }
118 ImGui::SetNextItemWidth(width - ImGui::GetStyle().IndentSpacing);
119 changed |= gui::widgets::EnumCombo(fmt::format("Decorrelation Algorithm##{}", id).c_str(), params.decorrelationAlgorithm);
120 if (params.searchAlgorithm == AmbiguityResolutionParameters::SearchAlgorithm::None) { ImGui::EndDisabled(); }
121
122 ImGui::SetNextItemWidth(width - ImGui::GetStyle().IndentSpacing);
123 changed |= gui::widgets::EnumComboAbbreviation(fmt::format("Search Algorithm##{}", id).c_str(), params.searchAlgorithm);
124
125 changed |= ImGui::Checkbox(fmt::format("Partial fixing##{}", id).c_str(), &params.partialFixing);
126
127 if (params.searchAlgorithm == AmbiguityResolutionParameters::SearchAlgorithm::None) { ImGui::BeginDisabled(); }
128 {
129 ImGui::SetNextItemWidth(width - ImGui::GetStyle().IndentSpacing);
130 changed |= gui::widgets::EnumCombo(fmt::format("Validation Algorithm##{}", id).c_str(), params.validationAlgorithm);
131
132 if (params.validationAlgorithm == AmbiguityResolutionParameters::ValidationAlgorithm::RatioTestFailureRate)
133 {
134 changed |= ImGui::Checkbox(fmt::format("Validate with Bootstrapped Upper Bound##{}", id).c_str(), &params.validationBootstrappedSuccessRate);
135 ImGui::SameLine();
136 gui::widgets::HelpMarker("Bootstrapped failure rate is an upper bound for the ILS failure rate\n"
137 "and can be analytically calculated. If the bootstrapped failure rate is\n"
138 "smaller than the selected failure rate, the ratio test can be skipped.");
139 }
140
141 ImGui::SetNextItemWidth(width - ImGui::GetStyle().IndentSpacing);
142 if (params.validationAlgorithm == AmbiguityResolutionParameters::ValidationAlgorithm::DifferenceTest)
143 {
144 changed |= ImGui::InputDouble(fmt::format("Critical Value c (R2 - R1 ≥ c)##{}", id).c_str(), &params.validationTestCriticalValueC, 0.0, 0.0, "%.3g");
145 }
146 else if (params.validationAlgorithm == AmbiguityResolutionParameters::ValidationAlgorithm::RatioTestCriticalValue)
147 {
148 changed |= ImGui::InputDoubleL(fmt::format("Critical Value µ ∈ (0, 1] (R1/R2 ≤ µ)##{}", id).c_str(), &params.validationTestCriticalValueMu, 1e-10, 1.0, 0.0, 0.0, "%.3g");
149 }
150 else if (params.validationAlgorithm == AmbiguityResolutionParameters::ValidationAlgorithm::ProjectorTest)
151 {
152 changed |= ImGui::InputDoubleL(fmt::format("Critical Value µ ∈ (0, 1]##{}", id).c_str(), &params.validationTestCriticalValueMu, 1e-10, 1.0, 0.0, 0.0, "%.3g");
153 }
154 else if (params.validationAlgorithm == AmbiguityResolutionParameters::ValidationAlgorithm::RatioTestFailureRate)
155 {
156 int item_current = 0;
157 for (size_t i = 0; i < AmbiguityResolutionParameters::allowedFailureRateValues.size(); i++)
158 {
159 if (params.validationRatioTestFailureRate == AmbiguityResolutionParameters::allowedFailureRateValues.at(i))
160 {
161 item_current = static_cast<int>(i);
162 break;
163 }
164 }
165 if (ImGui::Combo(fmt::format("Failure rate##{}", id).c_str(), &item_current, "0.1 %\0001 %\0\0"))
166 {
167 params.validationRatioTestFailureRate = AmbiguityResolutionParameters::allowedFailureRateValues.at(static_cast<size_t>(item_current));
168 changed = true;
169 }
170 }
171 }
172 if (params.searchAlgorithm == AmbiguityResolutionParameters::SearchAlgorithm::None) { ImGui::EndDisabled(); }
173
174 return changed;
175 }
176
177 void to_json(json& j, const AmbiguityResolutionParameters& obj)
178 {
179 j = json{
180 { "decorrelationAlgorithm", obj.decorrelationAlgorithm },
181 { "searchAlgorithm", obj.searchAlgorithm },
182 { "partialFixing", obj.partialFixing },
183 { "validationBootstrappedSuccessRate", obj.validationBootstrappedSuccessRate },
184 { "validationAlgorithm", obj.validationAlgorithm },
185 { "validationTestCriticalValueC", obj.validationTestCriticalValueC },
186 { "validationTestCriticalValueMu", obj.validationTestCriticalValueMu },
187 { "validationRatioTestFailureRate", obj.validationRatioTestFailureRate },
188 };
189 }
190
191 1 void from_json(const json& j, AmbiguityResolutionParameters& obj)
192 {
193
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (j.contains("decorrelationAlgorithm")) { j.at("decorrelationAlgorithm").get_to(obj.decorrelationAlgorithm); }
194
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (j.contains("searchAlgorithm")) { j.at("searchAlgorithm").get_to(obj.searchAlgorithm); }
195
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (j.contains("partialFixing")) { j.at("partialFixing").get_to(obj.partialFixing); }
196
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (j.contains("validationBootstrappedSuccessRate")) { j.at("validationBootstrappedSuccessRate").get_to(obj.validationBootstrappedSuccessRate); }
197
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (j.contains("validationAlgorithm")) { j.at("validationAlgorithm").get_to(obj.validationAlgorithm); }
198
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (j.contains("validationTestCriticalValueC")) { j.at("validationTestCriticalValueC").get_to(obj.validationTestCriticalValueC); }
199
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (j.contains("validationTestCriticalValueMu")) { j.at("validationTestCriticalValueMu").get_to(obj.validationTestCriticalValueMu); }
200
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (j.contains("validationRatioTestFailureRate")) { j.at("validationRatioTestFailureRate").get_to(obj.validationRatioTestFailureRate); }
201 1 }
202
203 } // namespace NAV
204