GNSS-SDR  0.0.19
An Open Source GNSS Software Defined Receiver
rinex_printer.h
Go to the documentation of this file.
1 /*!
2  * \file rinex_printer.h
3  * \brief Interface of a RINEX 2.11 / 3.01 printer
4  * See ftp://igs.org/pub/data/format/rinex301.pdf
5  *
6  * Receiver Independent EXchange Format (RINEX):
7  * The first proposal for the Receiver Independent Exchange Format RINEX
8  * was developed by the Astronomical Institute of the University of Berne
9  * for the easy exchange of the GPS data to be collected during the large
10  * European GPS campaign EUREF 89, which involved more than 60 GPS receivers
11  * of 4 different manufacturers.
12  * The governing aspect during the development was the fact that most geodetic
13  * processing software for GPS data use a well-defined set of observables:
14  * 1) The carrier-phase measurement at one or both carriers (actually being a
15  * measurement on the beat frequency between the received carrier of the
16  * satellite signal and a receiver-generated reference frequency).
17  * 2) The pseudorange (code) measurement , equivalent to the difference
18  * of the time of reception (expressed in the time frame of the receiver)
19  * and the time of transmission (expressed in the time frame of the satellite)
20  * of a distinct satellite signal.
21  * 3) The observation time being the reading of the receiver clock at the
22  * instant of validity of the carrier-phase and/or the code measurements.
23  * Note: A collection of the formats currently used by the IGS can be found
24  * here: https://kb.igs.org/hc/en-us/articles/201096516-IGS-Formats
25  * \author Carles Fernandez Prades, 2011. cfernandez(at)cttc.es
26  *
27  * -----------------------------------------------------------------------------
28  *
29  * GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
30  * This file is part of GNSS-SDR.
31  *
32  * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
33  * SPDX-License-Identifier: GPL-3.0-or-later
34  *
35  * -----------------------------------------------------------------------------
36  */
37 
38 #ifndef GNSS_SDR_RINEX_PRINTER_H
39 #define GNSS_SDR_RINEX_PRINTER_H
40 
41 #include <boost/date_time/posix_time/posix_time.hpp>
42 #include <cstdint> // for int32_t
43 #include <cstdlib> // for strtol, strtod
44 #include <fstream> // for fstream
45 #include <iomanip> // for setprecision
46 #include <map> // for map
47 #include <sstream> // for stringstream
48 #include <string> // for string
49 #include <unordered_map> // for unordered_map
50 #include <vector> // for vector
51 
52 
53 /** \addtogroup PVT
54  * \{ */
55 /** \addtogroup PVT_libs
56  * \{ */
57 
58 
60 class Beidou_Dnav_Iono;
62 class Galileo_Ephemeris;
63 class Galileo_Iono;
64 class Galileo_Utc_Model;
68 class Gnss_Synchro;
69 class Gps_CNAV_Ephemeris;
70 class Gps_CNAV_Iono;
71 class Gps_CNAV_Utc_Model;
72 class Gps_Ephemeris;
73 class Gps_Iono;
75 class Gps_Utc_Model;
76 class Rtklib_Solver;
77 
78 
79 /*!
80  * \brief Class that handles the generation of Receiver
81  * INdependent EXchange format (RINEX) files
82  */
84 {
85 public:
86  /*!
87  * \brief Constructor. Creates GNSS Navigation and Observables RINEX files.
88  */
89  explicit Rinex_Printer(int version = 0,
90  const std::string& base_path = ".",
91  const std::string& base_name = "-");
92 
93  /*!
94  * \brief Destructor. Removes created files if empty.
95  */
97 
98  /*!
99  * \brief Print RINEX annotation. If it is the first annotation, it also
100  * prints the RINEX headers for navigation and observation files. If it is
101  * not the first annotation, it only annotates the observation, and updates
102  * the navigation header if UTC data was not available when writing it for
103  * the first time. The meaning of type_of_rx is as follows:
104  *
105  * type_of_rx | Signals
106  * ------------- | -------------
107  * 0 | Unknown
108  * 1 | GPS L1 C/A
109  * 2 | GPS L2C
110  * 3 | GPS L5
111  * 4 | Galileo E1B
112  * 5 | Galileo E5a
113  * 6 | Galileo E5b
114  * 7 | GPS L1 C/A + GPS L2C
115  * 8 | GPS L1 C/A + GPS L5
116  * 9 | GPS L1 C/A + Galileo E1B
117  * 10 | GPS L1 C/A + Galileo E5a
118  * 11 | GPS L1 C/A + Galileo E5b
119  * 12 | Galileo E1B + GPS L2C
120  * 13 | Galileo E5a + GPS L5
121  * 14 | Galileo E1B + Galileo E5a
122  * 15 | Galileo E1B + Galileo E5b
123  * 16 | GPS L2C + GPS L5
124  * 17 | GPS L2C + Galileo E5a
125  * 20 | GPS L5 + Galileo E5b
126  * 21 | GPS L1 C/A + Galileo E1B + GPS L2C
127  * 22 | GPS L1 C/A + Galileo E1B + GPS L5
128  * 23 | GLONASS L1 C/A
129  * 24 | GLONASS L2 C/A
130  * 25 | GLONASS L1 C/A + GLONASS L2 C/A
131  * 26 | GPS L1 C/A + GLONASS L1 C/A
132  * 27 | Galileo E1B + GLONASS L1 C/A
133  * 28 | GPS L2C + GLONASS L1 C/A
134  * 29 | GPS L1 C/A + GLONASS L2 C/A
135  * 30 | Galileo E1B + GLONASS L2 C/A
136  * 31 | GPS L2C + GLONASS L2 C/A
137  * 32 | GPS L1 C/A + Galileo E1B + GPS L5 + Galileo E5a
138  * 33 | GPS L1 C/A + Galileo E1B + Galileo E5a
139  * 100 | Galileo E6B
140  * 101 | Galileo E1B + Galileo E6B
141  * 102 | Galileo E5a + Galileo E6B
142  * 103 | Galileo E5b + Galileo E6B
143  * 104 | Galileo E1B + Galileo E5a + Galileo E6B
144  * 105 | Galileo E1B + Galileo E5b + Galileo E6B
145  * 106 | GPS L1 C/A + Galileo E1B + Galileo E6B
146  * 107 | GPS L1 C/A + Galileo E6B
147  * 108 | GPS L1 C/A + Galileo E1B + GPS L5 + Galileo E5a + Galileo E6B
148  * 500 | BeiDou B1I
149  * 501 | BeiDou B1I + GPS L1 C/A
150  * 502 | BeiDou B1I + Galileo E1B
151  * 503 | BeiDou B1I + GLONASS L1 C/A
152  * 504 | BeiDou B1I + GPS L1 C/A + Galileo E1B
153  * 505 | BeiDou B1I + GPS L1 C/A + GLONASS L1 C/A + Galileo E1B
154  * 506 | BeiDou B1I + Beidou B3I
155  * 600 | BeiDou B3I
156  * 601 | BeiDou B3I + GPS L2C
157  * 602 | BeiDou B3I + GLONASS L2 C/A
158  * 603 | BeiDou B3I + GPS L2C + GLONASS L2 C/A
159  * 604 | BeiDou B3I + GPS L1 C/A
160  * 605 | BeiDou B3I + Galileo E1B
161  * 606 | BeiDou B3I + GLONASS L1 C/A
162  * 607 | BeiDou B3I + GPS L1 C/A + Galileo E1B
163  * 608 | BeiDou B3I + GPS L1 C/A + Galileo E1B + BeiDou B1I
164  * 609 | BeiDou B3I + GPS L1 C/A + Galileo E1B + GLONASS L1 C/A
165  * 610 | BeiDou B3I + GPS L1 C/A + Galileo E1B + GLONASS L1 C/A + BeiDou B1I
166  * 1000 | GPS L1 C/A + GPS L2C + GPS L5
167  * 1001 | GPS L1 C/A + Galileo E1B + GPS L2C + GPS L5 + Galileo E5a
168  *
169  */
170  void print_rinex_annotation(const Rtklib_Solver* pvt_solver,
171  const std::map<int, Gnss_Synchro>& gnss_observables_map,
172  double rx_time,
173  int type_of_rx,
174  bool flag_write_RINEX_obs_output);
175 
176  /*!
177  * \brief Print RINEX annotation for GPS NAV message
178  */
179  void log_rinex_nav_gps_nav(int type_of_rx,
180  const std::map<int32_t, Gps_Ephemeris>& new_eph);
181 
182  /*!
183  * \brief Print RINEX annotation for GPS CNAV message
184  */
185  void log_rinex_nav_gps_cnav(int type_of_rx,
186  const std::map<int32_t, Gps_CNAV_Ephemeris>& new_cnav_eph);
187 
188  /*!
189  * \brief Print RINEX annotation for Galileo NAV message
190  */
191  void log_rinex_nav_gal_nav(int type_of_rx,
192  const std::map<int32_t, Galileo_Ephemeris>& new_gal_eph);
193 
194  /*!
195  * \brief Print RINEX annotation for Glonass GNAV message
196  */
197  void log_rinex_nav_glo_gnav(int type_of_rx,
198  const std::map<int32_t, Glonass_Gnav_Ephemeris>& new_glo_eph);
199 
200  /*!
201  * \brief Print RINEX annotation for BeiDou DNAV message
202  */
203  void log_rinex_nav_bds_dnav(int type_of_rx,
204  const std::map<int32_t, Beidou_Dnav_Ephemeris>& new_bds_eph);
205 
206  /*!
207  * \brief Set processing for signals older than 2009
208  */
209  void set_pre_2009_file(bool pre_2009_file);
210 
211  /*!
212  * \brief Returns true is the RINEX file headers are already written
213  */
214  inline bool is_rinex_header_written() const
215  {
216  return d_rinex_header_written;
217  }
218 
219  /*!
220  * \brief Returns name of RINEX navigation file(s)
221  */
222  inline std::vector<std::string> get_navfilename() const
223  {
224  return output_navfilename;
225  }
226 
227  /*!
228  * \brief Returns name of RINEX observation file
229  */
230  inline std::string get_obsfilename() const
231  {
232  return obsfilename;
233  }
234 
235 
236 private:
237  const std::unordered_map<std::string, std::string> satelliteSystem = {
238  {"GPS", "G"},
239  {"GLONASS", "R"},
240  {"SBAS payload", "S"},
241  {"Galileo", "E"},
242  {"Beidou", "C"},
243  {"Mixed", "M"}}; // RINEX v3.02 codes
244 
245  /*
246  * Generates the GPS Observation data header
247  */
248  void rinex_obs_header(std::fstream& out,
249  const Gps_Ephemeris& eph,
250  double d_TOW_first_observation);
251 
252  /*
253  * Generates the GPS L2 Observation data header
254  */
255  void rinex_obs_header(std::fstream& out,
256  const Gps_CNAV_Ephemeris& eph,
257  double d_TOW_first_observation,
258  const std::string& gps_bands = "2S");
259 
260  /*
261  * Generates the dual frequency GPS L1 & L2/L5 Observation data header
262  */
263  void rinex_obs_header(std::fstream& out,
264  const Gps_Ephemeris& eph,
265  const Gps_CNAV_Ephemeris& eph_cnav,
266  double d_TOW_first_observation,
267  const std::string& gps_bands = "1C 2S");
268 
269  /*
270  * Generates the Galileo Observation data header.
271  * Example: bands("1B"), bands("1B 5X"), bands("5X"), ... Default: "1B".
272  */
273  void rinex_obs_header(std::fstream& out,
274  const Galileo_Ephemeris& eph,
275  double d_TOW_first_observation,
276  const std::string& bands = "1B");
277 
278  /*
279  * Generates the Mixed (GPS/Galileo) Observation data header.
280  * Example: galileo_bands("1B"), galileo_bands("1B 5X"),
281  * galileo_bands("5X"), ... Default: "1B".
282  */
283  void rinex_obs_header(std::fstream& out,
284  const Gps_Ephemeris& gps_eph,
285  const Galileo_Ephemeris& galileo_eph,
286  double d_TOW_first_observation,
287  const std::string& galileo_bands = "1B");
288 
289  /*
290  * Generates the Mixed (GPS/Galileo) Observation data header.
291  * Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
292  */
293  void rinex_obs_header(std::fstream& out,
294  const Gps_Ephemeris& gps_eph,
295  const Gps_CNAV_Ephemeris& eph_cnav,
296  const Galileo_Ephemeris& galileo_eph,
297  double d_TOW_first_observation,
298  const std::string& gps_bands = "1C 2S",
299  const std::string& galileo_bands = "1B");
300 
301  /*
302  * Generates the Mixed (GPS/Galileo) Observation data header.
303  * Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
304  */
305  void rinex_obs_header(std::fstream& out,
306  const Gps_CNAV_Ephemeris& eph_cnav,
307  const Galileo_Ephemeris& galileo_eph,
308  double d_TOW_first_observation,
309  const std::string& gps_bands = "2S",
310  const std::string& galileo_bands = "1B");
311 
312  /*
313  * Generates the GLONASS GNAV Observation data header.
314  * Example: bands("1C"), bands("1C 2C"), bands("2C"), ... Default: "1C".
315  */
316  void rinex_obs_header(std::fstream& out,
317  const Glonass_Gnav_Ephemeris& eph,
318  double d_TOW_first_observation,
319  const std::string& bands = "1G");
320 
321  /*
322  * Generates the Mixed (GPS L1 C/A /GLONASS) Observation data header.
323  * Example: galileo_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
324  */
325  void rinex_obs_header(std::fstream& out,
326  const Gps_Ephemeris& gps_eph,
327  const Glonass_Gnav_Ephemeris& glonass_gnav_eph,
328  double d_TOW_first_observation,
329  const std::string& glonass_bands = "1C");
330 
331  /*
332  * Generates the Mixed (Galileo/GLONASS) Observation data header.
333  * Example: galileo_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
334  */
335  void rinex_obs_header(std::fstream& out,
336  const Galileo_Ephemeris& galileo_eph,
337  const Glonass_Gnav_Ephemeris& glonass_gnav_eph,
338  double d_TOW_first_observation,
339  const std::string& galileo_bands = "1B",
340  const std::string& glonass_bands = "1C");
341 
342  /*
343  * Generates the Mixed (GPS L2C/GLONASS) Observation data header.
344  * Example: galileo_bands("1G")... Default: "1G".
345  */
346  void rinex_obs_header(std::fstream& out,
347  const Gps_CNAV_Ephemeris& gps_cnav_eph,
348  const Glonass_Gnav_Ephemeris& glonass_gnav_eph,
349  double d_TOW_first_observation,
350  const std::string& glonass_bands = "1G");
351 
352  /*
353  * Generates the a Beidou B1I Observation data header. Example: beidou_bands("B1")
354  */
355  void rinex_obs_header(std::fstream& out,
356  const Beidou_Dnav_Ephemeris& eph,
357  double d_TOW_first_observation,
358  const std::string& bands);
359 
360  /*
361  * Generates the SBAS raw data header
362  */
363  void rinex_sbs_header(std::fstream& out) const;
364 
365  /*
366  * Writes GPS L1 observables into the RINEX file
367  */
368  void log_rinex_obs(std::fstream& out,
369  const Gps_Ephemeris& eph,
370  double obs_time,
371  const std::map<int32_t, Gnss_Synchro>& observables) const;
372 
373  /*
374  * Writes GPS L2 observables into the RINEX file
375  */
376  void log_rinex_obs(std::fstream& out,
377  const Gps_CNAV_Ephemeris& eph,
378  double obs_time,
379  const std::map<int32_t, Gnss_Synchro>& observables) const;
380 
381  /*
382  * Writes dual frequency GPS L1 and L2 observables into the RINEX file
383  */
384  void log_rinex_obs(std::fstream& out,
385  const Gps_Ephemeris& eph,
386  const Gps_CNAV_Ephemeris& eph_cnav,
387  double obs_time,
388  const std::map<int32_t, Gnss_Synchro>& observables,
389  bool triple_band = false) const;
390 
391  /*
392  * Writes Galileo observables into the RINEX file.
393  * Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
394  */
395  void log_rinex_obs(std::fstream& out,
396  const Galileo_Ephemeris& eph,
397  double obs_time,
398  const std::map<int32_t, Gnss_Synchro>& observables,
399  const std::string& galileo_bands = "1B") const;
400 
401  /*
402  * Writes Mixed GPS / Galileo observables into the RINEX file
403  */
404  void log_rinex_obs(std::fstream& out,
405  const Gps_Ephemeris& gps_eph,
406  const Galileo_Ephemeris& galileo_eph,
407  double gps_obs_time,
408  const std::map<int32_t, Gnss_Synchro>& observables) const;
409 
410  /*
411  * Writes Mixed GPS / Galileo observables into the RINEX file
412  */
413  void log_rinex_obs(std::fstream& out,
414  const Gps_CNAV_Ephemeris& eph,
415  const Galileo_Ephemeris& galileo_eph,
416  double gps_obs_time,
417  const std::map<int32_t, Gnss_Synchro>& observables) const;
418 
419  /*
420  * Writes Mixed GPS / Galileo observables into the RINEX file
421  */
422  void log_rinex_obs(std::fstream& out,
423  const Gps_Ephemeris& gps_eph,
424  const Gps_CNAV_Ephemeris& gps_cnav_eph,
425  const Galileo_Ephemeris& galileo_eph,
426  double gps_obs_time,
427  const std::map<int32_t, Gnss_Synchro>& observables,
428  bool triple_band = false) const;
429 
430  /*
431  * Writes GLONASS GNAV observables into the RINEX file.
432  * Example: glonass_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
433  */
434  void log_rinex_obs(std::fstream& out,
435  const Glonass_Gnav_Ephemeris& eph,
436  double obs_time,
437  const std::map<int32_t, Gnss_Synchro>& observables,
438  const std::string& glonass_bands = "1C") const;
439 
440  /*
441  * Writes Mixed GPS L1 C/A - GLONASS observables into the RINEX file
442  */
443  void log_rinex_obs(std::fstream& out,
444  const Gps_Ephemeris& gps_eph,
445  const Glonass_Gnav_Ephemeris& glonass_gnav_eph,
446  double gps_obs_time,
447  const std::map<int32_t, Gnss_Synchro>& observables) const;
448 
449  /*
450  * Writes Mixed GPS L2C - GLONASS observables into the RINEX file
451  */
452  void log_rinex_obs(std::fstream& out,
453  const Gps_CNAV_Ephemeris& gps_eph,
454  const Glonass_Gnav_Ephemeris& glonass_gnav_eph,
455  double gps_obs_time,
456  const std::map<int32_t, Gnss_Synchro>& observables) const;
457 
458  /*
459  * Writes Mixed Galileo/GLONASS observables into the RINEX file
460  */
461  void log_rinex_obs(std::fstream& out,
462  const Galileo_Ephemeris& galileo_eph,
463  const Glonass_Gnav_Ephemeris& glonass_gnav_eph,
464  double galileo_obs_time,
465  const std::map<int32_t, Gnss_Synchro>& observables) const;
466 
467  /*
468  * Writes BDS B1I observables into the RINEX file
469  */
470  void log_rinex_obs(std::fstream& out,
471  const Beidou_Dnav_Ephemeris& eph,
472  double obs_time,
473  const std::map<int32_t, Gnss_Synchro>& observables,
474  const std::string& bds_bands) const;
475 
476  /*
477  * Generates the GPS L1 C/A Navigation Data header
478  */
479  void rinex_nav_header(std::fstream& out,
480  const Gps_Iono& iono,
481  const Gps_Utc_Model& utc_model,
482  const Gps_Ephemeris& eph) const;
483 
484  /*
485  * Generates the GPS L2C(M) Navigation Data header
486  */
487  void rinex_nav_header(std::fstream& out,
488  const Gps_CNAV_Iono& iono,
489  const Gps_CNAV_Utc_Model& utc_model) const;
490 
491  /*
492  * Generates the Galileo Navigation Data header
493  */
494  void rinex_nav_header(std::fstream& out,
495  const Galileo_Iono& iono,
496  const Galileo_Utc_Model& utc_model) const;
497 
498  /*
499  * Generates the Mixed (GPS/Galileo) Navigation Data header
500  */
501  void rinex_nav_header(std::fstream& out,
502  const Gps_Iono& gps_iono,
503  const Gps_Utc_Model& gps_utc_model,
504  const Gps_Ephemeris& eph,
505  const Galileo_Iono& galileo_iono,
506  const Galileo_Utc_Model& galileo_utc_model) const;
507 
508  /*
509  * Generates the Mixed (GPS CNAV/Galileo) Navigation Data header
510  */
511  void rinex_nav_header(std::fstream& out,
512  const Gps_CNAV_Iono& iono,
513  const Gps_CNAV_Utc_Model& utc_model,
514  const Galileo_Iono& galileo_iono,
515  const Galileo_Utc_Model& galileo_utc_model) const;
516 
517  /*
518  * Generates the GLONASS L1, L2 C/A Navigation Data header
519  */
520  void rinex_nav_header(std::fstream& out,
521  const Glonass_Gnav_Utc_Model& utc_model,
522  const Glonass_Gnav_Ephemeris& glonass_gnav_eph);
523 
524  /*
525  * Generates the Mixed (Galileo/GLONASS) Navigation Data header
526  */
527  void rinex_nav_header(std::fstream& out,
528  const Galileo_Iono& galileo_iono,
529  const Galileo_Utc_Model& galileo_utc_model,
530  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
531  const Glonass_Gnav_Almanac& glonass_gnav_almanac) const;
532 
533  /*
534  * Generates the Mixed (GPS L1 C/A/GLONASS L1, L2) Navigation Data header
535  */
536  void rinex_nav_header(std::fstream& out,
537  const Gps_Iono& gps_iono,
538  const Gps_Utc_Model& gps_utc_model,
539  const Gps_Ephemeris& eph,
540  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
541  const Glonass_Gnav_Almanac& glonass_gnav_almanac);
542 
543  /*
544  * Generates the Mixed (GPS L2C C/A/GLONASS L1, L2) Navigation Data header
545  */
546  void rinex_nav_header(std::fstream& out,
547  const Gps_CNAV_Iono& gps_iono,
548  const Gps_CNAV_Utc_Model& gps_utc_model,
549  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
550  const Glonass_Gnav_Almanac& glonass_gnav_almanac);
551 
552  /*
553  * Generates the BDS B1I or B3I Navigation Data header
554  */
555  void rinex_nav_header(std::fstream& out,
556  const Beidou_Dnav_Iono& iono,
557  const Beidou_Dnav_Utc_Model& utc_model) const;
558 
559  /*
560  * Generates the Mixed GPS L1,L5 + BDS B1I, B3I Navigation Data header
561  */
562  void rinex_nav_header(std::fstream& out,
563  const Gps_Iono& gps_iono,
564  const Gps_Utc_Model& gps_utc_model,
565  const Gps_Ephemeris& eph,
566  const Beidou_Dnav_Iono& bds_dnav_iono,
567  const Beidou_Dnav_Utc_Model& bds_dnav_utc_model) const;
568 
569  /*
570  * Generates the Mixed GPS L2C + BDS B1I, B3I Navigation Data header
571  */
572  void rinex_nav_header(std::fstream& out,
573  const Gps_CNAV_Iono& gps_cnav_iono,
574  const Gps_CNAV_Utc_Model& gps_cnav_utc_model,
575  const Beidou_Dnav_Iono& bds_dnav_iono,
576  const Beidou_Dnav_Utc_Model& bds_dnav_utc_model);
577 
578  /*
579  * Generates the Mixed GLONASS L1,L2 + BDS B1I, B3I Navigation Data header
580  */
581  void rinex_nav_header(std::fstream& out,
582  const Glonass_Gnav_Utc_Model& glo_gnav_utc_model,
583  const Beidou_Dnav_Iono& bds_dnav_iono,
584  const Beidou_Dnav_Utc_Model& bds_dnav_utc_model) const;
585 
586  /*
587  * Generates the Mixed (Galileo/BDS B1I, B3I) Navigation Data header
588  */
589  void rinex_nav_header(std::fstream& out,
590  const Galileo_Iono& galileo_iono,
591  const Galileo_Utc_Model& galileo_utc_model,
592  const Beidou_Dnav_Iono& bds_dnav_iono,
593  const Beidou_Dnav_Utc_Model& bds_dnav_utc_model) const;
594 
595  /*
596  * Writes data from the GPS L1 C/A navigation message into the RINEX file
597  */
598  void log_rinex_nav(std::fstream& out,
599  const std::map<int32_t, Gps_Ephemeris>& eph_map) const;
600 
601  /*
602  * Writes data from the GPS L2 navigation message into the RINEX file
603  */
604  void log_rinex_nav(std::fstream& out,
605  const std::map<int32_t, Gps_CNAV_Ephemeris>& eph_map);
606 
607  /*
608  * Writes data from the Galileo navigation message into the RINEX file
609  */
610  void log_rinex_nav(std::fstream& out,
611  const std::map<int32_t, Galileo_Ephemeris>& eph_map) const;
612 
613  /*
614  * Writes data from the Mixed (GPS/Galileo) navigation message into the RINEX file
615  */
616  void log_rinex_nav(std::fstream& out,
617  const std::map<int32_t, Gps_Ephemeris>& gps_eph_map,
618  const std::map<int32_t, Galileo_Ephemeris>& galileo_eph_map);
619 
620  /*
621  * Writes data from the Mixed (GPS/Galileo) navigation message into the RINEX file
622  */
623  void log_rinex_nav(std::fstream& out,
624  const std::map<int32_t, Gps_CNAV_Ephemeris>& gps_cnav_eph_map,
625  const std::map<int32_t, Galileo_Ephemeris>& galileo_eph_map);
626 
627  /*
628  * Writes data from the GLONASS GNAV navigation message into the RINEX file
629  */
630  void log_rinex_nav(std::fstream& out,
631  const std::map<int32_t, Glonass_Gnav_Ephemeris>& eph_map) const;
632 
633  /*
634  * Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file
635  */
636  void log_rinex_nav(std::fstream& out,
637  const std::map<int32_t, Gps_Ephemeris>& gps_eph_map,
638  const std::map<int32_t, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map) const;
639 
640  /*
641  * Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file
642  */
643  void log_rinex_nav(std::fstream& out,
644  const std::map<int32_t, Gps_CNAV_Ephemeris>& gps_cnav_eph_map,
645  const std::map<int32_t, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map);
646 
647  /*
648  * Writes data from the Mixed (Galileo/ GLONASS GNAV) navigation message into the RINEX file
649  */
650  void log_rinex_nav(std::fstream& out,
651  const std::map<int32_t, Galileo_Ephemeris>& galileo_eph_map,
652  const std::map<int32_t, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map);
653 
654  /*
655  * Writes data from the Beidou B1I navigation message into the RINEX file
656  */
657  void log_rinex_nav(std::fstream& out,
658  const std::map<int32_t, Beidou_Dnav_Ephemeris>& eph_map) const;
659 
660  /*
661  * Computes the BDS Time and returns a boost::posix_time::ptime object
662  * \details Function used to convert the observation time into BDT time which is used
663  * as the default time for RINEX files
664  * \param eph BeiDou DNAV Ephemeris object
665  * \param obs_time Observation time in BDT seconds of week
666  */
667  boost::posix_time::ptime compute_BDS_time(const Beidou_Dnav_Ephemeris& eph, double obs_time) const;
668 
669  /*
670  * Computes the UTC time and returns a boost::posix_time::ptime object
671  */
672  boost::posix_time::ptime compute_UTC_time(const Gps_Navigation_Message& nav_msg) const;
673 
674  /*
675  * Computes the GPS time and returns a boost::posix_time::ptime object
676  */
677  boost::posix_time::ptime compute_GPS_time(const Gps_Ephemeris& eph, double obs_time) const;
678 
679  /*
680  * Computes the GPS time and returns a boost::posix_time::ptime object
681  */
682  boost::posix_time::ptime compute_GPS_time(const Gps_CNAV_Ephemeris& eph, double obs_time) const;
683 
684  /*
685  * Computes the Galileo time and returns a boost::posix_time::ptime object
686  */
687  boost::posix_time::ptime compute_Galileo_time(const Galileo_Ephemeris& eph, double obs_time) const;
688 
689  /*
690  * Computes the UTC Time and returns a boost::posix_time::ptime object
691  * \details Function used as a method to convert the observation time into UTC time which is used
692  * as the default time for RINEX files
693  * \param eph GLONASS GNAV Ephemeris object
694  * \param obs_time Observation time in GPS seconds of week
695  */
696  boost::posix_time::ptime compute_UTC_time(const Glonass_Gnav_Ephemeris& eph, double obs_time) const;
697 
698  /*
699  * Computes number of leap seconds of GPS relative to UTC
700  * \param eph GLONASS GNAV Ephemeris object
701  * \param gps_obs_time Observation time in GPS seconds of week
702  */
703  double get_leap_second(const Glonass_Gnav_Ephemeris& eph, double gps_obs_time) const;
704 
705  /*
706  * Represents GPS time in the date time format. Leap years are considered, but leap seconds are not.
707  */
708  void to_date_time(int gps_week,
709  int gps_tow,
710  int& year,
711  int& month,
712  int& day,
713  int& hour,
714  int& minute,
715  int& second) const;
716 
717  /*
718  * Writes raw SBAS messages into the RINEX file
719  */
720  // void log_rinex_sbs(std::fstream & out, const Sbas_Raw_Msg & sbs_message);
721 
722  void update_nav_header(std::fstream& out,
723  const Gps_Utc_Model& utc_model,
724  const Gps_Iono& gps_iono, const Gps_Ephemeris& eph) const;
725 
726  void update_nav_header(std::fstream& out,
727  const Gps_CNAV_Utc_Model& utc_model,
728  const Gps_CNAV_Iono& iono) const;
729 
730  void update_nav_header(std::fstream& out,
731  const Gps_Iono& gps_iono,
732  const Gps_Utc_Model& gps_utc_model,
733  const Gps_Ephemeris& eph,
734  const Galileo_Iono& galileo_iono,
735  const Galileo_Utc_Model& galileo_utc_model) const;
736 
737  void update_nav_header(std::fstream& out,
738  const Gps_CNAV_Utc_Model& utc_model,
739  const Gps_CNAV_Iono& iono,
740  const Galileo_Iono& galileo_iono,
741  const Galileo_Utc_Model& galileo_utc_model) const;
742 
743  void update_nav_header(std::fstream& out,
744  const Galileo_Iono& galileo_iono,
745  const Galileo_Utc_Model& utc_model) const;
746 
747  void update_nav_header(std::fstream& out,
748  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
749  const Glonass_Gnav_Almanac& glonass_gnav_almanac) const;
750 
751  void update_nav_header(std::fstream& out,
752  const Gps_Iono& gps_iono,
753  const Gps_Utc_Model& gps_utc,
754  const Gps_Ephemeris& eph,
755  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
756  const Glonass_Gnav_Almanac& glonass_gnav_almanac) const;
757 
758  void update_nav_header(std::fstream& out,
759  const Gps_CNAV_Iono& gps_iono,
760  const Gps_CNAV_Utc_Model& gps_utc_model,
761  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
762  const Glonass_Gnav_Almanac& glonass_gnav_almanac) const;
763 
764  void update_nav_header(std::fstream& out,
765  const Galileo_Iono& galileo_iono,
766  const Galileo_Utc_Model& galileo_utc_model,
767  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
768  const Glonass_Gnav_Almanac& glonass_gnav_almanac) const;
769 
770  void update_nav_header(std::fstream& out,
771  const Beidou_Dnav_Utc_Model& utc_model,
772  const Beidou_Dnav_Iono& beidou_dnav_iono) const;
773 
774  void update_obs_header(std::fstream& out,
775  const Gps_Utc_Model& utc_model) const;
776 
777  void update_obs_header(std::fstream& out,
778  const Gps_CNAV_Utc_Model& utc_model) const;
779 
780  void update_obs_header(std::fstream& out,
781  const Galileo_Utc_Model& galileo_utc_model) const;
782 
783  void update_obs_header(std::fstream& out,
784  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model) const;
785 
786  void update_obs_header(std::fstream& out,
787  const Beidou_Dnav_Utc_Model& utc_model) const;
788 
789  /*
790  * Generation of RINEX signal strength indicators
791  */
792  int signalStrength(double snr) const;
793 
794  /* Creates RINEX file names according to the naming convention
795  *
796  * See ftp://igs.org/pub/data/format/rinex301.pdf
797  * Section 4, page 6
798  *
799  * \param[in] type of RINEX file. Can be:
800  * "RINEX_FILE_TYPE_OBS" - Observation file.
801  * "RINEX_FILE_TYPE_GPS_NAV" - GPS navigation message file.
802  * "RINEX_FILE_TYPE_MET" - Meteorological data file.
803  * "RINEX_FILE_TYPE_GLO_NAV" - GLONASS navigation file.
804  * "RINEX_FILE_TYPE_GAL_NAV" - Galileo navigation message file.
805  * "RINEX_FILE_TYPE_MIXED_NAV" - Mixed GNSS navigation message file.
806  * "RINEX_FILE_TYPE_GEO_NAV" - SBAS Payload navigation message file.
807  * "RINEX_FILE_TYPE_SBAS" - SBAS broadcast data file.
808  * "RINEX_FILE_TYPE_CLK" - Clock file.
809  */
810  std::string createFilename(const std::string& type, const std::string& base_name) const;
811 
812  /*
813  * Generates the data for the PGM / RUN BY / DATE line
814  */
815  std::string getLocalTime() const;
816 
817  /*
818  * Checks that the line is 80 characters length
819  */
820  void lengthCheck(const std::string& line) const;
821 
822  /*
823  * If the string is bigger than length, truncate it from the right.
824  * otherwise, add pad characters to its right.
825  *
826  * Left-justifies the input in a string of the specified
827  * length. If the new length (\a length) is larger than the
828  * current length, the string is extended by the pad
829  * character (\a pad). The default pad character is a
830  * blank.
831  * \param[in] s string to be modified.
832  * \param[in] length new desired length of string.
833  * \param[in] pad character to pad string with (blank by default).
834  * \return a reference to \a s. */
835  inline std::string& leftJustify(std::string& s,
836  std::string::size_type length,
837  char pad = ' ') const;
838 
839  /*
840  * If the string is bigger than length, truncate it from the right.
841  * otherwise, add pad characters to its right.
842  *
843  * Left-justifies the receiver in a string of the specified
844  * length (const version). If the new length (\a length) is larger
845  * than the current length, the string is extended by the pad
846  * character (\a pad). The default pad character is a
847  * blank.
848  * \param[in] s string to be modified.
849  * \param[in] length new desired length of string.
850  * \param[in] pad character to pad string with (blank by default).
851  * \return a reference to \a s. */
852  inline std::string leftJustify(const std::string& s,
853  std::string::size_type length,
854  char pad = ' ') const
855  {
856  std::string t(s);
857  return leftJustify(t, length, pad);
858  }
859 
860 
861  /*
862  * Right-justifies the receiver in a string of the specified
863  * length. If the receiver's data is shorter than the
864  * requested length (\a length), it is padded on the left with
865  * the pad character (\a pad). The default pad
866  * character is a blank. */
867  inline std::string& rightJustify(std::string& s,
868  std::string::size_type length,
869  char pad = ' ') const;
870 
871  /*
872  * Right-justifies the receiver in a string of the specified
873  * length (const version). If the receiver's data is shorter than the
874  * requested length (\a length), it is padded on the left with
875  * the pad character (\a pad). The default pad
876  * character is a blank.*/
877  inline std::string rightJustify(const std::string& s,
878  std::string::size_type length,
879  char pad = ' ') const
880  {
881  std::string t(s);
882  return rightJustify(t, length, pad);
883  }
884 
885 
886  /*
887  * Convert a double to a scientific notation number.
888  * @param d the double to convert
889  * @param length length (in characters) of output, including exponent
890  * @param expLen length (in characters) of the exponent, with sign
891  * @param showSign if true, reserves 1 character for +/- sign
892  * @param checkSwitch if true, keeps the exponential sanity check for
893  * exponentials above three characters in length. If false, it removes
894  * that check.
895  */
896  inline std::string doub2sci(double d,
897  std::string::size_type length,
898  std::string::size_type expLen,
899  bool showSign = true,
900  bool checkSwitch = true) const;
901 
902 
903  /*
904  * Convert scientific notation to FORTRAN notation.
905  * As an example, the string "1.5636E5" becomes " .15636D6".
906  * Note that the first character of the string will be '-' if
907  * the number is negative or ' ' if the first character is positive.
908  * @param aStr string with number to convert
909  * @param startPos start position of number in string
910  * @param length length (in characters) of number, including exponent.
911  * @param expLen length (in characters of exponent, not including sign.
912  * @param checkSwitch will keep the method running as originally programmed
913  * when set to true. If false, the method will always resize exponentials,
914  * produce an exponential with an E instead of a D, and always have a leading
915  * zero. For example -> 0.87654E-0004 or -0.1234E00005.
916  */
917  inline std::string& sci2for(std::string& aStr,
918  std::string::size_type startPos = 0,
919  std::string::size_type length = std::string::npos,
920  std::string::size_type expLen = 3,
921  bool checkSwitch = true) const;
922 
923 
924  /*
925  * Convert double precision floating point to a string
926  * containing the number in FORTRAN notation.
927  * As an example, the number 156360 becomes ".15636D6".
928  * @param d number to convert.
929  * @param length length (in characters) of number, including exponent.
930  * @param expLen length (in characters of exponent, including sign.
931  * @param checkSwitch if true, keeps the exponential sanity check for
932  * exponentials above three characters in length. If false, it removes
933  * that check.
934  * @return a string containing \a d in FORTRAN notation.
935  */
936  inline std::string doub2for(double d,
937  std::string::size_type length,
938  std::string::size_type expLen,
939  bool checkSwitch = true) const;
940 
941 
942  /*
943  * Convert a string to a double precision floating point number.
944  * @param s string containing a number.
945  * @return double representation of string.
946  */
947  inline double asDouble(const std::string& s) const
948  {
949  return strtod(s.c_str(), nullptr);
950  }
951 
952 
953  inline int toInt(const std::string& bitString, int sLength) const;
954 
955  /*
956  * Convert a string to an integer.
957  * @param s string containing a number.
958  * @return int64_t integer representation of string.
959  */
960  inline int64_t asInt(const std::string& s) const
961  {
962  return strtol(s.c_str(), nullptr, 10);
963  }
964 
965 
966  /*
967  * Convert a double to a string in fixed notation.
968  * @param x double.
969  * @param precision the number of decimal places you want displayed.
970  * @return string representation of \a x.
971  */
972  inline std::string asString(double x,
973  std::string::size_type precision = 17) const;
974 
975 
976  /*
977  * Convert a long double to a string in fixed notation.
978  * @param x long double.
979  * @param precision the number of decimal places you want displayed.
980  * @return string representation of \a x.
981  */
982  inline std::string asString(long double x,
983  std::string::size_type precision = 21) const;
984 
985 
986  /*
987  * Convert any old object to a string.
988  * The class must have stream operators defined.
989  * @param x object to turn into a string.
990  * @return string representation of \a x.
991  */
992  template <class X>
993  inline std::string asString(const X x) const;
994 
995  inline std::string asFixWidthString(int x, int width, char fill_digit) const;
996 
997  std::map<std::string, std::string> observationType; // PSEUDORANGE, CARRIER_PHASE, DOPPLER, SIGNAL_STRENGTH
998  std::map<std::string, std::string> observationCode; // GNSS observation descriptors
999 
1000  std::fstream obsFile; // Output file stream for RINEX observation file
1001  std::fstream navFile; // Output file stream for RINEX navigation data file
1002  std::fstream sbsFile; // Output file stream for RINEX SBAS raw data file
1003  std::fstream navGalFile; // Output file stream for RINEX Galileo navigation data file
1004  std::fstream navGloFile; // Output file stream for RINEX GLONASS navigation data file
1005  std::fstream navBdsFile; // Output file stream for RINEX Galileo navigation data file
1006  std::fstream navMixFile; // Output file stream for RINEX Mixed navigation data file
1007 
1008  std::string navfilename; // Name of RINEX navigation file for GPS L1
1009  std::string obsfilename; // Name of RINEX observation file
1010  std::string sbsfilename; // Name of RINEX SBAS file
1011  std::string navGalfilename; // Name of RINEX navigation file for Galileo
1012  std::string navGlofilename; // Name of RINEX navigation file for Glonass
1013  std::string navBdsfilename; // Name of RINEX navigation file for BeiDou
1014  std::string navMixfilename; // Name of RINEX navigation file for fixed signals
1015  std::vector<std::string> output_navfilename; // Name of output RINEX navigation file(s)
1016 
1017  std::string d_stringVersion; // RINEX version (2.10/2.11 or 3.01/3.02)
1018 
1019  double d_fake_cnav_iode;
1020  int d_version; // RINEX version (2 for 2.10/2.11 and 3 for 3.01)
1021  int d_numberTypesObservations; // Number of available types of observable in the system. Should be public?
1022  bool d_rinex_header_updated;
1023  bool d_rinex_header_written;
1024  bool d_pre_2009_file;
1025 };
1026 
1027 
1028 // Implementation of inline functions (modified versions from GNSSTk https://github.com/SGL-UT/gnsstk)
1029 
1030 inline std::string& Rinex_Printer::leftJustify(std::string& s,
1031  std::string::size_type length,
1032  char pad) const
1033 {
1034  if (length < s.length())
1035  {
1036  s = s.substr(0, length);
1037  }
1038  else
1039  {
1040  s.append(length - s.length(), pad);
1041  }
1042  return s;
1043 }
1044 
1045 
1046 // if the string is bigger than length, truncate it from the left.
1047 // otherwise, add pad characters to its left.
1048 inline std::string& Rinex_Printer::rightJustify(std::string& s,
1049  std::string::size_type length,
1050  char pad) const
1051 {
1052  if (length < s.length())
1053  {
1054  s = s.substr(s.length() - length, std::string::npos);
1055  }
1056  else
1057  {
1058  s.insert(static_cast<std::string::size_type>(0), length - s.length(), pad);
1059  }
1060  return s;
1061 }
1062 
1063 
1064 inline std::string Rinex_Printer::doub2for(double d,
1065  std::string::size_type length,
1066  std::string::size_type expLen,
1067  bool checkSwitch) const
1068 {
1069  int16_t exponentLength = expLen;
1070 
1071  /* Validate the assumptions regarding the input arguments */
1072  if (exponentLength < 0)
1073  {
1074  exponentLength = 1;
1075  }
1076 
1077  if (exponentLength > 3 && checkSwitch)
1078  {
1079  exponentLength = 3;
1080  }
1081 
1082  std::string toReturn = doub2sci(d, length, exponentLength, true, checkSwitch);
1083  sci2for(toReturn, 0, length, exponentLength, checkSwitch);
1084 
1085  return toReturn;
1086 }
1087 
1088 
1089 inline std::string Rinex_Printer::doub2sci(double d,
1090  std::string::size_type length,
1091  std::string::size_type expLen,
1092  bool showSign,
1093  bool checkSwitch) const
1094 {
1095  std::string toReturn;
1096  int16_t exponentLength = expLen;
1097 
1098  /* Validate the assumptions regarding the input arguments */
1099  if (exponentLength < 0)
1100  {
1101  exponentLength = 1;
1102  }
1103 
1104  if (exponentLength > 3 && checkSwitch)
1105  {
1106  exponentLength = 3;
1107  }
1108 
1109  std::stringstream c;
1110  c.setf(std::ios::scientific, std::ios::floatfield);
1111 
1112  // length - 3 for special characters ('.', 'e', '+' or '-')
1113  // - exponentlength (e04)
1114  // - 1 for the digit before the decimal (2.)
1115  // and if showSign == true,
1116  // an extra -1 for '-' or ' ' if it's positive or negative
1117  int expSize = 0;
1118  if (showSign)
1119  {
1120  expSize = 1;
1121  }
1122 
1123  c.precision(length - 3 - exponentLength - 1 - expSize);
1124  c << d;
1125  c >> toReturn;
1126  return toReturn;
1127 }
1128 
1129 
1130 inline std::string& Rinex_Printer::sci2for(std::string& aStr,
1131  std::string::size_type startPos,
1132  std::string::size_type length,
1133  std::string::size_type expLen,
1134  bool checkSwitch) const
1135 {
1136  std::string::size_type idx = aStr.find('.', startPos);
1137  int expAdd = 0;
1138  std::string exp;
1139  int64_t iexp;
1140  // If checkSwitch is false, always redo the exponential. Otherwise,
1141  // set it to false.
1142  bool redoexp = !checkSwitch;
1143 
1144  // Check for decimal place within specified boundaries
1145  if ((idx <= 0) || (idx >= (startPos + length - expLen - 1)))
1146  {
1147  // Error: no decimal point in string
1148  return aStr;
1149  }
1150 
1151  // Here, account for the possibility that there are
1152  // no numbers to the left of the decimal, but do not
1153  // account for the possibility of non-scientific
1154  // notation (more than one digit to the left of the
1155  // decimal)
1156  if (idx > startPos)
1157  {
1158  redoexp = true;
1159  // Swap digit and decimal.
1160  aStr[idx] = aStr[idx - 1];
1161  aStr[idx - 1] = '.';
1162  // Only add one to the exponent if the number is non-zero
1163  if (asDouble(aStr.substr(startPos, length)) != 0.0)
1164  {
1165  expAdd = 1;
1166  }
1167  }
1168 
1169  idx = aStr.find('e', startPos);
1170  if (idx == std::string::npos)
1171  {
1172  idx = aStr.find('E', startPos);
1173  if (idx == std::string::npos)
1174  {
1175  // Error: no 'e' or 'E' in string";
1176  }
1177  }
1178 
1179  // Change the exponent character to D normally, or E of checkSwitch is false.
1180  if (checkSwitch)
1181  {
1182  aStr[idx] = 'D';
1183  }
1184  else
1185  {
1186  aStr[idx] = 'E';
1187  }
1188 
1189  // Change the exponent itself
1190  if (redoexp)
1191  {
1192  exp = aStr.substr(idx + 1, std::string::npos);
1193  iexp = asInt(exp);
1194  iexp += expAdd;
1195 
1196  aStr.erase(idx + 1);
1197  if (iexp < 0)
1198  {
1199  aStr += "-";
1200  iexp -= iexp * 2;
1201  }
1202  else
1203  {
1204  aStr += "+";
1205  }
1206 
1207  aStr += Rinex_Printer::rightJustify(asString(iexp), expLen, '0');
1208  }
1209 
1210  // if the number is positive, append a space
1211  // (if it's negative, there's a leading '-'
1212  if (aStr[0] == '.')
1213  {
1214  aStr.insert(static_cast<std::string::size_type>(0), 1, ' ');
1215  }
1216 
1217  // If checkSwitch is false, add on one leading zero to the string
1218  if (!checkSwitch)
1219  {
1220  aStr.insert(static_cast<std::string::size_type>(1), 1, '0');
1221  }
1222 
1223  return aStr;
1224 } // end sci2for
1225 
1226 
1227 inline std::string asString(long double x, std::string::size_type precision)
1228 {
1229  std::ostringstream ss;
1230  ss << std::fixed << std::setprecision(precision) << x;
1231  return ss.str();
1232 }
1233 
1234 
1235 inline std::string Rinex_Printer::asString(double x, std::string::size_type precision) const
1236 {
1237  std::ostringstream ss;
1238  ss << std::fixed << std::setprecision(precision) << x;
1239  return ss.str();
1240 }
1241 
1242 
1243 inline std::string Rinex_Printer::asFixWidthString(int x, int width, char fill_digit) const
1244 {
1245  std::ostringstream ss;
1246  ss << std::setfill(fill_digit) << std::setw(width) << x;
1247  return ss.str().substr(ss.str().size() - width);
1248 }
1249 
1250 
1251 inline int64_t asInt(const std::string& s)
1252 {
1253  return strtol(s.c_str(), nullptr, 10);
1254 }
1255 
1256 
1257 inline int Rinex_Printer::toInt(const std::string& bitString, int sLength) const
1258 {
1259  int tempInt;
1260  int num = 0;
1261  for (int i = 0; i < sLength; i++)
1262  {
1263  tempInt = bitString[i] - '0';
1264  num |= (1 << (sLength - 1 - i)) * tempInt;
1265  }
1266  return num;
1267 }
1268 
1269 
1270 template <class X>
1271 inline std::string Rinex_Printer::asString(const X x) const
1272 {
1273  std::ostringstream ss;
1274  ss << x;
1275  return ss.str();
1276 }
1277 
1278 
1279 /** \} */
1280 /** \} */
1281 #endif // GNSS_SDR_RINEX_PRINTER_H
This class is a storage for the GPS IONOSPHERIC data as described in IS-GPS-200M. ...
Definition: gps_iono.h:35
std::string get_obsfilename() const
Returns name of RINEX observation file.
This is a storage class for the GPS CNAV ephemeris data as described in IS-GPS-200M.
This class is a storage for the BeiDou DNAV UTC Model.
This class is a storage and orbital model functions for the GPS SV ephemeris data as described in IS-...
Definition: gps_ephemeris.h:40
bool is_rinex_header_written() const
Returns true is the RINEX file headers are already written.
Rinex_Printer(int version=0, const std::string &base_path=".", const std::string &base_name="-")
Constructor. Creates GNSS Navigation and Observables RINEX files.
This class is a storage for the BEIDOU IONOSPHERIC data as described in ICD v2.1. ...
Class that handles the generation of Receiver INdependent EXchange format (RINEX) files...
Definition: rinex_printer.h:83
void print_rinex_annotation(const Rtklib_Solver *pvt_solver, const std::map< int, Gnss_Synchro > &gnss_observables_map, double rx_time, int type_of_rx, bool flag_write_RINEX_obs_output)
Print RINEX annotation. If it is the first annotation, it also prints the RINEX headers for navigatio...
This class is a storage and orbital model functions for the GLONASS SV ephemeris data as described in...
This class implements a PVT solution based on RTKLIB.
Definition: rtklib_solver.h:81
~Rinex_Printer()
Destructor. Removes created files if empty.
This is a storage class for the Beidou SV ephemeris data as described in BeiDou Navigation Satellite ...
This is the class that contains the information that is shared by the processing blocks.
Definition: gnss_synchro.h:38
void log_rinex_nav_gal_nav(int type_of_rx, const std::map< int32_t, Galileo_Ephemeris > &new_gal_eph)
Print RINEX annotation for Galileo NAV message.
void log_rinex_nav_gps_cnav(int type_of_rx, const std::map< int32_t, Gps_CNAV_Ephemeris > &new_cnav_eph)
Print RINEX annotation for GPS CNAV message.
void log_rinex_nav_gps_nav(int type_of_rx, const std::map< int32_t, Gps_Ephemeris > &new_eph)
Print RINEX annotation for GPS NAV message.
This class is a storage for the GPS UTC MODEL data as described in in IS-GPS-200M.
This class decodes a GPS NAV Data message as described in IS-GPS-200M.
This class is a storage for the GALILEO IONOSPHERIC data as described in Galileo ICD paragraph 5...
Definition: galileo_iono.h:37
void set_pre_2009_file(bool pre_2009_file)
Set processing for signals older than 2009.
This class is a storage and orbital model functions for the Galileo SV ephemeris data as described in...
This class is a storage for the GLONASS GNAV UTC MODEL data as described in GLONASS ICD (Edition 5...
This class is a storage for the GPS UTC MODEL data as described in IS-GPS-200M.
Definition: gps_utc_model.h:35
This class is a storage for the GLONASS SV ALMANAC data as described GLONASS ICD (Edition 5...
void log_rinex_nav_glo_gnav(int type_of_rx, const std::map< int32_t, Glonass_Gnav_Ephemeris > &new_glo_eph)
Print RINEX annotation for Glonass GNAV message.
This class is a storage for the GALILEO UTC MODEL data as described in Galileo ICD https://www...
std::vector< std::string > get_navfilename() const
Returns name of RINEX navigation file(s)
This class is a storage for the GPS IONOSPHERIC data as described in IS-GPS-200M. ...
Definition: gps_cnav_iono.h:34
void log_rinex_nav_bds_dnav(int type_of_rx, const std::map< int32_t, Beidou_Dnav_Ephemeris > &new_bds_eph)
Print RINEX annotation for BeiDou DNAV message.