INSTINCT Code Coverage Report


Directory: src/
File: Navigation/GNSS/Errors/MeasurementErrors.cpp
Date: 2025-02-07 16:54:41
Exec Total Coverage
Lines: 90 315 28.6%
Functions: 15 26 57.7%
Branches: 48 430 11.2%

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 #include "MeasurementErrors.hpp"
10
11 #include <limits>
12 #include <implot.h>
13 #include <fmt/format.h>
14
15 #include "internal/gui/widgets/EnumCombo.hpp"
16 #include "internal/gui/widgets/imgui_ex.hpp"
17 #include "internal/gui/widgets/InputWithUnit.hpp"
18 #include "internal/gui/NodeEditorApplication.hpp"
19
20 #include "Navigation/GNSS/Functions.hpp"
21
22 #include "util/Logger.hpp"
23
24 namespace NAV
25 {
26
27
2/4
✓ Branch 8 taken 120 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 120 times.
✗ Branch 12 not taken.
480 GnssMeasurementErrorModel::GnssMeasurementErrorModel()
28 {
29
2/2
✓ Branch 0 taken 960 times.
✓ Branch 1 taken 120 times.
1080 for (size_t i = 0; i < Model::COUNT; i++)
30 {
31
1/2
✓ Branch 1 taken 960 times.
✗ Branch 2 not taken.
960 updateStdDevCurvePlot(static_cast<Model>(i));
32 }
33 120 }
34
35 41798 double GnssMeasurementErrorModel::psrMeasErrorVar(const SatelliteSystem& satSys, double elevation, double cn0) const
36 {
37 41798 return satSysErrorFactorVariance(satSys) * std::pow(_codeStdDev * weightingFunction(_model, elevation, cn0), 2.0);
38 }
39
40 double GnssMeasurementErrorModel::carrierMeasErrorVar(const SatelliteSystem& satSys, double elevation, double cn0) const
41 {
42 return satSysErrorFactorVariance(satSys) * std::pow(_carrierStdDev * weightingFunction(_model, elevation, cn0), 2.0);
43 }
44
45 40922 double GnssMeasurementErrorModel::psrRateMeasErrorVar(const Frequency& freq, int8_t num, double elevation, double cn0) const
46 {
47 40922 double psrRateMeasStdDev = doppler2rangeRate(_dopplerStdDev, freq, num);
48
3/6
✓ Branch 1 taken 40922 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40922 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 40922 times.
✗ Branch 8 not taken.
40922 return satSysErrorFactorVariance(freq.getSatSys()) * std::pow(psrRateMeasStdDev * weightingFunction(_model, elevation, cn0), 2.0);
49 }
50
51 41798 double GnssMeasurementErrorModel::codeBiasErrorVar() const // NOLINT(readability-convert-member-functions-to-static)
52 {
53 // Rtklib model, as no other available
54
55 41798 constexpr double ERR_CBIAS = 0.3; // Code bias error Std [m]
56 41798 return std::pow(ERR_CBIAS, 2);
57 }
58
59 82720 double GnssMeasurementErrorModel::satSysErrorFactorVariance(const SatelliteSystem& satSys)
60 {
61 82720 double satSysErrFactor = 1.0;
62
1/5
✓ Branch 1 taken 82720 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
82720 switch (static_cast<SatelliteSystem_>(satSys))
63 {
64 82720 case GPS:
65 case GAL:
66 case BDS:
67 case QZSS:
68 82720 satSysErrFactor = 1.0;
69 82720 break;
70 case GLO:
71 case IRNSS:
72 satSysErrFactor = 1.5;
73 break;
74 case SBAS:
75 satSysErrFactor = 3.0;
76 break;
77 case SatSys_None:
78 break;
79 }
80 82720 return std::pow(satSysErrFactor, 2);
81 }
82
83 8723680 double GnssMeasurementErrorModel::weightingFunction(Model model, double elevation, double cn0) const
84 {
85
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8723680 times.
8723680 if (std::isnan(elevation)) { return 1.0; }
86 8723680 elevation = std::max(elevation, deg2rad(0.1));
87
8/9
✓ Branch 0 taken 1084500 times.
✓ Branch 1 taken 1080120 times.
✓ Branch 2 taken 1080120 times.
✓ Branch 3 taken 1158460 times.
✓ Branch 4 taken 1080120 times.
✓ Branch 5 taken 1080120 times.
✓ Branch 6 taken 1080120 times.
✓ Branch 7 taken 1080120 times.
✗ Branch 8 not taken.
8723680 switch (model)
88 {
89 1084500 case Model::SINE:
90 1084500 return _modelParametersSine.a / std::sin(elevation);
91 1080120 case Model::SINE_OFFSET:
92 1080120 return _modelParametersSineOffset.a + _modelParametersSineOffset.b / std::sin(elevation);
93 1080120 case Model::SINE_CN0:
94 1080120 cn0 = std::pow(10, cn0 / 10); // See Groves, ch 9.1.4.3, eq. 9.22, p. 363
95 1080120 return _modelParametersSineCN0.a / std::sin(elevation) * (_modelParametersSineCN0.b + _modelParametersSineCN0.c / std::sqrt(cn0));
96 1158460 case Model::RTKLIB:
97 1158460 elevation = std::max(elevation, deg2rad(5.0));
98 1158460 return std::sqrt(std::pow(_modelParametersRtklib.a, 2) + std::pow(_modelParametersRtklib.b / std::sin(elevation), 2));
99 1080120 case Model::SINE_SQRT:
100 1080120 return std::sqrt(std::pow(_modelParametersSineSqrt.a, 2) + std::pow(_modelParametersSineSqrt.b, 2) / std::pow(std::sin(elevation), 2));
101 1080120 case Model::EXPONENTIAL:
102 1080120 return _modelParametersExponential.a + _modelParametersExponential.b * std::exp(-elevation / deg2rad(_modelParametersExponential.e0));
103 1080120 case Model::COSINE_TYPE:
104 1080120 return std::sqrt(_modelParametersCosineType.a + _modelParametersCosineType.b * std::pow(std::cos(elevation), _modelParametersCosineType.n));
105 1080120 case Model::None:
106 case Model::COUNT:
107 1080120 break;
108 }
109 1080120 return 1.0;
110 }
111
112 960 void GnssMeasurementErrorModel::updateStdDevCurvePlot(Model model)
113 {
114
2/2
✓ Branch 0 taken 8640960 times.
✓ Branch 1 taken 960 times.
8642880 for (size_t i = 0; i < _elevation.size(); ++i)
115 {
116 8640960 _stdDevCurvePlot.at(static_cast<size_t>(model)).at(i) = weightingFunction(model, _elevation.at(i), _plotCN0);
117 }
118 960 }
119
120 bool GnssMeasurementErrorModel::ShowGuiWidgets(const char* id, float width)
121 {
122 const float UNIT_WIDTH = 100.0F * gui::NodeEditorApplication::windowFontRatio();
123 const float BUTTON_WIDTH = 25.0F * gui::NodeEditorApplication::windowFontRatio();
124
125 ImGui::SetNextItemWidth(width - BUTTON_WIDTH - 2 * ImGui::GetStyle().ItemInnerSpacing.x);
126 bool changed = gui::widgets::EnumCombo(fmt::format("##GNSS Measurement Error Model EnumCombo {}", id).c_str(), _model);
127 ImGui::SameLine();
128 if (ImGui::Button(fmt::format("...## GnssMeasurementError {}", id).c_str(), ImVec2(BUTTON_WIDTH, 0)))
129 {
130 ImGui::OpenPopup(fmt::format("{} GnssMeasurementError Popup", id).c_str());
131 }
132 ImGui::SameLine(0.0F, ImGui::GetStyle().ItemInnerSpacing.x);
133 ImGui::TextUnformatted("Weighting Function");
134
135 int combo_current_item = 0;
136 changed |= gui::widgets::InputDoubleWithUnit(fmt::format("Carrier-Phase StdDev σ₀##{}", id).c_str(), width, UNIT_WIDTH,
137 &_carrierStdDev, combo_current_item, "m\0\0", 0.0, 0.0, "%.3g", ImGuiInputTextFlags_CharsScientific);
138 changed |= gui::widgets::InputDoubleWithUnit(fmt::format("Code/Pseudorange StdDev σ₀##{}", id).c_str(), width, UNIT_WIDTH,
139 &_codeStdDev, combo_current_item, "m\0\0", 0.0, 0.0, "%.3g", ImGuiInputTextFlags_CharsScientific);
140
141 changed |= gui::widgets::InputDoubleWithUnit(fmt::format("Doppler StdDev σ₀##{}", id).c_str(), width, UNIT_WIDTH,
142 &_dopplerStdDev, combo_current_item, "Hz\0\0", 0.0, 0.0, "%.3g", ImGuiInputTextFlags_CharsScientific);
143 ImGui::SameLine();
144 ImGui::Text("= %.2g m/s (G1)", std::abs(doppler2rangeRate(_dopplerStdDev, G01, -128)));
145
146 if (ImGui::BeginPopup(fmt::format("{} GnssMeasurementError Popup", id).c_str()))
147 {
148 const float PLOT_WIDTH = 500.0F * gui::NodeEditorApplication::windowFontRatio();
149 const float PLOT_HEIGHT = 450.0F * gui::NodeEditorApplication::windowFontRatio();
150 const float TABLE_WIDTH = 440.0F * gui::NodeEditorApplication::windowFontRatio();
151 const float ITEM_WIDTH = 160.0F * gui::NodeEditorApplication::windowFontRatio();
152
153 const float WINDOW_HEIGHT = PLOT_HEIGHT + 30.0F * gui::NodeEditorApplication::windowFontRatio();
154
155 if (ImGui::BeginChild("left pane", ImVec2(PLOT_WIDTH, WINDOW_HEIGHT), false, ImGuiWindowFlags_NoScrollbar))
156 {
157 ImPlot::SetNextAxesLimits(_elevation_deg[0], _elevation_deg[PLOT_SAMPLES - 1], 0, 5, ImPlotCond_Once);
158 if (ImPlot::BeginPlot("Weighting function", ImVec2(ImGui::GetContentRegionAvail().x, PLOT_HEIGHT)))
159 {
160 ImPlot::SetupAxisLimitsConstraints(ImAxis_X1, _elevation_deg[0], _elevation_deg[PLOT_SAMPLES - 1]);
161 ImPlot::SetupAxisLimitsConstraints(ImAxis_Y1, 0.0, std::numeric_limits<double>::max());
162 ImPlot::SetupAxes("Elevation [deg]", "Weighting function [-]");
163 ImPlot::SetupLegend(ImPlotLocation_NorthEast);
164 for (size_t i = 0; i < Model::COUNT; i++)
165 {
166 ImPlot::PlotLine(to_string(static_cast<Model>(i)), _elevation_deg.data(), _stdDevCurvePlot.at(i).data(), static_cast<int>(_elevation_deg.size()));
167 }
168 ImPlot::EndPlot();
169 }
170 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 40.0F * gui::NodeEditorApplication::windowFontRatio());
171 if (ImGui::SliderDouble(fmt::format("c/n₀##{}", id).c_str(), &_plotCN0, 0.0, 60.0, "%.2f dB-Hz"))
172 {
173 updateStdDevCurvePlot(Model::SINE_CN0);
174 changed = true;
175 }
176 }
177 ImGui::EndChild();
178
179 ImGui::SameLine();
180
181 if (ImGui::BeginTable("parameter settings", 2, ImGuiTableFlags_SizingStretchSame, ImVec2(TABLE_WIDTH, 0.0F)))
182 {
183 ImGui::TableNextColumn();
184 ImGui::SetNextItemOpen(true, ImGuiCond_Always);
185 if (ImGui::CollapsingHeader(fmt::format("{}##{}", to_string(Model::SINE), id).c_str()))
186 {
187 ImGui::TextUnformatted("wf = a/sin(e)");
188 ImGui::SetNextItemWidth(ITEM_WIDTH);
189 if (ImGui::DragDouble(fmt::format("a##{} - {}", fmt::underlying(Model::SINE), id).c_str(), &_modelParametersSine.a, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
190 {
191 updateStdDevCurvePlot(Model::SINE);
192 changed = true;
193 }
194 }
195 ImGui::TableNextColumn();
196 ImGui::SetNextItemOpen(true, ImGuiCond_Always);
197 if (ImGui::CollapsingHeader(fmt::format("{}##{}", to_string(Model::SINE_OFFSET), id).c_str(), ImGuiTreeNodeFlags_DefaultOpen))
198 {
199 ImGui::TextUnformatted("wf = (a + b/sin(e))");
200 ImGui::SetNextItemWidth(ITEM_WIDTH);
201 if (ImGui::DragDouble(fmt::format("a##{} - {}", fmt::underlying(Model::SINE_OFFSET), id).c_str(), &_modelParametersSineOffset.a, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
202 {
203 updateStdDevCurvePlot(Model::SINE_OFFSET);
204 changed = true;
205 }
206 ImGui::SetNextItemWidth(ITEM_WIDTH);
207 if (ImGui::DragDouble(fmt::format("b##{} - {}", fmt::underlying(Model::SINE_OFFSET), id).c_str(), &_modelParametersSineOffset.b, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
208 {
209 updateStdDevCurvePlot(Model::SINE_OFFSET);
210 changed = true;
211 }
212 }
213 ImGui::TableNextColumn();
214 ImGui::SetNextItemOpen(true, ImGuiCond_Always);
215 if (ImGui::CollapsingHeader(fmt::format("{}##{}", to_string(Model::SINE_CN0), id).c_str(), ImGuiTreeNodeFlags_DefaultOpen))
216 {
217 ImGui::TextUnformatted("wf = a/sin(e) * √(b + c/(c/n₀))");
218 ImGui::SetNextItemWidth(ITEM_WIDTH);
219 if (ImGui::DragDouble(fmt::format("a##{} - {}", fmt::underlying(Model::SINE_CN0), id).c_str(), &_modelParametersSineCN0.a, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
220 {
221 updateStdDevCurvePlot(Model::SINE_CN0);
222 changed = true;
223 }
224 ImGui::SetNextItemWidth(ITEM_WIDTH);
225 if (ImGui::DragDouble(fmt::format("b##{} - {}", fmt::underlying(Model::SINE_CN0), id).c_str(), &_modelParametersSineCN0.b, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
226 {
227 updateStdDevCurvePlot(Model::SINE_CN0);
228 changed = true;
229 }
230 ImGui::SetNextItemWidth(ITEM_WIDTH);
231 if (ImGui::DragDouble(fmt::format("c##{} - {}", fmt::underlying(Model::SINE_CN0), id).c_str(), &_modelParametersSineCN0.c, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
232 {
233 updateStdDevCurvePlot(Model::SINE_CN0);
234 changed = true;
235 }
236 }
237 ImGui::TableNextColumn();
238 ImGui::SetNextItemOpen(true, ImGuiCond_Always);
239 if (ImGui::CollapsingHeader(fmt::format("{}##{}", to_string(Model::RTKLIB), id).c_str(), ImGuiTreeNodeFlags_DefaultOpen))
240 {
241 ImGui::TextUnformatted("wf = √(a² + b²/sin(e))");
242 ImGui::SetNextItemWidth(ITEM_WIDTH);
243 if (ImGui::DragDouble(fmt::format("a##{} - {}", fmt::underlying(Model::RTKLIB), id).c_str(), &_modelParametersRtklib.a, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
244 {
245 updateStdDevCurvePlot(Model::RTKLIB);
246 changed = true;
247 }
248 ImGui::SetNextItemWidth(ITEM_WIDTH);
249 if (ImGui::DragDouble(fmt::format("b##{} - {}", fmt::underlying(Model::RTKLIB), id).c_str(), &_modelParametersRtklib.b, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
250 {
251 updateStdDevCurvePlot(Model::RTKLIB);
252 changed = true;
253 }
254 }
255 ImGui::TableNextColumn();
256 ImGui::SetNextItemOpen(true, ImGuiCond_Always);
257 if (ImGui::CollapsingHeader(fmt::format("{}##{}", to_string(Model::SINE_SQRT), id).c_str(), ImGuiTreeNodeFlags_DefaultOpen))
258 {
259 ImGui::TextUnformatted("wf = √(a² + b²/sin²(e))");
260 ImGui::SetNextItemWidth(ITEM_WIDTH);
261 if (ImGui::DragDouble(fmt::format("a##{} - {}", fmt::underlying(Model::SINE_SQRT), id).c_str(), &_modelParametersSineSqrt.a, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
262 {
263 updateStdDevCurvePlot(Model::SINE_SQRT);
264 changed = true;
265 }
266 ImGui::SetNextItemWidth(ITEM_WIDTH);
267 if (ImGui::DragDouble(fmt::format("b##{} - {}", fmt::underlying(Model::SINE_SQRT), id).c_str(), &_modelParametersSineSqrt.b, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
268 {
269 updateStdDevCurvePlot(Model::SINE_SQRT);
270 changed = true;
271 }
272 }
273 ImGui::TableNextColumn();
274 ImGui::SetNextItemOpen(true, ImGuiCond_Always);
275 if (ImGui::CollapsingHeader(fmt::format("{}##{}", to_string(Model::EXPONENTIAL), id).c_str(), ImGuiTreeNodeFlags_DefaultOpen))
276 {
277 ImGui::TextUnformatted("wf = (a + b * exp(-e/e₀))");
278 ImGui::SetNextItemWidth(ITEM_WIDTH);
279 if (ImGui::DragDouble(fmt::format("a##{} - {}", fmt::underlying(Model::EXPONENTIAL), id).c_str(), &_modelParametersExponential.a, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
280 {
281 updateStdDevCurvePlot(Model::EXPONENTIAL);
282 changed = true;
283 }
284 ImGui::SetNextItemWidth(ITEM_WIDTH);
285 if (ImGui::DragDouble(fmt::format("b##{} - {}", fmt::underlying(Model::EXPONENTIAL), id).c_str(), &_modelParametersExponential.b, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
286 {
287 updateStdDevCurvePlot(Model::EXPONENTIAL);
288 changed = true;
289 }
290 ImGui::SetNextItemWidth(ITEM_WIDTH);
291 if (ImGui::DragDouble(fmt::format("e0##{} - {}", fmt::underlying(Model::EXPONENTIAL), id).c_str(), &_modelParametersExponential.e0, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.1f"))
292 {
293 updateStdDevCurvePlot(Model::EXPONENTIAL);
294 changed = true;
295 }
296 }
297 ImGui::TableNextColumn();
298 ImGui::SetNextItemOpen(true, ImGuiCond_Always);
299 if (ImGui::CollapsingHeader(fmt::format("{}##{}", to_string(Model::COSINE_TYPE), id).c_str(), ImGuiTreeNodeFlags_DefaultOpen))
300 {
301 ImGui::TextUnformatted("wf = √(a + b * cosⁿ(e))");
302 ImGui::SetNextItemWidth(ITEM_WIDTH);
303 if (ImGui::DragDouble(fmt::format("a##{} - {}", fmt::underlying(Model::COSINE_TYPE), id).c_str(), &_modelParametersCosineType.a, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
304 {
305 updateStdDevCurvePlot(Model::COSINE_TYPE);
306 changed = true;
307 }
308 ImGui::SetNextItemWidth(ITEM_WIDTH);
309 if (ImGui::DragDouble(fmt::format("b##{} - {}", fmt::underlying(Model::COSINE_TYPE), id).c_str(), &_modelParametersCosineType.b, 0.1F, 0.0, std::numeric_limits<double>::max(), "%.2f"))
310 {
311 updateStdDevCurvePlot(Model::COSINE_TYPE);
312 changed = true;
313 }
314 ImGui::SetNextItemWidth(ITEM_WIDTH);
315 if (ImGui::InputIntL(fmt::format("n##{} - {}", fmt::underlying(Model::COSINE_TYPE), id).c_str(), &_modelParametersCosineType.n, 0))
316 {
317 updateStdDevCurvePlot(Model::COSINE_TYPE);
318 changed = true;
319 }
320 }
321 ImGui::EndTable();
322 }
323 ImGui::EndPopup();
324 }
325 return changed;
326 }
327
328 const char* to_string(GnssMeasurementErrorModel::Model model)
329 {
330 switch (model)
331 {
332 case GnssMeasurementErrorModel::Model::None:
333 return "None";
334 case GnssMeasurementErrorModel::Model::SINE:
335 return "Sine";
336 case GnssMeasurementErrorModel::Model::SINE_OFFSET:
337 return "Sine + Offset";
338 case GnssMeasurementErrorModel::Model::SINE_CN0:
339 return "Sine + CN0";
340 case GnssMeasurementErrorModel::Model::RTKLIB:
341 return "RTKLIB";
342 case GnssMeasurementErrorModel::Model::SINE_SQRT:
343 return "Sine-Sqrt";
344 case GnssMeasurementErrorModel::Model::EXPONENTIAL:
345 return "Exponential";
346 case GnssMeasurementErrorModel::Model::COSINE_TYPE:
347 return "Cosine-Type";
348 case GnssMeasurementErrorModel::Model::COUNT:
349 break;
350 }
351 return "";
352 }
353
354 void to_json(json& j, const GnssMeasurementErrorModel& obj)
355 {
356 j = json{
357 { "model", obj._model },
358 { "carrierStdDev", obj._carrierStdDev },
359 { "codeStdDev", obj._codeStdDev },
360 { "dopplerStdDev", obj._dopplerStdDev },
361 { "plotCN0", obj._plotCN0 },
362 { "modelParametersSine", obj._modelParametersSine },
363 { "modelParametersSineOffset", obj._modelParametersSineOffset },
364 { "modelParametersSineCN0", obj._modelParametersSineCN0 },
365 { "modelParametersRtklib", obj._modelParametersRtklib },
366 { "modelParametersSineSqrt", obj._modelParametersSineSqrt },
367 { "modelParametersExponential", obj._modelParametersExponential },
368 { "modelParametersCosineType", obj._modelParametersCosineType },
369 };
370 }
371
372 8 void from_json(const json& j, GnssMeasurementErrorModel& obj)
373 {
374
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("model")) { j.at("model").get_to(obj._model); }
375
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("carrierStdDev")) { j.at("carrierStdDev").get_to(obj._carrierStdDev); }
376
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("codeStdDev")) { j.at("codeStdDev").get_to(obj._codeStdDev); }
377
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("dopplerStdDev")) { j.at("dopplerStdDev").get_to(obj._dopplerStdDev); }
378
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("plotCN0")) { j.at("plotCN0").get_to(obj._plotCN0); }
379
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("modelParametersSine")) { j.at("modelParametersSine").get_to(obj._modelParametersSine); }
380
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("modelParametersSineOffset")) { j.at("modelParametersSineOffset").get_to(obj._modelParametersSineOffset); }
381
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("modelParametersSineCN0")) { j.at("modelParametersSineCN0").get_to(obj._modelParametersSineCN0); }
382
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("modelParametersRtklib")) { j.at("modelParametersRtklib").get_to(obj._modelParametersRtklib); }
383
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("modelParametersSineSqrt")) { j.at("modelParametersSineSqrt").get_to(obj._modelParametersSineSqrt); }
384
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("modelParametersExponential")) { j.at("modelParametersExponential").get_to(obj._modelParametersExponential); }
385
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("modelParametersCosineType")) { j.at("modelParametersCosineType").get_to(obj._modelParametersCosineType); }
386 8 }
387
388 void to_json(json& j, const GnssMeasurementErrorModel::ModelParametersSine& obj)
389 {
390 j = json{
391 { "a", obj.a },
392 };
393 }
394 8 void from_json(const json& j, GnssMeasurementErrorModel::ModelParametersSine& obj)
395 {
396
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("a")) { j.at("a").get_to(obj.a); }
397 8 }
398
399 void to_json(json& j, const GnssMeasurementErrorModel::ModelParametersSineOffset& obj)
400 {
401 j = json{
402 { "a", obj.a },
403 { "b", obj.b },
404 };
405 }
406 8 void from_json(const json& j, GnssMeasurementErrorModel::ModelParametersSineOffset& obj)
407 {
408
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("a")) { j.at("a").get_to(obj.a); }
409
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("b")) { j.at("b").get_to(obj.b); }
410 8 }
411
412 void to_json(json& j, const GnssMeasurementErrorModel::ModelParametersSineCN0& obj)
413 {
414 j = json{
415 { "a", obj.a },
416 { "b", obj.b },
417 { "c", obj.c },
418 };
419 }
420 8 void from_json(const json& j, GnssMeasurementErrorModel::ModelParametersSineCN0& obj)
421 {
422
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("a")) { j.at("a").get_to(obj.a); }
423
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("b")) { j.at("b").get_to(obj.b); }
424
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("c")) { j.at("c").get_to(obj.c); }
425 8 }
426
427 void to_json(json& j, const GnssMeasurementErrorModel::ModelParametersRtklib& obj)
428 {
429 j = json{
430 { "a", obj.a },
431 { "b", obj.b },
432 };
433 }
434 8 void from_json(const json& j, GnssMeasurementErrorModel::ModelParametersRtklib& obj)
435 {
436
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("a")) { j.at("a").get_to(obj.a); }
437
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("b")) { j.at("b").get_to(obj.b); }
438 8 }
439
440 void to_json(json& j, const GnssMeasurementErrorModel::ModelParametersSineSqrt& obj)
441 {
442 j = json{
443 { "a", obj.a },
444 { "b", obj.b },
445 };
446 }
447 8 void from_json(const json& j, GnssMeasurementErrorModel::ModelParametersSineSqrt& obj)
448 {
449
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("a")) { j.at("a").get_to(obj.a); }
450
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("b")) { j.at("b").get_to(obj.b); }
451 8 }
452
453 void to_json(json& j, const GnssMeasurementErrorModel::ModelParametersExponential& obj)
454 {
455 j = json{
456 { "a", obj.a },
457 { "b", obj.b },
458 { "e0", obj.e0 },
459 };
460 }
461 8 void from_json(const json& j, GnssMeasurementErrorModel::ModelParametersExponential& obj)
462 {
463
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("a")) { j.at("a").get_to(obj.a); }
464
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("b")) { j.at("b").get_to(obj.b); }
465
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("e0")) { j.at("e0").get_to(obj.e0); }
466 8 }
467
468 void to_json(json& j, const GnssMeasurementErrorModel::ModelParametersCosineType& obj)
469 {
470 j = json{
471 { "a", obj.a },
472 { "b", obj.b },
473 { "n", obj.n },
474 };
475 }
476 8 void from_json(const json& j, GnssMeasurementErrorModel::ModelParametersCosineType& obj)
477 {
478
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("a")) { j.at("a").get_to(obj.a); }
479
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("b")) { j.at("b").get_to(obj.b); }
480
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (j.contains("n")) { j.at("n").get_to(obj.n); }
481 8 }
482
483 } // namespace NAV
484