INSTINCT Code Coverage Report


Directory: src/
File: Navigation/GNSS/Positioning/SPP/Algorithm.hpp
Date: 2025-02-07 16:54:41
Exec Total Coverage
Lines: 0 4 0.0%
Functions: 0 2 0.0%
Branches: 0 4 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 Algorithm.hpp
10 /// @brief Single Point Positioning Algorithm
11 /// @author T. Topp (topp@ins.uni-stuttgart.de)
12 /// @date 2023-12-20
13
14 #pragma once
15
16 #include <fmt/format.h>
17 #include <cstdint>
18 #include <set>
19
20 #include "Navigation/GNSS/Positioning/Observation.hpp"
21 #include "Navigation/GNSS/Positioning/ObservationEstimator.hpp"
22 #include "Navigation/GNSS/Positioning/ObservationFilter.hpp"
23 #include "Navigation/GNSS/Positioning/Receiver.hpp"
24 #include "Navigation/GNSS/Positioning/SPP/Keys.hpp"
25 #include "Navigation/GNSS/Positioning/SPP/KalmanFilter.hpp"
26
27 #include "NodeData/GNSS/GnssObs.hpp"
28 #include "NodeData/GNSS/SppSolution.hpp"
29
30 namespace NAV
31 {
32
33 namespace SPP
34 {
35
36 /// Single Point Positioning Algorithm
37 class Algorithm
38 {
39 public:
40 /// Possible SPP estimation algorithms
41 enum class EstimatorType : uint8_t
42 {
43 LeastSquares, ///< Linear Least Squares
44 WeightedLeastSquares, ///< Weighted Linear Least Squares
45 KalmanFilter, ///< Kalman Filter
46 COUNT, ///< Amount of items in the enum
47 };
48
49 /// @brief Receiver Types
50 enum ReceiverType : uint8_t
51 {
52 Rover, ///< Rover
53 ReceiverType_COUNT, ///< Amount of receiver types
54 };
55
56 /// @brief Shows the GUI input to select the options
57 /// @param[in] id Unique id for ImGui.
58 /// @param[in] itemWidth Width of the widgets
59 /// @param[in] unitWidth Width on unit inputs
60 bool ShowGuiWidgets(const char* id, float itemWidth, float unitWidth);
61
62 /// Reset the algorithm
63 void reset();
64
65 /// @brief Get the Estimator Type
66 [[nodiscard]] EstimatorType getEstimatorType() const { return _estimatorType; }
67
68 /// @brief Get the last update time
69 const InsTime& getLastUpdateTime() const { return _lastUpdate; }
70
71 /// @brief Calculate the SPP solution
72 /// @param[in] gnssObs GNSS observation
73 /// @param[in] gnssNavInfos Collection of GNSS Nav information
74 /// @param[in] nameId Name and id of the node calling this (only used for logging purposes)
75 /// @return The SPP Solution if it could be calculated, otherwise nullptr
76 std::shared_ptr<SppSolution> calcSppSolution(const std::shared_ptr<const GnssObs>& gnssObs,
77 const std::vector<const GnssNavInfo*>& gnssNavInfos,
78 const std::string& nameId);
79
80 /// Observation Filter
81 ObservationFilter _obsFilter{ ReceiverType_COUNT,
82 /* available */ std::unordered_set{ GnssObs::Pseudorange, GnssObs::Doppler },
83 /* needed */ std::unordered_set{ GnssObs::Pseudorange } };
84
85 /// Observation Estimator
86 ObservationEstimator _obsEstimator{ ReceiverType_COUNT };
87
88 /// Estimate Inter-frequency biases
89 bool _estimateInterFreqBiases = true;
90
91 private:
92 using Receiver = NAV::Receiver<ReceiverType>; ///< Receiver
93
94 /// @brief All position keys
95 const std::vector<SPP::States::StateKeyType>& PosKey = Keys::Pos<SPP::States::StateKeyType>;
96 /// @brief All velocity keys
97 const std::vector<SPP::States::StateKeyType>& VelKey = Keys::Vel<SPP::States::StateKeyType>;
98 /// @brief All position and velocity keys
99 const std::vector<SPP::States::StateKeyType>& PosVelKey = Keys::PosVel<SPP::States::StateKeyType>;
100
101 /// @brief Checks if the SPP algorithm can calculate the position (always true for Kalman filter)
102 /// @param[in] nDoppMeas Amount of Doppler measurements
103 [[nodiscard]] bool canCalculateVelocity(size_t nDoppMeas) const;
104
105 /// @brief Checks if the SPP algorithm can estimate inter-frequency biases
106 [[nodiscard]] bool canEstimateInterFrequencyBias() const;
107
108 /// @brief Updates the inter frequency biases
109 /// @param[in] observations List of GNSS observation data used for the calculation
110 /// @param[in] nameId Name and id of the node calling this (only used for logging purposes)
111 void updateInterFrequencyBiases(const Observations& observations, const std::string& nameId);
112
113 /// @brief Returns a list of state keys
114 /// @param[in] usedSatSystems Used Satellite systems this epoch
115 /// @param[in] nDoppMeas Amount of Doppler measurements
116 /// @param[in] nameId Name and id of the node calling this (only used for logging purposes)
117 std::vector<States::StateKeyType> determineStateKeys(const std::set<SatelliteSystem>& usedSatSystems, size_t nDoppMeas, const std::string& nameId) const;
118
119 /// @brief Returns a list of measurement keys
120 /// @param[in] observations List of GNSS observation data used for the calculation
121 /// @param[in] nPsrMeas Amount of pseudo-range measurements
122 /// @param[in] nDoppMeas Amount of doppler measurements
123 /// @param[in] nameId Name and id of the node calling this (only used for logging purposes)
124 std::vector<Meas::MeasKeyTypes> determineMeasKeys(const Observations& observations, size_t nPsrMeas, size_t nDoppMeas, const std::string& nameId) const;
125
126 /// @brief Calculates the measurement sensitivity matrix 𝐇
127 /// @param[in] stateKeys State Keys
128 /// @param[in] measKeys Measurement Keys
129 /// @param[in] observations List of GNSS observation data used for the calculation
130 /// @param[in] nameId Name and id of the node calling this (only used for logging purposes)
131 /// @return The 𝐇 matrix
132 [[nodiscard]] KeyedMatrixXd<Meas::MeasKeyTypes, States::StateKeyType> calcMatrixH(const std::vector<States::StateKeyType>& stateKeys,
133 const std::vector<Meas::MeasKeyTypes>& measKeys,
134 const Observations& observations,
135 const std::string& nameId) const;
136
137 /// @brief Calculates the measurement noise covariance matrix 𝐑
138 /// @param[in] measKeys Measurement Keys
139 /// @param[in] observations List of GNSS observation data used for the calculation
140 /// @param[in] nameId Name and id of the node calling this (only used for logging purposes)
141 /// @return The 𝐑 matrix
142 [[nodiscard]] static KeyedMatrixXd<Meas::MeasKeyTypes, Meas::MeasKeyTypes> calcMatrixR(const std::vector<Meas::MeasKeyTypes>& measKeys,
143 const Observations& observations,
144 const std::string& nameId);
145
146 /// @brief Calculates the measurement innovation vector 𝜹𝐳
147 /// @param[in] measKeys Measurement Keys
148 /// @param[in] observations List of GNSS observation data used for the calculation
149 /// @param[in] nameId Name and id of the node calling this (only used for logging purposes)
150 /// @return The measurement innovation 𝜹𝐳 vector
151 [[nodiscard]] static KeyedVectorXd<Meas::MeasKeyTypes> calcMeasInnovation(const std::vector<Meas::MeasKeyTypes>& measKeys,
152 const Observations& observations,
153 const std::string& nameId);
154
155 /// @brief Assigns the result to the receiver variable
156 /// @param[in] state Delta state
157 /// @param[in] variance Variance of the state
158 /// @param[in] e_oldPos Old position in ECEF coordinates in [m]
159 /// @param[in] nParams Number of parameters to estimate the position
160 /// @param[in] nUniqueDopplerMeas Number of available doppler measurements (unique per satellite)
161 /// @param[in] dt Time step size in [s]
162 /// @param[in] nameId Name and id of the node calling this (only used for logging purposes)
163 void assignLeastSquaresResult(const KeyedVectorXd<States::StateKeyType>& state,
164 const KeyedMatrixXd<States::StateKeyType, States::StateKeyType>& variance,
165 const Eigen::Vector3d& e_oldPos,
166 size_t nParams, size_t nUniqueDopplerMeas, double dt, const std::string& nameId);
167
168 /// @brief Assigns the result to the receiver variable
169 /// @param state Total state
170 /// @param variance Variance of the state
171 /// @param[in] nameId Name and id of the node calling this (only used for logging purposes)
172 void assignKalmanFilterResult(const KeyedVectorXd<States::StateKeyType>& state,
173 const KeyedMatrixXd<States::StateKeyType, States::StateKeyType>& variance,
174 const std::string& nameId);
175
176 /// @brief Computes all DOP values (by reference)
177 /// @param[in, out] sppSol SppSol to fill with DOP values
178 /// @param[in] H Measurement sensitivity matrix 𝐇
179 /// @param[in] nameId Name and id of the node calling this (only used for logging purposes)
180 void computeDOPs(const std::shared_ptr<SppSolution>& sppSol,
181 const KeyedMatrixXd<Meas::MeasKeyTypes, States::StateKeyType>& H,
182 const std::string& nameId);
183
184 /// Receiver
185 Receiver _receiver{ Rover, _obsFilter.getSystemFilter().toVector() };
186
187 /// Estimator type used for the calculations
188 EstimatorType _estimatorType = EstimatorType::WeightedLeastSquares;
189
190 /// SPP specific Kalman filter
191 SPP::KalmanFilter _kalmanFilter;
192
193 /// Time of last update
194 InsTime _lastUpdate;
195
196 Eigen::Matrix3d _e_lastPositionCovarianceMatrix; ///< Last position covariance matrix
197 Eigen::Matrix3d _e_lastVelocityCovarianceMatrix; ///< Last velocity covariance matrix
198
199 friend void to_json(json& j, const Algorithm& obj);
200 friend void from_json(const json& j, Algorithm& obj);
201 };
202
203 /// @brief Converts the provided object into json
204 /// @param[out] j Json object which gets filled with the info
205 /// @param[in] obj Object to convert into json
206 void to_json(json& j, const Algorithm& obj);
207 /// @brief Converts the provided json object into a node object
208 /// @param[in] j Json object with the needed values
209 /// @param[out] obj Object to fill from the json
210 void from_json(const json& j, Algorithm& obj);
211
212 } // namespace SPP
213
214 /// @brief Converts the enum to a string
215 /// @param[in] estimatorType Enum value to convert into text
216 /// @return String representation of the enum
217 [[nodiscard]] const char* to_string(SPP::Algorithm::EstimatorType estimatorType);
218
219 /// @brief Converts the enum to a string
220 /// @param[in] receiver Enum value to convert into text
221 /// @return String representation of the enum
222 [[nodiscard]] const char* to_string(SPP::Algorithm::ReceiverType receiver);
223
224 } // namespace NAV
225
226 /// @brief Stream insertion operator overload
227 /// @param[in, out] os Output stream object to stream the time into
228 /// @param[in] obj Object to print
229 /// @return Returns the output stream object in order to chain stream insertions
230 std::ostream& operator<<(std::ostream& os, const NAV::SPP::Algorithm::EstimatorType& obj);
231
232 /// @brief Stream insertion operator overload
233 /// @param[in, out] os Output stream object to stream the time into
234 /// @param[in] obj Object to print
235 /// @return Returns the output stream object in order to chain stream insertions
236 std::ostream& operator<<(std::ostream& os, const NAV::SPP::Algorithm::ReceiverType& obj);
237
238 #ifndef DOXYGEN_IGNORE
239
240 /// @brief Formatter
241 template<>
242 struct fmt::formatter<NAV::SPP::Algorithm::EstimatorType> : fmt::formatter<const char*>
243 {
244 /// @brief Defines how to format structs
245 /// @param[in] type Struct to format
246 /// @param[in, out] ctx Format context
247 /// @return Output iterator
248 template<typename FormatContext>
249 auto format(const NAV::SPP::Algorithm::EstimatorType& type, FormatContext& ctx) const
250 {
251 return fmt::formatter<const char*>::format(NAV::to_string(type), ctx);
252 }
253 };
254
255 /// @brief Formatter
256 template<>
257 struct fmt::formatter<NAV::SPP::Algorithm::ReceiverType> : fmt::formatter<const char*>
258 {
259 /// @brief Defines how to format structs
260 /// @param[in] type Struct to format
261 /// @param[in, out] ctx Format context
262 /// @return Output iterator
263 template<typename FormatContext>
264 auto format(const NAV::SPP::Algorithm::ReceiverType& type, FormatContext& ctx) const
265 {
266 return fmt::formatter<const char*>::format(NAV::to_string(type), ctx);
267 }
268 };
269
270 #endif
271