INSTINCT Code Coverage Report


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