INSTINCT Code Coverage Report


Directory: src/
File: Nodes/DataProcessor/GNSS/GnssAnalyzer.hpp
Date: 2025-02-07 16:54:41
Exec Total Coverage
Lines: 0 24 0.0%
Functions: 0 2 0.0%
Branches: 0 43 0.0%

Line Branch Exec Source
1 // This file is part of INSTINCT, the INS Toolkit for Integrated
2 // Navigation Concepts and Training by the Institute of Navigation of
3 // the University of Stuttgart, Germany.
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9 /// @file GnssAnalyzer.hpp
10 /// @brief Allows creation of GNSS measurement combinations
11 /// @author T. Topp (topp@ins.uni-stuttgart.de)
12 /// @date 2023-10-17
13
14 #pragma once
15
16 #include <vector>
17
18 #include "internal/Node/Node.hpp"
19
20 #include "Navigation/GNSS/Core/SatelliteIdentifier.hpp"
21 #include "Navigation/GNSS/Ambiguity/CycleSlipDetector.hpp"
22 #include "Navigation/Math/Polynomial.hpp"
23
24 namespace NAV
25 {
26 /// @brief Allows creation of GNSS measurement combinations
27 class GnssAnalyzer : public Node
28 {
29 public:
30 /// @brief Default constructor
31 GnssAnalyzer();
32 /// @brief Destructor
33 ~GnssAnalyzer() override;
34 /// @brief Copy constructor
35 GnssAnalyzer(const GnssAnalyzer&) = delete;
36 /// @brief Move constructor
37 GnssAnalyzer(GnssAnalyzer&&) = delete;
38 /// @brief Copy assignment operator
39 GnssAnalyzer& operator=(const GnssAnalyzer&) = delete;
40 /// @brief Move assignment operator
41 GnssAnalyzer& operator=(GnssAnalyzer&&) = delete;
42
43 /// @brief String representation of the Class Type
44 [[nodiscard]] static std::string typeStatic();
45
46 /// @brief String representation of the Class Type
47 [[nodiscard]] std::string type() const override;
48
49 /// @brief String representation of the Class Category
50 [[nodiscard]] static std::string category();
51
52 /// @brief ImGui config window which is shown on double click
53 /// @attention Don't forget to set _hasConfig to true in the constructor of the node
54 void guiConfig() override;
55
56 /// @brief Saves the node into a json object
57 [[nodiscard]] json save() const override;
58
59 /// @brief Restores the node from a json object
60 /// @param[in] j Json object with the node state
61 void restore(const json& j) override;
62
63 private:
64 constexpr static size_t INPUT_PORT_INDEX_GNSS_OBS = 0; ///< @brief Flow (GnssObs)
65 constexpr static size_t OUTPUT_PORT_INDEX_GNSS_COMBINATION = 0; ///< @brief Flow (GnssCombination)
66
67 /// Combination of GNSS measurements
68 struct Combination
69 {
70 /// Possible units to calculate the combination in
71 enum class Unit : uint8_t
72 {
73 Meters, ///< Meters
74 Cycles, ///< Cycles
75 };
76
77 /// Unit to calculate the combination in
78 Unit unit = Unit::Meters;
79
80 /// Term of a combination equation
81 struct Term
82 {
83 /// @brief Observation types
84 enum class ObservationType : uint8_t
85 {
86 Pseudorange, ///< Pseudorange
87 Carrier, ///< Carrier-Phase
88 };
89
90 int sign = +1; ///< +1 or -1
91 SatSigId satSigId = { Code::G1C, 1 }; ///< SignalId and satellite number
92 int8_t freqNum = -128; ///< Frequency number. Only used for GLONASS G1 and G2 // TODO: Set this somewhere
93 ObservationType obsType = ObservationType::Carrier; ///< Observation Type
94 bool receivedDuringRun = false; ///< Flag weather the signal was received
95 };
96 std::vector<Term> terms{ Term() }; ///< List of terms making up the combination
97
98 /// Cycle-slip detector
99 PolynomialCycleSlipDetector<std::string> polynomialCycleSlipDetector{ /* windowSize = */ 4, /* polyDegree = */ 2 };
100 /// Threshold to categorize a measurement as cycle slip [% of smallest wavelength]
101 double polynomialCycleSlipDetectorThresholdPercentage = 0.5;
102 /// Whether to output the prediction even when the window size is not reached
103 bool polynomialCycleSlipDetectorOutputWhenWindowSizeNotReached = false;
104 /// Whether the polynomials should be outputted
105 bool polynomialCycleSlipDetectorOutputPolynomials = false;
106 /// Polynomial collection
107 std::vector<std::pair<InsTime, Polynomial<double>>> polynomials;
108
109 /// @brief Get a string description of the combination
110 [[nodiscard]] std::string description() const
111 {
112 std::string desc;
113 for (const auto& term : terms)
114 {
115 if (!desc.empty()) { desc += " "; }
116 desc += term.sign == 1 ? "+" : "-";
117 desc += " ";
118 switch (term.obsType)
119 {
120 case Term::ObservationType::Pseudorange:
121 desc += unit == Unit::Cycles ? "P" : "p";
122 break;
123 case Term::ObservationType::Carrier:
124 desc += unit == Unit::Cycles ? "Φ" : "φ";
125 break;
126 }
127 desc += fmt::format("({})", term.satSigId);
128 }
129 if (unit == Unit::Cycles) { desc += " [cycles]"; }
130 else { desc += " [m]"; }
131
132 return desc;
133 }
134
135 /// @brief Calculates the combined frequency of all terms
136 [[nodiscard]] double calcCombinationFrequency() const
137 {
138 double combinedFreq = 0.0;
139 for (const auto& term : terms)
140 {
141 double freq = term.satSigId.freq().getFrequency(term.freqNum);
142 combinedFreq += static_cast<double>(term.sign) * freq;
143 }
144 return combinedFreq == 0 ? terms.front().satSigId.freq().getFrequency(terms.front().freqNum) : combinedFreq;
145 }
146 };
147
148 /// Combinations to calculate
149 std::vector<Combination> _combinations{ Combination() };
150
151 /// @brief Initialize the node
152 bool initialize() override;
153
154 /// @brief Deinitialize the node
155 void deinitialize() override;
156
157 /// @brief Receive Gnss observation
158 /// @param[in] queue Queue with all the received data messages
159 /// @param[in] pinIdx Index of the pin the data is received on
160 void receiveGnssObs(InputPin::NodeDataQueue& queue, size_t pinIdx);
161
162 /// @brief Write info to a json object
163 /// @param[out] j Json output
164 /// @param[in] data Object to read info from
165 friend void to_json(json& j, const Combination& data);
166 /// @brief Read info from a json object
167 /// @param[in] j Json variable to read info from
168 /// @param[out] data Output object
169 friend void from_json(const json& j, Combination& data);
170 /// @brief Write info to a json object
171 /// @param[out] j Json output
172 /// @param[in] data Object to read info from
173 friend void to_json(json& j, const Combination::Term& data);
174 /// @brief Read info from a json object
175 /// @param[in] j Json variable to read info from
176 /// @param[out] data Output object
177 friend void from_json(const json& j, Combination::Term& data);
178 };
179
180 } // namespace NAV
181