Repository navigation
Expand file tree
/
Copy pathrinex_printer.h
More file actions
320 lines (278 loc) · 11.7 KB
/
Copy pathrinex_printer.h
File metadata and controls
320 lines (278 loc) · 11.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
/*!
* \file rinex_printer.h
* \brief Interface of a RINEX 2.11 / 3.02 / 4.02 printer
* See https://files.igs.org/pub/data/format/rinex_4.02.pdf
*
* Receiver Independent EXchange Format (RINEX):
* The first proposal for the Receiver Independent Exchange Format RINEX
* was developed by the Astronomical Institute of the University of Berne
* for the easy exchange of the GPS data to be collected during the large
* European GPS campaign EUREF 89, which involved more than 60 GPS receivers
* of 4 different manufacturers.
* The governing aspect during the development was the fact that most geodetic
* processing software for GPS data use a well-defined set of observables:
* 1) The carrier-phase measurement at one or both carriers (actually being a
* measurement on the beat frequency between the received carrier of the
* satellite signal and a receiver-generated reference frequency).
* 2) The pseudorange (code) measurement , equivalent to the difference
* of the time of reception (expressed in the time frame of the receiver)
* and the time of transmission (expressed in the time frame of the satellite)
* of a distinct satellite signal.
* 3) The observation time being the reading of the receiver clock at the
* instant of validity of the carrier-phase and/or the code measurements.
* Note: A collection of the formats currently used by the IGS can be found
* here: https://igs.org/formats-and-standards/
* \author Carles Fernandez Prades, 2011-2026. cfernandez(at)cttc.es
* \author Mathieu Favreau, 2025-2026. favreau.mathieu(at)hotmail.com
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2026 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_RINEX_PRINTER_H
#define GNSS_SDR_RINEX_PRINTER_H
#include "signal_enabled_flags.h"
#include <boost/date_time/posix_time/posix_time.hpp>
#include <cstdint> // for int32_t
#include <cstdlib> // for strtol, strtod
#include <fstream> // for fstream
#include <map> // for map
#include <string> // for string
#include <vector> // for vector
/** \addtogroup PVT
* \{ */
/** \addtogroup PVT_libs
* \{ */
struct Bds3_B1c_PageData;
class Beidou_Cnav1_Ephemeris;
class Beidou_Dnav_Ephemeris;
class Beidou_Dnav_Iono;
class Beidou_Dnav_Utc_Model;
class Galileo_Ephemeris;
class Galileo_Iono;
class Galileo_Utc_Model;
class Glonass_Gnav_Almanac;
class Glonass_Gnav_Ephemeris;
class Glonass_Gnav_Utc_Model;
class Gnss_Synchro;
class Gps_CNAV_Ephemeris;
class Gps_CNAV_Iono;
class Gps_CNAV_Utc_Model;
class Gps_Ephemeris;
class Gps_Iono;
class Gps_Navigation_Message;
class Gps_Utc_Model;
class Rtklib_Solver;
/*!
* \brief Class that handles the generation of Receiver
* INdependent EXchange format (RINEX) files
*/
class Rinex_Printer
{
public:
/*!
* \brief Constructor. Creates GNSS Navigation and Observables RINEX files.
*/
explicit Rinex_Printer(uint32_t signal_enabled_flags,
int version = 3,
const std::string& base_path = ".",
const std::string& base_name = "-",
int32_t ref_gps_week = 0);
/*!
* \brief Destructor. Removes created files if empty.
*/
~Rinex_Printer() noexcept;
/*!
* \brief Print RINEX annotation. If it is the first annotation, it also
* prints the RINEX headers for navigation and observation files. If it is
* not the first annotation, it only annotates the observation, and updates
* the navigation header if UTC data was not available when writing it for
* the first time.
*
*/
void print_rinex_annotation(const Rtklib_Solver* pvt_solver,
const std::map<int, Gnss_Synchro>& gnss_observables_map,
double rx_time,
bool flag_write_RINEX_obs_output);
/*!
* \brief Print RINEX annotation for GPS NAV message
*/
void log_rinex_nav_gps_nav(const std::map<int32_t, Gps_Ephemeris>& new_eph);
/*!
* \brief Print RINEX 4 annotation for GPS/QZSS CNAV message
*/
void log_rinex_nav_gps_cnav(const std::map<int32_t, Gps_CNAV_Ephemeris>& new_cnav_eph);
/*!
* \brief Print RINEX annotation for Galileo NAV message
*/
void log_rinex_nav_gal_nav(const std::map<int32_t, Galileo_Ephemeris>& new_gal_eph);
/*!
* \brief Print RINEX annotation for Glonass GNAV message
*/
void log_rinex_nav_glo_gnav(const std::map<int32_t, Glonass_Gnav_Ephemeris>& new_glo_eph);
/*!
* \brief Print RINEX annotation for BeiDou DNAV message
*/
void log_rinex_nav_bds_dnav(const std::map<int32_t, Beidou_Dnav_Ephemeris>& new_bds_eph);
/*!
* \brief Print RINEX navigation records for BeiDou B-CNAV1 ephemerides.
*
* RINEX 4 writes proper CNV1 records (Table A24), taking SISAI/SISMAI/
* integrity and t_op from the last decoded SF3 page when it carries them.
* RINEX 3 has no CNAV1 representation, so records are written as D1-style
* stand-ins: sqrt(A0) in the sqrtA field with the Adot term dropped,
* IODE/IODC in AODE/AODC, and TGD_B1Cp/TGD_B2ap mapped into TGD1/TGD2.
*/
void log_rinex_nav_bds_cnav1(const std::map<int32_t, Beidou_Cnav1_Ephemeris>& new_bds_eph,
const std::map<int32_t, Bds3_B1c_PageData>& bds_page_data);
/*!
* \brief Print RINEX navigation records for BeiDou B-CNAV2 ephemerides.
*
* RINEX 4 writes CNV2 records (Table A25) with ISC_B2ad in the second field of orbit line 7.
* RINEX 3 has no CNV2 representation; records are omitted rather than
* written as CNV1 or D1 stand-ins.
*/
void log_rinex_nav_bds_cnav2(const std::map<int32_t, Beidou_Cnav1_Ephemeris>& new_bds_eph);
/*!
* \brief Returns true is the RINEX file headers are already written
*/
inline bool is_rinex_header_written() const
{
return d_rinex_header_written;
}
/*!
* \brief Returns name of RINEX navigation file(s)
*/
inline std::vector<std::string> get_navfilename() const
{
return output_navfilename;
}
/*!
* \brief Returns name of RINEX observation file
*/
inline std::string get_obsfilename() const
{
return obsfilename;
}
private:
// Not the best, but reorder params to select the correct constructor
explicit Rinex_Printer(uint32_t signal_enabled_flags,
const std::string& base_name,
const std::string& base_rinex_path,
int version,
int32_t ref_gps_week);
/*
* Generates the GPS Observation data header
*/
void rinex_obs_header(std::fstream& out,
const std::string& time_constellation,
const boost::posix_time::ptime& system_time,
double seconds);
/*
* Generates the Navigation Data header
*/
void rinex_nav_header(std::fstream& out,
const std::vector<std::string>& iono_lines,
const std::vector<std::string>& time_corr_lines,
const std::string& leap_second_line) const;
/*
* Logs RINEX 4 auxiliary data records for the enabled constellations as
* soon as they become available, and updates the LEAP SECONDS header line
* of the observation and navigation files
*/
void log_rinex_nav_v4_aux_records(const Rtklib_Solver* pvt_solver,
double rx_time,
const std::string& system_time_str);
/*
* Computes the BDS Time and returns a boost::posix_time::ptime object
* \details Function used to convert the observation time into BDT time which is used
* as the default time for RINEX files
* \param eph BeiDou DNAV Ephemeris object
* \param obs_time Observation time in BDT seconds of week
*/
boost::posix_time::ptime compute_BDS_time(const Beidou_Dnav_Ephemeris& eph, double obs_time) const;
boost::posix_time::ptime compute_BDS_time(const Beidou_Cnav1_Ephemeris& eph, double obs_time) const;
/*
* Computes the UTC time and returns a boost::posix_time::ptime object
*/
boost::posix_time::ptime compute_UTC_time(const Gps_Navigation_Message& nav_msg) const;
/*
* Computes the GPS time and returns a boost::posix_time::ptime object
*/
boost::posix_time::ptime compute_GPS_time(const Gps_Ephemeris& eph, double obs_time) const;
/*
* Computes the GPS time and returns a boost::posix_time::ptime object
*/
boost::posix_time::ptime compute_GPS_time(const Gps_CNAV_Ephemeris& eph, double obs_time) const;
/*
* Computes the Galileo time and returns a boost::posix_time::ptime object
*/
boost::posix_time::ptime compute_Galileo_time(const Galileo_Ephemeris& eph, double obs_time) const;
/*
* Computes the UTC Time and returns a boost::posix_time::ptime object
* \details Function used as a method to convert the observation time into UTC time which is used
* as the default time for RINEX files
* \param eph GLONASS GNAV Ephemeris object
* \param obs_time Observation time in GPS seconds of week
*/
boost::posix_time::ptime compute_UTC_time(const Glonass_Gnav_Ephemeris& eph, double obs_time) const;
/*
* Represents GPS time in the date time format. Leap years are considered, but leap seconds are not.
*/
void to_date_time(int gps_week,
int gps_tow,
int& year,
int& month,
int& day,
int& hour,
int& minute,
int& second) const;
void update_obs_header(std::fstream& out, const std::string& leap_second_line) const;
const std::map<std::string, std::string> observationType; // PSEUDORANGE, CARRIER_PHASE, DOPPLER, SIGNAL_STRENGTH
const std::map<std::string, std::string> observationCode; // GNSS observation descriptors
const Signal_Enabled_Flags d_flags;
const int d_version; // RINEX version (2 for 2.11, 3 for 3.02, 4 for 4.02)
const std::string d_stringVersion; // RINEX version (2.11, 3.02 or 4.02)
std::string d_last_gps_lnav_iono_signature;
std::string d_last_gps_lnav_sto_signature;
std::string d_last_gps_cnav_eop_signature;
std::string d_last_gps_cnav_iono_signature;
std::string d_last_gps_cnav_sto_signature;
std::string d_last_qzss_lnav_iono_signature;
std::string d_last_qzss_lnav_sto_signature;
std::string d_last_qzss_cnav_eop_signature;
std::string d_last_qzss_cnav_iono_signature;
std::string d_last_qzss_cnav_sto_signature;
std::string d_last_galileo_iono_signature;
std::string d_last_galileo_sto_signature;
std::string d_last_glonass_sto_signature;
std::string d_last_beidou_iono_signature;
std::string d_last_beidou_sto_signature;
std::string d_last_bds_cnav1_iono_signature;
std::string d_last_bds_cnav1_sto_signature;
std::string d_last_leap_second_line;
const int32_t d_ref_gps_week;
const std::string navfilename; // Name of RINEX navigation file
const std::string obsfilename; // Name of RINEX observation file
const std::string navGlofilename; // Name of RINEX navigation file for Glonass
std::vector<std::string> output_navfilename; // Name of output RINEX navigation file(s)
std::fstream obsFile; // Output file stream for RINEX observation file
std::fstream navFile; // Output file stream for RINEX navigation data file
std::fstream navGloFile; // Output file stream for RINEX GLONASS navigation data file
bool d_rinex_header_updated;
bool d_rinex_header_gps_updated;
bool d_rinex_header_galileo_updated;
bool d_rinex_header_glonass_updated;
bool d_rinex_header_beidou_iono_updated;
bool d_rinex_header_beidou_time_updated;
bool d_rinex_header_written;
};
/** \} */
/** \} */
#endif // GNSS_SDR_RINEX_PRINTER_H