17#include <unordered_map>
18#include <unordered_set>
32#include "Navigation/Transformations/Units.hpp"
53 std::unordered_set<GnssObs::ObservationType> neededObsTypes = {})
54 : _snrMask(receiverCount), _availableObsTypes(availableObsTypes), _neededObsTypes(std::move(neededObsTypes)), _usedObsTypes(availableObsTypes) {}
67 _filterFreq = other._filterFreq;
68 _filterCode = other._filterCode;
69 _excludedSatellites = other._excludedSatellites;
70 _elevationMask = other._elevationMask;
71 _snrMask = other._snrMask;
72 _sameSnrMaskForAllReceivers = other._sameSnrMaskForAllReceivers;
73 _neededObsTypes = other._neededObsTypes;
74 _usedObsTypes = other._usedObsTypes;
75 std::vector<GnssObs::ObservationType> obsTypeToRemove;
76 for (
const auto& obsType : _usedObsTypes)
78 if (!_availableObsTypes.contains(obsType)) { obsTypeToRemove.push_back(obsType); }
80 for (
const auto& obsType : obsTypeToRemove)
82 _usedObsTypes.erase(obsType);
92 _filterFreq = other._filterFreq;
93 _filterCode = other._filterCode;
94 _excludedSatellites = std::move(other._excludedSatellites);
95 _elevationMask = other._elevationMask;
96 _snrMask = std::move(other._snrMask);
97 _sameSnrMaskForAllReceivers = other._sameSnrMaskForAllReceivers;
98 _neededObsTypes = std::move(other._neededObsTypes);
99 _usedObsTypes = std::move(other._usedObsTypes);
100 std::vector<GnssObs::ObservationType> obsTypeToRemove;
101 for (
const auto& obsType : _usedObsTypes)
103 if (!_availableObsTypes.contains(obsType)) { obsTypeToRemove.push_back(obsType); }
105 for (
const auto& obsType : obsTypeToRemove)
107 _usedObsTypes.erase(obsType);
116 _temporarilyExcludedSignalsSatellites.clear();
125 template<
typename ReceiverType>
127 const std::vector<const GnssNavInfo*>& gnssNavInfos,
128 [[maybe_unused]]
const std::string& nameId,
129 bool ignoreElevationMask =
false)
132 observations.
signals.reserve(receivers.front().gnssObs->data.size());
136 for (
const auto& obsData : receivers.front().gnssObs->data)
138 SatId satId = obsData.satSigId.toSatId();
140 if (!(obsData.satSigId.freq() & _filterFreq)
141 || !(obsData.satSigId.code & _filterCode)
142 || !obsData.pseudorange
143 || _temporarilyExcludedSignalsSatellites.contains(obsData.satSigId)
144 || std::find(_excludedSatellites.begin(), _excludedSatellites.end(), satId) != _excludedSatellites.end())
146 if (_temporarilyExcludedSignalsSatellites.contains(obsData.satSigId))
148 _temporarilyExcludedSignalsSatellites.at(obsData.satSigId)--;
149 if (_temporarilyExcludedSignalsSatellites.at(obsData.satSigId) == 0) { _temporarilyExcludedSignalsSatellites.erase(obsData.satSigId); }
151 LOG_DATA(
"{}: [{}] Skipping obs due to GUI filter selections", nameId, obsData.satSigId);
155 LOG_DATA(
"{}: [{}] Searching if observation in all receivers", nameId, obsData.satSigId);
157 if (std::any_of(receivers.begin(), receivers.end(),
159 auto obsDataOther = std::find_if(recv.gnssObs->data.begin(), recv.gnssObs->data.end(),
160 [&obsData](const GnssObs::ObservationData& obsDataOther) {
161 return obsDataOther.satSigId == obsData.satSigId;
164 if (obsDataOther == recv.
gnssObs->data.end())
166 LOG_DATA(
"{}: [{}] Receiver '{}' did not observe the signal.", nameId, obsData.satSigId, recv.
type);
170 for (
const auto& obsType : _usedObsTypes)
175 if (obsDataOther->pseudorange) { availableObservations[obsType]++; }
178 if (obsDataOther->carrierPhase) { availableObservations[obsType]++; }
181 if (obsDataOther->doppler) { availableObservations[obsType]++; }
187 if (!obsDataOther->pseudorange)
189 LOG_DATA(
"{}: [{}] Receiver '{}' did not have a pseudorange observation.", nameId, obsData.satSigId, recv.
type);
191 return !obsDataOther->pseudorange;
196 LOG_DATA(
"{}: [{}] Observed psr {}x, carrier {}x, doppler {}x", nameId, obsData.satSigId,
201 std::shared_ptr<NAV::SatNavData> satNavData =
nullptr;
202 for (
const auto& gnssNavInfo : gnssNavInfos)
204 auto satNav = gnssNavInfo->searchNavigationData(satId, receivers.front().gnssObs->insTime);
205 if (satNav && satNav->isHealthy())
211 if (satNavData ==
nullptr) {
continue; }
213 int8_t freqNum = -128;
214 if (satId.satSys ==
GLO)
216 if (
auto gloSatNavData = std::dynamic_pointer_cast<GLONASSEphemeris>(satNavData))
218 freqNum = gloSatNavData->frequencyNumber;
224 bool skipObservation =
false;
225 for (
const auto& recv : receivers)
227 auto recvObsData = std::find_if(recv.gnssObs->data.begin(), recv.gnssObs->data.end(),
229 return recvObsData.satSigId == obsData.satSigId;
231 auto satClk = satNavData->calcClockCorrections(recv.gnssObs->insTime,
234 auto satPosVel = satNavData->calcSatellitePosVel(satClk.transmitTime);
236 LOG_DATA(
"{}: Adding satellite [{}] for receiver {}", nameId, obsData.satSigId, recv.type);
237 sigObs.
recvObs.emplace_back(recv.gnssObs,
static_cast<size_t>(recvObsData - recv.gnssObs->data.begin()),
238 recv.e_posMarker, recv.lla_posMarker, recv.e_vel,
239 satPosVel.e_pos, satPosVel.e_vel, satClk);
241 if (!ignoreElevationMask)
243 const auto& satElevation = sigObs.
recvObs.back().satElevation();
244 if (satElevation < _elevationMask)
246 LOG_DATA(
"{}: Signal {} is skipped because of elevation mask. ({} < {})", nameId, obsData.satSigId,
247 rad2deg(satElevation), rad2deg(_elevationMask));
248 skipObservation =
true;
253 .at(_sameSnrMaskForAllReceivers ?
static_cast<ReceiverType
>(0) : recv.type)
254 .checkSNRMask(obsData.satSigId.freq(), satElevation, recvObsData->
CN0.value()))
256 LOG_DEBUG(
"{}: [{}] SNR mask triggered for [{}] on receiver [{}] with CN0 {} dbHz",
257 nameId, receivers.front().gnssObs->insTime.toYMDHMS(
GPST), obsData.satSigId, recv.type, recvObsData->
CN0.value());
258 skipObservation =
true;
263 if (skipObservation) {
continue; }
265 for (
const auto& recv : receivers)
267 auto& recvObsData = sigObs.
recvObs.at(recv.type);
269 for (
const auto& obsType : _usedObsTypes)
271 if (availableObservations.contains(obsType) && availableObservations.at(obsType) == receivers.size())
274 nMeasUniqueSat.at(obsType).insert(satId);
278 recvObsData.obs[obsType].measurement = recvObsData.gnssObsData().pseudorange->value;
279 LOG_DATA(
"{}: [{}] Taking {:11} observation into account on {:5} receiver ({:.3f} [m])", nameId, obsData.satSigId,
280 obsType, recv.type, recvObsData.obs[obsType].measurement);
283 recvObsData.obs[obsType].measurement =
InsConst<>::C / obsData.satSigId.freq().getFrequency(freqNum)
284 * recvObsData.gnssObsData().carrierPhase->value;
285 LOG_DATA(
"{}: [{}] Taking {:11} observation into account on {:5} receiver ({:.3f} [m] = {:.3f} [cycles])", nameId, obsData.satSigId,
286 obsType, recv.type, recvObsData.obs[obsType].measurement, recvObsData.gnssObsData().carrierPhase->value);
289 recvObsData.obs[obsType].measurement =
doppler2rangeRate(recvObsData.gnssObsData().doppler.value(),
290 obsData.satSigId.freq(),
292 LOG_DATA(
"{}: [{}] Taking {:11} observation into account on {:5} receiver ({:.3f} [m/s] = {:.3f} [Hz])", nameId, obsData.satSigId,
293 obsType, recv.type, recvObsData.obs[obsType].measurement, recvObsData.gnssObsData().doppler.value());
302 observations.
systems.insert(satId.satSys);
304 observations.
signals.insert(std::make_pair(obsData.satSigId, sigObs));
309 observations.nObservablesUniqueSatellite.at(obsType) = nMeasUniqueSat.at(obsType).size();
312#if LOG_LEVEL <= LOG_LEVEL_DATA
313 LOG_DATA(
"{}: usedSatSystems = [{}]", nameId, joinToString(observations.systems));
314 size_t nMeasTotal = 0;
315 std::string nMeasStr;
318 auto& nMeas = observations.nObservables.at(obsType);
319 nMeas /= receivers.size();
323 if (nMeasStr.ends_with(
", ")) { nMeasStr = nMeasStr.erase(nMeasStr.length() - 2); }
325 LOG_DATA(
"{}: Using {} measurements ({}) from {} satellites", nameId, nMeasTotal, nMeasStr, observations.satellites.size());
329 for (
const auto& obs : observations.signals)
331 satData[obs.first.toSatId()].first |= obs.first.freq();
332 satData[obs.first.toSatId()].second |= obs.first.code;
335 if (std::all_of(obs.second.recvObs.begin(), obs.second.recvObs.end(), [&obsType](
const Observations::SignalObservation::ReceiverSpecificData& recvObs) {
336 return recvObs.obs.contains(static_cast<GnssObs::ObservationType>(obsType));
343 for ([[maybe_unused]]
const auto& [satId, freqCode] : satData)
345 LOG_DATA(
"{}: [{}] on frequencies [{}] with codes [{}]", nameId, satId, freqCode.first, freqCode.second);
346 for (
const auto& [satSigId, obs] : sigData)
348 if (satSigId.toSatId() != satId) {
continue; }
350 for (
const auto& o : obs)
352 if (!str.empty()) { str +=
", "; }
353 str += fmt::format(
"{}", o);
355 LOG_DATA(
"{}: [{}] has obs: {}", nameId, satSigId.code, str);
366 template<
typename ReceiverType>
369 bool changed =
false;
371 ImGui::SetNextItemWidth(itemWidth);
377 ImGui::SetNextItemWidth(itemWidth);
378 if (
ShowCodeSelector(fmt::format(
"Signal Codes##{}",
id).c_str(), _filterCode, _filterFreq))
383 ImGui::SetNextItemWidth(itemWidth);
389 double elevationMaskDeg = rad2deg(_elevationMask);
390 ImGui::SetNextItemWidth(itemWidth);
391 if (ImGui::InputDoubleL(fmt::format(
"Elevation mask##{}",
id).c_str(), &elevationMaskDeg, 0.0, 90.0, 5.0, 5.0,
"%.1f°", ImGuiInputTextFlags_AllowTabInput))
393 _elevationMask = deg2rad(elevationMaskDeg);
394 LOG_DEBUG(
"{}: Elevation mask changed to {}°",
id, elevationMaskDeg);
398 for (
size_t i = 0; i < ReceiverType::ReceiverType_COUNT; ++i)
403 if (_sameSnrMaskForAllReceivers) { ImGui::BeginDisabled(); }
405 if (_snrMask.at(i).ShowGuiWidgets(fmt::format(
"{} SNR Mask",
static_cast<ReceiverType
>(i)).c_str()))
409 if (i != 0 && _sameSnrMaskForAllReceivers) { ImGui::EndDisabled(); }
411 if (ReceiverType::ReceiverType_COUNT > 1)
414 if (ImGui::Checkbox(fmt::format(
"Use same SNR for all receivers##{}",
id).c_str(), &_sameSnrMaskForAllReceivers))
420 ImGui::BeginHorizontal(fmt::format(
"Observables##{}",
id).c_str(),
421 ImVec2(itemWidth - ImGui::GetStyle().ItemSpacing.x + ImGui::GetStyle().ItemInnerSpacing.x, 0.0F));
425 if (!_availableObsTypes.contains(obsType)) {
continue; }
426 if (_neededObsTypes.contains(obsType)) { ImGui::BeginDisabled(); }
427 bool enabled = _usedObsTypes.contains(obsType);
428 if (ImGui::Checkbox(fmt::format(
"{}##{}", obsType,
id).c_str(), &enabled))
430 LOG_DEBUG(
"{}: Using {}: {}",
id, obsType, enabled);
431 if (enabled) { _usedObsTypes.insert(obsType); }
432 else { _usedObsTypes.erase(obsType); }
435 if (_neededObsTypes.contains(obsType)) { ImGui::EndDisabled(); }
437 ImGui::EndHorizontal();
440 ImGui::TextUnformatted(
"Used observables");
449 return (satId.
satSys & _filterFreq)
450 && std::find(_excludedSatellites.begin(), _excludedSatellites.end(), satId) == _excludedSatellites.end();
457 return _usedObsTypes.contains(obsType);
464 _usedObsTypes.insert(obsType);
472 if (needed) { _neededObsTypes.insert(obsType); }
473 else if (_neededObsTypes.contains(obsType)) { _neededObsTypes.erase(obsType); }
481 if (count == 0) {
return; }
482 _temporarilyExcludedSignalsSatellites.emplace(satSigId, count);
499 return _filterFreq.getSatSys();
505 return _usedObsTypes;
515 std::vector<SatId> _excludedSatellites;
517 double _elevationMask =
static_cast<double>(10.0_deg);
519 std::vector<SNRMask> _snrMask;
521 bool _sameSnrMaskForAllReceivers =
true;
523 const std::unordered_set<GnssObs::ObservationType> _availableObsTypes;
525 std::unordered_set<GnssObs::ObservationType> _neededObsTypes;
527 std::unordered_set<GnssObs::ObservationType> _usedObsTypes;
530 std::unordered_map<SatSigId, size_t> _temporarilyExcludedSignalsSatellites;
538 {
"frequencies",
Frequency_(obj._filterFreq) },
539 {
"codes", obj._filterCode },
540 {
"excludedSatellites", obj._excludedSatellites },
541 {
"elevationMask", rad2deg(obj._elevationMask) },
542 {
"snrMask", obj._snrMask },
543 {
"sameSnrMaskForAllReceivers", obj._sameSnrMaskForAllReceivers },
544 {
"usedObsTypes", obj._usedObsTypes },
545 {
"neededObsType", obj._neededObsTypes },
553 if (j.contains(
"frequencies"))
556 j.at(
"frequencies").get_to(value);
559 if (j.contains(
"codes")) { j.at(
"codes").get_to(obj._filterCode); }
560 if (j.contains(
"excludedSatellites")) { j.at(
"excludedSatellites").get_to(obj._excludedSatellites); }
561 if (j.contains(
"elevationMask"))
563 j.at(
"elevationMask").get_to(obj._elevationMask);
564 obj._elevationMask = deg2rad(obj._elevationMask);
566 if (j.contains(
"snrMask")) { j.at(
"snrMask").get_to(obj._snrMask); }
567 if (j.contains(
"sameSnrMaskForAllReceivers")) { j.at(
"sameSnrMaskForAllReceivers").get_to(obj._sameSnrMaskForAllReceivers); }
568 if (j.contains(
"usedObsTypes")) { j.at(
"usedObsTypes").get_to(obj._usedObsTypes); }
569 if (j.contains(
"neededObsTypes")) { j.at(
"neededObsTypes").get_to(obj._neededObsTypes); }
bool ShowCodeSelector(const char *label, Code &code, const Frequency &filterFreq, bool singleSelect=false)
Shows a ComboBox to select signal codes.
const Code Code_Default
Default selection for codes.
Definition Code.hpp:654
nlohmann::json json
json namespace
Definition FlowManager.hpp:21
Frequency definition for different satellite systems.
Frequency_
Enumerate for GNSS frequencies.
Definition Frequency.hpp:26
@ E07
Galileo E5b (1207.14 MHz).
Definition Frequency.hpp:34
@ E06
Galileo E6 (1278.75 MHz).
Definition Frequency.hpp:33
@ E01
Galileo, "E1" (1575.42 MHz).
Definition Frequency.hpp:31
@ E05
Galileo E5a (1176.45 MHz).
Definition Frequency.hpp:32
@ G02
GPS L2 (1227.6 MHz).
Definition Frequency.hpp:29
@ G01
GPS L1 (1575.42 MHz).
Definition Frequency.hpp:28
@ E08
Galileo E5 (E5a + E5b) (1191.795MHz).
Definition Frequency.hpp:35
@ G05
GPS L5 (1176.45 MHz).
Definition Frequency.hpp:30
bool ShowFrequencySelector(const char *label, Frequency &frequency, bool singleSelect=false)
Shows a ComboBox to select GNSS frequencies.
double doppler2rangeRate(double doppler, Frequency freq, int8_t num)
Transforms a doppler-shift into a range-rate.
Navigation message information.
GNSS Observation messages.
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
Observation data used for calculations.
Signal to Noise Ratio Mask.
Algorithms concerning the STL containers.
Structs identifying a unique satellite.
bool ShowSatelliteSelector(const char *label, std::vector< SatId > &satellites, SatelliteSystem filterSys=SatSys_All, bool displayOnlyNumber=false)
Shows a ComboBox to select satellites.
@ GLO
Globalnaja nawigazionnaja sputnikowaja sistema (GLONASS)
Definition SatelliteSystem.hpp:34
@ GPST
GPS Time.
Definition TimeSystem.hpp:29
ankerl::unordered_dense::map< Key, T > unordered_map
Unordered map type.
Definition Unordered_map.hpp:34
Enumerate for GNSS Codes.
Definition Code.hpp:88
Frequency definition for different satellite systems.
Definition Frequency.hpp:59
ObservationType
Observation types.
Definition GnssObs.hpp:36
@ Doppler
Doppler (Pseudorange rate)
Definition GnssObs.hpp:39
@ ObservationType_COUNT
Count.
Definition GnssObs.hpp:40
@ Carrier
Carrier-Phase.
Definition GnssObs.hpp:38
@ Pseudorange
Pseudorange.
Definition GnssObs.hpp:37
Constants.
Definition Constants.hpp:26
Observation Filter.
Definition ObservationFilter.hpp:45
const std::unordered_set< GnssObs::ObservationType > & getUsedObservationTypes() const
Get the used observation types.
Definition ObservationFilter.hpp:503
Observations selectObservationsForCalculation(const std::array< Receiver< ReceiverType >, ReceiverType::ReceiverType_COUNT > &receivers, const std::vector< const GnssNavInfo * > &gnssNavInfos, const std::string &nameId, bool ignoreElevationMask=false)
Returns a list of satellites and observations filtered by GUI settings & NAV data available & ....
Definition ObservationFilter.hpp:126
ObservationFilter(ObservationFilter &&other) noexcept=default
Move constructor.
friend void to_json(json &j, const ObservationFilter &obj)
Converts the provided object into json.
Definition ObservationFilter.hpp:535
ObservationFilter & operator=(ObservationFilter &&other) noexcept
Move assignment operator.
Definition ObservationFilter.hpp:88
bool isSatelliteAllowed(const SatId &satId) const
Checks if the satellite is allowed. Does not check elevation or SNR mask.
Definition ObservationFilter.hpp:447
friend void from_json(const json &j, ObservationFilter &obj)
Converts the provided json object into a node object.
Definition ObservationFilter.hpp:551
const Code & getCodeFilter() const
Get the Code Filter.
Definition ObservationFilter.hpp:491
void useObsType(GnssObs::ObservationType obsType)
Set the observation type to use.
Definition ObservationFilter.hpp:462
~ObservationFilter()=default
Destructor.
bool isObsTypeUsed(GnssObs::ObservationType obsType) const
Checks if the Observation type is used by the GUI settings.
Definition ObservationFilter.hpp:455
void markObsTypeAsNeeded(GnssObs::ObservationType obsType, bool needed=true)
Set the observation type as needed (cannot be unchecked in the GUI) or unneeded.
Definition ObservationFilter.hpp:470
SatelliteSystem getSystemFilter() const
Get the Satellite System Filter.
Definition ObservationFilter.hpp:497
void reset()
Reset the temporary settings.
Definition ObservationFilter.hpp:114
bool ShowGuiWidgets(const char *id, float itemWidth)
Shows the GUI input to select the options.
Definition ObservationFilter.hpp:367
ObservationFilter(size_t receiverCount, const std::unordered_set< GnssObs::ObservationType > &availableObsTypes={ GnssObs::Pseudorange, GnssObs::Carrier, GnssObs::Doppler }, std::unordered_set< GnssObs::ObservationType > neededObsTypes={})
Constructor.
Definition ObservationFilter.hpp:51
const Frequency & getFrequencyFilter() const
Get the Frequency Filter.
Definition ObservationFilter.hpp:486
ObservationFilter(const ObservationFilter &other)=default
Copy constructor.
ObservationFilter & operator=(const ObservationFilter &other)
Copy assignment operator.
Definition ObservationFilter.hpp:63
void excludeSignalTemporarily(const SatSigId &satSigId, size_t count)
Temporarily excludes a signal.
Definition ObservationFilter.hpp:479
Stores the satellites observations.
Definition GnssObs.hpp:45
std::optional< Pseudorange > pseudorange
Pseudorange measurement [m].
Definition GnssObs.hpp:120
std::optional< double > CN0
Carrier-to-Noise density [dBHz].
Definition GnssObs.hpp:123
SatSigId satSigId
SignalId and satellite number.
Definition GnssObs.hpp:119
Receiver specific observation of the signal.
Definition Observation.hpp:41
std::vector< ReceiverSpecificData > recvObs
Receiver specific data.
Definition Observation.hpp:136
Observation storage type.
Definition Observation.hpp:38
std::set< SatelliteSystem > systems
Satellite systems used.
Definition Observation.hpp:150
std::array< size_t, GnssObs::ObservationType_COUNT > nObservables
Number of observables.
Definition Observation.hpp:152
std::unordered_set< SatId > satellites
Satellites used.
Definition Observation.hpp:151
unordered_map< SatSigId, SignalObservation > signals
Observations and calculated data for each signal.
Definition Observation.hpp:148
Receiver information.
Definition Receiver.hpp:35
std::shared_ptr< const GnssObs > gnssObs
Latest GNSS observation.
Definition Receiver.hpp:53
ReceiverType type
Receiver Type.
Definition Receiver.hpp:41
Identifies a satellite (satellite system and number)
Definition SatelliteIdentifier.hpp:32
SatelliteSystem satSys
Satellite system (GPS, GLONASS, GALILEO, QZSS, BDS, IRNSS, SBAS)
Definition SatelliteIdentifier.hpp:42
Identifies a satellite signal (satellite frequency and number)
Definition SatelliteIdentifier.hpp:62
Frequency freq() const
Returns the frequency of the satellite signal.
Definition SatelliteIdentifier.hpp:103
Satellite System type.
Definition SatelliteSystem.hpp:43