INSTINCT Code Coverage Report


Directory: src/
File: Nodes/DataProvider/GNSS/FileReader/RinexNavFile.cpp
Date: 2025-06-06 13:17:47
Exec Total Coverage
Lines: 567 743 76.3%
Functions: 23 28 82.1%
Branches: 1194 2541 47.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 #include "RinexNavFile.hpp"
10
11 #include <bitset>
12 #include <fmt/ranges.h>
13
14 #include "internal/NodeManager.hpp"
15 namespace nm = NAV::NodeManager;
16 #include "internal/FlowManager.hpp"
17
18 #include "util/StringUtil.hpp"
19
20 #include "Navigation/GNSS/Core/SatelliteSystem.hpp"
21 #include "Navigation/Atmosphere/Ionosphere/IonosphericCorrections.hpp"
22 #include "Navigation/GNSS/Satellite/Ephemeris/GPSEphemeris.hpp"
23 #include "Navigation/GNSS/Satellite/Ephemeris/GalileoEphemeris.hpp"
24 #include "Navigation/GNSS/Satellite/Ephemeris/GLONASSEphemeris.hpp"
25 #include "Navigation/GNSS/Satellite/Ephemeris/BDSEphemeris.hpp"
26 #include "Navigation/GNSS/Satellite/Ephemeris/QZSSEphemeris.hpp"
27
28 namespace NAV
29 {
30 159 RinexNavFile::RinexNavFile()
31
3/6
✓ Branch 1 taken 159 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 159 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 159 times.
✗ Branch 9 not taken.
159 : Node(typeStatic())
32 {
33 LOG_TRACE("{}: called", name);
34
35 159 _hasConfig = true;
36 159 _guiConfigDefaultWindowSize = { 517, 87 };
37
38
5/10
✓ Branch 2 taken 159 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 159 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 159 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 159 times.
✓ Branch 15 taken 159 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
636 nm::CreateOutputPin(this, GnssNavInfo::type().c_str(), Pin::Type::Object, { GnssNavInfo::type() }, &_gnssNavInfo);
39 318 }
40
41 412 RinexNavFile::~RinexNavFile()
42 {
43 LOG_TRACE("{}: called", nameId());
44 412 }
45
46 271 std::string RinexNavFile::typeStatic()
47 {
48
1/2
✓ Branch 1 taken 271 times.
✗ Branch 2 not taken.
542 return "RinexNavFile";
49 }
50
51 std::string RinexNavFile::type() const
52 {
53 return typeStatic();
54 }
55
56 112 std::string RinexNavFile::category()
57 {
58
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
224 return "Data Provider";
59 }
60
61 void RinexNavFile::guiConfig()
62 {
63 if (auto res = FileReader::guiConfig(R"(Rinex Nav (.nav .rnx .gal .geo .glo .*N .*P){.nav,.rnx,.gal,.geo,.glo,(.+[.]\d\d?[Nn]),(.+[.]\d\d?[Ll]),(.+[.]\d\d?[Pp])},.*)",
64 { ".nav", ".rnx", ".gal", ".geo", ".glo", "(.+[.]\\d\\d?[Nn])", "(.+[.]\\d\\d?[Ll])", "(.+[.]\\d\\d?[Pp])" }, size_t(id), nameId()))
65 {
66 LOG_DEBUG("{}: Path changed to {}", nameId(), _path);
67 flow::ApplyChanges();
68 if (res == FileReader::PATH_CHANGED)
69 {
70 doReinitialize();
71 }
72 else
73 {
74 doDeinitialize();
75 }
76 }
77 ImGui::Text("Supported versions: ");
78 std::ranges::for_each(_supportedVersions, [](double x) {
79 ImGui::SameLine();
80 ImGui::Text("%0.2f", x);
81 });
82 }
83
84 [[nodiscard]] json RinexNavFile::save() const
85 {
86 LOG_TRACE("{}: called", nameId());
87
88 json j;
89
90 j["FileReader"] = FileReader::save();
91
92 return j;
93 }
94
95 47 void RinexNavFile::restore(json const& j)
96 {
97 LOG_TRACE("{}: called", nameId());
98
99
1/2
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
47 if (j.contains("FileReader"))
100 {
101 47 FileReader::restore(j.at("FileReader"));
102 }
103 47 }
104
105 47 bool RinexNavFile::initialize()
106 {
107 LOG_TRACE("{}: called", nameId());
108
109 {
110 // The guards needs to be released before FileReader::initialize()
111
1/2
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
47 auto guard = requestOutputValueLock(OUTPUT_PORT_INDEX_GNSS_NAV_INFO);
112 47 _gnssNavInfo.reset();
113 47 }
114 47 _version = 0.0;
115 47 _sbasNotSupportedWarned = false;
116
117
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 47 times.
47 if (!FileReader::initialize())
118 {
119 return false;
120 }
121
122 47 readOrbits();
123
124 47 return true;
125 }
126
127 47 void RinexNavFile::deinitialize()
128 {
129 LOG_TRACE("{}: called", nameId());
130
131 47 FileReader::deinitialize();
132 47 }
133
134 94 bool RinexNavFile::resetNode()
135 {
136 LOG_TRACE("{}: called", nameId());
137
138 94 FileReader::resetReader();
139
140 94 return true;
141 }
142
143 47 FileReader::FileType RinexNavFile::determineFileType()
144 {
145 344 auto extHeaderLabel = [](const std::string& line) {
146
1/2
✓ Branch 2 taken 344 times.
✗ Branch 3 not taken.
344 return str::trim_copy(std::string_view(line).substr(60, 20));
147 };
148
149
1/2
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
47 std::filesystem::path filepath = getFilepath();
150
151
1/2
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
47 auto filestreamHeader = std::ifstream(filepath);
152
1/2
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
47 if (filestreamHeader.good())
153 {
154 47 std::string line;
155 // --------------------------------------- RINEX VERSION / TYPE ------------------------------------------
156
5/6
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 47 times.
✓ Branch 4 taken 59 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 59 times.
✓ Branch 7 taken 47 times.
106 while (line.find("RINEX VERSION / TYPE") == std::string::npos && !filestreamHeader.eof())
157 {
158
1/2
✓ Branch 1 taken 59 times.
✗ Branch 2 not taken.
59 std::getline(filestreamHeader, line);
159 }
160
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 47 times.
47 if (filestreamHeader.eof())
161 {
162 LOG_ERROR("{}: Not a valid RINEX NAV file. Could not read 'RINEX VERSION / TYPE' line.", nameId());
163 return FileReader::FileType::NONE;
164 }
165
1/2
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
47 str::rtrim(line);
166
3/6
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 47 times.
✗ Branch 5 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 47 times.
47 if (str::rtrim_copy(line).size() != 80)
167 {
168 LOG_ERROR("{}: Not a valid RINEX NAV file. Lines should be 80 characters long but the file has {}.", nameId(), line.size() - 1);
169 return FileReader::FileType::NONE;
170 }
171
172
2/4
✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 47 times.
47 if (extHeaderLabel(line) != "RINEX VERSION / TYPE")
173 {
174 LOG_ERROR("{}: Not a valid RINEX NAV file. Could not read 'RINEX VERSION / TYPE' line.", nameId());
175 return FileReader::FileType::NONE;
176 }
177
178
3/6
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 47 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 47 times.
✗ Branch 8 not taken.
47 _version = std::stod(str::trim_copy(line.substr(0, 20))); // FORMAT: F9.2,11X
179
2/4
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 47 times.
47 if (!_supportedVersions.contains(_version))
180 {
181 LOG_ERROR("{}: RINEX version {} is not supported. Supported versions are [{}]", nameId(),
182 _version, fmt::join(_supportedVersions.begin(), _supportedVersions.end(), ", "));
183 _version = 0.0;
184 return FileReader::FileType::NONE;
185 }
186
187
2/4
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 47 times.
✗ Branch 5 not taken.
47 std::string fileType = str::trim_copy(line.substr(20, 20)); // FORMAT: A1,19X
188
1/2
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
47 if (fileType.at(0) != 'N' // N: GNSS NAV DATA
189
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 && fileType != "NAVIGATION DATA"
190
5/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 45 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 47 times.
49 && fileType != "GLONASS NAV DATA")
191 {
192 LOG_ERROR("{}: Not a valid RINEX NAV file. File type '{}' not recognized.", nameId(), fileType);
193 doDeinitialize();
194 return FileReader::FileType::NONE;
195 }
196 47 std::string satSystem;
197
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 43 times.
47 if (_version < 3.0)
198 {
199
3/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
4 if (fileType == "NAVIGATION DATA")
200 {
201
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 satSystem = 'G';
202 }
203
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 else if (fileType == "GLONASS NAV DATA")
204 {
205
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 satSystem = 'R';
206 }
207 else if (fileType.at(0) == 'N')
208 {
209 satSystem = fileType.substr(3, 3);
210 }
211 }
212 else
213 {
214
2/4
✓ Branch 1 taken 43 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
43 satSystem = str::trim_copy(line.substr(40, 20)); // FORMAT: A1,19X
215 }
216
8/14
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 47 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 47 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8 times.
✓ Branch 11 taken 39 times.
✓ Branch 13 taken 8 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 47 times.
47 if (satSystem.empty() || (SatelliteSystem::fromChar(satSystem.at(0)) == SatSys_None && satSystem.at(0) != 'M'))
217 {
218 LOG_ERROR("{}: Not a valid RINEX NAV file. Satellite System '{}' not recognized.", nameId(), satSystem);
219 doDeinitialize();
220 return FileReader::FileType::NONE;
221 }
222 // ---------------------------------------- PGM / RUN BY / DATE ------------------------------------------
223
1/2
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
47 std::getline(filestreamHeader, line);
224
1/2
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
47 str::rtrim(line);
225
2/4
✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 47 times.
47 if (extHeaderLabel(line) != "PGM / RUN BY / DATE")
226 {
227 LOG_ERROR("{}: Not a valid RINEX NAV file. Could not read 'PGM / RUN BY / DATE' line.", nameId());
228 return FileReader::FileType::NONE;
229 }
230
231 // ----------------------------------------- END OF HEADER -------------------------------------------
232
5/10
✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 250 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 250 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 250 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 250 times.
✗ Branch 12 not taken.
250 while (std::getline(filestreamHeader, line) && !filestreamHeader.eof())
233 {
234
1/2
✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
250 str::rtrim(line);
235
3/4
✓ Branch 2 taken 250 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 47 times.
✓ Branch 6 taken 203 times.
250 if (extHeaderLabel(line) == "END OF HEADER")
236 {
237 47 return FileReader::FileType::ASCII;
238 }
239 }
240 LOG_ERROR("{}: Not a valid RINEX NAV file. Could not read 'END OF HEADER' line.", nameId());
241 return FileReader::FileType::NONE;
242 47 }
243
244 LOG_ERROR("{}: Could not determine file type because file could not be opened '{}' line.", nameId(), filepath.string());
245 return FileReader::FileType::NONE;
246 47 }
247
248 namespace
249 {
250
251 297 std::string_view extHeaderLabel(const std::string& line)
252 {
253
2/4
✓ Branch 1 taken 297 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 297 times.
✗ Branch 6 not taken.
594 return line.size() >= 60 ? str::trim_copy(std::string_view(line).substr(60, 20))
254 297 : std::string_view{};
255 };
256
257 } // namespace
258
259 47 void RinexNavFile::executeHeaderParser(double version)
260 {
261
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 43 times.
47 if (version < 3.0)
262 {
263 4 parseHeader2();
264 }
265
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 5 times.
43 else if (version < 4.0)
266 {
267 38 parseHeader3();
268 }
269
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 else if (version == 4.0)
270 {
271 5 parseHeader4();
272 }
273 else
274 {
275 LOG_ERROR("{}: Unsupported RINEX version {}.", nameId(), version);
276 // return nullptr;
277 }
278 47 }
279
280 47 void RinexNavFile::executeOrbitParser(double version)
281 {
282
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 43 times.
47 if (version < 3.0)
283 {
284 4 parseOrbit2();
285 }
286
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 5 times.
43 else if (version < 4.0)
287 {
288 38 parseOrbit3();
289 }
290
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 else if (version == 4.0)
291 {
292 5 parseOrbit4();
293 }
294 else
295 {
296 LOG_ERROR("{}: Unsupported RINEX version {}.", nameId(), version);
297 // return nullptr;
298 }
299 47 }
300
301 4 void RinexNavFile::parseHeader2()
302 {
303 4 std::string line;
304 // --------------------------------------- RINEX VERSION / TYPE ------------------------------------------
305
6/8
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 4 times.
8 while (line.find("RINEX VERSION / TYPE") == std::string::npos && !eof())
306 {
307
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 getline(line);
308 }
309 4 SatelliteSystem satSys = SatSys_None;
310
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
4 LOG_DEBUG("{}: Version: {:3.2f}", nameId(), _version); // FORMAT: F9.2,11X
311
7/14
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 2 times.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 2 times.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
8 if ((line.substr(20, 15) == "N: GPS NAV DATA" || line.substr(20, 15) == "NAVIGATION DATA")
312
17/32
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 1 times.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 1 times.
✓ Branch 26 taken 3 times.
✓ Branch 28 taken 1 times.
✓ Branch 29 taken 3 times.
✓ Branch 31 taken 2 times.
✓ Branch 32 taken 2 times.
✓ Branch 34 taken 4 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
8 && (line.substr(40, 3) == "GPS" || str::trim_copy(line.substr(40, 3)).empty()))
313 {
314
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
2 LOG_DEBUG("{}: SatSys : {}", nameId(), "G: GPS"); // FORMAT: A1,19X
315 2 satSys = GPS;
316 2 _gnssNavInfo.satelliteSystems |= satSys;
317 }
318
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
2 else if (line.substr(20, 16) == "GLONASS NAV DATA")
319 {
320
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
2 LOG_DEBUG("{}: SatSys : {}", nameId(), "R: GLONASS"); // FORMAT: A1,19X
321 2 satSys = GLO;
322 2 _gnssNavInfo.satelliteSystems |= satSys;
323 }
324 // #######################################################################################################
325
6/12
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 24 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 24 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 24 times.
✗ Branch 14 not taken.
24 while (getline(line) && !eof())
326 {
327
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 str::rtrim(line);
328
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 auto headerLabel = extHeaderLabel(line);
329
2/2
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 4 times.
24 if (headerLabel == "PGM / RUN BY / DATE")
330 {
331 // Name of program creating current file
332 LOG_DATA("{}: Program: {}", nameId(), str::trim_copy(line.substr(0, 20))); // FORMAT: A20
333 // Name of agency creating current file
334 LOG_DATA("{}: Run by : {}", nameId(), str::trim_copy(line.substr(20, 20))); // FORMAT: A20
335 // Date and time of file creation
336 LOG_DATA("{}: Date : {}", nameId(), str::trim_copy(line.substr(40, 20))); // FORMAT: A20
337 }
338
2/2
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 4 times.
20 else if (headerLabel == "COMMENT")
339 {
340 LOG_DATA("{}: Comment: {}", nameId(), line.substr(0, 60)); // FORMAT: A60
341 }
342
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
16 else if (headerLabel == "IONOSPHERIC CORR")
343 {
344 auto correctionType = str::trim_copy(line.substr(0, 4)); // FORMAT: A4,1X,
345 std::array<double, 4> values{};
346 values[0] = str::stod(str::replaceAll_copy(line.substr(5, 12), "d", "e", str::IgnoreCase), 0.0); // FORMAT: 4D12.4
347 values[1] = str::stod(str::replaceAll_copy(line.substr(17, 12), "d", "e", str::IgnoreCase), 0.0);
348 values[2] = str::stod(str::replaceAll_copy(line.substr(29, 12), "d", "e", str::IgnoreCase), 0.0);
349 values[3] = str::stod(str::replaceAll_copy(line.substr(41, 12), "d", "e", str::IgnoreCase), 0.0);
350
351 auto satSys = SatelliteSystem::fromString(correctionType.substr(0, 3));
352 IonosphericCorrections::AlphaBeta alphaBeta = (correctionType.size() == 4 && correctionType.at(3) == 'B')
353 ? IonosphericCorrections::Beta
354 : IonosphericCorrections::Alpha;
355 _gnssNavInfo.ionosphericCorrections.insert(satSys, alphaBeta, values);
356 LOG_DATA("{}: Ionospheric Correction: {}-{}: [{}]", nameId(),
357 std::string(satSys), alphaBeta == IonosphericCorrections::Alpha ? "Alpha" : "Beta",
358 fmt::join(values.begin(), values.end(), ", "));
359 }
360
6/6
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 2 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 12 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 12 times.
16 else if (headerLabel == "ION ALPHA" || headerLabel == "ION BETA")
361 {
362
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 auto correctionType = headerLabel.substr(4, 1);
363
6/12
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
20 auto valuesStr = str::split_wo_empty(str::replaceAll_copy(line.substr(4, 60 - 4), "d", "e", str::IgnoreCase), " ");
364 4 std::array<double, 4> values{};
365
2/2
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 4 times.
20 for (size_t i = 0; i < valuesStr.size(); i++)
366 {
367
3/6
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 8 not taken.
16 values.at(i) = std::stod(valuesStr.at(i));
368 }
369
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
4 IonosphericCorrections::AlphaBeta alphaBeta = correctionType == "B" ? IonosphericCorrections::Beta
370 4 : IonosphericCorrections::Alpha;
371
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 _gnssNavInfo.ionosphericCorrections.insert(satSys, alphaBeta, values);
372 LOG_DATA("{}: Ionospheric Correction: {}-{}: [{}]", nameId(),
373 std::string(satSys), alphaBeta == IonosphericCorrections::Alpha ? "Alpha" : "Beta",
374 fmt::join(values.begin(), values.end(), ", "));
375 4 }
376 12 else if (headerLabel == "TIME SYSTEM CORR"
377
5/6
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 10 times.
12 || headerLabel == "CORR TO SYSTEM TIME")
378 {
379
4/8
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
6 auto tau_c = str::stod(str::replaceAll_copy(line.substr(21, 19), "d", "e", str::IgnoreCase), 0.0);
380 LOG_DATA("{}: tau_c {}", nameId(), tau_c);
381
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (tau_c != 0)
382 {
383
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 _gnssNavInfo.timeSysCorr[{ satSys.getTimeSystem(), UTC }] = { .a0 = tau_c, .a1 = 0 };
384 }
385 }
386
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
10 else if (headerLabel == "DELTA-UTC: A0,A1,T,W")
387 {
388
5/10
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
8 auto a0 = std::stod(str::replaceAll_copy(line.substr(3, 19), "d", "e", str::IgnoreCase));
389 LOG_DATA("{}: a0 {}", nameId(), a0);
390
5/10
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
6 auto a1 = std::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase));
391 LOG_DATA("{}: a1 {}", nameId(), a1);
392
393
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if (a0 != 0 || a1 != 0)
394 {
395
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 _gnssNavInfo.timeSysCorr[{ satSys.getTimeSystem(), UTC }] = { .a0 = a0, .a1 = a1 };
396 }
397 }
398
2/2
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
8 else if (headerLabel == "LEAP SECONDS")
399 {
400 LOG_DATA("{}: Leap seconds: {}", nameId(), std::stoi(line.substr(0, 6)));
401 }
402
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 else if (headerLabel == "END OF HEADER")
403 {
404 4 break;
405 }
406 }
407 4 }
408
409 38 void RinexNavFile::parseHeader3()
410 {
411 38 std::string line;
412 // --------------------------------------- RINEX VERSION / TYPE ------------------------------------------
413
6/8
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 38 times.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 50 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 50 times.
✓ Branch 9 taken 38 times.
88 while (line.find("RINEX VERSION / TYPE") == std::string::npos && !eof())
414 {
415
1/2
✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
50 getline(line);
416 }
417 38 SatelliteSystem satSys = SatSys_None;
418
3/6
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 38 times.
✗ Branch 9 not taken.
38 LOG_DEBUG("{}: Version: {:3.2f}", nameId(), _version); // FORMAT: F9.2,11X
419
5/10
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 38 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 38 times.
✗ Branch 15 not taken.
38 LOG_DEBUG("{}: SatSys : {}", nameId(), str::trim_copy(line.substr(40, 20))); // FORMAT: A1,19X
420 // #######################################################################################################
421
6/12
✓ Branch 1 taken 258 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 258 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 258 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 258 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 258 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 258 times.
✗ Branch 14 not taken.
258 while (getline(line) && !eof())
422 {
423
1/2
✓ Branch 1 taken 258 times.
✗ Branch 2 not taken.
258 str::rtrim(line);
424
1/2
✓ Branch 1 taken 258 times.
✗ Branch 2 not taken.
258 auto headerLabel = extHeaderLabel(line);
425
2/2
✓ Branch 2 taken 220 times.
✓ Branch 3 taken 38 times.
258 if (headerLabel == "PGM / RUN BY / DATE")
426 {
427 // Name of program creating current file
428 LOG_DATA("{}: Program: {}", nameId(), str::trim_copy(line.substr(0, 20))); // FORMAT: A20
429 // Name of agency creating current file
430 LOG_DATA("{}: Run by : {}", nameId(), str::trim_copy(line.substr(20, 20))); // FORMAT: A20
431 // Date and time of file creation
432 LOG_DATA("{}: Date : {}", nameId(), str::trim_copy(line.substr(40, 20))); // FORMAT: A20
433 }
434
2/2
✓ Branch 2 taken 207 times.
✓ Branch 3 taken 13 times.
220 else if (headerLabel == "COMMENT")
435 {
436 LOG_DATA("{}: Comment: {}", nameId(), line.substr(0, 60)); // FORMAT: A60
437 }
438
2/2
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 107 times.
207 else if (headerLabel == "IONOSPHERIC CORR")
439 {
440
2/4
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
100 auto correctionType = str::trim_copy(line.substr(0, 4)); // FORMAT: A4,1X,
441 100 std::array<double, 4> values{};
442
4/8
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 100 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 100 times.
✗ Branch 11 not taken.
400 values[0] = str::stod(str::replaceAll_copy(line.substr(5, 12), "d", "e", str::IgnoreCase), 0.0); // FORMAT: 4D12.4
443
4/8
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 100 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 100 times.
✗ Branch 11 not taken.
400 values[1] = str::stod(str::replaceAll_copy(line.substr(17, 12), "d", "e", str::IgnoreCase), 0.0);
444
4/8
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 100 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 100 times.
✗ Branch 11 not taken.
400 values[2] = str::stod(str::replaceAll_copy(line.substr(29, 12), "d", "e", str::IgnoreCase), 0.0);
445
4/8
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 100 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 100 times.
✗ Branch 11 not taken.
300 values[3] = str::stod(str::replaceAll_copy(line.substr(41, 12), "d", "e", str::IgnoreCase), 0.0);
446
447
2/4
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
100 auto satSys = SatelliteSystem::fromString(correctionType.substr(0, 3));
448
3/4
✓ Branch 2 taken 90 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 45 times.
✓ Branch 5 taken 45 times.
190 IonosphericCorrections::AlphaBeta alphaBeta = (correctionType.size() == 4 && correctionType.at(3) == 'B')
449
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 10 times.
190 ? IonosphericCorrections::Beta
450 100 : IonosphericCorrections::Alpha;
451
1/2
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
100 _gnssNavInfo.ionosphericCorrections.insert(satSys, alphaBeta, values);
452 LOG_DATA("{}: Ionospheric Correction: {}-{}: [{}]", nameId(),
453 std::string(satSys), alphaBeta == IonosphericCorrections::Alpha ? "Alpha" : "Beta",
454 fmt::join(values.begin(), values.end(), ", "));
455 100 }
456
3/6
✓ Branch 2 taken 107 times.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 107 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 107 times.
107 else if (headerLabel == "ION ALPHA" || headerLabel == "ION BETA")
457 {
458 auto correctionType = headerLabel.substr(4, 1);
459 auto valuesStr = str::split_wo_empty(str::replaceAll_copy(line.substr(4, 60 - 4), "d", "e", str::IgnoreCase), " ");
460 std::array<double, 4> values{};
461 for (size_t i = 0; i < valuesStr.size(); i++)
462 {
463 values.at(i) = std::stod(valuesStr.at(i));
464 }
465 IonosphericCorrections::AlphaBeta alphaBeta = correctionType == "B" ? IonosphericCorrections::Beta
466 : IonosphericCorrections::Alpha;
467 _gnssNavInfo.ionosphericCorrections.insert(satSys, alphaBeta, values);
468 LOG_DATA("{}: Ionospheric Correction: {}-{}: [{}]", nameId(),
469 std::string(satSys), alphaBeta == IonosphericCorrections::Alpha ? "Alpha" : "Beta",
470 fmt::join(values.begin(), values.end(), ", "));
471 }
472 107 else if (headerLabel == "TIME SYSTEM CORR"
473
5/6
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 41 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 66 times.
✓ Branch 6 taken 41 times.
✓ Branch 7 taken 66 times.
107 || headerLabel == "CORR TO SYSTEM TIME")
474 {
475
2/4
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
41 auto correctionType = str::trim_copy(line.substr(0, 4)); // FORMAT: A4,1X,
476 LOG_DATA("{}: Time System Correction: {}", nameId(), correctionType);
477
478 41 std::array<size_t, 2> x{ 5, 22 };
479 41 std::array<size_t, 2> n{ 17, 16 };
480
481
2/4
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 41 times.
41 if (correctionType == "SBUT")
482 {
483 x = { 7, 26 };
484 n = { 19, 19 };
485 }
486
3/4
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 36 times.
41 else if (correctionType == "GLUT")
487 {
488 5 x = { 5, 24 };
489 5 n = { 19, 19 };
490 }
491
492
4/8
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 41 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 41 times.
✗ Branch 13 not taken.
164 auto a0 = str::stod(str::replaceAll_copy(line.substr(x[0], n[0]), "d", "e", str::IgnoreCase), std::nan(""));
493 LOG_DATA("{}: a0 {}", nameId(), a0);
494
4/8
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 41 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 41 times.
✗ Branch 13 not taken.
123 auto a1 = str::stod(str::replaceAll_copy(line.substr(x[1], n[1]), "d", "e", str::IgnoreCase), std::nan(""));
495 LOG_DATA("{}: a1 {}", nameId(), a1);
496
497
3/6
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 41 times.
✗ Branch 7 not taken.
41 if (!std::isnan(a0) && !std::isnan(a1))
498 {
499 41 std::pair<TimeSystem, TimeSystem> timeSystems;
500
3/4
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
✓ Branch 4 taken 28 times.
41 if (correctionType == "GPUT") { timeSystems = { GPST, UTC }; }
501
3/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 23 times.
28 else if (correctionType == "GLUT") { timeSystems = { GLNT, UTC }; }
502
3/4
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 13 times.
23 else if (correctionType == "GAUT") { timeSystems = { GST, UTC }; }
503
3/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 8 times.
13 else if (correctionType == "BDUT") { timeSystems = { BDT, UTC }; }
504
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
8 else if (correctionType == "QZUT") { timeSystems = { QZSST, UTC }; }
505
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
8 else if (correctionType == "IRUT") { timeSystems = { IRNSST, UTC }; }
506 // else if (correctionType == "SBUT") { timeSystems = { SBAST, UTC }; }
507
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
8 else if (correctionType == "GLGP") { timeSystems = { GLNT, GPST }; }
508
3/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 3 times.
8 else if (correctionType == "GAGP") { timeSystems = { GST, GPST }; }
509
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
3 else if (correctionType == "GPGA") { timeSystems = { GST, GPST }; } // Pre RINEX 3.04
510 else if (correctionType == "QZGP") { timeSystems = { QZSST, GPST }; }
511 else if (correctionType == "IRGP") { timeSystems = { IRNSST, GPST }; }
512 else
513 {
514 LOG_TRACE("{}: Time System Correction '{}' not implemented yet", nameId(), correctionType);
515 continue;
516 }
517
1/2
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
41 _gnssNavInfo.timeSysCorr[timeSystems] = { .a0 = a0, .a1 = a1 };
518 }
519 41 }
520
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 66 times.
66 else if (headerLabel == "DELTA-UTC: A0,A1,T,W")
521 {
522 auto a0 = std::stod(str::replaceAll_copy(line.substr(3, 19), "d", "e", str::IgnoreCase));
523 LOG_DATA("{}: a0 {}", nameId(), a0);
524 auto a1 = std::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase));
525 LOG_DATA("{}: a1 {}", nameId(), a1);
526
527 if (a0 != 0 || a1 != 0)
528 {
529 _gnssNavInfo.timeSysCorr[{ satSys.getTimeSystem(), UTC }] = { .a0 = a0, .a1 = a1 };
530 }
531 }
532
2/2
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 28 times.
66 else if (headerLabel == "LEAP SECONDS")
533 {
534 LOG_DATA("{}: Leap seconds: {}", nameId(), std::stoi(line.substr(0, 6)));
535 }
536
1/2
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
38 else if (headerLabel == "END OF HEADER")
537 {
538 38 break;
539 }
540 }
541 38 }
542
543 5 void RinexNavFile::parseHeader4()
544 {
545 5 std::string line;
546 // --------------------------------------- RINEX VERSION / TYPE ------------------------------------------
547
6/8
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 5 times.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5 times.
✓ Branch 9 taken 5 times.
10 while (line.find("RINEX VERSION / TYPE") == std::string::npos && !eof())
548 {
549
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 getline(line);
550 }
551 // SatelliteSystem satSys = SatSys_None;
552
3/6
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
5 LOG_DEBUG("{}: Version: {:3.2f}", nameId(), _version); // FORMAT: F9.2,11X
553
5/10
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 5 times.
✗ Branch 15 not taken.
5 LOG_DEBUG("{}: SatSys : {}", nameId(), str::trim_copy(line.substr(40, 20))); // FORMAT: A1,19X
554 // #######################################################################################################
555
6/12
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 15 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 15 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 15 times.
✗ Branch 14 not taken.
15 while (getline(line) && !eof())
556 {
557
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 str::rtrim(line);
558
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 auto headerLabel = extHeaderLabel(line);
559
2/2
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 5 times.
15 if (headerLabel == "PGM / RUN BY / DATE")
560 {
561 // Name of program creating current file
562 LOG_DATA("{}: Program: {}", nameId(), str::trim_copy(line.substr(0, 20))); // FORMAT: A20
563 // Name of agency creating current file
564 LOG_DATA("{}: Run by : {}", nameId(), str::trim_copy(line.substr(20, 20))); // FORMAT: A20
565 // Date and time of file creation
566 LOG_DATA("{}: Date : {}", nameId(), str::trim_copy(line.substr(40, 20))); // FORMAT: A20
567 }
568
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 else if (headerLabel == "COMMENT")
569 {
570 LOG_DATA("{}: Comment: {}", nameId(), line.substr(0, 60)); // FORMAT: A60
571 }
572
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 else if (headerLabel == "REC # / TYPE / VERS") // Not in mixed station files
573 {
574 // Receiver number of station
575 LOG_DATA("{}: Receiver number : {}", nameId(), str::trim_copy(line.substr(0, 20))); // FORMAT: A20
576 // Receiver type of station
577 LOG_DATA("{}: Receiver type : {}", nameId(), str::trim_copy(line.substr(20, 20))); // FORMAT: A20
578 // Receiver software version of station
579 LOG_DATA("{}: Receiver version : {}", nameId(), str::trim_copy(line.substr(40, 20))); // FORMAT: A20
580 }
581
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 else if (headerLabel == "Merged File")
582 {
583 if (!str::trim_copy(line.substr(0, 9)).empty())
584 {
585 // Numbers of files merged
586 LOG_DATA("{}: Number of files merged : {}", nameId(), str::trim_copy(line.substr(0, 9))); // FORMAT: I9
587 }
588 }
589
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 else if (headerLabel == "DOI")
590 {
591 // Digital Object Identifier
592 LOG_DATA("{}: Comment: {}", nameId(), line.substr(0, 60)); // FORMAT: A60
593 }
594
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 else if (headerLabel == "LICENSE OF USE")
595 {
596 // License of Use
597 LOG_DATA("{}: Comment: {}", nameId(), line.substr(0, 60)); // FORMAT: A60
598 }
599
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 else if (headerLabel == "LICENSE OF USE")
600 {
601 // License of Use
602 LOG_DATA("{}: Comment: {}", nameId(), line.substr(0, 60)); // FORMAT: A60
603 }
604
2/2
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 5 times.
10 else if (headerLabel == "LEAP SECONDS")
605 {
606 LOG_DATA("{}: Leap seconds: {}", nameId(), std::stoi(line.substr(0, 6))); // I6
607 }
608
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 else if (headerLabel == "END OF HEADER")
609 {
610 5 break;
611 }
612 }
613 5 }
614
615 4 void RinexNavFile::parseOrbit2()
616 {
617 4 std::string line;
618
619 try
620 {
621
8/12
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✓ Branch 7 taken 4 times.
✓ Branch 9 taken 13 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 13 times.
✓ Branch 14 taken 4 times.
17 while (getline(line) && !eof())
622 {
623
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 if (line.size() > 82)
624 {
625 abortReading();
626 return;
627 } // 80 + \n\r
628
629 // -------------------------------------- SV / EPOCH / SV CLK ----------------------------------------
630
631 // Satellite system (G), sat number (PRN) - A1,I2.2,
632 // Satellite system (E), satellite number - A1,I2.2,
633 // Satellite system (R), satellite number (slot number in sat. constellation) - A1,I2.2,
634 // Satellite system (J), Satellite PRN-192 - A1,I2,
635 // Satellite system (C), sat number (PRN) - A1,I2.2,
636 // Satellite system (S), satellite number (slot number in sat. constellation) - A1,I2.2,
637 // Satellite system (I), sat number (PRN) - A1,I2.2,
638 13 SatelliteSystem satSys = SatSys_None;
639
640 // Offset for RINEX 2.xx versions. Has only 3 leading spaces
641 13 satSys = _gnssNavInfo.satelliteSystems;
642
643
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 if (satSys == SatSys_None) { continue; } // To intercept comment lines
644
645
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 auto satNumStr = line.substr(0, 2);
646
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
13 if (satNumStr == " ") { continue; }
647
648 13 auto satNum = static_cast<uint8_t>(str::stoi(satNumStr, 0));
649
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (satNum == 0) { continue; }
650 // Epoch: Toc - Time of Clock (GPS) year (4 digits) - 1X,I4,
651 // month, day, hour, minute, second - 5(1X,I2.2),
652
3/6
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
13 auto timeSplit = str::split_wo_empty(line.substr(2, 20), " ");
653
3/4
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 6 times.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
13 auto timeSystem = satSys == GLO ? UTC : satSys.getTimeSystem();
654
655
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
13 int year = std::stoi(timeSplit.at(0));
656
657 // RINEX 2.xx has 2-Digit Years
658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 year += (year >= 80 ? 1900 : 2000);
659
660 InsTime epoch{ static_cast<uint16_t>(year),
661
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 static_cast<uint16_t>(std::stoi(timeSplit.at(1))),
662
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 static_cast<uint16_t>(std::stoi(timeSplit.at(2))),
663
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 static_cast<uint16_t>(std::stoi(timeSplit.at(3))),
664
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 static_cast<uint16_t>(std::stoi(timeSplit.at(4))),
665 26 std::stold(timeSplit.at(5)),
666
7/14
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 13 times.
✗ Branch 20 not taken.
65 timeSystem };
667
668 LOG_DATA("{}: {}-{} {} (read as {} time)", nameId(), satSys, satNum, epoch.toYMDHMS(), std::string(timeSystem));
669
670
7/10
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 6 times.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 7 times.
✓ Branch 12 taken 6 times.
✓ Branch 13 taken 7 times.
13 if (satSys == GPS || satSys == GAL || satSys == QZSS || satSys == BDS) // NOLINT(misc-redundant-expression) // bugged warning
671 {
672 // Polynomial coefficients for clock correction
673 6 std::array<double, 3> a{};
674 // SV clock bias [seconds]
675
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 a[0] = std::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase));
676 // SV clock drift [sec/sec]
677
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 a[1] = std::stod(str::replaceAll_copy(line.substr(41, 19), "d", "e", str::IgnoreCase));
678 // SV clock drift rate [sec/sec^2]
679
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
18 a[2] = std::stod(str::replaceAll_copy(line.substr(60, 19), "d", "e", str::IgnoreCase));
680
681 LOG_DATA("{}: clkBias {}, clkDrift {}, clkDriftRate {}", nameId(), a[0], a[1], a[2]);
682
683 // ------------------------------------ BROADCAST ORBIT - 1 --------------------------------------
684
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 getline(line);
685
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (line.size() > 82)
686 {
687 abortReading();
688 return;
689 } // 80 + \n\r
690
691 // GPS/QZSS: Issue of Data, Ephemeris (IODE)
692 // GAL: IODnav Issue of Data of the nav batch
693 // BDS: AODE Age of Data, Ephemeris (as specified in BeiDou ICD Table Section 5.2.4.11 Table 5-8)
694 // and field range is: 0-31.
695 // IRNSS: IODEC Issue of Data, Ephemeris and Clock
696
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 auto IODE_IODnav_AODE_IODEC = static_cast<size_t>(std::stod(str::replaceAll_copy(line.substr(3, 19), "d", "e", str::IgnoreCase)));
697 // Crs (meters)
698
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 double Crs = std::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase));
699 // Delta n (radians/sec)
700
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 double delta_n = std::stod(str::replaceAll_copy(line.substr(41, 19), "d", "e", str::IgnoreCase));
701 // M0 (radians)
702
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
18 double M_0 = std::stod(str::replaceAll_copy(line.substr(60, 19), "d", "e", str::IgnoreCase));
703
704 LOG_DATA("{}: IODE_IODnav_AODE_IODEC {}, Crs {}, Delta_n {}, M0 {}", nameId(), IODE_IODnav_AODE_IODEC, Crs, delta_n, M_0);
705
706 // ------------------------------------ BROADCAST ORBIT - 2 --------------------------------------
707
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 getline(line);
708
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (line.size() > 82)
709 {
710 abortReading();
711 return;
712 } // 80 + \n\r
713
714 // Cuc (radians)
715
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 double Cuc = std::stod(str::replaceAll_copy(line.substr(3, 19), "d", "e", str::IgnoreCase));
716 // e Eccentricity
717
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 double e = std::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase));
718 // Cus (radians)
719
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 double Cus = std::stod(str::replaceAll_copy(line.substr(41, 19), "d", "e", str::IgnoreCase));
720 // sqrt(A) (sqrt(m))
721
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
18 double sqrt_A = std::stod(str::replaceAll_copy(line.substr(60, 19), "d", "e", str::IgnoreCase));
722
723 LOG_DATA("{}: Cuc {}, e {}, Cus {}, sqrt_A {}", nameId(), Cuc, e, Cus, sqrt_A);
724
725 // ------------------------------------ BROADCAST ORBIT - 3 --------------------------------------
726
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 getline(line);
727
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (line.size() > 82)
728 {
729 abortReading();
730 return;
731 } // 80 + \n\r
732
733 // Toe Time of Ephemeris (sec of GPS week)
734
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 double toeSec = std::stod(str::replaceAll_copy(line.substr(3, 19), "d", "e", str::IgnoreCase));
735 // Cic (radians)
736
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 double Cic = std::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase));
737 // OMEGA0 (radians)
738
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 double Omega_0 = std::stod(str::replaceAll_copy(line.substr(41, 19), "d", "e", str::IgnoreCase));
739 // Cis (radians)
740
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
18 double Cis = std::stod(str::replaceAll_copy(line.substr(60, 19), "d", "e", str::IgnoreCase));
741
742 LOG_DATA("{}: toe {}, Cic {}, Omega_0 {}, Cis {}", nameId(), toeSec, Cic, Omega_0, Cis);
743
744 // ------------------------------------ BROADCAST ORBIT - 4 --------------------------------------
745
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 getline(line);
746
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (line.size() > 82)
747 {
748 abortReading();
749 return;
750 } // 80 + \n\r
751
752 // i0 (radians)
753
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 double i_0 = std::stod(str::replaceAll_copy(line.substr(3, 19), "d", "e", str::IgnoreCase));
754 // Crc (meters)
755
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 double Crc = std::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase));
756 // omega (radians)
757
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 double omega = std::stod(str::replaceAll_copy(line.substr(41, 19), "d", "e", str::IgnoreCase));
758 // OMEGA DOT (radians/sec)
759
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
18 double Omega_dot = std::stod(str::replaceAll_copy(line.substr(60, 19), "d", "e", str::IgnoreCase));
760
761 LOG_DATA("{}: i_0 {}, Crc {}, omega {}, Omega_dot {}", nameId(), i_0, Crc, omega, Omega_dot);
762
763 // ------------------------------------ BROADCAST ORBIT - 5 --------------------------------------
764
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 getline(line);
765
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (line.size() > 82)
766 {
767 abortReading();
768 return;
769 } // 80 + \n\r
770
771 // IDOT (radians/sec)
772
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 double i_dot = std::stod(str::replaceAll_copy(line.substr(3, 19), "d", "e", str::IgnoreCase));
773 // GPS: Codes on L2 channel
774 // QZSS: Codes on L2 channel (fixed to 2, see IS-QZSS-PNT 4.1.2.7)
775 // GAL: Data sources (FLOAT --> INTEGER)
776 // Bit 0 set: I/NAV E1-B
777 // Bit 1 set: F/NAV E5a-I
778 // Bit 2 set: I/NAV E5b-I
779 // Bits 0 and 2 : Both can be set if the navigation messages were merged, however, bits 0-2
780 // cannot all be set, as the I/NAV and F/NAV messages contain different information
781 // Bit 3 reserved for Galileo internal use
782 // Bit 4 reserved for Galileo internal use
783 // Bit 8 set: af0-af2, Toc, SISA are for E5a,E1
784 // Bit 9 set: af0-af2, Toc, SISA are for E5b,E1
785 // Bits 8-9 : exclusive (only one bit can be set)
786 // BDS/IRNSS: Spare
787
4/8
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
18 auto codesOnL2Channel_dataSources = static_cast<uint16_t>(str::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase), 0));
788
789 // GPS Week # (to go with TOE) Continuous number, not mod(1024)!
790
5/10
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 6 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 6 times.
✗ Branch 15 not taken.
24 auto gpsWeek = static_cast<int32_t>(str::stod(str::replaceAll_copy(line.substr(41, 19), "d", "e", str::IgnoreCase), epoch.toGPSweekTow().gpsWeek));
791
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (satSys == BDS) { gpsWeek += InsTimeUtil::DIFF_BDT_WEEK_TO_GPST_WEEK; }
792
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 auto toe = InsTime(0, gpsWeek, toeSec, satSys.getTimeSystem());
793
794 // GPS: L2 P data flag
795 // QZSS: L2P data flag set to 1 since QZSS does not track L2P
796 // GAL/BDS/IRNSS: Spare
797
4/8
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
18 bool L2PdataFlag = static_cast<bool>(str::stod(str::replaceAll_copy(line.substr(60, 19), "d", "e", str::IgnoreCase), 0.0));
798
799 LOG_DATA("{}: i_dot {}, codesOnL2Channel/dataSources {} ({}), gpsWeek {}, L2PdataFlag {}", nameId(),
800 i_dot, codesOnL2Channel_dataSources, std::bitset<10>(codesOnL2Channel_dataSources).to_string(), gpsWeek, L2PdataFlag);
801
802 // ------------------------------------ BROADCAST ORBIT - 6 --------------------------------------
803
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 getline(line);
804
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (line.size() > 82)
805 {
806 abortReading();
807 return;
808 } // 80 + \n\r
809
810 // GPS: SV accuracy (meters) See GPS ICD 200H Section 20.3.3.3.1.3 use specified equations to define
811 // nominal values, N = 0-6: use 2(1+N/2) (round to one decimal place i.e. 2.8, 5.7 and 11.3) ,
812 // N= 7-15:use 2 (N-2), 8192 specifies use at own risk
813 // QZSS: SV accuracy (meters) (IS -QZSS-PNT, Section 5.4.3.1) which refers to: IS GPS 200H Section 20.3.3.3.1.3
814 // use specified equations to define nominal values, N = 0-6: use 2(1+N/2) (round to one decimal
815 // place i.e. 2.8, 5.7 and 11.3) , N= 7-15:use 2 (N-2), 8192 specifies use at own risk
816 // IRNSS: User Range Accuracy(m), See IRNSS ICD Section 6.2.1.4 , use specified equations to define
817 // nominal values, N = 0-6: use 2(1+N/2) (round to one decimal place i.e. 2.8, 5.7 and 11.3) ,
818 // N= 7-15:use 2 (N-2), 8192 specifies use at own risk
819
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 double signalAccuracy = std::stod(str::replaceAll_copy(line.substr(3, 19), "d", "e", str::IgnoreCase));
820 // GPS/QZSS: SV health (bits 17-22 w 3 sf 1)
821 // GAL: SV health (FLOAT converted to INTEGER) See Galileo ICD Section 5.1.9.3
822 // Bit 0: E1B DVS Bits 1-2: E1B HS Bit 3: E5a DVS
823 // Bits 4-5: E5a HS Bit 6: E5b DVS Bits 7-8: E5b HS
824 // BDS: SatH1
825 // IRNSS: Health (Sub frame 1,bits 155(most significant) and 156(least significant)),
826 // where 0 = L5 and S healthy, 1 = L5 healthy and S unhealthy, 2= L5 unhealthy
827 // and S healthy, 3= both L5 and S unhealthy
828
5/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
24 auto svHealth = static_cast<uint16_t>(std::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase)));
829 // GPS: TGD (seconds)
830 // QZSS: TGD (seconds) The QZSS ICD specifies a do not use bit pattern "10000000" this condition is represented by a blank field.
831 // GAL: BGD E5a/E1 (seconds)
832 // BDS: TGD1 B1/B3 (seconds)
833
4/8
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
24 double tgd_bgd5a_TGD1 = str::stod(str::replaceAll_copy(line.substr(41, 19), "d", "e", str::IgnoreCase), 0.0);
834
835 // GPS/QZSS: IODC Issue of Data, Clock
836 // GAL: BGD E5b/E1 (seconds)
837 // BDS: TGD2 B2/B3 (seconds)
838 // IRNSS: Blank
839
4/8
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
18 double IODC_bgd5b_TGD2 = str::stod(str::replaceAll_copy(line.substr(60, 19), "d", "e", str::IgnoreCase), 0.0);
840
841 LOG_DATA("{}: svAccuracy {}, svHealth {}, TGD {}, IODC {}", nameId(), signalAccuracy, svHealth, tgd_bgd5a_TGD1, IODC_bgd5b_TGD2);
842
843 // ------------------------------------ BROADCAST ORBIT - 7 --------------------------------------
844
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 getline(line);
845
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (line.size() > 82)
846 {
847 abortReading();
848 return;
849 } // 80 + \n\r
850
851 // Transmission time of message (sec of GPS week, derived e.g.from Z-count in Hand Over Word (HOW))
852
4/8
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
24 [[maybe_unused]] auto transmissionTime = str::stod(str::replaceAll_copy(line.substr(3, 19), "d", "e", str::IgnoreCase), 0.0);
853 // GPS/QZSS: Fit Interval in hours see section 6.11. (BNK).
854 // GAL: Spare
855 // BDS: AODC Age of Data Clock (as specified in BeiDou ICD Table Section 5.2.4.9 Table 5-6) and field range is: 0-31.
856
4/8
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
18 auto fitInterval_AODC = str::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase), 0.0);
857 // Spare
858 // std::stod(str::replaceAll_copy(line.substr(41, 19), "d", "e", str::IgnoreCase));
859 // Spare
860 // std::stod(str::replaceAll_copy(line.substr(60, 19), "d", "e", str::IgnoreCase));
861
862 LOG_DATA("{}: transmissionTime {}, fitInterval/AODC {}", nameId(), transmissionTime, fitInterval_AODC);
863
864
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 if (satSys == GPS)
865 {
866
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
6 _gnssNavInfo.addSatelliteNavData({ satSys, satNum }, std::make_shared<GPSEphemeris>(epoch, toe,
867 IODE_IODnav_AODE_IODEC, IODC_bgd5b_TGD2, a,
868 sqrt_A, e, i_0, Omega_0, omega, M_0,
869 delta_n, Omega_dot, i_dot, Cus, Cuc,
870 Cis, Cic, Crs, Crc,
871 signalAccuracy, svHealth,
872 codesOnL2Channel_dataSources, L2PdataFlag,
873 tgd_bgd5a_TGD1, fitInterval_AODC));
874 }
875 else if (satSys == GAL)
876 {
877 // The same satellite can appear multiple times with different dataSource bits
878 // We want to prefer 'I/NAV E1-B' (Bit 0 set) over 'F/NAV E5a-I' (Bit 1 set) or 'I/NAV E5b-I' (Bit 2 set)
879
880 if (_gnssNavInfo.satellites().contains({ satSys, satNum }) // We have this satellite already
881 && !std::bitset<10>(codesOnL2Channel_dataSources)[0]) // This message is not 'I/NAV E1-B'
882 {
883 const auto& navData = _gnssNavInfo.satellites().at({ satSys, satNum }).getNavigationData();
884 auto existingEph = std::ranges::find_if(navData, [&](const std::shared_ptr<SatNavData>& satNavData) {
885 return satNavData->type == SatNavData::GalileoEphemeris && satNavData->refTime == epoch
886 && std::dynamic_pointer_cast<GalileoEphemeris>(satNavData)->dataSource[0];
887 });
888 if (existingEph != navData.end()) // There is already a 'I/NAV E1-B' message
889 {
890 LOG_DATA("{}: Skipping ephemeris data because of dataSource priority", nameId());
891 continue;
892 }
893 }
894
895 GalileoEphemeris::SvHealth health = { .E5a_DataValidityStatus = static_cast<GalileoEphemeris::SvHealth::DataValidityStatus>((svHealth & 0b000001000) >> 3),
896 .E5b_DataValidityStatus = static_cast<GalileoEphemeris::SvHealth::DataValidityStatus>((svHealth & 0b001000000) >> 6),
897 .E1B_DataValidityStatus = static_cast<GalileoEphemeris::SvHealth::DataValidityStatus>((svHealth & 0b000000001) >> 0),
898 .E5a_SignalHealthStatus = static_cast<GalileoEphemeris::SvHealth::SignalHealthStatus>((svHealth & 0b000110000) >> 4),
899 .E5b_SignalHealthStatus = static_cast<GalileoEphemeris::SvHealth::SignalHealthStatus>((svHealth & 0b110000000) >> 7),
900 .E1B_SignalHealthStatus = static_cast<GalileoEphemeris::SvHealth::SignalHealthStatus>((svHealth & 0b000000110) >> 1) };
901 _gnssNavInfo.addSatelliteNavData({ satSys, satNum }, std::make_shared<GalileoEphemeris>(epoch, toe, IODE_IODnav_AODE_IODEC, a,
902 sqrt_A, e, i_0, Omega_0, omega, M_0,
903 delta_n, Omega_dot, i_dot, Cus, Cuc,
904 Cis, Cic, Crs, Crc,
905 codesOnL2Channel_dataSources, signalAccuracy, health,
906 tgd_bgd5a_TGD1, IODC_bgd5b_TGD2));
907 }
908 else if (satSys == BDS)
909 {
910 _gnssNavInfo.addSatelliteNavData({ satSys, satNum }, std::make_shared<BDSEphemeris>(satNum, epoch, toe,
911 IODE_IODnav_AODE_IODEC, fitInterval_AODC, a,
912 sqrt_A, e, i_0, Omega_0, omega, M_0,
913 delta_n, Omega_dot, i_dot, Cus, Cuc,
914 Cis, Cic, Crs, Crc,
915 signalAccuracy, svHealth,
916 tgd_bgd5a_TGD1, IODC_bgd5b_TGD2));
917 }
918 else if (satSys == QZSS)
919 {
920 _gnssNavInfo.addSatelliteNavData({ satSys, satNum }, std::make_shared<QZSSEphemeris>(epoch, toe,
921 IODE_IODnav_AODE_IODEC, IODC_bgd5b_TGD2, a,
922 sqrt_A, e, i_0, Omega_0, omega, M_0,
923 delta_n, Omega_dot, i_dot, Cus, Cuc,
924 Cis, Cic, Crs, Crc,
925 signalAccuracy, svHealth,
926 codesOnL2Channel_dataSources, L2PdataFlag,
927 tgd_bgd5a_TGD1, fitInterval_AODC));
928 }
929 }
930
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
7 else if (satSys == GLO || satSys == SBAS) // NOLINT(misc-redundant-expression) // bugged warning
931 {
932 // TODO: Offset
933
934
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 Eigen::Vector3d pos;
935
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 Eigen::Vector3d vel;
936
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 Eigen::Vector3d accelLuniSolar;
937
938 7 double tau_c{};
939 // Coefficient of linear polynomial of time system difference [s]
940
3/6
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 7 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
7 if (_gnssNavInfo.timeSysCorr.contains({ satSys.getTimeSystem(), UTC }))
941 {
942
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 7 times.
✗ Branch 6 not taken.
7 tau_c = _gnssNavInfo.timeSysCorr.at({ satSys.getTimeSystem(), UTC }).a0;
943 }
944
945 // GLO: SV clock bias (sec) (-TauN)
946 // SBAS: SV clock bias (sec) (aGf0)
947
5/10
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
28 double m_tau_n = std::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase));
948 // GLO: SV relative frequency bias (+GammaN)
949 // SBAS: SV relative frequency bias (aGf1)
950
5/10
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
28 double gamma_n = std::stod(str::replaceAll_copy(line.substr(41, 19), "d", "e", str::IgnoreCase));
951 // GLO: Message frame time (tk+nd*86400) in seconds of the UTC week
952 // SBAS: Transmission time of message (start of the message) in GPS seconds of the week
953
5/10
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
21 [[maybe_unused]] auto msgFrameTime = std::stod(str::replaceAll_copy(line.substr(60, 19), "d", "e", str::IgnoreCase));
954 LOG_DATA("{}: clkBias {}, relFreqBias {}, msgFrameTime {}", nameId(), m_tau_n, gamma_n, msgFrameTime);
955
956 // ------------------------------------ BROADCAST ORBIT - 1 --------------------------------------
957
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 getline(line);
958
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 if (line.size() > 82)
959 {
960 abortReading();
961 return;
962 } // 80 + \n\r
963
964 // Satellite position X (km)
965
6/12
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 17 not taken.
28 pos.x() = std::stod(str::replaceAll_copy(line.substr(3, 19), "d", "e", str::IgnoreCase)) * 1e3;
966 // velocity X dot (km/sec)
967
6/12
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 17 not taken.
28 vel.x() = std::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase)) * 1e3;
968 // X acceleration (km/sec2)
969
6/12
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 17 not taken.
28 accelLuniSolar.x() = std::stod(str::replaceAll_copy(line.substr(41, 19), "d", "e", str::IgnoreCase)) * 1e3;
970 // GLO: health (0=healthy, 1=unhealthy) (MSB of 3-bit Bn)
971 // SBAS: Health: SBAS: See Section 8.3.3 bit mask for: health, health availability and User Range Accuracy.
972
5/10
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
21 [[maybe_unused]] auto health = std::stod(str::replaceAll_copy(line.substr(60, 19), "d", "e", str::IgnoreCase));
973
974 LOG_DATA("{}: satPosX {}, velX {}, accelX {}, health {}", nameId(), pos.x(), vel.x(), accelLuniSolar.x(), health);
975
976 // ------------------------------------ BROADCAST ORBIT - 2 --------------------------------------
977
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 getline(line);
978
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 if (line.size() > 82)
979 {
980 abortReading();
981 return;
982 } // 80 + \n\r
983
984 // Satellite position Y (km)
985
6/12
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 17 not taken.
28 pos.y() = std::stod(str::replaceAll_copy(line.substr(3, 19), "d", "e", str::IgnoreCase)) * 1e3;
986 // velocity Y dot (km/sec)
987
6/12
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 17 not taken.
28 vel.y() = std::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase)) * 1e3;
988 // Y acceleration (km/sec2)
989
6/12
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 17 not taken.
28 accelLuniSolar.y() = std::stod(str::replaceAll_copy(line.substr(41, 19), "d", "e", str::IgnoreCase)) * 1e3;
990 // GLO: frequency number(-7...+13) (-7...+6 ICD 5.1)
991 // SBAS: Accuracy code (URA, meters)
992
5/10
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
21 double frequencyNumber_accuracyCode = std::stod(str::replaceAll_copy(line.substr(60, 19), "d", "e", str::IgnoreCase));
993
994 LOG_DATA("{}: satPosY {}, velY {}, accelY {}, freqNum/accuracyCode {}", nameId(), pos.y(), vel.y(), accelLuniSolar.y(), frequencyNumber_accuracyCode);
995
996 // ------------------------------------ BROADCAST ORBIT - 3 --------------------------------------
997
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 getline(line);
998
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 if (line.size() > 82)
999 {
1000 abortReading();
1001 return;
1002 } // 80 + \n\r
1003
1004 // Satellite position Z (km)
1005
6/12
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 17 not taken.
28 pos.z() = std::stod(str::replaceAll_copy(line.substr(3, 19), "d", "e", str::IgnoreCase)) * 1e3;
1006 // velocity Z dot (km/sec)
1007
6/12
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 17 not taken.
28 vel.z() = std::stod(str::replaceAll_copy(line.substr(22, 19), "d", "e", str::IgnoreCase)) * 1e3;
1008 // Z acceleration (km/sec2)
1009
6/12
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 17 not taken.
28 accelLuniSolar.z() = std::stod(str::replaceAll_copy(line.substr(41, 19), "d", "e", str::IgnoreCase)) * 1e3;
1010 // GLO: Age of oper. information (days) (E)
1011 // SBAS: IODN (Issue of Data Navigation, DO229, 8 first bits after Message Type if MT9)
1012
4/8
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
21 [[maybe_unused]] auto ageOfOperation_IODN = str::stod(str::replaceAll_copy(line.substr(60, 19), "d", "e", str::IgnoreCase), 0.0);
1013
1014 LOG_DATA("{}: satPosZ {}, velZ {}, accelZ {}, ageOfOperation/IODN {}", nameId(), pos.z(), vel.z(), accelLuniSolar.z(), ageOfOperation_IODN);
1015
1016
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 if (satSys == GLO)
1017 {
1018
1/2
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
7 _gnssNavInfo.addSatelliteNavData({ satSys, satNum }, std::make_shared<GLONASSEphemeris>(epoch, tau_c,
1019
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
14 -m_tau_n, gamma_n, static_cast<bool>(health),
1020 pos, vel, accelLuniSolar,
1021 frequencyNumber_accuracyCode));
1022 }
1023 else if (satSys == SBAS && !_sbasNotSupportedWarned)
1024 {
1025 LOG_WARN("SBAS is not yet supported. Therefore the Navigation file data will be skipped.");
1026 _sbasNotSupportedWarned = true;
1027 }
1028 }
1029 13 }
1030 }
1031 catch (const std::exception& e)
1032 {
1033 abortReading();
1034 }
1035 4 }
1036
1037 38 void RinexNavFile::parseOrbit3()
1038 {
1039 38 std::string line;
1040 try
1041 {
1042
8/12
✓ Branch 1 taken 6587 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6587 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6553 times.
✓ Branch 7 taken 34 times.
✓ Branch 9 taken 6553 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 6553 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 6553 times.
✓ Branch 14 taken 34 times.
6587 while (getline(line) && !eof())
1043 {
1044
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 6551 times.
6553 if (line.size() > 82)
1045 {
1046
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 abortReading();
1047 2 return;
1048 } // 80 + \n\r
1049
1050 // -------------------------------------- SV / EPOCH / SV CLK ----------------------------------------
1051
1052 // Satellite system (G), sat number (PRN) - A1,I2.2,
1053 // Satellite system (E), satellite number - A1,I2.2,
1054 // Satellite system (R), satellite number (slot number in sat. constellation) - A1,I2.2,
1055 // Satellite system (J), Satellite PRN-192 - A1,I2,
1056 // Satellite system (C), sat number (PRN) - A1,I2.2,
1057 // Satellite system (S), satellite number (slot number in sat. constellation) - A1,I2.2,
1058 // Satellite system (I), sat number (PRN) - A1,I2.2,
1059 6551 SatelliteSystem satSys = SatSys_None;
1060
1061
2/4
✓ Branch 1 taken 6551 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6550 times.
✗ Branch 5 not taken.
6551 satSys = SatelliteSystem::fromChar(line.at(0));
1062 6550 _gnssNavInfo.satelliteSystems |= satSys;
1063
1064
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 6544 times.
13077 if (satSys == SatSys_None) { continue; } // To intercept comment lines
1065
1066
1/2
✓ Branch 1 taken 6545 times.
✗ Branch 2 not taken.
6544 auto satNumStr = line.substr(1, 2);
1067
2/4
✓ Branch 1 taken 6545 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 6545 times.
6545 if (satNumStr == " ") { continue; }
1068
1069 6545 auto satNum = static_cast<uint8_t>(str::stoi(satNumStr, 0));
1070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6545 times.
6545 if (satNum == 0) { continue; }
1071
1072
4/4
✓ Branch 1 taken 6543 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6528 times.
✓ Branch 4 taken 15 times.
6545 if (parseEphemeris(line, satSys, satNum))
1073 {
1074 6528 continue;
1075 }
1076 6545 }
1077 }
1078
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 catch (const std::exception& e)
1079 {
1080
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 abortReading();
1081 2 }
1082 38 }
1083
1084 5 void RinexNavFile::parseOrbit4()
1085 {
1086 5 std::string line;
1087 try
1088 {
1089
8/12
✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 64 times.
✓ Branch 7 taken 5 times.
✓ Branch 9 taken 64 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 64 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 64 times.
✓ Branch 14 taken 5 times.
74 while (getline(line) && !eof())
1090 {
1091
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
64 if (line.size() > 82)
1092 {
1093 abortReading();
1094 return;
1095 } // 80 + \n\r
1096
1097
2/4
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
✗ Branch 4 not taken.
64 if (line.at(0) == '>')
1098 {
1099 // -------------------------------------- Type / SV / MSSG ----------------------------------------
1100
1101 // Satellite system (G), sat number (PRN) - A1,I2.2,
1102 // Satellite system (E), satellite number - A1,I2.2,
1103 // Satellite system (R), satellite number (slot number in sat. constellation) - A1,I2.2,
1104 // Satellite system (J), Satellite PRN-192 - A1,I2,
1105 // Satellite system (C), sat number (PRN) - A1,I2.2,
1106 // Satellite system (S), satellite number (slot number in sat. constellation) - A1,I2.2,
1107 // Satellite system (I), sat number (PRN) - A1,I2.2,
1108
1109 64 SatelliteSystem satSys = SatSys_None;
1110
2/4
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 64 times.
✗ Branch 5 not taken.
64 satSys = SatelliteSystem::fromChar(line.at(6));
1111 64 _gnssNavInfo.satelliteSystems |= satSys;
1112
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
101 if (satSys == SatSys_None) { continue; } // To intercept comment lines
1113
1114
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 auto satNumStr = line.substr(7, 2);
1115
2/4
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 64 times.
64 if (satNumStr == " ") { continue; }
1116
1117 64 auto satNum = static_cast<uint8_t>(str::stoi(satNumStr, 0));
1118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
64 if (satNum == 0) { continue; }
1119
1120
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 std::string msgType = line.substr(2, 3);
1121
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 NavMsgType navMsgType = getNavMsgType(msgType);
1122
1123 // std::string satMsgType = line.substr(10, 4);
1124
1125
3/5
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
64 switch (navMsgType)
1126 {
1127 41 case NavMsgType::EPH:
1128 {
1129 // Code for EPH
1130
1/2
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
41 getline(line);
1131
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
41 if (line.size() > 82)
1132 {
1133 abortReading();
1134 return;
1135 }
1136
1137
7/16
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 41 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 41 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 41 times.
✓ Branch 15 taken 41 times.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 41 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
41 if (satSys != SatelliteSystem::fromChar(line.at(0)) || satNumStr != line.substr(1, 2)) { continue; }
1138
1139
3/4
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 37 times.
✓ Branch 4 taken 4 times.
41 if (parseEphemeris(line, satSys, satNum))
1140 {
1141 37 continue;
1142 }
1143 }
1144 4 break;
1145 18 case NavMsgType::STO:
1146 {
1147 // Code for STO
1148
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 getline(line);
1149
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
18 if (line.size() > 82)
1150 {
1151 abortReading();
1152 return;
1153 }
1154
1155 // Epoch: Toc - Time of Clock (GPS) year (4 digits) - 4X,I4,
1156 // month, day, hour, minute, second - 5(1X,I2.2),
1157
3/6
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 18 times.
✗ Branch 8 not taken.
18 auto timeSplit = str::split_wo_empty(line.substr(4, 20), " ");
1158
3/4
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 14 times.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
18 auto timeSystem = satSys == GLO ? UTC : satSys.getTimeSystem();
1159
1160
2/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
18 int year = std::stoi(timeSplit.at(0));
1161
1162 InsTime epoch{ static_cast<uint16_t>(year),
1163
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 static_cast<uint16_t>(std::stoi(timeSplit.at(1))),
1164
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 static_cast<uint16_t>(std::stoi(timeSplit.at(2))),
1165
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 static_cast<uint16_t>(std::stoi(timeSplit.at(3))),
1166
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 static_cast<uint16_t>(std::stoi(timeSplit.at(4))),
1167 36 std::stold(timeSplit.at(5)),
1168
7/14
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 18 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 18 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 18 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 18 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 18 times.
✗ Branch 20 not taken.
90 timeSystem };
1169
1170 LOG_DATA("{}: {}-{} {} (read as {} time)", nameId(), satSys, satNum, epoch.toYMDHMS(), std::string(timeSystem));
1171
2/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
18 auto correctionType = str::trim_copy(line.substr(24, 4)); // FORMAT: 1X,A18
1172 LOG_DATA("{}: Time System Correction: {}", nameId(), correctionType);
1173
1174
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 getline(line);
1175
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
18 if (line.size() > 82)
1176 {
1177 abortReading();
1178 return;
1179 }
1180
1181 // auto t_tm = str::stod(str::trim_copy(line.substr(4, 19)), std::nan(""));
1182 // LOG_DATA("{}: t_tm {}", nameId(), t_tm);
1183
2/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
18 auto a0 = str::stod(str::trim_copy(line.substr(23, 19)), std::nan(""));
1184 LOG_DATA("{}: a0 {}", nameId(), a0);
1185
2/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
18 auto a1 = str::stod(str::trim_copy(line.substr(42, 19)), std::nan(""));
1186 LOG_DATA("{}: a1 {}", nameId(), a1);
1187 // auto a2 = str::stod(str::trim_copy(line.substr(61, 19)), std::nan(""));
1188 // LOG_DATA("{}: a2 {}", nameId(), a2);
1189
1190
3/6
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 18 times.
✗ Branch 7 not taken.
18 if (!std::isnan(a0) && !std::isnan(a1))
1191 {
1192 18 std::pair<TimeSystem, TimeSystem> timeSystems;
1193
3/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 16 times.
18 if (correctionType == "GPUT")
1194 {
1195 2 timeSystems = { GPST, UTC };
1196 }
1197
3/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 14 times.
16 else if (correctionType == "GLUT")
1198 {
1199 2 timeSystems = { GLNT, UTC };
1200 }
1201
3/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 6 times.
14 else if (correctionType == "GAUT")
1202 {
1203 8 timeSystems = { GST, UTC };
1204 }
1205
3/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 4 times.
6 else if (correctionType == "BDUT")
1206 {
1207 2 timeSystems = { BDT, UTC };
1208 }
1209
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
4 else if (correctionType == "QZUT")
1210 {
1211 timeSystems = { QZSST, UTC };
1212 }
1213
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
4 else if (correctionType == "IRUT")
1214 {
1215 timeSystems = { IRNSST, UTC };
1216 }
1217 // else if (correctionType == "SBUT") { timeSystems = { SBAST, UTC }; }
1218
3/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
4 else if (correctionType == "GLGP")
1219 {
1220 2 timeSystems = { GLNT, GPST };
1221 }
1222
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 else if (correctionType == "GAGP")
1223 {
1224 2 timeSystems = { GST, GPST };
1225 }
1226 else if (correctionType == "GPGA")
1227 {
1228 timeSystems = { GST, GPST };
1229 } // Pre RINEX 3.04
1230 else if (correctionType == "QZGP")
1231 {
1232 timeSystems = { QZSST, GPST };
1233 }
1234 else if (correctionType == "IRGP")
1235 {
1236 timeSystems = { IRNSST, GPST };
1237 }
1238 else
1239 {
1240 LOG_TRACE("{}: Time System Correction '{}' not implemented yet", nameId(), correctionType);
1241 continue;
1242 }
1243
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 _gnssNavInfo.timeSysCorr[timeSystems] = { .a0 = a0, .a1 = a1 };
1244 }
1245 18 }
1246 18 break;
1247 case NavMsgType::EOP:
1248 // Code for EOP
1249 // TODO: Implement EOP
1250 break;
1251 5 case NavMsgType::ION:
1252 {
1253 // Code for ION
1254
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 getline(line);
1255
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 if (line.size() > 82)
1256 {
1257 abortReading();
1258 return;
1259 }
1260
1261 // Epoch: t_tm - Transmission timne of ION data, year (4 digits) - 4X,I4,
1262 // month, day, hour, minute, second - 5(1X,I2.2),
1263
3/6
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
5 auto timeSplit = str::split_wo_empty(line.substr(4, 20), " ");
1264
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
5 auto timeSystem = satSys == GLO ? UTC : satSys.getTimeSystem();
1265
1266
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 int year = std::stoi(timeSplit.at(0));
1267
1268 InsTime t_tm{ static_cast<uint16_t>(year),
1269
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 static_cast<uint16_t>(std::stoi(timeSplit.at(1))),
1270
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 static_cast<uint16_t>(std::stoi(timeSplit.at(2))),
1271
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 static_cast<uint16_t>(std::stoi(timeSplit.at(3))),
1272
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 static_cast<uint16_t>(std::stoi(timeSplit.at(4))),
1273 10 std::stold(timeSplit.at(5)),
1274
7/14
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 5 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 5 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 5 times.
✗ Branch 20 not taken.
25 timeSystem };
1275
1276 LOG_DATA("{}: {}-{} {} (read as {} time)", nameId(), satSys, satNum, t_tm.toYMDHMS(), std::string(timeSystem));
1277
1278 // TODO: Destinction of BDS unclear in RINEX versin 4.00 BDGIM or Klobuchar model
1279 // Klobuchar
1280
8/10
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 2 times.
✓ Branch 12 taken 3 times.
✓ Branch 13 taken 2 times.
5 if (satSys == GPS || satSys == QZSS || satSys == IRNSS || satSys == BDS) // NOLINT(misc-redundant-expression) // bugged warning
1281 {
1282 3 std::array<double, 4> alpha{};
1283 3 std::array<double, 4> beta{};
1284
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 alpha[0] = str::stod(str::trim_copy(line.substr(23, 19)), 0.0);
1285
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 alpha[1] = str::stod(str::trim_copy(line.substr(42, 19)), 0.0);
1286
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 alpha[2] = str::stod(str::trim_copy(line.substr(61, 19)), 0.0);
1287
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 getline(line);
1288
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (line.size() > 82)
1289 {
1290 abortReading();
1291 return;
1292 }
1293
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 alpha[3] = str::stod(str::trim_copy(line.substr(4, 19)), 0.0);
1294
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 beta[0] = str::stod(str::trim_copy(line.substr(23, 19)), 0.0);
1295
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 beta[1] = str::stod(str::trim_copy(line.substr(42, 19)), 0.0);
1296
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 beta[2] = str::stod(str::trim_copy(line.substr(61, 19)), 0.0);
1297
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 getline(line);
1298
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (line.size() > 82)
1299 {
1300 abortReading();
1301 return;
1302 }
1303
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 beta[3] = str::stod(str::trim_copy(line.substr(4, 19)), 0.0);
1304
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 _gnssNavInfo.ionosphericCorrections.insert(satSys, IonosphericCorrections::Alpha, alpha);
1305
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 _gnssNavInfo.ionosphericCorrections.insert(satSys, IonosphericCorrections::Beta, beta);
1306 LOG_DATA("{}: Ionospheric Correction: {}-Alpha: [{}]", nameId(),
1307 std::string(satSys), fmt::join(alpha.begin(), alpha.end(), ", "));
1308 LOG_DATA("{}: Ionospheric Correction: {}-Beta: [{}]", nameId(),
1309 std::string(satSys), fmt::join(beta.begin(), beta.end(), ", "));
1310
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 [[maybe_unused]] auto regionCode = str::stod(str::trim_copy(line.substr(23, 19)), std::nan(""));
1311 }
1312
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 else if (satSys == GAL) // Nequick-G
1313 {
1314 2 std::array<double, 4> alpha{};
1315
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 alpha[0] = str::stod(str::trim_copy(line.substr(23, 19)), 0.0);
1316
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 alpha[1] = str::stod(str::trim_copy(line.substr(42, 19)), 0.0);
1317
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 alpha[2] = str::stod(str::trim_copy(line.substr(61, 19)), 0.0);
1318
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 getline(line);
1319
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (line.size() > 82)
1320 {
1321 abortReading();
1322 return;
1323 }
1324 // TODO: Change Correction format to support Nequick-G
1325 // This is a hack this data is not an alpha value but a disturbance flag
1326
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 alpha[3] = str::stod(str::trim_copy(line.substr(4, 19)), 0.0);
1327
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 _gnssNavInfo.ionosphericCorrections.insert(satSys, IonosphericCorrections::Alpha, alpha);
1328 LOG_DATA("{}: Ionospheric Correction: {}-Alpha: [{}]", nameId(),
1329 std::string(satSys), fmt::join(alpha.begin(), alpha.end(), ", "));
1330 } /*
1331 else if (satSys == BDS) // BDGIM
1332 {
1333 // TODO: Implement Beidou ION message
1334 }*/
1335 else
1336 {
1337 continue;
1338 }
1339 5 }
1340 5 break;
1341 default:
1342 // Abort
1343 break;
1344 }
1345 101 }
1346 }
1347 }
1348 catch (const std::exception& e)
1349 {
1350 abortReading();
1351 }
1352 5 }
1353
1354 6586 bool RinexNavFile::parseEphemeris(std::string& line, SatelliteSystem satSys, uint8_t satNum)
1355 {
1356 // Epoch: Toc - Time of Clock (GPS) year (4 digits) - 1X,I4,
1357 // month, day, hour, minute, second - 5(1X,I2.2),
1358
3/6
✓ Branch 1 taken 6586 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6586 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6586 times.
✗ Branch 8 not taken.
6586 auto timeSplit = str::split_wo_empty(line.substr(3, 20), " ");
1359
3/4
✓ Branch 1 taken 3621 times.
✓ Branch 2 taken 2964 times.
✓ Branch 5 taken 2965 times.
✗ Branch 6 not taken.
6584 auto timeSystem = satSys == GLO ? UTC : satSys.getTimeSystem();
1360
1361
2/4
✓ Branch 1 taken 6584 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6584 times.
✗ Branch 5 not taken.
6586 int year = std::stoi(timeSplit.at(0));
1362
1363 InsTime epoch{ static_cast<uint16_t>(year),
1364
1/2
✓ Branch 1 taken 6584 times.
✗ Branch 2 not taken.
6585 static_cast<uint16_t>(std::stoi(timeSplit.at(1))),
1365
1/2
✓ Branch 1 taken 6586 times.
✗ Branch 2 not taken.
6585 static_cast<uint16_t>(std::stoi(timeSplit.at(2))),
1366
1/2
✓ Branch 1 taken 6586 times.
✗ Branch 2 not taken.
6586 static_cast<uint16_t>(std::stoi(timeSplit.at(3))),
1367
1/2
✓ Branch 1 taken 6586 times.
✗ Branch 2 not taken.
6586 static_cast<uint16_t>(std::stoi(timeSplit.at(4))),
1368 13171 std::stold(timeSplit.at(5)),
1369
7/14
✓ Branch 1 taken 6585 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6585 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6586 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6586 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6585 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 6586 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 6586 times.
✗ Branch 20 not taken.
32926 timeSystem };
1370
1371 LOG_DATA("{}: {}-{} {} (read as {} time)", nameId(), satSys, satNum, epoch.toYMDHMS(), std::string(timeSystem));
1372
1373
10/10
✓ Branch 1 taken 5419 times.
✓ Branch 2 taken 1167 times.
✓ Branch 4 taken 3791 times.
✓ Branch 5 taken 1628 times.
✓ Branch 7 taken 3787 times.
✓ Branch 8 taken 4 times.
✓ Branch 10 taken 160 times.
✓ Branch 11 taken 3627 times.
✓ Branch 12 taken 2959 times.
✓ Branch 13 taken 3627 times.
6586 if (satSys == GPS || satSys == GAL || satSys == QZSS || satSys == BDS) // NOLINT(misc-redundant-expression) // bugged warning
1374 {
1375 // Polynomial coefficients for clock correction
1376 2959 std::array<double, 3> a{};
1377 // SV clock bias [seconds]
1378
5/10
✓ Branch 1 taken 2959 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2959 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2959 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2959 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2959 times.
✗ Branch 14 not taken.
11836 a[0] = std::stod(str::replaceAll_copy(line.substr(23, 19), "d", "e", str::IgnoreCase));
1379 // SV clock drift [sec/sec]
1380
5/10
✓ Branch 1 taken 2959 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2959 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2959 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2959 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2959 times.
✗ Branch 14 not taken.
11836 a[1] = std::stod(str::replaceAll_copy(line.substr(42, 19), "d", "e", str::IgnoreCase));
1381 // SV clock drift rate [sec/sec^2]
1382
5/10
✓ Branch 1 taken 2959 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2959 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2959 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2959 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2959 times.
✗ Branch 14 not taken.
8877 a[2] = std::stod(str::replaceAll_copy(line.substr(61, 19), "d", "e", str::IgnoreCase));
1383
1384 LOG_DATA("{}: clkBias {}, clkDrift {}, clkDriftRate {}", nameId(), a[0], a[1], a[2]);
1385
1386 // ------------------------------------ BROADCAST ORBIT - 1 --------------------------------------
1387
1/2
✓ Branch 1 taken 2959 times.
✗ Branch 2 not taken.
2959 getline(line);
1388
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2959 times.
2959 if (line.size() > 82)
1389 {
1390 abortReading();
1391 19 return false;
1392 } // 80 + \n\r
1393
1394 // GPS/QZSS: Issue of Data, Ephemeris (IODE)
1395 // GAL: IODnav Issue of Data of the nav batch
1396 // BDS: AODE Age of Data, Ephemeris (as specified in BeiDou ICD Table Section 5.2.4.11 Table 5-8)
1397 // and field range is: 0-31.
1398 // IRNSS: IODEC Issue of Data, Ephemeris and Clock
1399
5/10
✓ Branch 1 taken 2959 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2959 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2959 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2959 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2959 times.
✗ Branch 14 not taken.
11836 auto IODE_IODnav_AODE_IODEC = static_cast<size_t>(std::stod(str::replaceAll_copy(line.substr(4, 19), "d", "e", str::IgnoreCase)));
1400 // Crs (meters)
1401
5/10
✓ Branch 1 taken 2959 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2959 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2959 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2959 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2959 times.
✗ Branch 14 not taken.
11836 double Crs = std::stod(str::replaceAll_copy(line.substr(23, 19), "d", "e", str::IgnoreCase));
1402 // Delta n (radians/sec)
1403
7/10
✓ Branch 1 taken 2959 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2959 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2958 times.
✓ Branch 8 taken 1 times.
✓ Branch 10 taken 2958 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2957 times.
✓ Branch 14 taken 1 times.
11838 double delta_n = std::stod(str::replaceAll_copy(line.substr(42, 19), "d", "e", str::IgnoreCase));
1404 // M0 (radians)
1405
5/10
✓ Branch 1 taken 2957 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2957 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2957 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2957 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2957 times.
✗ Branch 14 not taken.
8871 double M_0 = std::stod(str::replaceAll_copy(line.substr(61, 19), "d", "e", str::IgnoreCase));
1406
1407 LOG_DATA("{}: IODE_IODnav_AODE_IODEC {}, Crs {}, Delta_n {}, M0 {}", nameId(), IODE_IODnav_AODE_IODEC, Crs, delta_n, M_0);
1408
1409 // ------------------------------------ BROADCAST ORBIT - 2 --------------------------------------
1410
1/2
✓ Branch 1 taken 2957 times.
✗ Branch 2 not taken.
2957 getline(line);
1411
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2957 times.
2957 if (line.size() > 82)
1412 {
1413 abortReading();
1414 return false;
1415 } // 80 + \n\r
1416
1417 // Cuc (radians)
1418
5/10
✓ Branch 1 taken 2957 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2957 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2957 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2957 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2957 times.
✗ Branch 14 not taken.
11828 double Cuc = std::stod(str::replaceAll_copy(line.substr(4, 19), "d", "e", str::IgnoreCase));
1419 // e Eccentricity
1420
5/10
✓ Branch 1 taken 2957 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2957 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2957 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2957 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2957 times.
✗ Branch 14 not taken.
11828 double e = std::stod(str::replaceAll_copy(line.substr(23, 19), "d", "e", str::IgnoreCase));
1421 // Cus (radians)
1422
5/10
✓ Branch 1 taken 2957 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2957 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2957 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2957 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2957 times.
✗ Branch 14 not taken.
11828 double Cus = std::stod(str::replaceAll_copy(line.substr(42, 19), "d", "e", str::IgnoreCase));
1423 // sqrt(A) (sqrt(m))
1424
5/10
✓ Branch 1 taken 2957 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2957 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2957 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2957 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2957 times.
✗ Branch 14 not taken.
8871 double sqrt_A = std::stod(str::replaceAll_copy(line.substr(61, 19), "d", "e", str::IgnoreCase));
1425
1426 LOG_DATA("{}: Cuc {}, e {}, Cus {}, sqrt_A {}", nameId(), Cuc, e, Cus, sqrt_A);
1427
1428 // ------------------------------------ BROADCAST ORBIT - 3 --------------------------------------
1429
1/2
✓ Branch 1 taken 2957 times.
✗ Branch 2 not taken.
2957 getline(line);
1430
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2957 times.
2957 if (line.size() > 82)
1431 {
1432 abortReading();
1433 return false;
1434 } // 80 + \n\r
1435
1436 // Toe Time of Ephemeris (sec of GPS week)
1437
5/10
✓ Branch 1 taken 2957 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2957 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2957 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2957 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2957 times.
✗ Branch 14 not taken.
11828 double toeSec = std::stod(str::replaceAll_copy(line.substr(4, 19), "d", "e", str::IgnoreCase));
1438 // Cic (radians)
1439
5/10
✓ Branch 1 taken 2956 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2957 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2957 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2957 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2957 times.
✗ Branch 14 not taken.
11827 double Cic = std::stod(str::replaceAll_copy(line.substr(23, 19), "d", "e", str::IgnoreCase));
1440 // OMEGA0 (radians)
1441
5/10
✓ Branch 1 taken 2957 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2957 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2957 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2957 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2957 times.
✗ Branch 14 not taken.
11828 double Omega_0 = std::stod(str::replaceAll_copy(line.substr(42, 19), "d", "e", str::IgnoreCase));
1442 // Cis (radians)
1443
5/10
✓ Branch 1 taken 2957 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2957 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2957 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2957 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2957 times.
✗ Branch 14 not taken.
8871 double Cis = std::stod(str::replaceAll_copy(line.substr(61, 19), "d", "e", str::IgnoreCase));
1444
1445 LOG_DATA("{}: toe {}, Cic {}, Omega_0 {}, Cis {}", nameId(), toeSec, Cic, Omega_0, Cis);
1446
1447 // ------------------------------------ BROADCAST ORBIT - 4 --------------------------------------
1448
1/2
✓ Branch 1 taken 2957 times.
✗ Branch 2 not taken.
2957 getline(line);
1449
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2956 times.
2957 if (line.size() > 82)
1450 {
1451
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 abortReading();
1452 1 return false;
1453 } // 80 + \n\r
1454
1455 // i0 (radians)
1456
5/10
✓ Branch 1 taken 2956 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2956 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2956 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2956 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2956 times.
✗ Branch 14 not taken.
11824 double i_0 = std::stod(str::replaceAll_copy(line.substr(4, 19), "d", "e", str::IgnoreCase));
1457 // Crc (meters)
1458
5/10
✓ Branch 1 taken 2956 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2956 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2956 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2956 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2956 times.
✗ Branch 14 not taken.
11824 double Crc = std::stod(str::replaceAll_copy(line.substr(23, 19), "d", "e", str::IgnoreCase));
1459 // omega (radians)
1460
5/10
✓ Branch 1 taken 2956 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2956 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2956 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2956 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2956 times.
✗ Branch 14 not taken.
11824 double omega = std::stod(str::replaceAll_copy(line.substr(42, 19), "d", "e", str::IgnoreCase));
1461 // OMEGA DOT (radians/sec)
1462
5/10
✓ Branch 1 taken 2956 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2956 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2956 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2956 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2956 times.
✗ Branch 14 not taken.
8868 double Omega_dot = std::stod(str::replaceAll_copy(line.substr(61, 19), "d", "e", str::IgnoreCase));
1463
1464 LOG_DATA("{}: i_0 {}, Crc {}, omega {}, Omega_dot {}", nameId(), i_0, Crc, omega, Omega_dot);
1465
1466 // ------------------------------------ BROADCAST ORBIT - 5 --------------------------------------
1467
1/2
✓ Branch 1 taken 2956 times.
✗ Branch 2 not taken.
2956 getline(line);
1468
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2956 times.
2956 if (line.size() > 82)
1469 {
1470 abortReading();
1471 return false;
1472 } // 80 + \n\r
1473
1474 // IDOT (radians/sec)
1475
5/10
✓ Branch 1 taken 2956 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2956 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2956 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2956 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2956 times.
✗ Branch 14 not taken.
11824 double i_dot = std::stod(str::replaceAll_copy(line.substr(4, 19), "d", "e", str::IgnoreCase));
1476 // GPS: Codes on L2 channel
1477 // QZSS: Codes on L2 channel (fixed to 2, see IS-QZSS-PNT 4.1.2.7)
1478 // GAL: Data sources (FLOAT --> INTEGER)
1479 // Bit 0 set: I/NAV E1-B
1480 // Bit 1 set: F/NAV E5a-I
1481 // Bit 2 set: I/NAV E5b-I
1482 // Bits 0 and 2 : Both can be set if the navigation messages were merged, however, bits 0-2
1483 // cannot all be set, as the I/NAV and F/NAV messages contain different information
1484 // Bit 3 reserved for Galileo internal use
1485 // Bit 4 reserved for Galileo internal use
1486 // Bit 8 set: af0-af2, Toc, SISA are for E5a,E1
1487 // Bit 9 set: af0-af2, Toc, SISA are for E5b,E1
1488 // Bits 8-9 : exclusive (only one bit can be set)
1489 // BDS/IRNSS: Spare
1490
4/8
✓ Branch 1 taken 2956 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2956 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2956 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2956 times.
✗ Branch 11 not taken.
8868 auto codesOnL2Channel_dataSources = static_cast<uint16_t>(str::stod(str::replaceAll_copy(line.substr(23, 19), "d", "e", str::IgnoreCase), 0));
1491
1492 // GPS Week # (to go with TOE) Continuous number, not mod(1024)!
1493
5/10
✓ Branch 2 taken 2956 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2956 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2956 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 2956 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 2956 times.
✗ Branch 15 not taken.
11824 auto gpsWeek = static_cast<int32_t>(str::stod(str::replaceAll_copy(line.substr(42, 19), "d", "e", str::IgnoreCase), epoch.toGPSweekTow().gpsWeek));
1494
2/2
✓ Branch 1 taken 160 times.
✓ Branch 2 taken 2796 times.
2956 if (satSys == BDS) { gpsWeek += InsTimeUtil::DIFF_BDT_WEEK_TO_GPST_WEEK; }
1495
2/4
✓ Branch 1 taken 2956 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2956 times.
✗ Branch 5 not taken.
2956 auto toe = InsTime(0, gpsWeek, toeSec, satSys.getTimeSystem());
1496
1497 // GPS: L2 P data flag
1498 // QZSS: L2P data flag set to 1 since QZSS does not track L2P
1499 // GAL/BDS/IRNSS: Spare
1500
4/8
✓ Branch 1 taken 2956 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2956 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2956 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2956 times.
✗ Branch 11 not taken.
8868 bool L2PdataFlag = static_cast<bool>(str::stod(str::replaceAll_copy(line.substr(61, 19), "d", "e", str::IgnoreCase), 0.0));
1501
1502 LOG_DATA("{}: i_dot {}, codesOnL2Channel/dataSources {} ({}), gpsWeek {}, L2PdataFlag {}", nameId(),
1503 i_dot, codesOnL2Channel_dataSources, std::bitset<10>(codesOnL2Channel_dataSources).to_string(), gpsWeek, L2PdataFlag);
1504
1505 // ------------------------------------ BROADCAST ORBIT - 6 --------------------------------------
1506
1/2
✓ Branch 1 taken 2956 times.
✗ Branch 2 not taken.
2956 getline(line);
1507
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2955 times.
2956 if (line.size() > 82)
1508 {
1509
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 abortReading();
1510 1 return false;
1511 } // 80 + \n\r
1512
1513 // GPS: SV accuracy (meters) See GPS ICD 200H Section 20.3.3.3.1.3 use specified equations to define
1514 // nominal values, N = 0-6: use 2(1+N/2) (round to one decimal place i.e. 2.8, 5.7 and 11.3) ,
1515 // N= 7-15:use 2 (N-2), 8192 specifies use at own risk
1516 // QZSS: SV accuracy (meters) (IS -QZSS-PNT, Section 5.4.3.1) which refers to: IS GPS 200H Section 20.3.3.3.1.3
1517 // use specified equations to define nominal values, N = 0-6: use 2(1+N/2) (round to one decimal
1518 // place i.e. 2.8, 5.7 and 11.3) , N= 7-15:use 2 (N-2), 8192 specifies use at own risk
1519 // IRNSS: User Range Accuracy(m), See IRNSS ICD Section 6.2.1.4 , use specified equations to define
1520 // nominal values, N = 0-6: use 2(1+N/2) (round to one decimal place i.e. 2.8, 5.7 and 11.3) ,
1521 // N= 7-15:use 2 (N-2), 8192 specifies use at own risk
1522
5/10
✓ Branch 1 taken 2955 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2955 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2955 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2955 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2955 times.
✗ Branch 14 not taken.
11820 double signalAccuracy = std::stod(str::replaceAll_copy(line.substr(4, 19), "d", "e", str::IgnoreCase));
1523 // GPS/QZSS: SV health (bits 17-22 w 3 sf 1)
1524 // GAL: SV health (FLOAT converted to INTEGER) See Galileo ICD Section 5.1.9.3
1525 // Bit 0: E1B DVS Bits 1-2: E1B HS Bit 3: E5a DVS
1526 // Bits 4-5: E5a HS Bit 6: E5b DVS Bits 7-8: E5b HS
1527 // BDS: SatH1
1528 // IRNSS: Health (Sub frame 1,bits 155(most significant) and 156(least significant)),
1529 // where 0 = L5 and S healthy, 1 = L5 healthy and S unhealthy, 2= L5 unhealthy
1530 // and S healthy, 3= both L5 and S unhealthy
1531
5/10
✓ Branch 1 taken 2955 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2955 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2955 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2955 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2955 times.
✗ Branch 14 not taken.
11820 auto svHealth = static_cast<uint16_t>(std::stod(str::replaceAll_copy(line.substr(23, 19), "d", "e", str::IgnoreCase)));
1532 // GPS: TGD (seconds)
1533 // QZSS: TGD (seconds) The QZSS ICD specifies a do not use bit pattern "10000000" this condition is represented by a blank field.
1534 // GAL: BGD E5a/E1 (seconds)
1535 // BDS: TGD1 B1/B3 (seconds)
1536
4/8
✓ Branch 1 taken 2955 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2955 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2955 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2955 times.
✗ Branch 11 not taken.
11820 double tgd_bgd5a_TGD1 = str::stod(str::replaceAll_copy(line.substr(42, 19), "d", "e", str::IgnoreCase), 0.0);
1537
1538 // GPS/QZSS: IODC Issue of Data, Clock
1539 // GAL: BGD E5b/E1 (seconds)
1540 // BDS: TGD2 B2/B3 (seconds)
1541 // IRNSS: Blank
1542
4/8
✓ Branch 1 taken 2955 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2955 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2955 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2955 times.
✗ Branch 11 not taken.
8865 double IODC_bgd5b_TGD2 = str::stod(str::replaceAll_copy(line.substr(61, 19), "d", "e", str::IgnoreCase), 0.0);
1543
1544 LOG_DATA("{}: svAccuracy {}, svHealth {}, TGD {}, IODC {}", nameId(), signalAccuracy, svHealth, tgd_bgd5a_TGD1, IODC_bgd5b_TGD2);
1545
1546 // ------------------------------------ BROADCAST ORBIT - 7 --------------------------------------
1547
1/2
✓ Branch 1 taken 2955 times.
✗ Branch 2 not taken.
2955 getline(line);
1548
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2955 times.
2955 if (line.size() > 82)
1549 {
1550 abortReading();
1551 return false;
1552 } // 80 + \n\r
1553
1554 // Transmission time of message (sec of GPS week, derived e.g.from Z-count in Hand Over Word (HOW))
1555
4/8
✓ Branch 1 taken 2955 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2955 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2955 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2955 times.
✗ Branch 11 not taken.
11819 [[maybe_unused]] auto transmissionTime = str::stod(str::replaceAll_copy(line.substr(4, 19), "d", "e", str::IgnoreCase), 0.0);
1556 // GPS/QZSS: Fit Interval in hours see section 6.11. (BNK).
1557 // GAL: Spare
1558 // BDS: AODC Age of Data Clock (as specified in BeiDou ICD Table Section 5.2.4.9 Table 5-6) and field range is: 0-31.
1559
4/8
✓ Branch 1 taken 2955 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2955 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2955 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2955 times.
✗ Branch 11 not taken.
8865 auto fitInterval_AODC = str::stod(str::replaceAll_copy(line.substr(23, 19), "d", "e", str::IgnoreCase), 0.0);
1560 // Spare
1561 // std::stod(str::replaceAll_copy(line.substr(42, 19), "d", "e", str::IgnoreCase));
1562 // Spare
1563 // std::stod(str::replaceAll_copy(line.substr(61, 19), "d", "e", str::IgnoreCase));
1564
1565 LOG_DATA("{}: transmissionTime {}, fitInterval/AODC {}", nameId(), transmissionTime, fitInterval_AODC);
1566
1567
2/2
✓ Branch 1 taken 1167 times.
✓ Branch 2 taken 1788 times.
2955 if (satSys == GPS)
1568 {
1569
2/4
✓ Branch 1 taken 1167 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 1167 times.
✗ Branch 7 not taken.
1167 _gnssNavInfo.addSatelliteNavData({ satSys, satNum }, std::make_shared<GPSEphemeris>(epoch, toe,
1570 IODE_IODnav_AODE_IODEC, IODC_bgd5b_TGD2, a,
1571 sqrt_A, e, i_0, Omega_0, omega, M_0,
1572 delta_n, Omega_dot, i_dot, Cus, Cuc,
1573 Cis, Cic, Crs, Crc,
1574 signalAccuracy, svHealth,
1575 codesOnL2Channel_dataSources, L2PdataFlag,
1576 tgd_bgd5a_TGD1, fitInterval_AODC));
1577 }
1578
2/2
✓ Branch 1 taken 1624 times.
✓ Branch 2 taken 164 times.
1788 else if (satSys == GAL)
1579 {
1580 // The same satellite can appear multiple times with different dataSource bits
1581 // We want to prefer 'I/NAV E1-B' (Bit 0 set) over 'F/NAV E5a-I' (Bit 1 set) or 'I/NAV E5b-I' (Bit 2 set)
1582
1583
1/2
✓ Branch 2 taken 1624 times.
✗ Branch 3 not taken.
1624 if (_gnssNavInfo.satellites().contains({ satSys, satNum }) // We have this satellite already
1584
8/10
✓ Branch 1 taken 1523 times.
✓ Branch 2 taken 101 times.
✓ Branch 6 taken 21 times.
✓ Branch 7 taken 1502 times.
✓ Branch 8 taken 1523 times.
✓ Branch 9 taken 101 times.
✓ Branch 11 taken 21 times.
✓ Branch 12 taken 1603 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
3248 && !std::bitset<10>(codesOnL2Channel_dataSources)[0]) // This message is not 'I/NAV E1-B'
1585 {
1586
2/4
✓ Branch 3 taken 21 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 21 times.
✗ Branch 7 not taken.
21 const auto& navData = _gnssNavInfo.satellites().at({ satSys, satNum }).getNavigationData();
1587
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
21 auto existingEph = std::ranges::find_if(navData, [&](const std::shared_ptr<SatNavData>& satNavData) {
1588
2/2
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 7 times.
25 return satNavData->type == SatNavData::GalileoEphemeris && satNavData->refTime == epoch
1589
7/8
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 17 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 18 times.
✓ Branch 10 taken 7 times.
✓ Branch 12 taken 18 times.
✓ Branch 13 taken 7 times.
50 && std::dynamic_pointer_cast<GalileoEphemeris>(satNavData)->dataSource[0];
1590 });
1591
2/2
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 4 times.
21 if (existingEph != navData.end()) // There is already a 'I/NAV E1-B' message
1592 {
1593 LOG_DATA("{}: Skipping ephemeris data because of dataSource priority", nameId());
1594 17 return false;
1595 }
1596 }
1597
1598 1607 GalileoEphemeris::SvHealth health = { .E5a_DataValidityStatus = static_cast<GalileoEphemeris::SvHealth::DataValidityStatus>((svHealth & 0b000001000) >> 3),
1599 1607 .E5b_DataValidityStatus = static_cast<GalileoEphemeris::SvHealth::DataValidityStatus>((svHealth & 0b001000000) >> 6),
1600 1607 .E1B_DataValidityStatus = static_cast<GalileoEphemeris::SvHealth::DataValidityStatus>((svHealth & 0b000000001) >> 0),
1601 1607 .E5a_SignalHealthStatus = static_cast<GalileoEphemeris::SvHealth::SignalHealthStatus>((svHealth & 0b000110000) >> 4),
1602 1607 .E5b_SignalHealthStatus = static_cast<GalileoEphemeris::SvHealth::SignalHealthStatus>((svHealth & 0b110000000) >> 7),
1603 1607 .E1B_SignalHealthStatus = static_cast<GalileoEphemeris::SvHealth::SignalHealthStatus>((svHealth & 0b000000110) >> 1) };
1604
2/4
✓ Branch 1 taken 1607 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 1607 times.
✗ Branch 7 not taken.
1607 _gnssNavInfo.addSatelliteNavData({ satSys, satNum }, std::make_shared<GalileoEphemeris>(epoch, toe, IODE_IODnav_AODE_IODEC, a,
1605 sqrt_A, e, i_0, Omega_0, omega, M_0,
1606 delta_n, Omega_dot, i_dot, Cus, Cuc,
1607 Cis, Cic, Crs, Crc,
1608 codesOnL2Channel_dataSources, signalAccuracy, health,
1609 tgd_bgd5a_TGD1, IODC_bgd5b_TGD2));
1610 }
1611
2/2
✓ Branch 1 taken 160 times.
✓ Branch 2 taken 4 times.
164 else if (satSys == BDS)
1612 {
1613
2/4
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 160 times.
✗ Branch 7 not taken.
160 _gnssNavInfo.addSatelliteNavData({ satSys, satNum }, std::make_shared<BDSEphemeris>(satNum, epoch, toe,
1614 IODE_IODnav_AODE_IODEC, fitInterval_AODC, a,
1615 sqrt_A, e, i_0, Omega_0, omega, M_0,
1616 delta_n, Omega_dot, i_dot, Cus, Cuc,
1617 Cis, Cic, Crs, Crc,
1618 signalAccuracy, svHealth,
1619 tgd_bgd5a_TGD1, IODC_bgd5b_TGD2));
1620 }
1621
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 else if (satSys == QZSS)
1622 {
1623
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
4 _gnssNavInfo.addSatelliteNavData({ satSys, satNum }, std::make_shared<QZSSEphemeris>(epoch, toe,
1624 IODE_IODnav_AODE_IODEC, IODC_bgd5b_TGD2, a,
1625 sqrt_A, e, i_0, Omega_0, omega, M_0,
1626 delta_n, Omega_dot, i_dot, Cus, Cuc,
1627 Cis, Cic, Crs, Crc,
1628 signalAccuracy, svHealth,
1629 codesOnL2Channel_dataSources, L2PdataFlag,
1630 tgd_bgd5a_TGD1, fitInterval_AODC));
1631 }
1632 }
1633
4/6
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 3621 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3627 times.
✗ Branch 7 not taken.
3627 else if (satSys == GLO || satSys == SBAS) // NOLINT(misc-redundant-expression) // bugged warning
1634 {
1635 // TODO: Offset
1636
1637
1/2
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
3627 Eigen::Vector3d pos;
1638
1/2
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
3627 Eigen::Vector3d vel;
1639
1/2
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
3627 Eigen::Vector3d accelLuniSolar;
1640
1641 3627 double tau_c{};
1642 // Coefficient of linear polynomial of time system difference [s]
1643
4/6
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 3627 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 527 times.
✓ Branch 8 taken 3100 times.
3627 if (_gnssNavInfo.timeSysCorr.contains({ satSys.getTimeSystem(), UTC }))
1644 {
1645
2/4
✓ Branch 1 taken 527 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 527 times.
✗ Branch 6 not taken.
527 tau_c = _gnssNavInfo.timeSysCorr.at({ satSys.getTimeSystem(), UTC }).a0;
1646 }
1647
1648 // GLO: SV clock bias (sec) (-TauN)
1649 // SBAS: SV clock bias (sec) (aGf0)
1650
5/10
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
14508 double m_tau_n = std::stod(str::replaceAll_copy(line.substr(23, 19), "d", "e", str::IgnoreCase));
1651 // GLO: SV relative frequency bias (+GammaN)
1652 // SBAS: SV relative frequency bias (aGf1)
1653
5/10
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
14508 double gamma_n = std::stod(str::replaceAll_copy(line.substr(42, 19), "d", "e", str::IgnoreCase));
1654 // GLO: Message frame time (tk+nd*86400) in seconds of the UTC week
1655 // SBAS: Transmission time of message (start of the message) in GPS seconds of the week
1656
5/10
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
10881 [[maybe_unused]] auto msgFrameTime = std::stod(str::replaceAll_copy(line.substr(61, 19), "d", "e", str::IgnoreCase));
1657 LOG_DATA("{}: clkBias {}, relFreqBias {}, msgFrameTime {}", nameId(), m_tau_n, gamma_n, msgFrameTime);
1658
1659 // ------------------------------------ BROADCAST ORBIT - 1 --------------------------------------
1660
1/2
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
3627 getline(line);
1661
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3627 times.
3627 if (line.size() > 82)
1662 {
1663 abortReading();
1664 return false;
1665 } // 80 + \n\r
1666
1667 // Satellite position X (km)
1668
6/12
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3627 times.
✗ Branch 17 not taken.
14508 pos.x() = std::stod(str::replaceAll_copy(line.substr(4, 19), "d", "e", str::IgnoreCase)) * 1e3;
1669 // velocity X dot (km/sec)
1670
6/12
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3627 times.
✗ Branch 17 not taken.
14508 vel.x() = std::stod(str::replaceAll_copy(line.substr(23, 19), "d", "e", str::IgnoreCase)) * 1e3;
1671 // X acceleration (km/sec2)
1672
6/12
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3627 times.
✗ Branch 17 not taken.
14508 accelLuniSolar.x() = std::stod(str::replaceAll_copy(line.substr(42, 19), "d", "e", str::IgnoreCase)) * 1e3;
1673 // GLO: health (0=healthy, 1=unhealthy) (MSB of 3-bit Bn)
1674 // SBAS: Health: SBAS: See Section 8.3.3 bit mask for: health, health availability and User Range Accuracy.
1675
5/10
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
10881 [[maybe_unused]] auto health = std::stod(str::replaceAll_copy(line.substr(61, 19), "d", "e", str::IgnoreCase));
1676
1677 LOG_DATA("{}: satPosX {}, velX {}, accelX {}, health {}", nameId(), pos.x(), vel.x(), accelLuniSolar.x(), health);
1678
1679 // ------------------------------------ BROADCAST ORBIT - 2 --------------------------------------
1680
1/2
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
3627 getline(line);
1681
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3627 times.
3627 if (line.size() > 82)
1682 {
1683 abortReading();
1684 return false;
1685 } // 80 + \n\r
1686
1687 // Satellite position Y (km)
1688
6/12
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3627 times.
✗ Branch 17 not taken.
14508 pos.y() = std::stod(str::replaceAll_copy(line.substr(4, 19), "d", "e", str::IgnoreCase)) * 1e3;
1689 // velocity Y dot (km/sec)
1690
6/12
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3627 times.
✗ Branch 17 not taken.
14508 vel.y() = std::stod(str::replaceAll_copy(line.substr(23, 19), "d", "e", str::IgnoreCase)) * 1e3;
1691 // Y acceleration (km/sec2)
1692
6/12
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3627 times.
✗ Branch 17 not taken.
14508 accelLuniSolar.y() = std::stod(str::replaceAll_copy(line.substr(42, 19), "d", "e", str::IgnoreCase)) * 1e3;
1693 // GLO: frequency number(-7...+13) (-7...+6 ICD 5.1)
1694 // SBAS: Accuracy code (URA, meters)
1695
5/10
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
10881 double frequencyNumber_accuracyCode = std::stod(str::replaceAll_copy(line.substr(61, 19), "d", "e", str::IgnoreCase));
1696
1697 LOG_DATA("{}: satPosY {}, velY {}, accelY {}, freqNum/accuracyCode {}", nameId(), pos.y(), vel.y(), accelLuniSolar.y(), frequencyNumber_accuracyCode);
1698
1699 // ------------------------------------ BROADCAST ORBIT - 3 --------------------------------------
1700
1/2
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
3627 getline(line);
1701
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3627 times.
3627 if (line.size() > 82)
1702 {
1703 abortReading();
1704 return false;
1705 } // 80 + \n\r
1706
1707 // Satellite position Z (km)
1708
6/12
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3627 times.
✗ Branch 17 not taken.
14508 pos.z() = std::stod(str::replaceAll_copy(line.substr(4, 19), "d", "e", str::IgnoreCase)) * 1e3;
1709 // velocity Z dot (km/sec)
1710
6/12
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3627 times.
✗ Branch 17 not taken.
14508 vel.z() = std::stod(str::replaceAll_copy(line.substr(23, 19), "d", "e", str::IgnoreCase)) * 1e3;
1711 // Z acceleration (km/sec2)
1712
6/12
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3627 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3627 times.
✗ Branch 17 not taken.
14508 accelLuniSolar.z() = std::stod(str::replaceAll_copy(line.substr(42, 19), "d", "e", str::IgnoreCase)) * 1e3;
1713 // GLO: Age of oper. information (days) (E)
1714 // SBAS: IODN (Issue of Data Navigation, DO229, 8 first bits after Message Type if MT9)
1715
4/8
✓ Branch 1 taken 3627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3627 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3627 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3627 times.
✗ Branch 11 not taken.
10881 [[maybe_unused]] auto ageOfOperation_IODN = str::stod(str::replaceAll_copy(line.substr(61, 19), "d", "e", str::IgnoreCase), 0.0);
1716
1717 LOG_DATA("{}: satPosZ {}, velZ {}, accelZ {}, ageOfOperation/IODN {}", nameId(), pos.z(), vel.z(), accelLuniSolar.z(), ageOfOperation_IODN);
1718
1719 // ------------------------------------ BROADCAST ORBIT - 4 --------------------------------------
1720 // since version 3.05 GLONASS has an additional line
1721
6/6
✓ Branch 1 taken 3621 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 3609 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 3615 times.
3627 if (satSys == GLO && _version >= 3.05)
1722 {
1723
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 getline(line);
1724
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
12 if (line.size() > 82)
1725 {
1726 abortReading();
1727 return false;
1728 } // 80 + \n\r
1729
1730 // status flags (FLOAT converted to INTEGER) (can be blank)
1731 // M Bit 7-8: GLO type indicator (00=GLO, 01=GLO-M/K)
1732 // P4 Bit 6: GLO-M/K only, 1=data updated, 0=data not updated
1733 // P3 Bit 5: num of satellites in current frame alamanc (0=4 sats, 1=5 sats)
1734 // P2 Bit 4: indicate even (0) or odd (1) of time interval
1735 // P1 Bit 2-3: update and validity interval (00=0 min, 01=30 min, 10=45 min, 11=60 min)
1736 // P Bit 0-1: GLO-M/K only, time offset parameters tau_c, tau_GPS source (00=ground, 01 = tau_c ground, tau_GPS on-board, 10 = tau_c on-board, tau_GPS ground, 11 = on-board)
1737
5/10
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
48 [[maybe_unused]] double statusFlags = str::stod(str::replaceAll_copy(str::trim_copy(line.substr(4, 19)), "d", "e", str::IgnoreCase), std::nan(""));
1738 // L1/L2 group delay difference Δτ [sec]
1739
5/10
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
48 [[maybe_unused]] double L1L2groupDelayDifference = std::stod(str::replaceAll_copy(line.substr(23, 19), "d", "e", str::IgnoreCase));
1740 // URAI raw accuracy index F_T (GLO-M/K only)r
1741
5/10
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
48 [[maybe_unused]] double URAI = std::stod(str::replaceAll_copy(line.substr(42, 19), "d", "e", str::IgnoreCase));
1742 // health flags (FLOAT converted to INTEGER) (can be blank)
1743 // l(3) Bit 2: GLO-M/K only, health bit of string 3
1744 // A_C Bit 1: 1=almanac health reported in ephemerides record, 0=not reported
1745 // C Bit 0: almanac health bit (1=healthy, 0=not healthy)
1746
5/10
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
48 [[maybe_unused]] double healthFlags = str::stod(str::replaceAll_copy(str::trim_copy(line.substr(61, 19)), "d", "e", str::IgnoreCase), std::nan(""));
1747
1748 LOG_DATA("{}: statusFlags {}, L1L2groupDelayDifference {}, URAI {}, healthFlags {}", nameId(), statusFlags, L1L2groupDelayDifference, URAI, healthFlags);
1749 }
1750
1751
2/2
✓ Branch 1 taken 3621 times.
✓ Branch 2 taken 6 times.
3627 if (satSys == GLO)
1752 {
1753
1/2
✓ Branch 3 taken 3621 times.
✗ Branch 4 not taken.
3621 _gnssNavInfo.addSatelliteNavData({ satSys, satNum }, std::make_shared<GLONASSEphemeris>(epoch, tau_c,
1754
1/2
✓ Branch 1 taken 3621 times.
✗ Branch 2 not taken.
7242 -m_tau_n, gamma_n, static_cast<bool>(health),
1755 pos, vel, accelLuniSolar,
1756 frequencyNumber_accuracyCode));
1757 }
1758
5/6
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 4 times.
6 else if (satSys == SBAS && !_sbasNotSupportedWarned)
1759 {
1760
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 LOG_WARN("SBAS is not yet supported. Therefore the Navigation file data will be skipped.");
1761 2 _sbasNotSupportedWarned = true;
1762 }
1763 }
1764 6564 return true;
1765 6585 }
1766
1767 47 void RinexNavFile::readHeader()
1768 {
1769 LOG_TRACE("{}: called", nameId());
1770
1/2
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
47 auto guard = requestOutputValueLock(OUTPUT_PORT_INDEX_GNSS_NAV_INFO);
1771
1/2
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
47 executeHeaderParser(_version);
1772 47 }
1773
1774 47 void RinexNavFile::readOrbits()
1775 {
1776 LOG_TRACE("{}: called", nameId());
1777
1/2
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
47 auto guard = requestOutputValueLock(OUTPUT_PORT_INDEX_GNSS_NAV_INFO);
1778
1/2
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
47 executeOrbitParser(_version);
1779 47 }
1780
1781 } // namespace NAV
1782