0.3.0
Loading...
Searching...
No Matches
ObservationEstimator.hpp
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
13
14#pragma once
15
16#include <algorithm>
17#include <cmath>
18#include <cstddef>
19#include <cstdint>
20#include <memory>
21#include <unordered_map>
22#include <utility>
23#include <vector>
24
25#include <imgui.h>
26#include <application.h>
27#include <imgui_stdlib.h>
36
43
45#include "util/Json.hpp"
46#include <Eigen/src/Core/MatrixBase.h>
47#include <fmt/core.h>
48#include <fmt/format.h>
49
50namespace NAV
51{
52
55{
56 public:
59 explicit ObservationEstimator(size_t receiverCount)
60 : _receiverCount(receiverCount)
61 {
62 for (size_t i = 0; i < receiverCount; i++)
63 {
64 _antenna.emplace(i, Antenna{});
65 }
66 }
67
75
82 template<typename ReceiverType>
84 const Receiver<ReceiverType>& receiver,
85 const std::shared_ptr<const IonosphericCorrections>& ionosphericCorrections,
86 [[maybe_unused]] const std::string& nameId,
87 ObservationDifference obsDiff) const
88 {
89 LOG_DATA("{}: Calculating all observation estimates:", nameId);
90 for (auto& [satSigId, observation] : observations.signals)
91 {
92 calcObservationEstimate(satSigId, observation, receiver, ionosphericCorrections, nameId, obsDiff);
93 }
94 }
95
103 template<typename ReceiverType>
104 void calcObservationEstimate(const SatSigId& satSigId,
106 const Receiver<ReceiverType>& receiver,
107 const std::shared_ptr<const IonosphericCorrections>& ionosphericCorrections,
108 [[maybe_unused]] const std::string& nameId,
109 ObservationDifference obsDiff) const
110 {
111 LOG_DATA("{}: Calculating observation estimates for [{}]", nameId, satSigId);
112 const Frequency freq = satSigId.freq();
113 const SatelliteSystem satSys = freq.getSatSys();
114
115 auto& recvObs = observation.recvObs.at(receiver.type);
116
117 Eigen::Vector3d e_recvPosAPC = e_calcRecvPosAPC(freq,
118 receiver.type,
119 receiver.e_posMarker,
120 receiver.gnssObs, nameId);
121 Eigen::Vector3d lla_recvPosAPC = trafo::ecef2lla_WGS84(e_recvPosAPC);
122
123 double elevation = recvObs->satElevation(e_recvPosAPC, lla_recvPosAPC);
124 double azimuth = recvObs->satAzimuth(e_recvPosAPC, lla_recvPosAPC);
125 Eigen::Vector3d e_pLOS = recvObs->e_pLOS(e_recvPosAPC);
126
127 // Receiver-Satellite Range [m]
128 double rho_r_s = (recvObs->e_satPos() - e_recvPosAPC).norm();
129 recvObs->terms.rho_r_s = rho_r_s;
130 // Troposphere
131 auto tropo_r_s = calcTroposphericDelayAndMapping(receiver.gnssObs->insTime, lla_recvPosAPC,
132 elevation, azimuth, _troposphereModels, nameId);
133 recvObs->terms.tropoZenithDelay = tropo_r_s;
134 // Estimated troposphere propagation error [m]
135 double dpsr_T_r_s = tropo_r_s.ZHD * tropo_r_s.zhdMappingFactor + tropo_r_s.ZWD * tropo_r_s.zwdMappingFactor;
136 recvObs->terms.dpsr_T_r_s = dpsr_T_r_s;
137 // Estimated ionosphere propagation error [m]
138 double dpsr_I_r_s = calcIonosphericDelay(static_cast<double>(receiver.gnssObs->insTime.toGPSweekTow().tow),
139 freq, observation.freqNum(), lla_recvPosAPC, elevation, azimuth,
140 _ionosphereModel, ionosphericCorrections.get());
141 recvObs->terms.dpsr_I_r_s = dpsr_I_r_s;
142 // Sagnac correction [m]
143 double dpsr_ie_r_s = calcSagnacCorrection(e_recvPosAPC, recvObs->e_satPos());
144 recvObs->terms.dpsr_ie_r_s = dpsr_ie_r_s;
145
146 // Earth's gravitational field causes relativistic signal delay due to space-time curvature (Shapiro effect) [s]
147 // double posNorm = recvObs->e_satPos().norm() + e_recvPosAPC.norm();
148 // double dt_rel_stc = e_recvPosAPC.norm() > InsConst::WGS84::a / 2.0 ? 2.0 * InsConst::WGS84::MU / std::pow(InsConst::C, 3) * std::log((posNorm + rho_r_s) / (posNorm - rho_r_s))
149 // : 0.0;
150
151 double cn0 = recvObs->gnssObsData().CN0.value_or(1.0);
152
153 double pcv = calcPCV(freq, receiver.gnssObs->insTime, elevation, std::nullopt, receiver.type, receiver.gnssObs, nameId); // TODO: use 'azimuth', but need antenna azimuth
154
155 for (auto& [obsType, obsData] : recvObs->obs)
156 {
157 LOG_DATA("{}: [{}][{:11}][{:5}] Observation estimate", nameId, satSigId, obsType, receiver.type);
158 switch (obsType)
159 {
161 obsData.estimate = rho_r_s
162 + dpsr_ie_r_s
163 + dpsr_T_r_s
164 + dpsr_I_r_s
166 * (*receiver.recvClk.biasFor(satSys) - recvObs->satClock().bias
167 // + dt_rel_stc
168 + (receiver.interFrequencyBias.contains(freq) ? receiver.interFrequencyBias.at(freq).value : 0.0))
169 + pcv;
170 obsData.measVar = _gnssMeasurementErrorModel.psrMeasErrorVar(satSys, elevation, cn0);
171 LOG_DATA("{}: [{}][{:11}][{:5}] {:.4f} [m] Geometrical range", nameId, satSigId, obsType, receiver.type, rho_r_s);
172 LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m] Sagnac correction", nameId, satSigId, obsType, receiver.type, dpsr_ie_r_s);
173 if (dpsr_T_r_s != 0.0) { LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m] Tropospheric delay", nameId, satSigId, obsType, receiver.type, dpsr_T_r_s); }
174 if (dpsr_I_r_s != 0.0) { LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m] Ionospheric delay", nameId, satSigId, obsType, receiver.type, dpsr_I_r_s); }
175 if (*receiver.recvClk.biasFor(satSys) != 0.0) { LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m] Receiver clock bias", nameId, satSigId, obsType, receiver.type, InsConst::C * *receiver.recvClk.biasFor(satSys)); }
176 LOG_DATA("{}: [{}][{:11}][{:5}] - {:.4f} [m] Satellite clock bias", nameId, satSigId, obsType, receiver.type, InsConst::C * recvObs->satClock().bias);
177 // LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m] Shapiro effect", nameId, satSigId, obsType, receiver.type, InsConst::C * dt_rel_stc);
178 if (receiver.interFrequencyBias.contains(freq)) { LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m] Inter-frequency bias", nameId, satSigId, obsType, receiver.type, InsConst::C * receiver.interFrequencyBias.at(freq).value); }
179 LOG_DATA("{}: [{}][{:11}][{:5}] = {:.4f} [m] Pseudorange estimate", nameId, satSigId, obsType, receiver.type, obsData.estimate);
180 LOG_DATA("{}: [{}][{:11}][{:5}] {:.4f} [m] Pseudorange measurement", nameId, satSigId, obsType, receiver.type, obsData.measurement);
181 LOG_DATA("{}: [{}][{:11}][{:5}] {:.4e} [m] Difference to measurement", nameId, satSigId, obsType, receiver.type, obsData.measurement - obsData.estimate);
182 break;
183 case GnssObs::Carrier:
184 obsData.estimate = rho_r_s
185 + dpsr_ie_r_s
186 + dpsr_T_r_s
187 - dpsr_I_r_s
189 * (*receiver.recvClk.biasFor(satSys) - recvObs->satClock().bias
190 // + dt_rel_stc
191 )
192 + pcv;
193 obsData.measVar = _gnssMeasurementErrorModel.carrierMeasErrorVar(satSys, elevation, cn0);
194 LOG_DATA("{}: [{}][{:11}][{:5}] {:.4f} [m] Geometrical range", nameId, satSigId, obsType, receiver.type, rho_r_s);
195 LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m] Sagnac correction", nameId, satSigId, obsType, receiver.type, dpsr_ie_r_s);
196 if (dpsr_T_r_s != 0.0) { LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m] Tropospheric delay", nameId, satSigId, obsType, receiver.type, dpsr_T_r_s); }
197 if (dpsr_I_r_s != 0.0) { LOG_DATA("{}: [{}][{:11}][{:5}] - {:.4f} [m] Ionospheric delay", nameId, satSigId, obsType, receiver.type, dpsr_I_r_s); }
198 if (*receiver.recvClk.biasFor(satSys) != 0.0) { LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m] Receiver clock bias", nameId, satSigId, obsType, receiver.type, InsConst::C * *receiver.recvClk.biasFor(satSys)); }
199 LOG_DATA("{}: [{}][{:11}][{:5}] - {:.4f} [m] Satellite clock bias", nameId, satSigId, obsType, receiver.type, InsConst::C * recvObs->satClock().bias);
200 // LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m] Shapiro effect", nameId, satSigId, obsType, receiver.type, InsConst::C * dt_rel_stc);
201 LOG_DATA("{}: [{}][{:11}][{:5}] = {:.4f} [m] Carrier-phase estimate", nameId, satSigId, obsType, receiver.type, obsData.estimate);
202 LOG_DATA("{}: [{}][{:11}][{:5}] {:.4f} [m] Carrier-phase measurement", nameId, satSigId, obsType, receiver.type, obsData.measurement);
203 LOG_DATA("{}: [{}][{:11}][{:5}] {:.4e} [m] Difference to measurement", nameId, satSigId, obsType, receiver.type, obsData.measurement - obsData.estimate);
204 break;
205 case GnssObs::Doppler:
206 obsData.estimate = e_pLOS.dot(recvObs->e_satVel() - receiver.e_vel)
207 - calcSagnacRateCorrection(e_recvPosAPC, recvObs->e_satPos(), receiver.e_vel, recvObs->e_satVel())
209 * (*receiver.recvClk.driftFor(satSys)
210 - recvObs->satClock().drift);
211 obsData.measVar = _gnssMeasurementErrorModel.psrRateMeasErrorVar(freq, observation.freqNum(), elevation, cn0);
212 LOG_DATA("{}: [{}][{:11}][{:5}] {:.4f} [m/s] ", nameId, satSigId, obsType, receiver.type, e_pLOS.dot(recvObs->e_satVel() - receiver.e_vel));
213 LOG_DATA("{}: [{}][{:11}][{:5}] - {:.4f} [m/s] Sagnac rate correction", nameId, satSigId, obsType, receiver.type, calcSagnacRateCorrection(e_recvPosAPC, recvObs->e_satPos(), receiver.e_vel, recvObs->e_satVel()));
214 if (*receiver.recvClk.driftFor(satSys) != 0.0) { LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m/s] Receiver clock drift", nameId, satSigId, obsType, receiver.type, InsConst::C * *receiver.recvClk.driftFor(satSys)); }
215 LOG_DATA("{}: [{}][{:11}][{:5}] - {:.4f} [m/s] Satellite clock drift", nameId, satSigId, obsType, receiver.type, InsConst::C * recvObs->satClock().drift);
216 LOG_DATA("{}: [{}][{:11}][{:5}] = {:.4f} [m/s] Doppler estimate", nameId, satSigId, obsType, receiver.type, obsData.estimate);
217 LOG_DATA("{}: [{}][{:11}][{:5}] {:.4f} [m/s] Doppler measurement", nameId, satSigId, obsType, receiver.type, obsData.measurement);
218 LOG_DATA("{}: [{}][{:11}][{:5}] {:.4e} [m/s] Difference to measurement", nameId, satSigId, obsType, receiver.type, obsData.measurement - obsData.estimate);
219 break;
221 break;
222 }
223 LOG_DATA("{}: [{}][{:11}][{:5}] Observation error variance", nameId, satSigId, obsType, receiver.type);
224 LOG_DATA("{}: [{}][{:11}][{:5}] {:.4g} [{}] Measurement error variance", nameId, satSigId, obsType, receiver.type, obsData.measVar,
225 obsType == GnssObs::Doppler ? "m^2/s^2" : "m^2");
226
227 if (obsDiff == NoDifference)
228 {
229 if (obsType == GnssObs::Pseudorange || obsType == GnssObs::Carrier)
230 {
231 obsData.measVar += observation.navData()->calcSatellitePositionVariance()
232 + ionoErrorVar(dpsr_I_r_s, freq, observation.freqNum())
233 + tropoErrorVar(dpsr_T_r_s, elevation);
234 LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m^2] Satellite position variance", nameId, satSigId, obsType, receiver.type, observation.navData()->calcSatellitePositionVariance());
235 if (dpsr_I_r_s != 0.0) { LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m^2] Ionosphere variance", nameId, satSigId, obsType, receiver.type, ionoErrorVar(dpsr_I_r_s, freq, observation.freqNum())); }
236 if (dpsr_T_r_s != 0.0) { LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m^2] Troposphere variance", nameId, satSigId, obsType, receiver.type, tropoErrorVar(dpsr_T_r_s, elevation)); }
237 }
238 if (obsType == GnssObs::Pseudorange)
239 {
240 obsData.measVar += _gnssMeasurementErrorModel.codeBiasErrorVar();
241 LOG_DATA("{}: [{}][{:11}][{:5}] + {:.4f} [m^2] Code bias variance", nameId, satSigId, obsType, receiver.type, _gnssMeasurementErrorModel.codeBiasErrorVar());
242 }
243 }
244 LOG_DATA("{}: [{}][{:11}][{:5}] = {:.4g} [{}] Observation error variance", nameId, satSigId, obsType, receiver.type, obsData.measVar,
245 obsType == GnssObs::Doppler ? "m^2/s^2" : "m^2");
246 }
247 }
248
251 {
259
260 Eigen::Vector3d e_satPos;
261 Eigen::Vector3d e_satVel;
262 double satClockBias{};
263 double satClockDrift{};
264 };
265
279 template<typename Derived>
281 size_t receiverType,
282 const Eigen::MatrixBase<Derived>& e_recvPosAPC,
283 const auto& recvClockBias,
284 const auto& interFreqBias,
285 const auto& dpsr_T_r_s,
286 const auto& dpsr_I_r_s,
287 const std::shared_ptr<const SatelliteInfo>& satInfo,
288 const auto& elevation,
289 const std::shared_ptr<const GnssObs>& gnssObs,
290 [[maybe_unused]] const std::string& nameId) const
291 {
292 // Receiver-Satellite Range [m]
293 auto rho_r_s = (satInfo->e_satPos - e_recvPosAPC).norm();
294
295 // Sagnac correction [m]
296 auto dpsr_ie_r_s = calcSagnacCorrection(e_recvPosAPC, satInfo->e_satPos);
297
298 // Earth's gravitational field causes relativistic signal delay due to space-time curvature (Shapiro effect) [s]
299 // double posNorm = e_satPos.norm() + e_recvPosAPC.norm();
300 // double dt_rel_stc = e_recvPosAPC.norm() > InsConst::WGS84::a / 2.0 ? 2.0 * InsConst::WGS84::MU / std::pow(InsConst::C, 3) * std::log((posNorm + rho_r_s) / (posNorm - rho_r_s))
301 // : 0.0;
302
303 auto pcv = calcPCV(freq, gnssObs->insTime, elevation, std::nullopt, receiverType, gnssObs, nameId); // TODO: use 'azimuth', but need antenna azimuth
304
305 return rho_r_s
306 + dpsr_ie_r_s
307 + dpsr_T_r_s
308 + dpsr_I_r_s
309 + InsConst::C * (recvClockBias - satInfo->satClockBias /* + dt_rel_stc */ + interFreqBias)
310 + pcv;
311 }
312
324 template<typename Derived>
325 std::pair<double, Eigen::Vector3d>
327 int8_t freqNum,
328 size_t receiverType,
329 const Eigen::MatrixBase<Derived>& e_recvPosMarker,
330 double recvClockBias,
331 const std::shared_ptr<const SatelliteInfo>& satInfo,
332 const std::shared_ptr<const GnssObs>& gnssObs,
333 const std::shared_ptr<const IonosphericCorrections>& ionosphericCorrections,
334 [[maybe_unused]] const std::string& nameId) const
335 {
336 Eigen::Vector3d e_recvPosAPC = e_calcRecvPosAPC(freq, receiverType, e_recvPosMarker, gnssObs, nameId);
337 Eigen::Vector3d lla_recvPosAPC = trafo::ecef2lla_WGS84(e_recvPosAPC);
338
339 Eigen::Vector3d e_pLOS = e_calcLineOfSightUnitVector(e_recvPosAPC, satInfo->e_satPos);
340 Eigen::Vector3d n_lineOfSightUnitVector = trafo::n_Quat_e(lla_recvPosAPC(0), lla_recvPosAPC(1)) * e_pLOS;
341 double elevation = calcSatElevation(n_lineOfSightUnitVector);
342 double azimuth = calcSatAzimuth(n_lineOfSightUnitVector);
343
344 // Receiver-Satellite Range [m]
345 double rho_r_s = (satInfo->e_satPos - e_recvPosAPC).norm();
346 // Estimated troposphere propagation error [m]
347 double dpsr_T_r_s = calculateTroposphericDelay(lla_recvPosAPC, gnssObs, elevation, azimuth, nameId);
348 // Estimated ionosphere propagation error [m]
349 double dpsr_I_r_s = calculateIonosphericDelay(freq, freqNum, lla_recvPosAPC, gnssObs, ionosphericCorrections, elevation, azimuth);
350 // Sagnac correction [m]
351 double dpsr_ie_r_s = calcSagnacCorrection(e_recvPosAPC, satInfo->e_satPos);
352
353 // Earth's gravitational field causes relativistic signal delay due to space-time curvature (Shapiro effect) [s]
354 // double posNorm = e_satPos.norm() + e_recvPosAPC.norm();
355 // double dt_rel_stc = e_recvPosAPC.norm() > InsConst::WGS84::a / 2.0 ? 2.0 * InsConst::WGS84::MU / std::pow(InsConst::C, 3) * std::log((posNorm + rho_r_s) / (posNorm - rho_r_s))
356 // : 0.0;
357
358 auto pcv = calcPCV(freq, gnssObs->insTime, elevation, std::nullopt, receiverType, gnssObs, nameId); // TODO: use 'azimuth', but need antenna azimuth
359
360 double estimate = rho_r_s
361 + dpsr_ie_r_s
362 + dpsr_T_r_s
363 - dpsr_I_r_s
364 + InsConst::C * (recvClockBias - satInfo->satClockBias /* + dt_rel_stc */)
365 + pcv;
366
367 return { estimate, e_pLOS };
368 }
369
380 template<typename DerivedPos, typename DerivedVel>
382 size_t receiverType,
383 const Eigen::MatrixBase<DerivedPos>& e_recvPosMarker,
384 const Eigen::MatrixBase<DerivedVel>& e_recvVel,
385 const auto& recvClockDrift,
386 const std::shared_ptr<const SatelliteInfo>& satInfo,
387 const std::shared_ptr<const GnssObs>& gnssObs,
388 [[maybe_unused]] const std::string& nameId) const
389 {
390 auto e_recvPosAPC = e_calcRecvPosAPC(freq, receiverType, e_recvPosMarker, gnssObs, nameId);
391
392 auto e_pLOS = e_calcLineOfSightUnitVector(e_recvPosAPC, satInfo->e_satPos);
393
394 return e_pLOS.dot(satInfo->e_satVel - e_recvVel)
395 - calcSagnacRateCorrection(e_recvPosAPC, satInfo->e_satPos, e_recvVel, satInfo->e_satVel)
396 + InsConst::C * (recvClockDrift - satInfo->satClockDrift);
397 }
398
414 int8_t freqNum,
415 size_t receiverType,
417 const Eigen::Vector3d& e_recvPosMarker,
418 const Eigen::Vector3d& e_satPos,
419 double cn0,
420 const std::shared_ptr<const GnssObs>& gnssObs,
421 const std::shared_ptr<const SatNavData>& navData,
422 const std::shared_ptr<const IonosphericCorrections>& ionosphericCorrections,
423 [[maybe_unused]] const std::string& nameId,
424 ObservationDifference obsDiff) const
425 {
426 const SatelliteSystem satSys = freq.getSatSys();
427
428 Eigen::Vector3d e_recvPosAPC = e_calcRecvPosAPC(freq, receiverType, e_recvPosMarker, gnssObs, nameId);
429 Eigen::Vector3d lla_recvPosAPC = trafo::ecef2lla_WGS84(e_recvPosAPC);
430
431 Eigen::Vector3d e_pLOS = e_calcLineOfSightUnitVector(e_recvPosAPC, e_satPos);
432 Eigen::Vector3d n_lineOfSightUnitVector = trafo::n_Quat_e(lla_recvPosAPC(0), lla_recvPosAPC(1)) * e_pLOS;
433 double elevation = calcSatElevation(n_lineOfSightUnitVector);
434 double azimuth = calcSatAzimuth(n_lineOfSightUnitVector);
435
436 // Estimated troposphere propagation error [m]
437 double dpsr_T_r_s = calculateTroposphericDelay(lla_recvPosAPC, gnssObs, elevation, azimuth, nameId);
438 // Estimated ionosphere propagation error [m]
439 double dpsr_I_r_s = calculateIonosphericDelay(freq, freqNum, lla_recvPosAPC, gnssObs, ionosphericCorrections, elevation, azimuth);
440
441 double variance = 0.0;
442
443 switch (obsType)
444 {
446 variance = _gnssMeasurementErrorModel.psrMeasErrorVar(satSys, elevation, cn0);
447 break;
448 case GnssObs::Carrier:
449 variance = _gnssMeasurementErrorModel.carrierMeasErrorVar(satSys, elevation, cn0);
450 break;
451 case GnssObs::Doppler:
452 variance = _gnssMeasurementErrorModel.psrRateMeasErrorVar(freq, freqNum, elevation, cn0);
453 break;
455 break;
456 }
457
458 if (obsDiff == NoDifference)
459 {
460 if (obsType == GnssObs::Pseudorange || obsType == GnssObs::Carrier)
461 {
462 variance += navData->calcSatellitePositionVariance()
463 + ionoErrorVar(dpsr_I_r_s, freq, freqNum)
464 + tropoErrorVar(dpsr_T_r_s, elevation);
465 }
466 if (obsType == GnssObs::Pseudorange)
467 {
468 variance += _gnssMeasurementErrorModel.codeBiasErrorVar();
469 }
470 }
471
472 return variance;
473 }
474
481 template<typename Derived>
482 [[nodiscard]] Eigen::Vector3<typename Derived::Scalar> e_calcRecvPosAPC(const Frequency& freq,
483 size_t receiverType,
484 const Eigen::MatrixBase<Derived>& e_recvPosMarker,
485 const std::shared_ptr<const GnssObs>& gnssObs,
486 [[maybe_unused]] const std::string& nameId) const
487 {
488 const Antenna& antenna = _antenna.at(receiverType);
489
490 auto e_recvPosAPC = trafo::e_posMarker2ARP(e_recvPosMarker,
491 gnssObs,
492 antenna.hen_delta);
493 if (antenna.correctPCO)
494 {
495 std::string antennaType;
496 if (antenna.autoDetermine && gnssObs->receiverInfo)
497 {
498 antennaType = gnssObs->receiverInfo->get().antennaType;
499 }
500 else if (!antenna.autoDetermine)
501 {
502 antennaType = antenna.name;
503 }
504 e_recvPosAPC = trafo::e_posARP2APC(e_recvPosAPC, gnssObs, freq, antennaType, nameId);
505 }
506
507 return e_recvPosAPC;
508 }
509
519 template<typename T>
520 [[nodiscard]] T calcPCV(const Frequency& freq,
521 const InsTime& insTime,
522 const T& elevation,
523 std::optional<double> azimuth,
524 size_t receiverType,
525 const std::shared_ptr<const GnssObs>& gnssObs,
526 [[maybe_unused]] const std::string& nameId) const
527 {
528 if (std::isnan(elevation)
529 || (azimuth.has_value() && std::isnan(*azimuth))) { return T(0.0); }
530 const Antenna& antenna = _antenna.at(receiverType);
531 if (antenna.correctPCV)
532 {
533 std::string antennaType;
534 if (antenna.autoDetermine && gnssObs->receiverInfo)
535 {
536 antennaType = gnssObs->receiverInfo->get().antennaType;
537 }
538 else if (!antenna.autoDetermine)
539 {
540 antennaType = antenna.name;
541 }
543 Frequency_(freq),
544 insTime,
545 elevation,
546 azimuth,
547 nameId)
548 .value_or(T(0.0));
549 }
550
551 return T(0.0);
552 }
553
564 int8_t freqNum,
565 const Eigen::Vector3d& lla_recvPosAPC,
566 const std::shared_ptr<const GnssObs>& gnssObs,
567 const std::shared_ptr<const IonosphericCorrections>& ionosphericCorrections,
568 double elevation,
569 double azimuth) const
570 {
571 return calcIonosphericDelay(static_cast<double>(gnssObs->insTime.toGPSweekTow().tow),
572 freq, freqNum, lla_recvPosAPC,
573 elevation, azimuth,
574 _ionosphereModel, ionosphericCorrections.get());
575 }
576
584 double calculateTroposphericDelay(const Eigen::Vector3d& lla_recvPosAPC,
585 const std::shared_ptr<const GnssObs>& gnssObs,
586 double elevation,
587 double azimuth,
588 [[maybe_unused]] const std::string& nameId) const
589 {
590 auto tropo_r_s = calcTroposphericDelayAndMapping(gnssObs->insTime, lla_recvPosAPC,
591 elevation, azimuth, _troposphereModels, nameId);
592
593 return tropo_r_s.ZHD * tropo_r_s.zhdMappingFactor + tropo_r_s.ZWD * tropo_r_s.zwdMappingFactor;
594 }
595
599 template<typename ReceiverType>
600 bool ShowGuiWidgets(const char* id, float itemWidth)
601 {
602 bool changed = false;
603
604 ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver);
605 if (ImGui::TreeNode(fmt::format("Compensation models##{}", id).c_str()))
606 {
607 ImGui::SetNextItemWidth(itemWidth - ImGui::GetStyle().IndentSpacing);
608 if (ComboIonosphereModel(fmt::format("Ionosphere Model##{}", id).c_str(), _ionosphereModel))
609 {
610 LOG_DEBUG("{}: Ionosphere Model changed to {}", id, NAV::to_string(_ionosphereModel));
611 changed = true;
612 }
613 if (ComboTroposphereModel(fmt::format("Troposphere Model##{}", id).c_str(), _troposphereModels, itemWidth - ImGui::GetStyle().IndentSpacing))
614 {
615 changed = true;
616 }
617 ImGui::TreePop();
618 }
619
620 ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver);
621 if (ImGui::TreeNode(fmt::format("GNSS Measurement Error##{}", id).c_str()))
622 {
623 if (_gnssMeasurementErrorModel.ShowGuiWidgets(id, itemWidth - ImGui::GetStyle().IndentSpacing))
624 {
625 LOG_DEBUG("{}: GNSS Measurement Error Model changed.", id);
626 changed = true;
627 }
628 ImGui::TreePop();
629 }
630
631 if (ImGui::TreeNode(fmt::format("Antenna settings##{}", id).c_str()))
632 {
633 for (size_t i = 0; i < _receiverCount; ++i)
634 {
635 if (_receiverCount > 1)
636 {
637 ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver);
638 if (!ImGui::TreeNode(fmt::format("{}", static_cast<ReceiverType>(i)).c_str())) { continue; }
639 }
640
641 if (ImGui::Checkbox(fmt::format("Correct Phase-center offset##antenna {} {}", id, i).c_str(), &_antenna.at(i).correctPCO))
642 {
643 LOG_DEBUG("{}: Antenna {} correctPCO: {}", id, i, _antenna.at(i).correctPCO);
644 changed = true;
645 }
646 ImGui::SameLine();
647 if (ImGui::Checkbox(fmt::format("Correct Phase-center variation##antenna {} {}", id, i).c_str(), &_antenna.at(i).correctPCV))
648 {
649 LOG_DEBUG("{}: Antenna {} correctPCV: {}", id, i, _antenna.at(i).correctPCV);
650 changed = true;
651 }
652
653 if (!_antenna.at(i).correctPCO && !_antenna.at(i).correctPCV) { ImGui::BeginDisabled(); }
654 if (ImGui::Checkbox(fmt::format("Auto determine##antenna {} {}", id, i).c_str(), &_antenna.at(i).autoDetermine))
655 {
656 LOG_DEBUG("{}: Antenna {} auto: {}", id, i, _antenna.at(i).autoDetermine);
657 changed = true;
658 }
659 ImGui::SameLine();
660 if (_antenna.at(i).autoDetermine) { ImGui::BeginDisabled(); }
661 ImGui::SetNextItemWidth(itemWidth - (1.0F + static_cast<float>(_receiverCount > 1)) * ImGui::GetStyle().IndentSpacing);
662
663 if (ImGui::BeginCombo(fmt::format("Type##Combo {} {}", id, i).c_str(), _antenna.at(i).name.c_str()))
664 {
665 ImGui::PushFont(Application::MonoFont());
666 if (ImGui::Selectable(fmt::format("##Selectable {} {}", id, i).c_str(), _antenna.at(i).name.empty()))
667 {
668 _antenna.at(i).name = "";
669 }
670
671 for (const auto& iter : AntexReader::Get().antennas())
672 {
673 const bool is_selected = (_antenna.at(i).name == iter);
674 if (ImGui::Selectable(iter.c_str(), is_selected))
675 {
676 _antenna.at(i).name = iter;
677 }
678 if (is_selected) { ImGui::SetItemDefaultFocus(); }
679 }
680 ImGui::PopFont();
681 ImGui::EndCombo();
682 }
683 if (_antenna.at(i).autoDetermine) { ImGui::EndDisabled(); }
684 if (!_antenna.at(i).correctPCO && !_antenna.at(i).correctPCV) { ImGui::EndDisabled(); }
685 ImGui::SameLine();
686 gui::widgets::HelpMarker("Used for lookup in ANTEX file.");
687
688 ImGui::SetNextItemWidth(itemWidth - (1.0F + static_cast<float>(_receiverCount > 1)) * ImGui::GetStyle().IndentSpacing);
689 if (ImGui::InputDouble3(fmt::format("Delta H/E/N [m]##{} {}", id, i).c_str(), _antenna.at(i).hen_delta.data(), "%.3f"))
690 {
691 LOG_DEBUG("{}: Antenna {} delta: {}", id, i, _antenna.at(i).hen_delta.transpose());
692 changed = true;
693 }
694 ImGui::SameLine();
695 gui::widgets::HelpMarker("- Antenna height: Height of the antenna reference point (ARP) above the marker\n"
696 "- Horizontal eccentricity of ARP relative to the marker (east/north)");
697
698 if (_receiverCount > 1) { ImGui::TreePop(); }
699 }
700 ImGui::TreePop();
701 }
702
703 return changed;
704 }
705
707 [[nodiscard]] const IonosphereModel& getIonosphereModel() const { return _ionosphereModel; }
712
713 private:
717
719
721 struct Antenna
722 {
723 bool correctPCO = true;
724 bool correctPCV = true;
725 bool autoDetermine = true;
726 std::string name;
727 Eigen::Vector3d hen_delta = Eigen::Vector3d::Zero();
728 };
729
730 std::unordered_map<size_t, Antenna> _antenna;
731
735 friend void to_json(json& j, const ObservationEstimator::Antenna& obj)
736 {
737 j = json{
738 { "correctPCO", obj.correctPCO },
739 { "correctPCV", obj.correctPCV },
740 { "autoDetermine", obj.autoDetermine },
741 { "name", obj.name },
742 { "hen_delta", obj.hen_delta },
743 };
744 }
745
748 friend void from_json(const json& j, ObservationEstimator::Antenna& obj)
749 {
750 if (j.contains("correctPCO")) { j.at("correctPCO").get_to(obj.correctPCO); }
751 if (j.contains("correctPCV")) { j.at("correctPCV").get_to(obj.correctPCV); }
752 if (j.contains("autoDetermine")) { j.at("autoDetermine").get_to(obj.autoDetermine); }
753 if (j.contains("name")) { j.at("name").get_to(obj.name); }
754 if (j.contains("hen_delta")) { j.at("hen_delta").get_to(obj.hen_delta); }
755 }
756
760 friend void to_json(json& j, const ObservationEstimator& obj)
761 {
762 j = json{
763 { "ionosphereModel", obj._ionosphereModel },
764 { "troposphereModels", obj._troposphereModels },
765 { "gnssMeasurementError", obj._gnssMeasurementErrorModel },
766 { "antenna", obj._antenna },
767 };
768 }
769
772 friend void from_json(const json& j, ObservationEstimator& obj)
773 {
774 if (j.contains("ionosphereModel")) { j.at("ionosphereModel").get_to(obj._ionosphereModel); }
775 if (j.contains("troposphereModels")) { j.at("troposphereModels").get_to(obj._troposphereModels); }
776 if (j.contains("gnssMeasurementError")) { j.at("gnssMeasurementError").get_to(obj._gnssMeasurementErrorModel); }
777 if (j.contains("antenna")) { j.at("antenna").get_to(obj._antenna); }
778 }
779};
780
781} // namespace NAV
GNSS Antenna related transformations.
Eigen::Vector3< typename Derived::Scalar > e_posMarker2ARP(const Eigen::MatrixBase< Derived > &e_posMarker, const std::shared_ptr< const GnssObs > &gnssObs, const Eigen::Vector3d &hen_delta=Eigen::Vector3d::Zero())
Converts a marker position to the antenna reference point position.
Definition Antenna.hpp:33
Eigen::Vector3< typename Derived::Scalar > e_posARP2APC(const Eigen::MatrixBase< Derived > &e_posARP, const std::shared_ptr< const GnssObs > &gnssObs, Frequency freq, const std::string &antennaType, const std::string &nameId)
Converts a antenna reference point position position to the antenna phase center position.
Definition Antenna.hpp:89
ANTEX file reader.
Transformation collection.
Eigen::Vector3< typename Derived::Scalar > ecef2lla_WGS84(const Eigen::MatrixBase< Derived > &e_position)
Converts Earth-centered-Earth-fixed coordinates into latitude, longitude and altitude using WGS84.
Definition CoordinateFrames.hpp:420
Eigen::Quaternion< Scalar > n_Quat_e(const Scalar &latitude, const Scalar &longitude)
Quaternion for rotations from Earth-fixed to navigation frame.
Definition CoordinateFrames.hpp:320
nlohmann::json json
json namespace
Definition FlowManager.hpp:21
Frequency definition for different satellite systems.
Frequency_
Enumerate for GNSS frequencies.
Definition Frequency.hpp:26
Galileo Ephemeris information.
Derived::Scalar calcSatElevation(const Eigen::MatrixBase< Derived > &n_lineOfSightUnitVector)
Calculates the elevation of the satellite from the antenna.
Definition Functions.hpp:43
DerivedA::Scalar calcSagnacCorrection(const Eigen::MatrixBase< DerivedA > &e_posAnt, const Eigen::MatrixBase< DerivedB > &e_satPos)
Calculates the Earth rotation/Sagnac correction.
Definition Functions.hpp:66
DerivedA::Scalar calcSagnacRateCorrection(const Eigen::MatrixBase< DerivedA > &e_recvPos, const Eigen::MatrixBase< DerivedB > &e_satPos, const Eigen::MatrixBase< DerivedC > &e_recvVel, const Eigen::MatrixBase< DerivedD > &e_satVel)
Calculates the Range-rate Earth rotation/Sagnac correction.
Definition Functions.hpp:81
Derived::Scalar calcSatAzimuth(const Eigen::MatrixBase< Derived > &n_lineOfSightUnitVector)
Calculates the azimuth of the satellite from the antenna.
Definition Functions.hpp:54
Eigen::Vector3< typename DerivedA::Scalar > e_calcLineOfSightUnitVector(const Eigen::MatrixBase< DerivedA > &e_posAnt, const Eigen::MatrixBase< DerivedB > &e_posSat)
Calculates the line-of-sight unit vector from the user antenna to the satellite.
Definition Functions.hpp:31
GNSS Observation messages.
Text Help Marker (?) with Tooltip.
void HelpMarker(const char *desc, const char *symbol="(?)")
Text Help Marker, e.g. '(?)', with Tooltip.
Ionosphere Models.
IonosphereModel
Available Ionosphere Models.
Definition Ionosphere.hpp:28
@ Klobuchar
Klobuchar model (GPS), also called Broadcast sometimes.
Definition Ionosphere.hpp:30
double ionoErrorVar(double dpsr_I, Frequency freq, int8_t num)
Calculates the ionospheric error variance.
bool ComboIonosphereModel(const char *label, IonosphereModel &ionosphereModel)
Shows a ComboBox to select the ionosphere model.
double calcIonosphericDelay(double tow, Frequency freq, int8_t freqNum, const Eigen::Vector3d &lla_pos, double elevation, double azimuth, IonosphereModel ionosphereModel=IonosphereModel::None, const IonosphericCorrections *corrections=nullptr)
Calculates the ionospheric delay.
Defines how to save certain datatypes to json.
#define LOG_DEBUG
Debug information. Should not be called on functions which receive observations (spamming)
Definition Logger.hpp:67
#define LOG_DATA
All output which occurs repeatedly every time observations are received.
Definition Logger.hpp:29
Errors concerning GNSS observations.
Observation data used for calculations.
const char * to_string(gui::widgets::PositionWithFrame::ReferenceFrame refFrame)
Converts the enum to a string.
Receiver information.
Structs identifying a unique satellite.
Troposphere Models.
bool ComboTroposphereModel(const char *label, TroposphereModelSelection &troposphereModelSelection, float width=0.0F)
Shows a ComboBox and button for advanced configuration to select the troposphere models.
double tropoErrorVar(double dpsr_T, double elevation)
Calculates the tropospheric error variance.
ZenithDelay calcTroposphericDelayAndMapping(const InsTime &insTime, const Eigen::Vector3d &lla_pos, double elevation, double azimuth, const TroposphereModelSelection &troposphereModels, const std::string &nameId)
Calculates the tropospheric zenith hydrostatic and wet delays and corresponding mapping factors.
Values with an uncertainty (Standard Deviation)
void move(std::vector< T > &v, size_t sourceIdx, size_t targetIdx)
Moves an element within a vector to a new position.
Definition Vector.hpp:27
std::optional< T > getAntennaPhaseCenterVariation(const std::string &antennaType, Frequency_ freq, const InsTime &insTime, const T &elevation, std::optional< double > azimuth, const std::string &nameId) const
Gets the phase center variation for given elevation and azimuth.
Definition AntexReader.hpp:395
static AntexReader & Get()
Get the static Instance of the reader.
Definition AntexReader.hpp:98
Frequency definition for different satellite systems.
Definition Frequency.hpp:59
SatelliteSystem getSatSys() const
Get the satellite system for which this frequency is defined.
Definition Frequency.hpp:152
Errors concerning GNSS observations.
Definition MeasurementErrors.hpp:31
ObservationType
Observation types.
Definition GnssObs.hpp:37
@ Doppler
Doppler (Pseudorange rate)
Definition GnssObs.hpp:40
@ ObservationType_COUNT
Count.
Definition GnssObs.hpp:41
@ Carrier
Carrier-Phase.
Definition GnssObs.hpp:39
@ Pseudorange
Pseudorange.
Definition GnssObs.hpp:38
static constexpr double C
Speed of light [m/s].
Definition Constants.hpp:34
The class is responsible for all time-related tasks.
Definition InsTime.hpp:710
friend void to_json(json &j, const ObservationEstimator::Antenna &obj)
Converts the provided object into json.
Definition ObservationEstimator.hpp:735
const IonosphereModel & getIonosphereModel() const
Get the Ionosphere Model selected.
Definition ObservationEstimator.hpp:707
TroposphereModelSelection _troposphereModels
Troposphere Models used for the calculation.
Definition ObservationEstimator.hpp:715
friend void from_json(const json &j, ObservationEstimator &obj)
Converts the provided json object into a node object.
Definition ObservationEstimator.hpp:772
ObservationDifference
How the observation gets used. Influenced the measurement variance.
Definition ObservationEstimator.hpp:70
@ NoDifference
Estimation is not differenced.
Definition ObservationEstimator.hpp:71
@ DoubleDifference
Double Difference.
Definition ObservationEstimator.hpp:73
@ SingleDifference
Single Difference.
Definition ObservationEstimator.hpp:72
ObservationEstimator(size_t receiverCount)
Constructor.
Definition ObservationEstimator.hpp:59
GnssMeasurementErrorModel _gnssMeasurementErrorModel
GNSS measurement error model to use.
Definition ObservationEstimator.hpp:716
Eigen::Vector3< typename Derived::Scalar > e_calcRecvPosAPC(const Frequency &freq, size_t receiverType, const Eigen::MatrixBase< Derived > &e_recvPosMarker, const std::shared_ptr< const GnssObs > &gnssObs, const std::string &nameId) const
Calculates the antenna phase center position for the marker.
Definition ObservationEstimator.hpp:482
double calculateIonosphericDelay(const Frequency &freq, int8_t freqNum, const Eigen::Vector3d &lla_recvPosAPC, const std::shared_ptr< const GnssObs > &gnssObs, const std::shared_ptr< const IonosphericCorrections > &ionosphericCorrections, double elevation, double azimuth) const
Calculate the ionospheric delay with the model selected in the GUI.
Definition ObservationEstimator.hpp:563
const GnssMeasurementErrorModel & getGnssMeasurementErrorModel() const
Get the GNSS measurement error model.
Definition ObservationEstimator.hpp:711
size_t _receiverCount
Number of receivers (used for GUI)
Definition ObservationEstimator.hpp:718
IonosphereModel _ionosphereModel
Ionosphere Model used for the calculation.
Definition ObservationEstimator.hpp:714
double calcObservationVariance(Frequency freq, int8_t freqNum, size_t receiverType, GnssObs::ObservationType obsType, const Eigen::Vector3d &e_recvPosMarker, const Eigen::Vector3d &e_satPos, double cn0, const std::shared_ptr< const GnssObs > &gnssObs, const std::shared_ptr< const SatNavData > &navData, const std::shared_ptr< const IonosphericCorrections > &ionosphericCorrections, const std::string &nameId, ObservationDifference obsDiff) const
Calculates the observation variance.
Definition ObservationEstimator.hpp:413
void calcObservationEstimate(const SatSigId &satSigId, Observations::SignalObservation &observation, const Receiver< ReceiverType > &receiver, const std::shared_ptr< const IonosphericCorrections > &ionosphericCorrections, const std::string &nameId, ObservationDifference obsDiff) const
Calculates the observation estimate for the given signal.
Definition ObservationEstimator.hpp:104
double calculateTroposphericDelay(const Eigen::Vector3d &lla_recvPosAPC, const std::shared_ptr< const GnssObs > &gnssObs, double elevation, double azimuth, const std::string &nameId) const
Calculate the tropospheric delay with the model selected in the GUI.
Definition ObservationEstimator.hpp:584
std::pair< double, Eigen::Vector3d > calcCarrierEstimate(Frequency freq, int8_t freqNum, size_t receiverType, const Eigen::MatrixBase< Derived > &e_recvPosMarker, double recvClockBias, const std::shared_ptr< const SatelliteInfo > &satInfo, const std::shared_ptr< const GnssObs > &gnssObs, const std::shared_ptr< const IonosphericCorrections > &ionosphericCorrections, const std::string &nameId) const
Calculates the carrier-phase estimate.
Definition ObservationEstimator.hpp:326
bool ShowGuiWidgets(const char *id, float itemWidth)
Shows the GUI input to select the options.
Definition ObservationEstimator.hpp:600
const TroposphereModelSelection & getTroposphereModels() const
Get the Troposphere Model selection.
Definition ObservationEstimator.hpp:709
auto calcPseudorangeEstimate(Frequency freq, size_t receiverType, const Eigen::MatrixBase< Derived > &e_recvPosAPC, const auto &recvClockBias, const auto &interFreqBias, const auto &dpsr_T_r_s, const auto &dpsr_I_r_s, const std::shared_ptr< const SatelliteInfo > &satInfo, const auto &elevation, const std::shared_ptr< const GnssObs > &gnssObs, const std::string &nameId) const
Calculates the pseudorange estimate.
Definition ObservationEstimator.hpp:280
T calcPCV(const Frequency &freq, const InsTime &insTime, const T &elevation, std::optional< double > azimuth, size_t receiverType, const std::shared_ptr< const GnssObs > &gnssObs, const std::string &nameId) const
Calculates the phase center variation.
Definition ObservationEstimator.hpp:520
auto calcDopplerEstimate(Frequency freq, size_t receiverType, const Eigen::MatrixBase< DerivedPos > &e_recvPosMarker, const Eigen::MatrixBase< DerivedVel > &e_recvVel, const auto &recvClockDrift, const std::shared_ptr< const SatelliteInfo > &satInfo, const std::shared_ptr< const GnssObs > &gnssObs, const std::string &nameId) const
Calculates the doppler estimate.
Definition ObservationEstimator.hpp:381
friend void from_json(const json &j, ObservationEstimator::Antenna &obj)
Converts the provided json object into a node object.
Definition ObservationEstimator.hpp:748
std::unordered_map< size_t, Antenna > _antenna
User antenna selection. Key is receiver type.
Definition ObservationEstimator.hpp:730
friend void to_json(json &j, const ObservationEstimator &obj)
Converts the provided object into json.
Definition ObservationEstimator.hpp:760
void calcObservationEstimates(Observations &observations, const Receiver< ReceiverType > &receiver, const std::shared_ptr< const IonosphericCorrections > &ionosphericCorrections, const std::string &nameId, ObservationDifference obsDiff) const
Calculates the observation estimates.
Definition ObservationEstimator.hpp:83
ImGui extensions.
bool InputDouble3(const char *label, double v[3], const char *format="%.6f", ImGuiInputTextFlags flags=0)
Shows an InputText GUI element for an array of 'double[3]'.
Antenna information.
Definition ObservationEstimator.hpp:722
bool autoDetermine
Try determine antenna type from e.g. RINEX file.
Definition ObservationEstimator.hpp:725
Eigen::Vector3d hen_delta
Delta values of marker to antenna base.
Definition ObservationEstimator.hpp:727
bool correctPCV
Correct phase center variation.
Definition ObservationEstimator.hpp:724
std::string name
Type of the antenna for the Antex lookup.
Definition ObservationEstimator.hpp:726
bool correctPCO
Correct phase center offset.
Definition ObservationEstimator.hpp:723
Eigen::Vector3d e_satVel
Satellite velocity in ECEF frame [m/s].
Definition ObservationEstimator.hpp:261
SatelliteInfo(Eigen::Vector3d e_satPos, Eigen::Vector3d e_satVel, double satClockBias, double satClockDrift)
Constructor.
Definition ObservationEstimator.hpp:257
Eigen::Vector3d e_satPos
Satellite position in ECEF coordinates [m].
Definition ObservationEstimator.hpp:260
double satClockBias
Satellite clock bias [s].
Definition ObservationEstimator.hpp:262
double satClockDrift
Satellite clock drift [s/s].
Definition ObservationEstimator.hpp:263
Receiver specific observation of the signal.
Definition Observation.hpp:44
int8_t freqNum() const
Frequency number. Only used for GLONASS G1 and G2.
Definition Observation.hpp:198
std::unordered_map< size_t, std::shared_ptr< ReceiverSpecificData > > recvObs
Receiver specific data.
Definition Observation.hpp:193
const std::shared_ptr< const SatNavData > & navData() const
Satellite Navigation data.
Definition Observation.hpp:196
Observation storage type.
Definition Observation.hpp:41
unordered_map< SatSigId, SignalObservation > signals
Observations and calculated data for each signal.
Definition Observation.hpp:205
const double * biasFor(SatelliteSystem satSys) const
Get the bias for the given satellite system.
Definition ReceiverClock.hpp:81
const double * driftFor(SatelliteSystem satSys) const
Get the drift for the given satellite system.
Definition ReceiverClock.hpp:115
Receiver information.
Definition Receiver.hpp:34
std::shared_ptr< const GnssObs > gnssObs
Latest GNSS observation.
Definition Receiver.hpp:54
std::unordered_map< Frequency, UncertainValue< double > > interFrequencyBias
Inter frequency biases [s].
Definition Receiver.hpp:52
ReceiverType type
Receiver Type.
Definition Receiver.hpp:42
Eigen::Vector3d e_posMarker
Marker Position in ECEF frame [m].
Definition Receiver.hpp:44
Eigen::Vector3d e_vel
Velocity in ECEF frame [m/s].
Definition Receiver.hpp:48
ReceiverClock recvClk
Estimated receiver clock parameters.
Definition Receiver.hpp:50
Identifies a satellite signal (satellite frequency and number)
Definition SatelliteIdentifier.hpp:67
Frequency freq() const
Returns the frequency of the satellite signal.
Definition SatelliteIdentifier.hpp:108
Satellite System type.
Definition SatelliteSystem.hpp:44
Collection of troposphere model selections.
Definition Troposphere.hpp:63