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 SppSolution.hpp | ||
10 | /// @brief SPP Algorithm output | ||
11 | /// @author T. Topp (topp@ins.uni-stuttgart.de) | ||
12 | /// @date 2022-05-28 | ||
13 | |||
14 | #pragma once | ||
15 | |||
16 | #include <vector> | ||
17 | #include <optional> | ||
18 | #include <algorithm> | ||
19 | |||
20 | #include "Navigation/GNSS/Core/SatelliteIdentifier.hpp" | ||
21 | #include "Navigation/GNSS/Core/Code.hpp" | ||
22 | #include "Navigation/GNSS/Core/SatelliteSystem.hpp" | ||
23 | #include "Navigation/GNSS/Positioning/ReceiverClock.hpp" | ||
24 | #include "Navigation/GNSS/Positioning/SPP/Keys.hpp" | ||
25 | |||
26 | #include "NodeData/State/PosVel.hpp" | ||
27 | |||
28 | #include "util/Assert.h" | ||
29 | #include "util/Container/KeyedMatrix.hpp" | ||
30 | #include "util/Container/UncertainValue.hpp" | ||
31 | |||
32 | namespace NAV | ||
33 | { | ||
34 | /// SPP Algorithm output | ||
35 | class SppSolution : public PosVel | ||
36 | { | ||
37 | public: | ||
38 | /// @brief Returns the type of the data class | ||
39 | /// @return The data type | ||
40 | 860 | [[nodiscard]] static std::string type() | |
41 | { | ||
42 |
1/2✓ Branch 1 taken 860 times.
✗ Branch 2 not taken.
|
1720 | return "SppSolution"; |
43 | } | ||
44 | |||
45 | /// @brief Returns the type of the data class | ||
46 | /// @return The data type | ||
47 | ✗ | [[nodiscard]] std::string getType() const override { return type(); } | |
48 | |||
49 | /// @brief Returns the parent types of the data class | ||
50 | /// @return The parent data types | ||
51 | 112 | [[nodiscard]] static std::vector<std::string> parentTypes() | |
52 | { | ||
53 | 112 | auto parent = PosVel::parentTypes(); | |
54 |
2/4✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 112 times.
✗ Branch 5 not taken.
|
112 | parent.push_back(PosVel::type()); |
55 | 112 | return parent; | |
56 | ✗ | } | |
57 | |||
58 | /// @brief Returns a vector of data descriptors | ||
59 | 3 | [[nodiscard]] static std::vector<std::string> GetStaticDataDescriptors() | |
60 | { | ||
61 | 3 | auto desc = PosVel::GetStaticDataDescriptors(); | |
62 |
1/2✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
3 | desc.reserve(GetStaticDescriptorCount()); |
63 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Number satellites"); |
64 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias GPS [s]"); |
65 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift GPS [s/s]"); |
66 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias StDev GPS [s]"); |
67 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift StDev GPS [s/s]"); |
68 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias GAL [s]"); |
69 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift GAL [s/s]"); |
70 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias StDev GAL [s]"); |
71 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift StDev GAL [s/s]"); |
72 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias GLO [s]"); |
73 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift GLO [s/s]"); |
74 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias StDev GLO [s]"); |
75 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift StDev GLO [s/s]"); |
76 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias BDS [s]"); |
77 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift BDS [s/s]"); |
78 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias StDev BDS [s]"); |
79 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift StDev BDS [s/s]"); |
80 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias QZSS [s]"); |
81 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift QZSS [s/s]"); |
82 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias StDev QZSS [s]"); |
83 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift StDev QZSS [s/s]"); |
84 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias IRNSS [s]"); |
85 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift IRNSS [s/s]"); |
86 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias StDev IRNSS [s]"); |
87 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift StDev IRNSS [s/s]"); |
88 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias SBAS [s]"); |
89 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift SBAS [s/s]"); |
90 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock bias StDev SBAS [s]"); |
91 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("Receiver clock drift StDev SBAS [s/s]"); |
92 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("HDOP"); |
93 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("VDOP"); |
94 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | desc.emplace_back("PDOP"); |
95 | |||
96 | 3 | return desc; | |
97 | ✗ | } | |
98 | |||
99 | /// @brief Get the amount of descriptors | ||
100 | 3 | [[nodiscard]] static constexpr size_t GetStaticDescriptorCount() { return PosVel::GetStaticDescriptorCount() + 32; } | |
101 | |||
102 | /// @brief Returns a vector of data descriptors | ||
103 | ✗ | [[nodiscard]] std::vector<std::string> staticDataDescriptors() const override { return GetStaticDataDescriptors(); } | |
104 | |||
105 | /// @brief Get the amount of descriptors | ||
106 | ✗ | [[nodiscard]] size_t staticDescriptorCount() const override { return GetStaticDescriptorCount(); } | |
107 | |||
108 | /// @brief Get the value at the index | ||
109 | /// @param idx Index corresponding to data descriptor order | ||
110 | /// @return Value if in the observation | ||
111 | ✗ | [[nodiscard]] std::optional<double> getValueAt(size_t idx) const override | |
112 | { | ||
113 | ✗ | INS_ASSERT(idx < GetStaticDescriptorCount()); | |
114 | ✗ | if (idx < PosVel::GetStaticDescriptorCount()) { return PosVel::getValueAt(idx); } | |
115 | ✗ | switch (idx) | |
116 | { | ||
117 | ✗ | case PosVel::GetStaticDescriptorCount() + 0: // Number satellites | |
118 | ✗ | return static_cast<double>(nSatellites); | |
119 | |||
120 | ✗ | case PosVel::GetStaticDescriptorCount() + 1: // Receiver clock bias GPS [s] | |
121 | ✗ | if (const double* v = recvClk.biasFor(GPS)) { return *v; } | |
122 | ✗ | break; | |
123 | ✗ | case PosVel::GetStaticDescriptorCount() + 2: // Receiver clock drift GPS [s/s] | |
124 | ✗ | if (const double* v = recvClk.driftFor(GPS)) { return *v; } | |
125 | ✗ | break; | |
126 | ✗ | case PosVel::GetStaticDescriptorCount() + 3: // Receiver clock bias StDev GPS [s] | |
127 | ✗ | if (const double* v = recvClk.biasStdDevFor(GPS)) { return *v; } | |
128 | ✗ | break; | |
129 | ✗ | case PosVel::GetStaticDescriptorCount() + 4: // Receiver clock drift StDev GPS [s/s] | |
130 | ✗ | if (const double* v = recvClk.driftStdDevFor(GPS)) { return *v; } | |
131 | ✗ | break; | |
132 | |||
133 | ✗ | case PosVel::GetStaticDescriptorCount() + 5: // Receiver clock bias GAL [s] | |
134 | ✗ | if (const double* v = recvClk.biasFor(GAL)) { return *v; } | |
135 | ✗ | break; | |
136 | ✗ | case PosVel::GetStaticDescriptorCount() + 6: // Receiver clock drift GAL [s/s] | |
137 | ✗ | if (const double* v = recvClk.driftFor(GAL)) { return *v; } | |
138 | ✗ | break; | |
139 | ✗ | case PosVel::GetStaticDescriptorCount() + 7: // Receiver clock bias StDev GAL [s] | |
140 | ✗ | if (const double* v = recvClk.biasStdDevFor(GAL)) { return *v; } | |
141 | ✗ | break; | |
142 | ✗ | case PosVel::GetStaticDescriptorCount() + 8: // Receiver clock drift StDev GAL [s/s] | |
143 | ✗ | if (const double* v = recvClk.driftStdDevFor(GAL)) { return *v; } | |
144 | ✗ | break; | |
145 | |||
146 | ✗ | case PosVel::GetStaticDescriptorCount() + 9: // Receiver clock bias GLO [s] | |
147 | ✗ | if (const double* v = recvClk.biasFor(GLO)) { return *v; } | |
148 | ✗ | break; | |
149 | ✗ | case PosVel::GetStaticDescriptorCount() + 10: // Receiver clock drift GLO [s/s] | |
150 | ✗ | if (const double* v = recvClk.driftFor(GLO)) { return *v; } | |
151 | ✗ | break; | |
152 | ✗ | case PosVel::GetStaticDescriptorCount() + 11: // Receiver clock bias StDev GLO [s] | |
153 | ✗ | if (const double* v = recvClk.biasStdDevFor(GLO)) { return *v; } | |
154 | ✗ | break; | |
155 | ✗ | case PosVel::GetStaticDescriptorCount() + 12: // Receiver clock drift StDev GLO [s/s] | |
156 | ✗ | if (const double* v = recvClk.driftStdDevFor(GLO)) { return *v; } | |
157 | ✗ | break; | |
158 | |||
159 | ✗ | case PosVel::GetStaticDescriptorCount() + 13: // Receiver clock bias BDS [s] | |
160 | ✗ | if (const double* v = recvClk.biasFor(BDS)) { return *v; } | |
161 | ✗ | break; | |
162 | ✗ | case PosVel::GetStaticDescriptorCount() + 14: // Receiver clock drift BDS [s/s] | |
163 | ✗ | if (const double* v = recvClk.driftFor(BDS)) { return *v; } | |
164 | ✗ | break; | |
165 | ✗ | case PosVel::GetStaticDescriptorCount() + 15: // Receiver clock bias StDev BDS [s] | |
166 | ✗ | if (const double* v = recvClk.biasStdDevFor(BDS)) { return *v; } | |
167 | ✗ | break; | |
168 | ✗ | case PosVel::GetStaticDescriptorCount() + 16: // Receiver clock drift StDev BDS [s/s] | |
169 | ✗ | if (const double* v = recvClk.driftStdDevFor(BDS)) { return *v; } | |
170 | ✗ | break; | |
171 | |||
172 | ✗ | case PosVel::GetStaticDescriptorCount() + 17: // Receiver clock bias QZSS [s] | |
173 | ✗ | if (const double* v = recvClk.biasFor(QZSS)) { return *v; } | |
174 | ✗ | break; | |
175 | ✗ | case PosVel::GetStaticDescriptorCount() + 18: // Receiver clock drift QZSS [s/s] | |
176 | ✗ | if (const double* v = recvClk.driftFor(QZSS)) { return *v; } | |
177 | ✗ | break; | |
178 | ✗ | case PosVel::GetStaticDescriptorCount() + 19: // Receiver clock bias StDev QZSS [s] | |
179 | ✗ | if (const double* v = recvClk.biasStdDevFor(QZSS)) { return *v; } | |
180 | ✗ | break; | |
181 | ✗ | case PosVel::GetStaticDescriptorCount() + 20: // Receiver clock drift StDev QZSS [s/s] | |
182 | ✗ | if (const double* v = recvClk.driftStdDevFor(QZSS)) { return *v; } | |
183 | ✗ | break; | |
184 | |||
185 | ✗ | case PosVel::GetStaticDescriptorCount() + 21: // Receiver clock bias IRNSS [s] | |
186 | ✗ | if (const double* v = recvClk.biasFor(IRNSS)) { return *v; } | |
187 | ✗ | break; | |
188 | ✗ | case PosVel::GetStaticDescriptorCount() + 22: // Receiver clock drift IRNSS [s/s] | |
189 | ✗ | if (const double* v = recvClk.driftFor(IRNSS)) { return *v; } | |
190 | ✗ | break; | |
191 | ✗ | case PosVel::GetStaticDescriptorCount() + 23: // Receiver clock bias StDev IRNSS [s] | |
192 | ✗ | if (const double* v = recvClk.biasStdDevFor(IRNSS)) { return *v; } | |
193 | ✗ | break; | |
194 | ✗ | case PosVel::GetStaticDescriptorCount() + 24: // Receiver clock drift StDev IRNSS [s/s] | |
195 | ✗ | if (const double* v = recvClk.driftStdDevFor(IRNSS)) { return *v; } | |
196 | ✗ | break; | |
197 | |||
198 | ✗ | case PosVel::GetStaticDescriptorCount() + 25: // Receiver clock bias SBAS [s] | |
199 | ✗ | if (const double* v = recvClk.biasFor(SBAS)) { return *v; } | |
200 | ✗ | break; | |
201 | ✗ | case PosVel::GetStaticDescriptorCount() + 26: // Receiver clock drift SBAS [s/s] | |
202 | ✗ | if (const double* v = recvClk.driftFor(SBAS)) { return *v; } | |
203 | ✗ | break; | |
204 | ✗ | case PosVel::GetStaticDescriptorCount() + 27: // Receiver clock bias StDev SBAS [s] | |
205 | ✗ | if (const double* v = recvClk.biasStdDevFor(SBAS)) { return *v; } | |
206 | ✗ | break; | |
207 | ✗ | case PosVel::GetStaticDescriptorCount() + 28: // Receiver clock drift StDev SBAS [s/s] | |
208 | ✗ | if (const double* v = recvClk.driftStdDevFor(SBAS)) { return *v; } | |
209 | ✗ | break; | |
210 | ✗ | case PosVel::GetStaticDescriptorCount() + 29: // HDOP | |
211 | ✗ | return HDOP; | |
212 | ✗ | case PosVel::GetStaticDescriptorCount() + 30: // VDOP | |
213 | ✗ | return VDOP; | |
214 | ✗ | case PosVel::GetStaticDescriptorCount() + 31: // PDOP | |
215 | ✗ | return PDOP; | |
216 | ✗ | default: | |
217 | ✗ | return std::nullopt; | |
218 | } | ||
219 | ✗ | return std::nullopt; | |
220 | } | ||
221 | |||
222 | /// @brief Returns a vector of data descriptors for the dynamic data | ||
223 | ✗ | [[nodiscard]] std::vector<std::string> dynamicDataDescriptors() const override | |
224 | { | ||
225 | ✗ | std::vector<std::string> descriptors; | |
226 | ✗ | descriptors.reserve(interFrequencyBias.size() * 2 + satData.size() * 2); | |
227 | |||
228 | ✗ | for (const auto& bias : interFrequencyBias) | |
229 | { | ||
230 | ✗ | descriptors.push_back(fmt::format("{} Inter-freq bias [s]", bias.first)); | |
231 | ✗ | descriptors.push_back(fmt::format("{} Inter-freq bias StDev [s]", bias.first)); | |
232 | } | ||
233 | ✗ | for (const auto& [satId, satData] : satData) | |
234 | { | ||
235 | ✗ | descriptors.push_back(fmt::format("{} Elevation [deg]", satId)); | |
236 | ✗ | descriptors.push_back(fmt::format("{} Azimuth [deg]", satId)); | |
237 | // descriptors.push_back(fmt::format("{} Satellite clock bias [s]", satData.first)); | ||
238 | // descriptors.push_back(fmt::format("{} Satellite clock drift [s/s]", satData.first)); | ||
239 | // descriptors.push_back(fmt::format("{} SatPos ECEF X [m]", satData.first)); | ||
240 | // descriptors.push_back(fmt::format("{} SatPos ECEF Y [m]", satData.first)); | ||
241 | // descriptors.push_back(fmt::format("{} SatPos ECEF Z [m]", satData.first)); | ||
242 | // descriptors.push_back(fmt::format("{} SatPos Latitude [deg]", satData.first)); | ||
243 | // descriptors.push_back(fmt::format("{} SatPos Longitude [deg]", satData.first)); | ||
244 | // descriptors.push_back(fmt::format("{} SatPos Altitude [m]", satData.first)); | ||
245 | // descriptors.push_back(fmt::format("{} SatVel ECEF X [m/s]", satData.first)); | ||
246 | // descriptors.push_back(fmt::format("{} SatVel ECEF Y [m/s]", satData.first)); | ||
247 | // descriptors.push_back(fmt::format("{} SatVel ECEF Z [m/s]", satData.first)); | ||
248 | } | ||
249 | |||
250 | ✗ | return descriptors; | |
251 | ✗ | } | |
252 | |||
253 | /// @brief Get the value for the descriptor | ||
254 | /// @return Value if in the observation | ||
255 | ✗ | [[nodiscard]] std::optional<double> getDynamicDataAt(const std::string& descriptor) const override | |
256 | { | ||
257 | ✗ | for (const auto& bias : interFrequencyBias) | |
258 | { | ||
259 | ✗ | if (descriptor == fmt::format("{} Inter-freq bias [s]", bias.first)) { return bias.second.value; } | |
260 | ✗ | if (descriptor == fmt::format("{} Inter-freq bias StDev [s]", bias.first)) { return bias.second.stdDev; } | |
261 | } | ||
262 | ✗ | for (const auto& [satId, satData] : satData) | |
263 | { | ||
264 | ✗ | if (descriptor == fmt::format("{} Elevation [deg]", satId)) { return rad2deg(satData.satElevation); } | |
265 | ✗ | if (descriptor == fmt::format("{} Azimuth [deg]", satId)) { return rad2deg(satData.satAzimuth); } | |
266 | // if (descriptor == fmt::format("{} Satellite clock bias [s]", satData.first)) { return satData.second.satClock.bias; } | ||
267 | // if (descriptor == fmt::format("{} Satellite clock drift [s/s]", satData.first)) { return satData.second.satClock.drift; } | ||
268 | // if (descriptor == fmt::format("{} SatPos ECEF X [m]", satData.first)) { return satData.second.e_satPos.x(); } | ||
269 | // if (descriptor == fmt::format("{} SatPos ECEF Y [m]", satData.first)) { return satData.second.e_satPos.y(); } | ||
270 | // if (descriptor == fmt::format("{} SatPos ECEF Z [m]", satData.first)) { return satData.second.e_satPos.z(); } | ||
271 | // if (descriptor == fmt::format("{} SatPos Latitude [deg]", satData.first)) { return rad2deg(satData.second.lla_satPos.x()); } | ||
272 | // if (descriptor == fmt::format("{} SatPos Longitude [deg]", satData.first)) { return rad2deg(satData.second.lla_satPos.y()); } | ||
273 | // if (descriptor == fmt::format("{} SatPos Altitude [m]", satData.first)) { return satData.second.lla_satPos.z(); } | ||
274 | // if (descriptor == fmt::format("{} SatVel ECEF X [m/s]", satData.first)) { return satData.second.e_satVel.x(); } | ||
275 | // if (descriptor == fmt::format("{} SatVel ECEF Y [m/s]", satData.first)) { return satData.second.e_satVel.y(); } | ||
276 | // if (descriptor == fmt::format("{} SatVel ECEF Z [m/s]", satData.first)) { return satData.second.e_satVel.z(); } | ||
277 | } | ||
278 | ✗ | return std::nullopt; | |
279 | } | ||
280 | |||
281 | /// @brief Returns a vector of data descriptors and values for the dynamic data | ||
282 | ✗ | [[nodiscard]] std::vector<std::pair<std::string, double>> getDynamicData() const override | |
283 | { | ||
284 | ✗ | std::vector<std::pair<std::string, double>> dynData; | |
285 | ✗ | dynData.reserve(interFrequencyBias.size() * 2 + satData.size() * 2); | |
286 | |||
287 | ✗ | for (const auto& bias : interFrequencyBias) | |
288 | { | ||
289 | ✗ | dynData.emplace_back(fmt::format("{} Inter-freq bias [s]", bias.first), bias.second.value); | |
290 | ✗ | dynData.emplace_back(fmt::format("{} Inter-freq bias StDev [s]", bias.first), bias.second.stdDev); | |
291 | } | ||
292 | ✗ | for (const auto& [satId, satData] : satData) | |
293 | { | ||
294 | ✗ | dynData.emplace_back(fmt::format("{} Elevation [deg]", satId), rad2deg(satData.satElevation)); | |
295 | ✗ | dynData.emplace_back(fmt::format("{} Azimuth [deg]", satId), rad2deg(satData.satAzimuth)); | |
296 | // dynData.emplace_back(fmt::format("{} Satellite clock bias [s]", satData.first), satData.second.satClock.bias); | ||
297 | // dynData.emplace_back(fmt::format("{} Satellite clock drift [s/s]", satData.first), satData.second.satClock.drift); | ||
298 | // dynData.emplace_back(fmt::format("{} SatPos ECEF X [m]", satData.first), satData.second.e_satPos.x()); | ||
299 | // dynData.emplace_back(fmt::format("{} SatPos ECEF Y [m]", satData.first), satData.second.e_satPos.y()); | ||
300 | // dynData.emplace_back(fmt::format("{} SatPos ECEF Z [m]", satData.first), satData.second.e_satPos.z()); | ||
301 | // dynData.emplace_back(fmt::format("{} SatPos Latitude [deg]", satData.first), rad2deg(satData.second.lla_satPos.x())); | ||
302 | // dynData.emplace_back(fmt::format("{} SatPos Longitude [deg]", satData.first), rad2deg(satData.second.lla_satPos.y())); | ||
303 | // dynData.emplace_back(fmt::format("{} SatPos Altitude [m]", satData.first), satData.second.lla_satPos.z()); | ||
304 | // dynData.emplace_back(fmt::format("{} SatVel ECEF X [m/s]", satData.first), satData.second.e_satVel.x()); | ||
305 | // dynData.emplace_back(fmt::format("{} SatVel ECEF Y [m/s]", satData.first), satData.second.e_satVel.y()); | ||
306 | // dynData.emplace_back(fmt::format("{} SatVel ECEF Z [m/s]", satData.first), satData.second.e_satVel.z()); | ||
307 | } | ||
308 | ✗ | return dynData; | |
309 | ✗ | } | |
310 | |||
311 | // --------------------------------------------------------- Public Members ------------------------------------------------------------ | ||
312 | |||
313 | /// Amount of satellites used for the calculation | ||
314 | size_t nSatellites = 0; | ||
315 | /// Amount of pseudorange measurements used to calculate the position solution | ||
316 | size_t nMeasPsr = 0; | ||
317 | /// Amount of doppler measurements used to calculate the velocity solution | ||
318 | size_t nMeasDopp = 0; | ||
319 | /// Amount of Parameters estimated in this epoch | ||
320 | size_t nParam = 0; | ||
321 | |||
322 | /// HDOP value | ||
323 | double HDOP = std::nan(""); | ||
324 | /// VDOP value | ||
325 | double VDOP = std::nan(""); | ||
326 | /// PDOP value | ||
327 | double PDOP = std::nan(""); | ||
328 | |||
329 | /// Estimated receiver clock parameter | ||
330 | ReceiverClock recvClk{ {} }; | ||
331 | |||
332 | /// Inter-frequency biases | ||
333 | std::unordered_map<Frequency, UncertainValue<double>> interFrequencyBias; | ||
334 | |||
335 | /// Satellite specific data | ||
336 | struct SatData | ||
337 | { | ||
338 | double satElevation = 0.0; ///< Satellite Elevation [rad] | ||
339 | double satAzimuth = 0.0; ///< Satellite Azimuth [rad] | ||
340 | }; | ||
341 | |||
342 | /// Extended data for each satellite | ||
343 | std::vector<std::pair<SatId, SatData>> satData; | ||
344 | |||
345 | /// @brief Adds an event to the event list | ||
346 | /// @param event Event string | ||
347 | ✗ | void addEvent(const std::string& event) { _events.push_back(event); } | |
348 | |||
349 | private: | ||
350 | /// Standard deviation of Position in ECEF coordinates [m] | ||
351 | Eigen::Vector3d _e_positionStdev = Eigen::Vector3d::Zero() * std::nan(""); | ||
352 | /// Standard deviation of Position in local navigation frame coordinates [m] | ||
353 | Eigen::Vector3d _n_positionStdev = Eigen::Vector3d::Zero() * std::nan(""); | ||
354 | |||
355 | /// Standard deviation of Velocity in earth coordinates [m/s] | ||
356 | Eigen::Vector3d _e_velocityStdev = Eigen::Vector3d::Zero() * std::nan(""); | ||
357 | /// Standard deviation of Velocity in navigation coordinates [m/s] | ||
358 | Eigen::Vector3d _n_velocityStdev = Eigen::Vector3d::Zero() * std::nan(""); | ||
359 | |||
360 | /// Covariance matrix in ECEF coordinates | ||
361 | std::optional<KeyedMatrixXd<SPP::States::StateKeyType, SPP::States::StateKeyType>> _e_covarianceMatrix; | ||
362 | |||
363 | /// Covariance matrix in local navigation coordinates | ||
364 | std::optional<KeyedMatrixXd<SPP::States::StateKeyType, SPP::States::StateKeyType>> _n_covarianceMatrix; | ||
365 | }; | ||
366 | |||
367 | } // namespace NAV | ||
368 |