0.3.0
Loading...
Searching...
No Matches
MeasurementErrors.cpp
Go to the documentation of this file.
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
10
11#include <limits>
12#include <implot.h>
13#include <fmt/format.h>
14
19
21
22#include "util/Logger.hpp"
23
24namespace NAV
25{
26
28{
29 for (size_t i = 0; i < Model::COUNT; i++)
30 {
31 updateStdDevCurvePlot(static_cast<Model>(i));
32 }
33}
34
35double GnssMeasurementErrorModel::psrMeasErrorVar(const SatelliteSystem& satSys, double elevation, double cn0) const
36{
37 return satSysErrorFactorVariance(satSys) * std::pow(_codeStdDev * weightingFunction(_model, elevation, cn0), 2.0);
38}
39
40double 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
45double GnssMeasurementErrorModel::psrRateMeasErrorVar(const Frequency& freq, int8_t num, double elevation, double cn0) const
46{
47 double psrRateMeasStdDev = doppler2rangeRate(_dopplerStdDev, freq, num);
48 return satSysErrorFactorVariance(freq.getSatSys()) * std::pow(psrRateMeasStdDev * weightingFunction(_model, elevation, cn0), 2.0);
49}
50
51double GnssMeasurementErrorModel::codeBiasErrorVar() const // NOLINT(readability-convert-member-functions-to-static)
52{
53 // Rtklib model, as no other available
54
55 constexpr double ERR_CBIAS = 0.3; // Code bias error Std [m]
56 return std::pow(ERR_CBIAS, 2);
57}
58
60{
61 double satSysErrFactor = 1.0;
62 switch (static_cast<SatelliteSystem_>(satSys))
63 {
64 case GPS:
65 case GAL:
66 case BDS:
67 case QZSS:
68 satSysErrFactor = 1.0;
69 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 return std::pow(satSysErrFactor, 2);
81}
82
83double GnssMeasurementErrorModel::weightingFunction(Model model, double elevation, double cn0) const
84{
85 if (std::isnan(elevation)) { return 1.0; }
86 elevation = std::max(elevation, deg2rad(0.1));
87 switch (model)
88 {
89 case Model::SINE:
90 return _modelParametersSine.a / std::sin(elevation);
92 return _modelParametersSineOffset.a + _modelParametersSineOffset.b / std::sin(elevation);
93 case Model::SINE_CN0:
94 cn0 = std::pow(10, cn0 / 10); // See Groves, ch 9.1.4.3, eq. 9.22, p. 363
95 return _modelParametersSineCN0.a / std::sin(elevation) * (_modelParametersSineCN0.b + _modelParametersSineCN0.c / std::sqrt(cn0));
96 case Model::RTKLIB:
97 elevation = std::max(elevation, deg2rad(5.0));
98 return std::sqrt(std::pow(_modelParametersRtklib.a, 2) + std::pow(_modelParametersRtklib.b / std::sin(elevation), 2));
100 return std::sqrt(std::pow(_modelParametersSineSqrt.a, 2) + std::pow(_modelParametersSineSqrt.b, 2) / std::pow(std::sin(elevation), 2));
104 return std::sqrt(_modelParametersCosineType.a + _modelParametersCosineType.b * std::pow(std::cos(elevation), _modelParametersCosineType.n));
105 case Model::None:
106 case Model::COUNT:
107 break;
108 }
109 return 1.0;
110}
111
113{
114 for (size_t i = 0; i < _elevation.size(); ++i)
115 {
116 _stdDevCurvePlot.at(static_cast<size_t>(model)).at(i) = weightingFunction(model, _elevation.at(i), _plotCN0);
117 }
118}
119
120bool 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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
318 changed = true;
319 }
320 }
321 ImGui::EndTable();
322 }
323 ImGui::EndPopup();
324 }
325 return changed;
326}
327
329{
330 switch (model)
331 {
333 return "None";
335 return "Sine";
337 return "Sine + Offset";
339 return "Sine + CN0";
341 return "RTKLIB";
343 return "Sine-Sqrt";
345 return "Exponential";
347 return "Cosine-Type";
349 break;
350 }
351 return "";
352}
353
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
373{
374 if (j.contains("model")) { j.at("model").get_to(obj._model); }
375 if (j.contains("carrierStdDev")) { j.at("carrierStdDev").get_to(obj._carrierStdDev); }
376 if (j.contains("codeStdDev")) { j.at("codeStdDev").get_to(obj._codeStdDev); }
377 if (j.contains("dopplerStdDev")) { j.at("dopplerStdDev").get_to(obj._dopplerStdDev); }
378 if (j.contains("plotCN0")) { j.at("plotCN0").get_to(obj._plotCN0); }
379 if (j.contains("modelParametersSine")) { j.at("modelParametersSine").get_to(obj._modelParametersSine); }
380 if (j.contains("modelParametersSineOffset")) { j.at("modelParametersSineOffset").get_to(obj._modelParametersSineOffset); }
381 if (j.contains("modelParametersSineCN0")) { j.at("modelParametersSineCN0").get_to(obj._modelParametersSineCN0); }
382 if (j.contains("modelParametersRtklib")) { j.at("modelParametersRtklib").get_to(obj._modelParametersRtklib); }
383 if (j.contains("modelParametersSineSqrt")) { j.at("modelParametersSineSqrt").get_to(obj._modelParametersSineSqrt); }
384 if (j.contains("modelParametersExponential")) { j.at("modelParametersExponential").get_to(obj._modelParametersExponential); }
385 if (j.contains("modelParametersCosineType")) { j.at("modelParametersCosineType").get_to(obj._modelParametersCosineType); }
386}
387
389{
390 j = json{
391 { "a", obj.a },
392 };
393}
395{
396 if (j.contains("a")) { j.at("a").get_to(obj.a); }
397}
398
400{
401 j = json{
402 { "a", obj.a },
403 { "b", obj.b },
404 };
405}
407{
408 if (j.contains("a")) { j.at("a").get_to(obj.a); }
409 if (j.contains("b")) { j.at("b").get_to(obj.b); }
410}
411
413{
414 j = json{
415 { "a", obj.a },
416 { "b", obj.b },
417 { "c", obj.c },
418 };
419}
421{
422 if (j.contains("a")) { j.at("a").get_to(obj.a); }
423 if (j.contains("b")) { j.at("b").get_to(obj.b); }
424 if (j.contains("c")) { j.at("c").get_to(obj.c); }
425}
426
428{
429 j = json{
430 { "a", obj.a },
431 { "b", obj.b },
432 };
433}
435{
436 if (j.contains("a")) { j.at("a").get_to(obj.a); }
437 if (j.contains("b")) { j.at("b").get_to(obj.b); }
438}
439
441{
442 j = json{
443 { "a", obj.a },
444 { "b", obj.b },
445 };
446}
448{
449 if (j.contains("a")) { j.at("a").get_to(obj.a); }
450 if (j.contains("b")) { j.at("b").get_to(obj.b); }
451}
452
454{
455 j = json{
456 { "a", obj.a },
457 { "b", obj.b },
458 { "e0", obj.e0 },
459 };
460}
462{
463 if (j.contains("a")) { j.at("a").get_to(obj.a); }
464 if (j.contains("b")) { j.at("b").get_to(obj.b); }
465 if (j.contains("e0")) { j.at("e0").get_to(obj.e0); }
466}
467
469{
470 j = json{
471 { "a", obj.a },
472 { "b", obj.b },
473 { "n", obj.n },
474 };
475}
477{
478 if (j.contains("a")) { j.at("a").get_to(obj.a); }
479 if (j.contains("b")) { j.at("b").get_to(obj.b); }
480 if (j.contains("n")) { j.at("n").get_to(obj.n); }
481}
482
483} // namespace NAV
Combo representing an enumeration.
nlohmann::json json
json namespace
GNSS helper functions.
Defines Widgets which allow the input of values and the selection of the unit.
Utility class for logging to console and file.
Errors concerning GNSS observations.
Frequency definition for different satellite systems.
Definition Frequency.hpp:59
SatelliteSystem getSatSys() const
Get the satellite system for which this frequency is defined.
void updateStdDevCurvePlot(Model model)
Updates the curve plot data for the given model.
ModelParametersCosineType _modelParametersCosineType
Model parameters for the 'cosine - type' model.
ModelParametersExponential _modelParametersExponential
Model parameters for the 'exponential' model.
double _carrierStdDev
Carrier Measurement error standard deviation per Frequency [m].
double carrierMeasErrorVar(const SatelliteSystem &satSys, double elevation, double cn0) const
Calculates the measurement Error Variance for carrier-phase observations.
double _codeStdDev
Code/Pseudorange Measurement error standard deviation per Frequency [m].
GnssMeasurementErrorModel()
Default constructor.
ModelParametersSine _modelParametersSine
Model parameters for the 'sine' model.
double weightingFunction(Model model, double elevation, double cn0) const
Calculates the weighting function for the standard deviation.
ModelParametersSineOffset _modelParametersSineOffset
Model parameters for the 'sine + offset' model.
double _plotCN0
Carrier-to-Noise density [dB-Hz] to use in the plot.
std::vector< std::vector< double > > _stdDevCurvePlot
Standard deviations for plotting.
double codeBiasErrorVar() const
Returns the Code Bias Error Variance.
@ SINE_CN0
Sine and CN0 dependent. See groves2013 Groves, ch. 9.4.2.4, eq. 9.168, p. 422 (range acceleration is ...
@ None
Measurement error model turned off.
@ COUNT
Amount of items in the enum.
@ EXPONENTIAL
Exponential. See eulergoad1991 Euler and Goad 1991 / li2016 Li et al. 2016.
@ SINE
Sine. See dach2015 Dach 2015.
@ RTKLIB
RTKLIB error model. See rtklib RTKLIB ch. E.6, eq. E.6.24, p. 162.
@ COSINE_TYPE
Cosine Type. See hadas2020 Hadas 2020 eq. 14, p. 8.
@ SINE_SQRT
Sine square-root. See kiliszek2022 Kiliszek 2022, table 2, p. 5.
@ SINE_OFFSET
Sine with offset. See zhang2021 Zhang 2021 eq. 7, p. 3.
bool ShowGuiWidgets(const char *id, float width)
Shows a GUI widgets.
double psrRateMeasErrorVar(const Frequency &freq, int8_t num, double elevation, double cn0) const
Returns the Pseudo-range rate Error Variance.
static constexpr size_t PLOT_SAMPLES
Amount of samples for the plot.
ModelParametersSineCN0 _modelParametersSineCN0
Model parameters for the 'sine + CN0' model.
static constexpr std::array< double, PLOT_SAMPLES > _elevation_deg
Elevation data for plotting [rad].
double psrMeasErrorVar(const SatelliteSystem &satSys, double elevation, double cn0) const
Calculates the measurement Error Variance for pseudorange observations.
static double satSysErrorFactorVariance(const SatelliteSystem &satSys)
Returns an error factor for the variance depending on the satellite system.
double _dopplerStdDev
Doppler Frequency error factor [Hz] - Measurement error standard deviation.
ModelParametersRtklib _modelParametersRtklib
Model parameters for the 'RTKLIB' model.
ModelParametersSineSqrt _modelParametersSineSqrt
Model parameters for the 'sine - sqrt' model.
static constexpr std::array< double, PLOT_SAMPLES > _elevation
Elevation data for plotting [rad].
static float windowFontRatio()
Ratio to multiply for GUI window elements.
ImGui extensions.
bool InputIntL(const char *label, int *v, int v_min, int v_max, int step, int step_fast, ImGuiInputTextFlags flags)
Shows a value limited InputText GUI element for 'int'.
Definition imgui_ex.cpp:242
bool DragDouble(const char *label, double *v, float v_speed, double v_min, double v_max, const char *format, ImGuiSliderFlags flags)
Shows a Drag GUI element for 'double'.
Definition imgui_ex.cpp:19
bool SliderDouble(const char *label, double *v, double v_min, double v_max, const char *format, ImGuiSliderFlags flags)
Shows a Slider GUI element for 'double'.
Definition imgui_ex.cpp:85
InputWithUnitChange InputDoubleWithUnit(const char *label, float itemWidth, float unitWidth, double *v, U &combo_current_item, const char *combo_items_separated_by_zeros, double step=0.0, double step_fast=0.0, const char *format="%.6f", ImGuiInputTextFlags flags=0, int combo_popup_max_height_in_items=-1)
Shows an InputText GUI element to modify the provided value and also set its unit.
bool EnumCombo(const char *label, T &enumeration, size_t startIdx=0)
Combo representing an enumeration.
Definition EnumCombo.hpp:30
void to_json(json &j, const Node &node)
Converts the provided node into a json object.
Definition Node.cpp:990
@ G01
GPS L1 (1575.42 MHz).
Definition Frequency.hpp:28
const char * to_string(gui::widgets::PositionWithFrame::ReferenceFrame refFrame)
Converts the enum to a string.
void from_json(const json &j, Node &node)
Converts the provided json object into a node object.
Definition Node.cpp:1007
constexpr auto deg2rad(const T &deg)
Convert Degree to Radians.
Definition Units.hpp:21
double doppler2rangeRate(double doppler, Frequency freq, int8_t num)
Transforms a doppler-shift into a range-rate.
Definition Functions.cpp:14
SatelliteSystem_
Satellite System enumeration.
@ GPS
Global Positioning System.
@ QZSS
Quasi-Zenith Satellite System.
@ GLO
Globalnaja nawigazionnaja sputnikowaja sistema (GLONASS)
@ GAL
Galileo.
@ SBAS
Satellite Based Augmentation System.
@ BDS
Beidou.
@ SatSys_None
No Satellite system.
@ IRNSS
Indian Regional Navigation Satellite System.
Model parameters for the 'cosine - type' model.
Model parameters for the 'exponential' model.
Model parameters for the 'sine + CN0' model.
double c
Factor to weight the CN0 dependant part.
Model parameters for the 'sine + offset' model.
Model parameters for the 'sine - sqrt' model.
Satellite System type.