From b567e139a662996b2c7a0f5bd52c79feaf277b48 Mon Sep 17 00:00:00 2001 From: Mathieu Favreau Date: Wed, 28 Jan 2026 16:41:21 +0000 Subject: [PATCH 1/8] Cleanup RINEX log to not use hardcoded signal combination --- src/algorithms/PVT/libs/rinex_printer.cc | 610 ++++++----------------- src/algorithms/PVT/libs/rinex_printer.h | 151 ------ 2 files changed, 164 insertions(+), 597 deletions(-) diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 95878591c..31733b86b 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -57,6 +57,8 @@ namespace { +using Constellation_Observables_Map = std::map>>; + const std::unordered_map satelliteSystem = { {"GPS", 'G'}, {"GLONASS", 'R'}, @@ -1345,7 +1347,7 @@ std::string get_leap_second_line(const Beidou_Dnav_Utc_Model& utc_model) void write_two_digits_string(const std::string& two_digit_string, bool remove_leading_zero, std::string& line) { - if (remove_leading_zero && two_digit_string.compare(0, 1, "0") == 0) + if (remove_leading_zero && boost::lexical_cast(two_digit_string) < 10) { line += std::string(1, ' '); line += two_digit_string.substr(1, 1); @@ -1357,9 +1359,9 @@ void write_two_digits_string(const std::string& two_digit_string, bool remove_le } -void add_svclk_to_line(const boost::posix_time::ptime& utc_time, bool log_seconds, int version, std::string& line) +void add_svclk_to_line(const boost::posix_time::ptime& system_time, bool log_seconds, int version, std::string& line) { - const std::string timestring = boost::posix_time::to_iso_string(utc_time); + const std::string timestring = boost::posix_time::to_iso_string(system_time); const std::string year(timestring, 0, 4); const std::string month(timestring, 4, 2); const std::string day(timestring, 6, 2); @@ -1387,7 +1389,7 @@ void add_svclk_to_line(const boost::posix_time::ptime& utc_time, bool log_second } -std::string get_obs_epoch_record_lines(const boost::posix_time::ptime& utc_time, double seconds, int version) +std::string get_obs_epoch_record_lines(const boost::posix_time::ptime& system_time, double seconds, int version) { // -------- EPOCH record std::string line = std::string(1, '>'); @@ -1395,7 +1397,7 @@ std::string get_obs_epoch_record_lines(const boost::posix_time::ptime& utc_time, // double utc_t = nav_msg.utc_time(nav_msg.sv_clock_correction(obs_time)); // const double gps_t = eph.sv_clock_correction(obs_time); - add_svclk_to_line(utc_time, false, version, line); + add_svclk_to_line(system_time, false, version, line); // Add extra 0 if seconds are < 10 if (seconds < 10) @@ -1473,7 +1475,7 @@ void add_constellation_obs_sat_record_lines(std::fstream& out, const std::string } } -void add_constellation_obs_sat_record_lines(std::fstream& out, const std::initializer_list& systems, const Constellation_Observables_Map& observables, int version) +void add_constellation_obs_sat_record_lines(std::fstream& out, const std::vector& systems, const Constellation_Observables_Map& observables, int version) { for (const auto& system : systems) { @@ -1567,6 +1569,41 @@ void add_obs_time_first_obs(std::fstream& out, const std::string& constellation, } +std::string get_datetime_v2(const boost::posix_time::ptime& p_utc_time) +{ + std::string line; + + const std::string timestring = boost::posix_time::to_iso_string(p_utc_time); + const std::string year(timestring, 2, 2); + const std::string month(timestring, 4, 2); + const std::string day(timestring, 6, 2); + const std::string hour(timestring, 9, 2); + const std::string minutes(timestring, 11, 2); + const std::string seconds(timestring, 13, 2); + + line += year; + line += std::string(1, ' '); + write_two_digits_string(month, true, line); + line += std::string(1, ' '); + write_two_digits_string(day, true, line); + line += std::string(1, ' '); + write_two_digits_string(hour, true, line); + line += std::string(1, ' '); + write_two_digits_string(minutes, true, line); + line += std::string(1, ' '); + write_two_digits_string(seconds, true, line); + line += std::string(1, '.'); + std::string decimal = "0"; + if (timestring.size() > 16) + { + decimal = std::string(timestring, 16, 1); + } + line += decimal; + + return line; +} + + void add_obs_sys_obs_type(std::fstream& out, char sys_char, int numberTypesObservations, @@ -1762,9 +1799,9 @@ void add_obs_glonass_code_phase_bias(std::fstream& out, out << line << '\n'; } -void add_obs_epoch_record(std::fstream& out, const boost::posix_time::ptime& utc_time, double seconds, int version, const Constellation_Observables_Map& constel_observables) +void add_obs_epoch_record(std::fstream& out, const boost::posix_time::ptime& system_time, double seconds, int version, const Constellation_Observables_Map& constel_observables) { - std::string line = get_obs_epoch_record_lines(utc_time, seconds, version); + std::string line = get_obs_epoch_record_lines(system_time, seconds, version); int32_t number_satellites = 0; @@ -2002,31 +2039,26 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, { rinex_obs_header(obsFile, gps_ephemeris_iter->second, rx_time); rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second); - log_rinex_nav(navFile, pvt_solver->gps_ephemeris_map); } else if ((flags.check_only_enabled(GPS_2S) || flags.check_only_enabled(GPS_L5)) && has_gps_cnav_eph) { rinex_obs_header(obsFile, gps_cnav_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->gps_cnav_iono, pvt_solver->gps_cnav_utc_model); - log_rinex_nav(navFile, pvt_solver->gps_cnav_ephemeris_map); } else if (only_galileo && has_galileo_eph) { rinex_obs_header(obsFile, galileo_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model); - log_rinex_nav(navFile, pvt_solver->galileo_ephemeris_map); } else if (only_glonass && has_glonass_eph) { rinex_obs_header(obsFile, glonass_gnav_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); - log_rinex_nav(navFile, pvt_solver->glonass_gnav_ephemeris_map); } else if (only_beidou && has_beidou_dnav_eph) { rinex_obs_header(obsFile, beidou_dnav_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->beidou_dnav_iono, pvt_solver->beidou_dnav_utc_model); - log_rinex_nav(navFile, pvt_solver->beidou_dnav_ephemeris_map); } else if ((flags.check_only_enabled(GPS_1C, GPS_2S) || flags.check_only_enabled(GPS_1C, GPS_L5) || @@ -2035,29 +2067,18 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, { rinex_obs_header(obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second); - - if (flags.check_any_enabled(GPS_L5)) - { - log_rinex_nav(navFile, pvt_solver->gps_ephemeris_map); - } - else - { - log_rinex_nav(navFile, pvt_solver->gps_cnav_ephemeris_map); - } } else if ((flags.check_only_enabled(GPS_1C, GAL_1B) || flags.check_only_enabled(GPS_1C, GAL_E5a) || flags.check_only_enabled(GPS_1C, GAL_E5b)) && has_gps_lnav_eph && has_galileo_eph) { rinex_obs_header(obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model); - log_rinex_nav(navFile, pvt_solver->gps_ephemeris_map, pvt_solver->galileo_ephemeris_map); } else if (flags.check_only_enabled(GPS_L5, GAL_E5a) && has_gps_cnav_eph && has_galileo_eph) { rinex_obs_header(obsFile, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, signal, signal); rinex_nav_header(navFile, pvt_solver->gps_cnav_iono, pvt_solver->gps_cnav_utc_model, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model); - log_rinex_nav(navFile, pvt_solver->gps_cnav_ephemeris_map, pvt_solver->galileo_ephemeris_map); } else if ((flags.check_only_enabled(GPS_1C, GLO_1G) || flags.check_only_enabled(GPS_1C, GLO_2G) || flags.check_only_enabled(GPS_1C, GLO_1G, GLO_2G)) && has_gps_lnav_eph && has_glonass_eph) @@ -2066,15 +2087,12 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, if (d_version == 3) { rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second, pvt_solver->glonass_gnav_utc_model); - log_rinex_nav(navFile, pvt_solver->gps_ephemeris_map, pvt_solver->glonass_gnav_ephemeris_map); } if (d_version == 2) { rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second); rinex_nav_header(navGloFile, pvt_solver->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); output_navfilename.push_back(navGlofilename); - log_rinex_nav(navFile, pvt_solver->gps_ephemeris_map); - log_rinex_nav(navGloFile, pvt_solver->glonass_gnav_ephemeris_map); } } else if ((flags.check_only_enabled(GLO_1G, GPS_2S) || flags.check_only_enabled(GLO_2G, GPS_2S)) && @@ -2082,14 +2100,12 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, { rinex_obs_header(obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->gps_cnav_iono, pvt_solver->gps_cnav_utc_model, pvt_solver->glonass_gnav_utc_model); - log_rinex_nav(navFile, pvt_solver->gps_cnav_ephemeris_map, pvt_solver->glonass_gnav_ephemeris_map); } else if ((flags.check_only_enabled(GAL_1B, GLO_1G) || flags.check_only_enabled(GAL_1B, GLO_2G)) && has_galileo_eph && has_glonass_eph) { rinex_obs_header(obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, rx_time, signal, signal); rinex_nav_header(navFile, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model, pvt_solver->glonass_gnav_utc_model); - log_rinex_nav(navFile, pvt_solver->galileo_ephemeris_map, pvt_solver->glonass_gnav_ephemeris_map); } else if ((flags.check_only_enabled(GPS_1C, GAL_1B, GPS_L5, GAL_E5a) || flags.check_only_enabled(GPS_1C, GAL_1B, GPS_L5, GAL_E5a, GAL_E6) || @@ -2098,13 +2114,11 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, { rinex_obs_header(obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, signal, signal); rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model); - log_rinex_nav(navFile, pvt_solver->gps_ephemeris_map, pvt_solver->galileo_ephemeris_map); } else if ((flags.check_only_enabled(GPS_1C, GAL_1B, GAL_E5a) || flags.check_only_enabled(GPS_1C, GAL_1B, GAL_E5b)) && has_gps_lnav_eph && has_galileo_eph) { rinex_obs_header(obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model); - log_rinex_nav(navFile, pvt_solver->gps_ephemeris_map, pvt_solver->galileo_ephemeris_map); } else if (flags.check_only_enabled(GPS_1C, GAL_E6) && has_gps_lnav_eph) { @@ -2113,14 +2127,12 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, // we have Galileo ephemeris, maybe from assistance rinex_obs_header(obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model); - log_rinex_nav(navFile, pvt_solver->gps_ephemeris_map, pvt_solver->galileo_ephemeris_map); } else { // we do not have galileo ephemeris, print only GPS data rinex_obs_header(obsFile, gps_ephemeris_iter->second, rx_time); rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second); - log_rinex_nav(navFile, pvt_solver->gps_ephemeris_map); } } else if (has_beidou && has_beidou_dnav_eph) @@ -2133,6 +2145,38 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, rinex_header_written = false; } + if (rinex_header_written) + { + if (has_gps_lnav_eph && !flags.check_any_enabled(GPS_L5)) // That's how it used to be, not sure why + { + log_rinex_nav(navFile, pvt_solver->gps_ephemeris_map); + } + else if (has_gps_cnav_eph) + { + log_rinex_nav(navFile, pvt_solver->gps_cnav_ephemeris_map); + } + + if (has_galileo_eph) + { + log_rinex_nav(navFile, pvt_solver->galileo_ephemeris_map); + } + if (has_glonass_eph) + { + if (d_version == 2 && output_navfilename.size() == 2) + { + log_rinex_nav(navGloFile, pvt_solver->glonass_gnav_ephemeris_map); + } + else + { + log_rinex_nav(navFile, pvt_solver->glonass_gnav_ephemeris_map); + } + } + if (has_beidou_dnav_eph) + { + log_rinex_nav(navFile, pvt_solver->beidou_dnav_ephemeris_map); + } + } + d_rinex_header_written = rinex_header_written; } @@ -2141,9 +2185,81 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, const auto constel_signal_flags = get_constel_signal_flags(flags); const auto constel_observables = get_constellation_observables_map(constel_signal_flags, gnss_observables_map); + double seconds; + boost::posix_time::ptime system_time; + + // Order is important + if (flags.check_any_enabled(GPS_1C)) + { + if (has_gps_lnav_eph) + { + system_time = Rinex_Printer::compute_GPS_time(gps_ephemeris_iter->second, rx_time); + seconds = fmod(rx_time, 60); + } + } + else if (has_gps) + { + if (has_gps_cnav_eph) + { + system_time = Rinex_Printer::compute_GPS_time(gps_cnav_ephemeris_iter->second, rx_time); + seconds = fmod(rx_time, 60); + } + } + else if (has_galileo) + { + if (has_galileo_eph) + { + system_time = Rinex_Printer::compute_Galileo_time(galileo_ephemeris_iter->second, rx_time); + seconds = fmod(rx_time, 60); + } + } + else if (has_glonass) + { + if (has_glonass_eph) + { + double int_sec = 0; + system_time = Rinex_Printer::compute_UTC_time(glonass_gnav_ephemeris_iter->second, rx_time); + seconds = modf(rx_time, &int_sec) + system_time.time_of_day().seconds(); + } + } + else if (has_beidou) + { + if (has_beidou_dnav_eph) + { + system_time = Rinex_Printer::compute_BDS_time(beidou_dnav_ephemeris_iter->second, rx_time); + seconds = fmod(rx_time, 60); + } + } + + if (system_time.is_not_a_date_time()) + { + return; + } + + std::vector constellations; + + if (has_gps) + { + constellations.emplace_back("GPS"); + } + if (has_galileo) + { + constellations.emplace_back("Galileo"); + } + if (has_glonass) + { + constellations.emplace_back("GLONASS"); + } + if (has_beidou) + { + constellations.emplace_back("Beidou"); + } + + add_obs_epoch_record(obsFile, system_time, seconds, d_version, constel_observables); + add_constellation_obs_sat_record_lines(obsFile, constellations, constel_observables, d_version); + if (flags.check_only_enabled(GPS_1C) && has_gps_lnav_eph) { - log_rinex_obs(obsFile, gps_ephemeris_iter->second, rx_time, constel_observables); if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->gps_utc_model, d_version)); @@ -2153,7 +2269,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } else if (flags.check_only_enabled(GPS_1C, GPS_2S) && has_gps_lnav_eph && has_gps_cnav_eph) { - log_rinex_obs(obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, rx_time, constel_observables); if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->gps_utc_model, d_version)); @@ -2163,7 +2278,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } else if (flags.check_only_enabled(GPS_1C, GPS_L5) && has_gps_lnav_eph && has_gps_cnav_eph) { - log_rinex_obs(obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, rx_time, constel_observables); if (!d_rinex_header_updated && ((pvt_solver->gps_cnav_utc_model.A0 != 0) || (pvt_solver->gps_utc_model.A0 != 0))) { if (pvt_solver->gps_cnav_utc_model.A0 != 0) @@ -2181,10 +2295,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } else if (flags.check_only_enabled(GPS_2S) || flags.check_only_enabled(GPS_L5) || flags.check_only_enabled(GPS_2S, GPS_L5)) { - if (has_gps_cnav_eph) - { - log_rinex_obs(obsFile, gps_cnav_ephemeris_iter->second, rx_time, constel_observables); - } if (!d_rinex_header_updated && (pvt_solver->gps_cnav_utc_model.A0 != 0)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->gps_cnav_utc_model)); @@ -2194,10 +2304,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } else if (flags.check_only_enabled(GPS_1C, GPS_2S, GPS_L5)) { - if (has_gps_lnav_eph && has_gps_cnav_eph) - { - log_rinex_obs(obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, rx_time, constel_observables); - } if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0) && (has_gps_lnav_eph)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->gps_utc_model, d_version)); @@ -2207,10 +2313,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } else if (only_galileo) { - if (has_galileo_eph) - { - log_rinex_obs(obsFile, galileo_ephemeris_iter->second, rx_time, constel_observables); - } if (!d_rinex_header_updated && (pvt_solver->galileo_utc_model.A0 != 0)) { update_nav_header(navFile, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model); @@ -2220,10 +2322,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } else if (only_glonass) { - if (has_glonass_eph) - { - log_rinex_obs(obsFile, glonass_gnav_ephemeris_iter->second, rx_time, constel_observables); - } if (!d_rinex_header_updated && (pvt_solver->glonass_gnav_utc_model.d_tau_c != 0)) { update_nav_header(navFile, pvt_solver->glonass_gnav_utc_model); @@ -2232,10 +2330,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } else if (only_beidou) { - if (has_beidou_dnav_eph) - { - log_rinex_obs(obsFile, beidou_dnav_ephemeris_iter->second, rx_time, constel_observables); - } if (!d_rinex_header_updated && (pvt_solver->beidou_dnav_utc_model.A0_UTC != 0)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->beidou_dnav_utc_model)); @@ -2246,7 +2340,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, else if ((flags.check_only_enabled(GPS_1C, GAL_1B) || flags.check_only_enabled(GPS_1C, GAL_1B, GAL_E6)) && has_gps_lnav_eph && has_galileo_eph) { - log_rinex_obs(obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, constel_observables); if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->gps_utc_model, d_version)); @@ -2257,7 +2350,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, else if ((flags.check_only_enabled(GPS_1C, GLO_1G) || flags.check_only_enabled(GPS_1C, GLO_2G) || flags.check_only_enabled(GPS_1C, GLO_1G, GLO_2G)) && has_gps_lnav_eph && has_glonass_eph) { - log_rinex_obs(obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, rx_time, constel_observables); if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->gps_utc_model, d_version)); @@ -2267,10 +2359,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } else if (flags.check_only_enabled(GPS_L5, GAL_E5a)) { - if ((has_gps_cnav_eph) && (has_galileo_eph)) - { - log_rinex_obs(obsFile, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, constel_observables); - } if (!d_rinex_header_updated && (pvt_solver->gps_cnav_utc_model.A0 != 0) && (pvt_solver->galileo_utc_model.A0 != 0)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->gps_cnav_utc_model)); @@ -2280,10 +2368,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } else if (flags.check_only_enabled(GAL_1B, GLO_1G) || flags.check_only_enabled(GAL_1B, GLO_2G)) { - if ((has_glonass_eph) && (has_galileo_eph)) - { - log_rinex_obs(obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, rx_time, constel_observables); - } if (!d_rinex_header_updated && (pvt_solver->galileo_utc_model.A0 != 0)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->galileo_utc_model)); @@ -2293,10 +2377,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } else if (flags.check_only_enabled(GPS_2S, GLO_1G) || flags.check_only_enabled(GPS_2S, GLO_2G)) { - if ((has_glonass_eph) && (has_gps_cnav_eph)) - { - log_rinex_obs(obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, rx_time, constel_observables); - } if (!d_rinex_header_updated && (pvt_solver->gps_cnav_utc_model.A0 != 0)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->gps_cnav_utc_model)); @@ -2308,7 +2388,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, { if (has_gps_lnav_eph && has_gps_cnav_eph && has_galileo_eph) { - log_rinex_obs(obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, constel_observables); if (!d_rinex_header_updated && ((pvt_solver->gps_cnav_utc_model.A0 != 0) || (pvt_solver->gps_utc_model.A0 != 0)) && (pvt_solver->galileo_utc_model.A0 != 0)) { if (pvt_solver->gps_cnav_utc_model.A0 != 0) @@ -2329,7 +2408,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, { if (has_gps_lnav_eph && has_galileo_eph) { - log_rinex_obs(obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, constel_observables); if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0) && (pvt_solver->galileo_utc_model.A0 != 0)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->gps_utc_model, d_version)); @@ -2340,10 +2418,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } else if (flags.check_only_enabled(GPS_1C, GAL_1B, GPS_L5, GAL_E5a, GAL_E6) || flags.check_only_enabled(GPS_1C, GAL_1B, GPS_2S, GPS_L5, GAL_E5a)) { - if (has_galileo_eph && has_gps_lnav_eph && has_gps_cnav_eph) - { - log_rinex_obs(obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, constel_observables); - } if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0) && (pvt_solver->galileo_utc_model.A0 != 0) && (has_gps_lnav_eph)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->gps_utc_model, d_version)); @@ -2356,7 +2430,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, if (has_galileo_eph) { // we have Galileo ephemeris, maybe from assistance - log_rinex_obs(obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, constel_observables); if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->gps_utc_model, d_version)); @@ -2367,7 +2440,6 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, else { // we do not have galileo ephemeris, print only GPS data - log_rinex_obs(obsFile, gps_ephemeris_iter->second, rx_time, constel_observables); if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0)) { update_obs_header(obsFile, get_leap_second_line(pvt_solver->gps_utc_model, d_version)); @@ -2400,14 +2472,14 @@ void Rinex_Printer::log_rinex_nav_gal_nav(const std::map& new_glo_eph) { - if (d_version == 3) - { - log_rinex_nav(navFile, new_glo_eph); - } - else if (d_version == 2) + if (d_version == 2 && output_navfilename.size() == 2) { log_rinex_nav(navGloFile, new_glo_eph); } + else + { + log_rinex_nav(navFile, new_glo_eph); + } } @@ -2780,29 +2852,15 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, co line += rightJustify(doub2for(utc_model.A0, 18, 2), 19); line += rightJustify(doub2for(utc_model.A1, 18, 2), 19); line += rightJustify(std::to_string(utc_model.tot), 9); - if (d_pre_2009_file == false) + if (d_pre_2009_file == false && eph.WN < 512) { - if (eph.WN < 512) + if (utc_model.WN_T == 0) { - if (utc_model.WN_T == 0) - { - line += rightJustify(std::to_string(eph.WN + 2048), 9); // valid from 2019 to 2029 - } - else - { - line += rightJustify(std::to_string(utc_model.WN_T + (eph.WN / 256) * 256 + 1024), 9); // valid from 2019 to 2029 - } + line += rightJustify(std::to_string(eph.WN + 2048), 9); // valid from 2019 to 2029 } else { - if (utc_model.WN_T == 0) - { - line += rightJustify(std::to_string(eph.WN + 1024), 9); // valid from 2019 to 2029 - } - else - { - line += rightJustify(std::to_string(utc_model.WN_T + (eph.WN / 256) * 256 + 1024), 9); // valid from 2009 to 2019 - } + line += rightJustify(std::to_string(utc_model.WN_T + (eph.WN / 256) * 256 + 1024), 9); // valid from 2019 to 2029 } } else @@ -3336,73 +3394,9 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(month) < 10) - { - line += std::string(1, ' '); - line += std::string(month, 1, 1); - } - else - { - line += month; - } - line += std::string(1, ' '); - if (boost::lexical_cast(day) < 10) - { - line += std::string(1, ' '); - line += std::string(day, 1, 1); - } - else - { - line += day; - } - line += std::string(1, ' '); - if (boost::lexical_cast(hour) < 10) - { - line += std::string(1, ' '); - line += std::string(hour, 1, 1); - } - else - { - line += hour; - } - line += std::string(1, ' '); - if (boost::lexical_cast(minutes) < 10) - { - line += std::string(1, ' '); - line += std::string(minutes, 1, 1); - } - else - { - line += minutes; - } - line += std::string(1, ' '); - if (boost::lexical_cast(seconds) < 10) - { - line += std::string(1, ' '); - line += std::string(seconds, 1, 1); - } - else - { - line += seconds; - } - line += std::string(1, '.'); - std::string decimal = std::string("0"); - if (timestring.size() > 16) - { - decimal = std::string(timestring, 16, 1); - } - line += decimal; + line += get_datetime_v2(p_utc_time); line += std::string(1, ' '); line += doub2for(eph.af0, 18, 2); line += std::string(1, ' '); @@ -3642,40 +3636,8 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(eph.E1B_HS).to_string(); + std::string E5B_HS = std::bitset<2>(eph.E5b_HS).to_string(); std::string E1B_DVS = std::to_string(eph.E1B_DVS); const std::string SVhealth_str = std::move(E5B_HS) + std::to_string(eph.E5b_DVS) + "11" + "1" + std::move(E1B_DVS) + std::move(E1B_HS) + std::to_string(eph.E1B_DVS); @@ -3701,75 +3663,12 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(month) < 10) - { - line += std::string(1, ' '); - line += std::string(month, 1, 1); - } - else - { - line += month; - } - line += std::string(1, ' '); - if (boost::lexical_cast(day) < 10) - { - line += std::string(1, ' '); - line += std::string(day, 1, 1); - } - else - { - line += day; - } - line += std::string(1, ' '); - if (boost::lexical_cast(hour) < 10) - { - line += std::string(1, ' '); - line += std::string(hour, 1, 1); - } - else - { - line += hour; - } - line += std::string(1, ' '); - if (boost::lexical_cast(minutes) < 10) - { - line += std::string(1, ' '); - line += std::string(minutes, 1, 1); - } - else - { - line += minutes; - } - line += std::string(1, ' '); - if (boost::lexical_cast(seconds) < 10) - { - line += std::string(1, ' '); - line += std::string(seconds, 1, 1); - } - else - { - line += seconds; - } - line += std::string(1, '.'); - std::string decimal = std::string("0"); - if (timestring.size() > 16) - { - decimal = std::string(timestring, 16, 1); - } - line += decimal; + line += get_datetime_v2(p_utc_time); line += std::string(1, ' '); line += doub2for(-eph.d_tau_c, 18, 2); line += std::string(1, ' '); @@ -3799,41 +3698,6 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& galileo_eph_map) -{ - Rinex_Printer::log_rinex_nav(out, gps_eph_map); - Rinex_Printer::log_rinex_nav(out, galileo_eph_map); -} - - -void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_cnav_eph_map, const std::map& galileo_eph_map) -{ - Rinex_Printer::log_rinex_nav(out, gps_cnav_eph_map); - Rinex_Printer::log_rinex_nav(out, galileo_eph_map); -} - - -void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& glonass_gnav_eph_map) const -{ - Rinex_Printer::log_rinex_nav(out, gps_eph_map); - Rinex_Printer::log_rinex_nav(out, glonass_gnav_eph_map); -} - - -void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_cnav_eph_map, const std::map& glonass_gnav_eph_map) -{ - Rinex_Printer::log_rinex_nav(out, gps_cnav_eph_map); - Rinex_Printer::log_rinex_nav(out, glonass_gnav_eph_map); -} - - -void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& galileo_eph_map, const std::map& glonass_gnav_eph_map) -{ - Rinex_Printer::log_rinex_nav(out, galileo_eph_map); - Rinex_Printer::log_rinex_nav(out, glonass_gnav_eph_map); -} - - void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) const { const auto& sys_char = satelliteSystem.at("Beidou"); @@ -4299,93 +4163,6 @@ void Rinex_Printer::update_obs_header(std::fstream& out, const std::string& leap } -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, double obs_time, const Constellation_Observables_Map& constel_observables) const -{ - double int_sec = 0; - const boost::posix_time::ptime p_glonass_time = Rinex_Printer::compute_UTC_time(eph, obs_time); - const double utc_sec = modf(obs_time, &int_sec) + p_glonass_time.time_of_day().seconds(); - add_obs_epoch_record(out, p_glonass_time, utc_sec, d_version, constel_observables); - add_constellation_obs_sat_record_lines(out, "GLONASS", constel_observables, d_version); -} - - -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& /*glonass_gnav_eph*/, double gps_obs_time, const Constellation_Observables_Map& constel_observables) const -{ - add_obs_epoch_record(out, Rinex_Printer::compute_GPS_time(gps_eph, gps_obs_time), fmod(gps_obs_time, 60), d_version, constel_observables); - add_constellation_obs_sat_record_lines(out, {"GPS", "GLONASS"}, constel_observables, d_version); -} - - -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& /*glonass_gnav_eph*/, double gps_obs_time, const Constellation_Observables_Map& constel_observables) const -{ - add_obs_epoch_record(out, Rinex_Printer::compute_GPS_time(gps_eph, gps_obs_time), fmod(gps_obs_time, 60), d_version, constel_observables); - add_constellation_obs_sat_record_lines(out, {"GPS", "GLONASS"}, constel_observables, d_version); -} - - -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& /*glonass_gnav_eph*/, double galileo_obs_time, const Constellation_Observables_Map& constel_observables) const -{ - add_obs_epoch_record(out, Rinex_Printer::compute_Galileo_time(galileo_eph, galileo_obs_time), fmod(galileo_obs_time, 60), d_version, constel_observables); - add_constellation_obs_sat_record_lines(out, {"Galileo", "GLONASS"}, constel_observables, d_version); -} - - -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, double obs_time, const Constellation_Observables_Map& constel_observables) const -{ - add_obs_epoch_record(out, Rinex_Printer::compute_GPS_time(eph, obs_time), fmod(obs_time, 60), d_version, constel_observables); - add_constellation_obs_sat_record_lines(out, "GPS", constel_observables, d_version); -} - - -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& eph, double obs_time, const Constellation_Observables_Map& constel_observables) const -{ - add_obs_epoch_record(out, Rinex_Printer::compute_GPS_time(eph, obs_time), fmod(obs_time, 60), d_version, constel_observables); - add_constellation_obs_sat_record_lines(out, "GPS", constel_observables, d_version); -} - - -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& /*eph_cnav*/, double obs_time, const Constellation_Observables_Map& constel_observables) const -{ - add_obs_epoch_record(out, Rinex_Printer::compute_GPS_time(eph, obs_time), fmod(obs_time, 60), d_version, constel_observables); - add_constellation_obs_sat_record_lines(out, "GPS", constel_observables, d_version); -} - - -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& eph, double obs_time, const Constellation_Observables_Map& constel_observables) const -{ - add_obs_epoch_record(out, Rinex_Printer::compute_Galileo_time(eph, obs_time), fmod(obs_time, 60), d_version, constel_observables); - add_constellation_obs_sat_record_lines(out, "Galileo", constel_observables, d_version); -} - - -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& /*galileo_eph*/, double gps_obs_time, const Constellation_Observables_Map& constel_observables) const -{ - add_obs_epoch_record(out, Rinex_Printer::compute_GPS_time(gps_eph, gps_obs_time), fmod(gps_obs_time, 60), d_version, constel_observables); - add_constellation_obs_sat_record_lines(out, {"GPS", "Galileo"}, constel_observables, d_version); -} - - -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& eph, const Galileo_Ephemeris& /*galileo_eph*/, double gps_obs_time, const Constellation_Observables_Map& constel_observables) const -{ - add_obs_epoch_record(out, Rinex_Printer::compute_GPS_time(eph, gps_obs_time), fmod(gps_obs_time, 60), d_version, constel_observables); - add_constellation_obs_sat_record_lines(out, {"GPS", "Galileo"}, constel_observables, d_version); -} - - -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& /*gps_cnav_eph*/, const Galileo_Ephemeris& /*galileo_eph*/, double gps_obs_time, const Constellation_Observables_Map& constel_observables) const -{ - add_obs_epoch_record(out, Rinex_Printer::compute_GPS_time(gps_eph, gps_obs_time), fmod(gps_obs_time, 60), d_version, constel_observables); - add_constellation_obs_sat_record_lines(out, {"GPS", "Galileo"}, constel_observables, d_version); -} - - -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Beidou_Dnav_Ephemeris& eph, double obs_time, const Constellation_Observables_Map& constel_observables) const -{ - add_obs_epoch_record(out, Rinex_Printer::compute_BDS_time(eph, obs_time), fmod(obs_time, 60), d_version, constel_observables); - add_constellation_obs_sat_record_lines(out, "Beidou", constel_observables, d_version); -} - - void Rinex_Printer::to_date_time(int32_t gps_week, int32_t gps_tow, int& year, int& month, int& day, int& hour, int& minute, int& second) const { // represents GPS time (week, TOW) in the date time format of the Gregorian calendar. @@ -4695,65 +4472,6 @@ boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Glonass_Gnav_Ephe } -double Rinex_Printer::get_leap_second(const Glonass_Gnav_Ephemeris& eph, double gps_obs_time) const -{ - double tod = 0.0; - const double glot2utc = 3 * 3600; - double obs_time_glot = 0.0; - int32_t i = 0; - double leap_second = 0; - int J = 0; - if (eph.d_N_T >= 1 && eph.d_N_T <= 366) - { - J = 1; - } - else if (eph.d_N_T >= 367 && eph.d_N_T <= 731) - { - J = 2; - } - else if (eph.d_N_T >= 732 && eph.d_N_T <= 1096) - { - J = 3; - } - else if (eph.d_N_T >= 1097 && eph.d_N_T <= 1461) - { - J = 4; - } - - // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end - obs_time_glot = gps_obs_time + glot2utc; - - // Get seconds of day in glonass time - tod = fmod(obs_time_glot, 86400); - - // Form date and time duration types - const boost::posix_time::time_duration t1(0, 0, tod); - const boost::gregorian::date d1(eph.d_yr - J + 1.0, 1, 1); - const boost::gregorian::days d2(eph.d_N_T - 1); - const boost::posix_time::ptime glo_time(d1 + d2, t1); - - // Convert to utc - const boost::posix_time::time_duration t2(0, 0, glot2utc); - boost::posix_time::ptime utc_time = glo_time - t2; - - // Adjust for leap second correction - for (i = 0; GLONASS_LEAP_SECONDS[i][0] > 0; i++) - { - const boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); - const boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); - const boost::posix_time::ptime ls_time(d3, t3); - if (utc_time >= ls_time) - { - // We subtract the leap second when going from gpst to utc - leap_second = fabs(GLONASS_LEAP_SECONDS[i][6]); - break; - } - } - - return leap_second; -} - - /* enum RINEX_enumMarkerType { diff --git a/src/algorithms/PVT/libs/rinex_printer.h b/src/algorithms/PVT/libs/rinex_printer.h index 6bb745cc8..cc69d20a5 100644 --- a/src/algorithms/PVT/libs/rinex_printer.h +++ b/src/algorithms/PVT/libs/rinex_printer.h @@ -38,7 +38,6 @@ #ifndef GNSS_SDR_RINEX_PRINTER_H #define GNSS_SDR_RINEX_PRINTER_H -#include "signal_enabled_flags.h" #include #include // for int32_t #include // for strtol, strtod @@ -73,8 +72,6 @@ class Gps_Navigation_Message; class Gps_Utc_Model; class Rtklib_Solver; -using Constellation_Observables_Map = std::map>>; - /*! * \brief Class that handles the generation of Receiver @@ -288,112 +285,6 @@ private: */ void rinex_sbs_header(std::fstream& out) const; - /* - * Writes GPS L1 observables into the RINEX file - */ - void log_rinex_obs(std::fstream& out, - const Gps_Ephemeris& eph, - double obs_time, - const Constellation_Observables_Map& constel_observables) const; - - /* - * Writes GPS L2 observables into the RINEX file - */ - void log_rinex_obs(std::fstream& out, - const Gps_CNAV_Ephemeris& eph, - double obs_time, - const Constellation_Observables_Map& constel_observables) const; - - /* - * Writes dual frequency GPS L1 and L2 observables into the RINEX file - */ - void log_rinex_obs(std::fstream& out, - const Gps_Ephemeris& eph, - const Gps_CNAV_Ephemeris& eph_cnav, - double obs_time, - const Constellation_Observables_Map& constel_observables) const; - - /* - * Writes Galileo observables into the RINEX file. - * Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B". - */ - void log_rinex_obs(std::fstream& out, - const Galileo_Ephemeris& eph, - double obs_time, - const Constellation_Observables_Map& constel_observables) const; - - /* - * Writes Mixed GPS / Galileo observables into the RINEX file - */ - void log_rinex_obs(std::fstream& out, - const Gps_Ephemeris& gps_eph, - const Galileo_Ephemeris& galileo_eph, - double gps_obs_time, - const Constellation_Observables_Map& constel_observables) const; - - /* - * Writes Mixed GPS / Galileo observables into the RINEX file - */ - void log_rinex_obs(std::fstream& out, - const Gps_CNAV_Ephemeris& eph, - const Galileo_Ephemeris& galileo_eph, - double gps_obs_time, - const Constellation_Observables_Map& constel_observables) const; - - /* - * Writes Mixed GPS / Galileo observables into the RINEX file - */ - void log_rinex_obs(std::fstream& out, - const Gps_Ephemeris& gps_eph, - const Gps_CNAV_Ephemeris& gps_cnav_eph, - const Galileo_Ephemeris& galileo_eph, - double gps_obs_time, - const Constellation_Observables_Map& constel_observables) const; - - /* - * Writes GLONASS GNAV observables into the RINEX file. - * Example: glonass_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B". - */ - void log_rinex_obs(std::fstream& out, - const Glonass_Gnav_Ephemeris& eph, - double obs_time, - const Constellation_Observables_Map& constel_observables) const; - - /* - * Writes Mixed GPS L1 C/A - GLONASS observables into the RINEX file - */ - void log_rinex_obs(std::fstream& out, - const Gps_Ephemeris& gps_eph, - const Glonass_Gnav_Ephemeris& glonass_gnav_eph, - double gps_obs_time, - const Constellation_Observables_Map& constel_observables) const; - - /* - * Writes Mixed GPS L2C - GLONASS observables into the RINEX file - */ - void log_rinex_obs(std::fstream& out, - const Gps_CNAV_Ephemeris& gps_eph, - const Glonass_Gnav_Ephemeris& glonass_gnav_eph, - double gps_obs_time, - const Constellation_Observables_Map& constel_observables) const; - - /* - * Writes Mixed Galileo/GLONASS observables into the RINEX file - */ - void log_rinex_obs(std::fstream& out, - const Galileo_Ephemeris& galileo_eph, - const Glonass_Gnav_Ephemeris& glonass_gnav_eph, - double galileo_obs_time, - const Constellation_Observables_Map& constel_observables) const; - - /* - * Writes BDS B1I observables into the RINEX file - */ - void log_rinex_obs(std::fstream& out, - const Beidou_Dnav_Ephemeris& eph, - double obs_time, - const Constellation_Observables_Map& constel_observables) const; - /* * Generates the GPS L1 C/A Navigation Data header */ @@ -528,47 +419,12 @@ private: void log_rinex_nav(std::fstream& out, const std::map& eph_map) const; - /* - * Writes data from the Mixed (GPS/Galileo) navigation message into the RINEX file - */ - void log_rinex_nav(std::fstream& out, - const std::map& gps_eph_map, - const std::map& galileo_eph_map); - - /* - * Writes data from the Mixed (GPS/Galileo) navigation message into the RINEX file - */ - void log_rinex_nav(std::fstream& out, - const std::map& gps_cnav_eph_map, - const std::map& galileo_eph_map); - /* * Writes data from the GLONASS GNAV navigation message into the RINEX file */ void log_rinex_nav(std::fstream& out, const std::map& eph_map) const; - /* - * Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file - */ - void log_rinex_nav(std::fstream& out, - const std::map& gps_eph_map, - const std::map& glonass_gnav_eph_map) const; - - /* - * Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file - */ - void log_rinex_nav(std::fstream& out, - const std::map& gps_cnav_eph_map, - const std::map& glonass_gnav_eph_map); - - /* - * Writes data from the Mixed (Galileo/ GLONASS GNAV) navigation message into the RINEX file - */ - void log_rinex_nav(std::fstream& out, - const std::map& galileo_eph_map, - const std::map& glonass_gnav_eph_map); - /* * Writes data from the Beidou B1I navigation message into the RINEX file */ @@ -613,13 +469,6 @@ private: */ boost::posix_time::ptime compute_UTC_time(const Glonass_Gnav_Ephemeris& eph, double obs_time) const; - /* - * Computes number of leap seconds of GPS relative to UTC - * \param eph GLONASS GNAV Ephemeris object - * \param gps_obs_time Observation time in GPS seconds of week - */ - double get_leap_second(const Glonass_Gnav_Ephemeris& eph, double gps_obs_time) const; - /* * Represents GPS time in the date time format. Leap years are considered, but leap seconds are not. */ From 8d70abb7af322ffd1db44700babbd1c6faaa3249 Mon Sep 17 00:00:00 2001 From: Mathieu Favreau Date: Wed, 28 Jan 2026 16:56:31 +0000 Subject: [PATCH 2/8] Only create Glonass file if needed --- src/algorithms/PVT/libs/rinex_printer.cc | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 31733b86b..9dc8bd893 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -1942,10 +1942,14 @@ Rinex_Printer::Rinex_Printer(uint32_t signal_enabled_flags, navGlofilename(getFilePath("RINEX_FILE_TYPE_GLO_NAV", base_name, base_rinex_path)), output_navfilename({navfilename}) { - const std::map fileMap = { + std::map fileMap = { {navfilename, navFile}, - {obsfilename, obsFile}, - {navGlofilename, navGloFile}}; + {obsfilename, obsFile}}; + + if (d_version == 2 && navfilename != navGlofilename) + { + fileMap.emplace(navGlofilename, navGloFile); + } bool all_open = true; @@ -1966,10 +1970,14 @@ Rinex_Printer::~Rinex_Printer() { DLOG(INFO) << "RINEX printer destructor called."; - const std::map fileMap = { + std::map fileMap = { {navfilename, navFile}, - {obsfilename, obsFile}, - {navGlofilename, navGloFile}}; + {obsfilename, obsFile}}; + + if (d_version == 2 && navfilename != navGlofilename) + { + fileMap.emplace(navGlofilename, navGloFile); + } std::map filePosMap; @@ -2162,7 +2170,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } if (has_glonass_eph) { - if (d_version == 2 && output_navfilename.size() == 2) + if (d_version == 2 && navfilename != navGlofilename) { log_rinex_nav(navGloFile, pvt_solver->glonass_gnav_ephemeris_map); } @@ -2472,7 +2480,7 @@ void Rinex_Printer::log_rinex_nav_gal_nav(const std::map& new_glo_eph) { - if (d_version == 2 && output_navfilename.size() == 2) + if (d_version == 2 && navfilename != navGlofilename) { log_rinex_nav(navGloFile, new_glo_eph); } From 8ef03fe3cee604224e64e96e95834ac56b74648c Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Tue, 3 Feb 2026 14:40:12 +0100 Subject: [PATCH 3/8] GPS L2CM local replica now includes GPS L2CL contribution zeroing in tracking loops --- src/algorithms/libs/gps_l2c_signal_replica.cc | 121 ++++++++++++++++++ src/algorithms/libs/gps_l2c_signal_replica.h | 6 + .../gnuradio_blocks/dll_pll_veml_tracking.cc | 7 +- src/core/system_parameters/GPS_L2C.h | 20 +-- 4 files changed, 142 insertions(+), 12 deletions(-) diff --git a/src/algorithms/libs/gps_l2c_signal_replica.cc b/src/algorithms/libs/gps_l2c_signal_replica.cc index de7df8128..da5c9b209 100644 --- a/src/algorithms/libs/gps_l2c_signal_replica.cc +++ b/src/algorithms/libs/gps_l2c_signal_replica.cc @@ -53,6 +53,127 @@ void gps_l2c_m_code_gen_complex(own::span> dest, uint32_t pr } } +void gps_l2c_m_code_gen_float_cl_zeroed(own::span dest, uint32_t prn) +{ + // dest must be at least GPS_L2_M_CODE_LENGTH_CHIPS_L_ZEROED + // Layout: [ CM0, 0, CM1, 0, ..., CM10229, 0 ] -> 20460 "chips" + + std::array code_aux{}; + + if (prn > 0U && prn < 51U) + { + gps_l2c_m_code(code_aux, prn); + } + else + { + // out of range -> output zeros + const int32_t n = std::min(static_cast(dest.size()), + GPS_L2_M_CODE_LENGTH_CHIPS_L_ZEROED); + for (int32_t i = 0; i < n; i++) + { + dest[i] = 0.0F; + } + return; + } + + const int32_t n = std::min(static_cast(dest.size()), + GPS_L2_M_CODE_LENGTH_CHIPS_L_ZEROED); + + for (int32_t i = 0; i < n; i++) + { + const bool is_cm_slot = ((i & 1) == 0); // even indices: CM, odd: CL (zeroed) + + if (is_cm_slot) + { + const int32_t cm_idx = (i >> 1); // i/2 in [0..10229] + dest[i] = 1.0F - 2.0F * static_cast(code_aux[cm_idx]); + } + else + { + dest[i] = 0.0F; // CL slot zeroed + } + } +} + + +void gps_l2c_m_code_gen_complex_sampled( + own::span> dest, + uint32_t prn, + int32_t sampling_freq, + bool cl_zeroed) +{ + constexpr int32_t codeLength = GPS_L2_M_CODE_LENGTH_CHIPS; // 10230 + constexpr float tc_cm = 1.0F / static_cast(GPS_L2_M_CODE_RATE_CPS); // 511.5 kcps + constexpr float tc_l2c = tc_cm * 0.5F; // 1.023 Mcps (half-chip) + + const float ts = 1.0F / static_cast(sampling_freq); + + // --- Load CM (M-code) --- + std::array code_aux{}; + if (prn > 0U && prn < 51U) + { + gps_l2c_m_code(code_aux, prn); + } + else + { + for (auto &v : dest) + { + v = std::complex(0.0F, 0.0F); + } + return; + } + + // --- Effective chip configuration --- + const int32_t chips_per_epoch = cl_zeroed ? (2 * codeLength) : codeLength; + const float tc_used = cl_zeroed ? tc_l2c : tc_cm; + + const auto samplesPerCode = static_cast( + static_cast(sampling_freq) / + (static_cast(1.0F / tc_used) / static_cast(chips_per_epoch))); + + const int32_t nSamples = + std::min(static_cast(dest.size()), samplesPerCode); + + for (int32_t i = 0; i < nSamples; i++) + { + int32_t slotIndex = + static_cast(std::floor(ts * static_cast(i) / tc_used)); + + // Avoid rounding overflow at last sample + if (i == nSamples - 1) + { + slotIndex = chips_per_epoch - 1; + } + + if (!cl_zeroed) + { + // --- Classic CM-only (511.5 kcps) --- + const int32_t cm_idx = std::min(slotIndex, codeLength - 1); + dest[i] = std::complex(0.0F, + 1.0F - 2.0F * code_aux[cm_idx]); + } + else + { + // --- L2C effective 1.023 Mcps, CL zeroed --- + const bool is_cm_slot = ((slotIndex & 1) == 0); + + if (is_cm_slot) + { + const int32_t cm_idx = + std::min(slotIndex >> 1, codeLength - 1); + + dest[i] = std::complex(0.0F, + 1.0F - 2.0F * code_aux[cm_idx]); + } + else + { + // CL slot → zeroed + dest[i] = std::complex(0.0F, 0.0F); + } + } + } +} + void gps_l2c_m_code_gen_float(own::span dest, uint32_t prn) { diff --git a/src/algorithms/libs/gps_l2c_signal_replica.h b/src/algorithms/libs/gps_l2c_signal_replica.h index 0913f7cd8..8f6c08cfe 100644 --- a/src/algorithms/libs/gps_l2c_signal_replica.h +++ b/src/algorithms/libs/gps_l2c_signal_replica.h @@ -40,9 +40,15 @@ void gps_l2c_m_code_gen_complex(own::span> dest, uint32_t pr //! Generates float GPS L2C M code for the desired SV ID void gps_l2c_m_code_gen_float(own::span dest, uint32_t prn); +//! Generates float GPS L2C M code with double chip rate and L component zeroed for the desired SV ID +void gps_l2c_m_code_gen_float_cl_zeroed(own::span dest, uint32_t prn); + + //! Generates complex GPS L2C M code for the desired SV ID, and sampled to specific sampling frequency void gps_l2c_m_code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq); +//! Generates complex GPS L2C M code for the desired SV ID, and sampled to specific sampling frequency, optionally zeroing CL slots +void gps_l2c_m_code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq, bool cl_zeroed); /** \} */ /** \} */ diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index 5557f3c1a..12652f2d1 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -152,7 +152,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) this->set_msg_handler( pmt::mp("telemetry_to_trk"), #if HAS_GENERIC_LAMBDA - [this](auto &&PH1) { msg_handler_telemetry_to_trk(PH1); }); + [this](auto &&PH1) + { msg_handler_telemetry_to_trk(PH1); }); #else #if USE_BOOST_BIND_PLACEHOLDERS boost::bind(&dll_pll_veml_tracking::msg_handler_telemetry_to_trk, this, boost::placeholders::_1)); @@ -212,7 +213,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) // GPS L2C has 1 trk symbol (20 ms) per tlm bit, no symbol integration required d_symbols_per_bit = GPS_L2_SAMPLES_PER_SYMBOL; d_correlation_length_ms = 20; - d_code_samples_per_chip = 1; + d_code_samples_per_chip = 2; // for CM code with CL slots zeroed // GPS L2 does not have pilot component nor secondary code d_secondary = false; d_trk_parameters.track_pilot = false; @@ -736,7 +737,7 @@ void dll_pll_veml_tracking::start_tracking() } else if (d_systemName == "GPS" && d_signal_type == "2S") { - gps_l2c_m_code_gen_float(d_tracking_code, d_acquisition_gnss_synchro->PRN); + gps_l2c_m_code_gen_float_cl_zeroed(d_tracking_code, d_acquisition_gnss_synchro->PRN); } else if (d_systemName == "GPS" && d_signal_type == "L5") { diff --git a/src/core/system_parameters/GPS_L2C.h b/src/core/system_parameters/GPS_L2C.h index f9a2732d8..4dd2cd1dc 100644 --- a/src/core/system_parameters/GPS_L2C.h +++ b/src/core/system_parameters/GPS_L2C.h @@ -32,15 +32,17 @@ // carrier and code frequencies -constexpr double GPS_L2_FREQ_HZ = FREQ2; //!< L2 [Hz] -constexpr double GPS_L2_L_PERIOD_S = 1.5; //!< GPS L2 L code period [seconds] -constexpr double GPS_L2_M_CODE_RATE_CPS = 0.5115e6; //!< GPS L2 M code rate [chips/s] -constexpr double GPS_L2_M_PERIOD_S = 0.02; //!< GPS L2 M code period [seconds] -constexpr double GPS_L2_L_CODE_RATE_CPS = 0.5115e6; //!< GPS L2 L code rate [chips/s] -constexpr uint32_t GPS_L2_M_CODE_PERIOD_MS = 20; //!< GPS L2 L code period [ms] -constexpr int32_t GPS_L2_M_CODE_LENGTH_CHIPS = 10230; //!< GPS L2 M code length [chips] -constexpr int32_t GPS_L2_L_CODE_LENGTH_CHIPS = 767250; //!< GPS L2 L code length [chips] -constexpr int32_t GPS_L2_CNAV_DATA_PAGE_BITS = 300; //!< GPS L2 CNAV page length, including preamble and CRC [bits] +constexpr double GPS_L2_FREQ_HZ = FREQ2; //!< L2 [Hz] +constexpr double GPS_L2_L_PERIOD_S = 1.5; //!< GPS L2 L code period [seconds] +constexpr double GPS_L2_M_CODE_RATE_CPS = 0.5115e6; //!< GPS L2 M code rate [chips/s] +constexpr double GPS_L2_M_CODE_RATE_L_ZEROED_CPS = 1.023e6; //!< GPS L2 M code rate with L2 M Zeroed [chips/s] +constexpr double GPS_L2_M_PERIOD_S = 0.02; //!< GPS L2 M code period [seconds] +constexpr double GPS_L2_L_CODE_RATE_CPS = 0.5115e6; //!< GPS L2 L code rate [chips/s] +constexpr uint32_t GPS_L2_M_CODE_PERIOD_MS = 20; //!< GPS L2 L code period [ms] +constexpr int32_t GPS_L2_M_CODE_LENGTH_CHIPS = 10230; //!< GPS L2 M code length [chips] +constexpr int32_t GPS_L2_M_CODE_LENGTH_CHIPS_L_ZEROED = 2 * GPS_L2_M_CODE_LENGTH_CHIPS; //!< GPS L2 M code length with L2 CL zeroed [chips] +constexpr int32_t GPS_L2_L_CODE_LENGTH_CHIPS = 767250; //!< GPS L2 L code length [chips] +constexpr int32_t GPS_L2_CNAV_DATA_PAGE_BITS = 300; //!< GPS L2 CNAV page length, including preamble and CRC [bits] constexpr int32_t GPS_L2_SYMBOLS_PER_BIT = 2; constexpr int32_t GPS_L2_SAMPLES_PER_SYMBOL = 1; constexpr int32_t GPS_L2_CNAV_DATA_PAGE_SYMBOLS = 600; From 360cb61a6b191a54140743ab24d317f3249efe5b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 3 Feb 2026 14:59:56 +0100 Subject: [PATCH 4/8] Fix formatting --- .../tracking/gnuradio_blocks/dll_pll_veml_tracking.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index 12652f2d1..5f97938bf 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -152,8 +152,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) this->set_msg_handler( pmt::mp("telemetry_to_trk"), #if HAS_GENERIC_LAMBDA - [this](auto &&PH1) - { msg_handler_telemetry_to_trk(PH1); }); + [this](auto &&PH1) { msg_handler_telemetry_to_trk(PH1); }); #else #if USE_BOOST_BIND_PLACEHOLDERS boost::bind(&dll_pll_veml_tracking::msg_handler_telemetry_to_trk, this, boost::placeholders::_1)); From e391905e24b2055da403a065b279e2733e85cef6 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 3 Feb 2026 15:45:08 +0100 Subject: [PATCH 5/8] Update changelog --- docs/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index eccdb59c8..584b8c23a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -27,6 +27,7 @@ All notable changes to GNSS-SDR will be documented in this file. - Added a cycle-slip detector, with events reported in internal logging and RINEX observation files. This introduces a new field in `Gnss_Synchro` and in the corresponding `.proto` definition. +- Improved tracking of GPS L2C(M) signals. ### Improvements in Maintainability: From 9ba0527a4da0c7cfecd8fcfbc8b625e8844a024b Mon Sep 17 00:00:00 2001 From: Mathieu Favreau Date: Tue, 3 Feb 2026 20:31:01 +0000 Subject: [PATCH 6/8] Cleanup signal enabled flags --- .../PVT/gnuradio_blocks/rtklib_pvt_gs.cc | 3 +- src/algorithms/PVT/libs/rinex_printer.cc | 108 ++++++++---------- src/algorithms/PVT/libs/rinex_printer.h | 4 +- src/algorithms/PVT/libs/rtcm_printer.cc | 35 +++--- src/algorithms/PVT/libs/rtcm_printer.h | 4 +- .../PVT/libs/signal_enabled_flags.cc | 12 +- .../PVT/libs/signal_enabled_flags.h | 10 ++ .../pvt/rtcm_printer_test.cc | 5 +- 8 files changed, 93 insertions(+), 88 deletions(-) diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc index 4687ef8fc..eac5bd6e8 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc @@ -342,7 +342,7 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels, const std::string rtcm_dump_filename = d_dump_filename; if (conf_.flag_rtcm_server || conf_.flag_rtcm_tty_port || conf_.rtcm_output_file_enabled) { - d_rtcm_printer = std::make_unique(rtcm_dump_filename, conf_.rtcm_output_file_enabled, conf_.flag_rtcm_server, conf_.flag_rtcm_tty_port, conf_.rtcm_tcp_port, conf_.rtcm_station_id, conf_.rtcm_dump_devname, true, conf_.rtcm_output_file_path); + d_rtcm_printer = std::make_unique(rtcm_dump_filename, conf_.rtcm_output_file_enabled, conf_.flag_rtcm_server, conf_.flag_rtcm_tty_port, conf_.rtcm_tcp_port, conf_.rtcm_station_id, conf_.rtcm_dump_devname, d_signal_enabled_flags, true, conf_.rtcm_output_file_path); std::map rtcm_msg_rate_ms = conf_.rtcm_msg_rate_ms; if (rtcm_msg_rate_ms.find(1019) != rtcm_msg_rate_ms.end()) { @@ -2431,7 +2431,6 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item d_rtcm_printer->Print_Rtcm_Messages(d_user_pvt_solver.get(), d_gnss_observables_map, d_rx_time, - d_signal_enabled_flags, rtcm_MSM_enabled, rtcm_MT1019_enabled, rtcm_MT1020_enabled, diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 9dc8bd893..232b34eb2 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -35,7 +35,6 @@ #include "gps_navigation_message.h" #include "gps_utc_model.h" #include "rtklib_solver.h" -#include "signal_enabled_flags.h" #include #include #include @@ -1930,13 +1929,13 @@ Rinex_Printer::Rinex_Printer(uint32_t signal_enabled_flags, int version, bool pre_2009_file) : observationType(getObservationTypes()), observationCode(getObservationCodes()), + d_flags(signal_enabled_flags), d_version(get_version(signal_enabled_flags, version)), d_stringVersion(d_version == 2 ? "2.11" : "3.02"), // Only version 2.11 and 3.02 d_fake_cnav_iode(1), d_rinex_header_updated(false), d_rinex_header_written(false), d_pre_2009_file(pre_2009_file), - d_signal_enabled_flags(signal_enabled_flags), navfilename(getNavFilePath(signal_enabled_flags, d_version, base_name, base_rinex_path)), obsfilename(getFilePath("RINEX_FILE_TYPE_OBS", base_name, base_rinex_path)), navGlofilename(getFilePath("RINEX_FILE_TYPE_GLO_NAV", base_name, base_rinex_path)), @@ -2023,16 +2022,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, const auto glonass_gnav_ephemeris_iter = pvt_solver->glonass_gnav_ephemeris_map.cbegin(); const auto beidou_dnav_ephemeris_iter = pvt_solver->beidou_dnav_ephemeris_map.cbegin(); - const Signal_Enabled_Flags flags(d_signal_enabled_flags); - const auto signal = enabled_signal_flags_to_string(flags); - const auto has_gps = flags.check_any_enabled(GPS_1C, GPS_2S, GPS_L5); - const auto has_galileo = flags.check_any_enabled(GAL_1B, GAL_E5a, GAL_E5b, GAL_E6); - const auto has_glonass = flags.check_any_enabled(GLO_1G, GLO_2G); - const auto has_beidou = flags.check_any_enabled(BDS_B1, BDS_B3); - const auto only_galileo = has_galileo && !(has_gps || has_glonass || has_beidou); - const auto only_glonass = has_glonass && !(has_gps || has_galileo || has_beidou); - const auto only_beidou = has_beidou && !(has_gps || has_galileo || has_glonass); - + const auto signal = enabled_signal_flags_to_string(d_flags); const bool has_gps_lnav_eph = !pvt_solver->gps_ephemeris_map.empty(); const bool has_gps_cnav_eph = !pvt_solver->gps_cnav_ephemeris_map.empty(); const bool has_galileo_eph = !pvt_solver->galileo_ephemeris_map.empty(); @@ -2043,52 +2033,52 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, { bool rinex_header_written = true; - if (flags.check_only_enabled(GPS_1C) && has_gps_lnav_eph) + if (d_flags.check_only_enabled(GPS_1C) && has_gps_lnav_eph) { rinex_obs_header(obsFile, gps_ephemeris_iter->second, rx_time); rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second); } - else if ((flags.check_only_enabled(GPS_2S) || flags.check_only_enabled(GPS_L5)) && has_gps_cnav_eph) + else if ((d_flags.check_only_enabled(GPS_2S) || d_flags.check_only_enabled(GPS_L5)) && has_gps_cnav_eph) { rinex_obs_header(obsFile, gps_cnav_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->gps_cnav_iono, pvt_solver->gps_cnav_utc_model); } - else if (only_galileo && has_galileo_eph) + else if (d_flags.only_galileo && has_galileo_eph) { rinex_obs_header(obsFile, galileo_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model); } - else if (only_glonass && has_glonass_eph) + else if (d_flags.only_glonass && has_glonass_eph) { rinex_obs_header(obsFile, glonass_gnav_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); } - else if (only_beidou && has_beidou_dnav_eph) + else if (d_flags.only_beidou && has_beidou_dnav_eph) { rinex_obs_header(obsFile, beidou_dnav_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->beidou_dnav_iono, pvt_solver->beidou_dnav_utc_model); } - else if ((flags.check_only_enabled(GPS_1C, GPS_2S) || - flags.check_only_enabled(GPS_1C, GPS_L5) || - flags.check_only_enabled(GPS_1C, GPS_2S, GPS_L5)) && + else if ((d_flags.check_only_enabled(GPS_1C, GPS_2S) || + d_flags.check_only_enabled(GPS_1C, GPS_L5) || + d_flags.check_only_enabled(GPS_1C, GPS_2S, GPS_L5)) && has_gps_lnav_eph && has_gps_cnav_eph) { rinex_obs_header(obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second); } - else if ((flags.check_only_enabled(GPS_1C, GAL_1B) || flags.check_only_enabled(GPS_1C, GAL_E5a) || flags.check_only_enabled(GPS_1C, GAL_E5b)) && + else if ((d_flags.check_only_enabled(GPS_1C, GAL_1B) || d_flags.check_only_enabled(GPS_1C, GAL_E5a) || d_flags.check_only_enabled(GPS_1C, GAL_E5b)) && has_gps_lnav_eph && has_galileo_eph) { rinex_obs_header(obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model); } - else if (flags.check_only_enabled(GPS_L5, GAL_E5a) && + else if (d_flags.check_only_enabled(GPS_L5, GAL_E5a) && has_gps_cnav_eph && has_galileo_eph) { rinex_obs_header(obsFile, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, signal, signal); rinex_nav_header(navFile, pvt_solver->gps_cnav_iono, pvt_solver->gps_cnav_utc_model, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model); } - else if ((flags.check_only_enabled(GPS_1C, GLO_1G) || flags.check_only_enabled(GPS_1C, GLO_2G) || flags.check_only_enabled(GPS_1C, GLO_1G, GLO_2G)) && + else if ((d_flags.check_only_enabled(GPS_1C, GLO_1G) || d_flags.check_only_enabled(GPS_1C, GLO_2G) || d_flags.check_only_enabled(GPS_1C, GLO_1G, GLO_2G)) && has_gps_lnav_eph && has_glonass_eph) { rinex_obs_header(obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, rx_time, signal); @@ -2103,32 +2093,32 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, output_navfilename.push_back(navGlofilename); } } - else if ((flags.check_only_enabled(GLO_1G, GPS_2S) || flags.check_only_enabled(GLO_2G, GPS_2S)) && + else if ((d_flags.check_only_enabled(GLO_1G, GPS_2S) || d_flags.check_only_enabled(GLO_2G, GPS_2S)) && has_gps_cnav_eph && has_glonass_eph) { rinex_obs_header(obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->gps_cnav_iono, pvt_solver->gps_cnav_utc_model, pvt_solver->glonass_gnav_utc_model); } - else if ((flags.check_only_enabled(GAL_1B, GLO_1G) || flags.check_only_enabled(GAL_1B, GLO_2G)) && + else if ((d_flags.check_only_enabled(GAL_1B, GLO_1G) || d_flags.check_only_enabled(GAL_1B, GLO_2G)) && has_galileo_eph && has_glonass_eph) { rinex_obs_header(obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, rx_time, signal, signal); rinex_nav_header(navFile, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model, pvt_solver->glonass_gnav_utc_model); } - else if ((flags.check_only_enabled(GPS_1C, GAL_1B, GPS_L5, GAL_E5a) || - flags.check_only_enabled(GPS_1C, GAL_1B, GPS_L5, GAL_E5a, GAL_E6) || - flags.check_only_enabled(GPS_1C, GAL_1B, GPS_2S, GPS_L5, GAL_E5a)) && + else if ((d_flags.check_only_enabled(GPS_1C, GAL_1B, GPS_L5, GAL_E5a) || + d_flags.check_only_enabled(GPS_1C, GAL_1B, GPS_L5, GAL_E5a, GAL_E6) || + d_flags.check_only_enabled(GPS_1C, GAL_1B, GPS_2S, GPS_L5, GAL_E5a)) && has_gps_lnav_eph && has_gps_cnav_eph && has_galileo_eph) { rinex_obs_header(obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, signal, signal); rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model); } - else if ((flags.check_only_enabled(GPS_1C, GAL_1B, GAL_E5a) || flags.check_only_enabled(GPS_1C, GAL_1B, GAL_E5b)) && has_gps_lnav_eph && has_galileo_eph) + else if ((d_flags.check_only_enabled(GPS_1C, GAL_1B, GAL_E5a) || d_flags.check_only_enabled(GPS_1C, GAL_1B, GAL_E5b)) && has_gps_lnav_eph && has_galileo_eph) { rinex_obs_header(obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, rx_time, signal); rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second, pvt_solver->galileo_iono, pvt_solver->galileo_utc_model); } - else if (flags.check_only_enabled(GPS_1C, GAL_E6) && has_gps_lnav_eph) + else if (d_flags.check_only_enabled(GPS_1C, GAL_E6) && has_gps_lnav_eph) { if (has_galileo_eph) { @@ -2143,7 +2133,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, rinex_nav_header(navFile, pvt_solver->gps_iono, pvt_solver->gps_utc_model, gps_ephemeris_iter->second); } } - else if (has_beidou && has_beidou_dnav_eph) + else if (d_flags.has_beidou && has_beidou_dnav_eph) { rinex_obs_header(obsFile, beidou_dnav_ephemeris_iter->second, rx_time, signal); // Not implemented for beidou @@ -2155,7 +2145,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, if (rinex_header_written) { - if (has_gps_lnav_eph && !flags.check_any_enabled(GPS_L5)) // That's how it used to be, not sure why + if (has_gps_lnav_eph && !d_flags.check_any_enabled(GPS_L5)) // That's how it used to be, not sure why { log_rinex_nav(navFile, pvt_solver->gps_ephemeris_map); } @@ -2190,14 +2180,14 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, if (d_rinex_header_written && flag_write_RINEX_obs_output) // The header is already written, we can now log the navigation message data { - const auto constel_signal_flags = get_constel_signal_flags(flags); + const auto constel_signal_flags = get_constel_signal_flags(d_flags); const auto constel_observables = get_constellation_observables_map(constel_signal_flags, gnss_observables_map); double seconds; boost::posix_time::ptime system_time; // Order is important - if (flags.check_any_enabled(GPS_1C)) + if (d_flags.check_any_enabled(GPS_1C)) { if (has_gps_lnav_eph) { @@ -2205,7 +2195,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, seconds = fmod(rx_time, 60); } } - else if (has_gps) + else if (d_flags.has_gps) { if (has_gps_cnav_eph) { @@ -2213,7 +2203,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, seconds = fmod(rx_time, 60); } } - else if (has_galileo) + else if (d_flags.has_galileo) { if (has_galileo_eph) { @@ -2221,7 +2211,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, seconds = fmod(rx_time, 60); } } - else if (has_glonass) + else if (d_flags.has_glonass) { if (has_glonass_eph) { @@ -2230,7 +2220,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, seconds = modf(rx_time, &int_sec) + system_time.time_of_day().seconds(); } } - else if (has_beidou) + else if (d_flags.has_beidou) { if (has_beidou_dnav_eph) { @@ -2246,19 +2236,19 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, std::vector constellations; - if (has_gps) + if (d_flags.has_gps) { constellations.emplace_back("GPS"); } - if (has_galileo) + if (d_flags.has_galileo) { constellations.emplace_back("Galileo"); } - if (has_glonass) + if (d_flags.has_glonass) { constellations.emplace_back("GLONASS"); } - if (has_beidou) + if (d_flags.has_beidou) { constellations.emplace_back("Beidou"); } @@ -2266,7 +2256,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, add_obs_epoch_record(obsFile, system_time, seconds, d_version, constel_observables); add_constellation_obs_sat_record_lines(obsFile, constellations, constel_observables, d_version); - if (flags.check_only_enabled(GPS_1C) && has_gps_lnav_eph) + if (d_flags.check_only_enabled(GPS_1C) && has_gps_lnav_eph) { if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0)) { @@ -2275,7 +2265,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; } } - else if (flags.check_only_enabled(GPS_1C, GPS_2S) && has_gps_lnav_eph && has_gps_cnav_eph) + else if (d_flags.check_only_enabled(GPS_1C, GPS_2S) && has_gps_lnav_eph && has_gps_cnav_eph) { if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0)) { @@ -2284,7 +2274,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; } } - else if (flags.check_only_enabled(GPS_1C, GPS_L5) && has_gps_lnav_eph && has_gps_cnav_eph) + else if (d_flags.check_only_enabled(GPS_1C, GPS_L5) && has_gps_lnav_eph && has_gps_cnav_eph) { if (!d_rinex_header_updated && ((pvt_solver->gps_cnav_utc_model.A0 != 0) || (pvt_solver->gps_utc_model.A0 != 0))) { @@ -2301,7 +2291,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; } } - else if (flags.check_only_enabled(GPS_2S) || flags.check_only_enabled(GPS_L5) || flags.check_only_enabled(GPS_2S, GPS_L5)) + else if (d_flags.check_only_enabled(GPS_2S) || d_flags.check_only_enabled(GPS_L5) || d_flags.check_only_enabled(GPS_2S, GPS_L5)) { if (!d_rinex_header_updated && (pvt_solver->gps_cnav_utc_model.A0 != 0)) { @@ -2310,7 +2300,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; } } - else if (flags.check_only_enabled(GPS_1C, GPS_2S, GPS_L5)) + else if (d_flags.check_only_enabled(GPS_1C, GPS_2S, GPS_L5)) { if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0) && (has_gps_lnav_eph)) { @@ -2319,7 +2309,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; } } - else if (only_galileo) + else if (d_flags.only_galileo) { if (!d_rinex_header_updated && (pvt_solver->galileo_utc_model.A0 != 0)) { @@ -2328,7 +2318,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; } } - else if (only_glonass) + else if (d_flags.only_glonass) { if (!d_rinex_header_updated && (pvt_solver->glonass_gnav_utc_model.d_tau_c != 0)) { @@ -2336,7 +2326,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; } } - else if (only_beidou) + else if (d_flags.only_beidou) { if (!d_rinex_header_updated && (pvt_solver->beidou_dnav_utc_model.A0_UTC != 0)) { @@ -2345,7 +2335,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; } } - else if ((flags.check_only_enabled(GPS_1C, GAL_1B) || flags.check_only_enabled(GPS_1C, GAL_1B, GAL_E6)) && + else if ((d_flags.check_only_enabled(GPS_1C, GAL_1B) || d_flags.check_only_enabled(GPS_1C, GAL_1B, GAL_E6)) && has_gps_lnav_eph && has_galileo_eph) { if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0)) @@ -2355,7 +2345,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; } } - else if ((flags.check_only_enabled(GPS_1C, GLO_1G) || flags.check_only_enabled(GPS_1C, GLO_2G) || flags.check_only_enabled(GPS_1C, GLO_1G, GLO_2G)) && + else if ((d_flags.check_only_enabled(GPS_1C, GLO_1G) || d_flags.check_only_enabled(GPS_1C, GLO_2G) || d_flags.check_only_enabled(GPS_1C, GLO_1G, GLO_2G)) && has_gps_lnav_eph && has_glonass_eph) { if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0)) @@ -2365,7 +2355,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; // do not write header anymore } } - else if (flags.check_only_enabled(GPS_L5, GAL_E5a)) + else if (d_flags.check_only_enabled(GPS_L5, GAL_E5a)) { if (!d_rinex_header_updated && (pvt_solver->gps_cnav_utc_model.A0 != 0) && (pvt_solver->galileo_utc_model.A0 != 0)) { @@ -2374,7 +2364,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; // do not write header anymore } } - else if (flags.check_only_enabled(GAL_1B, GLO_1G) || flags.check_only_enabled(GAL_1B, GLO_2G)) + else if (d_flags.check_only_enabled(GAL_1B, GLO_1G) || d_flags.check_only_enabled(GAL_1B, GLO_2G)) { if (!d_rinex_header_updated && (pvt_solver->galileo_utc_model.A0 != 0)) { @@ -2383,7 +2373,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; // do not write header anymore } } - else if (flags.check_only_enabled(GPS_2S, GLO_1G) || flags.check_only_enabled(GPS_2S, GLO_2G)) + else if (d_flags.check_only_enabled(GPS_2S, GLO_1G) || d_flags.check_only_enabled(GPS_2S, GLO_2G)) { if (!d_rinex_header_updated && (pvt_solver->gps_cnav_utc_model.A0 != 0)) { @@ -2392,7 +2382,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; // do not write header anymore } } - else if (flags.check_only_enabled(GPS_1C, GAL_1B, GPS_L5, GAL_E5a)) + else if (d_flags.check_only_enabled(GPS_1C, GAL_1B, GPS_L5, GAL_E5a)) { if (has_gps_lnav_eph && has_gps_cnav_eph && has_galileo_eph) { @@ -2412,7 +2402,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } } } - else if (flags.check_only_enabled(GPS_1C, GAL_1B, GAL_E5a)) + else if (d_flags.check_only_enabled(GPS_1C, GAL_1B, GAL_E5a)) { if (has_gps_lnav_eph && has_galileo_eph) { @@ -2424,7 +2414,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, } } } - else if (flags.check_only_enabled(GPS_1C, GAL_1B, GPS_L5, GAL_E5a, GAL_E6) || flags.check_only_enabled(GPS_1C, GAL_1B, GPS_2S, GPS_L5, GAL_E5a)) + else if (d_flags.check_only_enabled(GPS_1C, GAL_1B, GPS_L5, GAL_E5a, GAL_E6) || d_flags.check_only_enabled(GPS_1C, GAL_1B, GPS_2S, GPS_L5, GAL_E5a)) { if (!d_rinex_header_updated && (pvt_solver->gps_utc_model.A0 != 0) && (pvt_solver->galileo_utc_model.A0 != 0) && (has_gps_lnav_eph)) { @@ -2433,7 +2423,7 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver, d_rinex_header_updated = true; } } - else if (flags.check_only_enabled(GPS_1C, GAL_E6) && has_gps_lnav_eph) + else if (d_flags.check_only_enabled(GPS_1C, GAL_E6) && has_gps_lnav_eph) { if (has_galileo_eph) { diff --git a/src/algorithms/PVT/libs/rinex_printer.h b/src/algorithms/PVT/libs/rinex_printer.h index cc69d20a5..b65f9c4e3 100644 --- a/src/algorithms/PVT/libs/rinex_printer.h +++ b/src/algorithms/PVT/libs/rinex_printer.h @@ -38,6 +38,7 @@ #ifndef GNSS_SDR_RINEX_PRINTER_H #define GNSS_SDR_RINEX_PRINTER_H +#include "signal_enabled_flags.h" #include #include // for int32_t #include // for strtol, strtod @@ -544,6 +545,8 @@ private: const std::map observationType; // PSEUDORANGE, CARRIER_PHASE, DOPPLER, SIGNAL_STRENGTH const std::map observationCode; // GNSS observation descriptors + const Signal_Enabled_Flags d_flags; + const int d_version; // RINEX version (2 for 2.10/2.11 and 3 for 3.01) const std::string d_stringVersion; // RINEX version (2.10/2.11 or 3.01/3.02) @@ -551,7 +554,6 @@ private: bool d_rinex_header_updated; bool d_rinex_header_written; const bool d_pre_2009_file; - const uint32_t d_signal_enabled_flags; const std::string navfilename; // Name of RINEX navigation file const std::string obsfilename; // Name of RINEX observation file diff --git a/src/algorithms/PVT/libs/rtcm_printer.cc b/src/algorithms/PVT/libs/rtcm_printer.cc index 382804f3f..4ac8d3389 100644 --- a/src/algorithms/PVT/libs/rtcm_printer.cc +++ b/src/algorithms/PVT/libs/rtcm_printer.cc @@ -29,7 +29,6 @@ #include "gps_ephemeris.h" #include "rtcm.h" #include "rtklib_solver.h" -#include "signal_enabled_flags.h" #include #include // for tm #include // for exception @@ -52,13 +51,15 @@ Rtcm_Printer::Rtcm_Printer(const std::string& filename, uint16_t rtcm_tcp_port, uint16_t rtcm_station_id, const std::string& rtcm_dump_devname, + uint32_t signal_enabled_flags, bool time_tag_name, const std::string& base_path) : rtcm_base_path(base_path), rtcm_devname(rtcm_dump_devname), port(rtcm_tcp_port), station_id(rtcm_station_id), d_rtcm_has_written_once(false), - d_rtcm_file_dump(flag_rtcm_file_dump) + d_rtcm_file_dump(flag_rtcm_file_dump), + d_flags(signal_enabled_flags) { const boost::posix_time::ptime pt = boost::posix_time::second_clock::local_time(); const tm timeinfo = boost::posix_time::to_tm(pt); @@ -226,7 +227,6 @@ Rtcm_Printer::~Rtcm_Printer() void Rtcm_Printer::Print_Rtcm_Messages(const Rtklib_Solver* pvt_solver, const std::map& gnss_observables_map, double rx_time, - uint32_t signal_enabled_flags, bool rtcm_MSM_enabled, bool rtcm_MT1019_enabled, bool rtcm_MT1020_enabled, @@ -242,33 +242,26 @@ void Rtcm_Printer::Print_Rtcm_Messages(const Rtklib_Solver* pvt_solver, { try { - const Signal_Enabled_Flags flags(signal_enabled_flags); - const auto has_gps = flags.check_any_enabled(GPS_1C, GPS_2S, GPS_L5); - const auto has_galileo = flags.check_any_enabled(GAL_1B, GAL_E5a, GAL_E5b, GAL_E6); - const auto has_glonass = flags.check_any_enabled(GLO_1G, GLO_2G); - const auto has_beidou = flags.check_any_enabled(BDS_B1, BDS_B3); - const auto only_galileo = has_galileo && !(has_gps || has_glonass || has_beidou); - const auto only_glonass = has_glonass && !(has_gps || has_galileo || has_beidou); const auto print_MT1019 = (!d_rtcm_has_written_once && rtcm_MT1019_enabled) || flag_write_RTCM_1019_output; const auto print_MT1020 = (!d_rtcm_has_written_once && rtcm_MT1020_enabled) || flag_write_RTCM_1020_output; const auto print_MT1045 = (!d_rtcm_has_written_once && rtcm_MT1045_enabled) || flag_write_RTCM_1045_output; const auto print_MSM = (!d_rtcm_has_written_once && rtcm_MSM_enabled) || flag_write_RTCM_MSM_output; - if (print_MT1019 && flags.check_any_enabled(GPS_1C)) + if (print_MT1019 && d_flags.check_any_enabled(GPS_1C)) { for (const auto& gps_eph_iter : pvt_solver->gps_ephemeris_map) { Print_Rtcm_MT1019(gps_eph_iter.second); } } - if (print_MT1020 && has_glonass) + if (print_MT1020 && d_flags.has_glonass) { for (const auto& glonass_gnav_eph_iter : pvt_solver->glonass_gnav_ephemeris_map) { Print_Rtcm_MT1020(glonass_gnav_eph_iter.second, pvt_solver->glonass_gnav_utc_model); } } - if (print_MT1045 && has_galileo) + if (print_MT1045 && d_flags.has_galileo) { for (const auto& gal_eph_iter : pvt_solver->galileo_ephemeris_map) { @@ -277,7 +270,7 @@ void Rtcm_Printer::Print_Rtcm_Messages(const Rtklib_Solver* pvt_solver, } if (print_MSM) { - if (rtcm_MT1077_enabled && (flags.check_only_enabled(GPS_1C) || flags.check_only_enabled(GPS_1C, GAL_E6))) + if (rtcm_MT1077_enabled && (d_flags.check_only_enabled(GPS_1C) || d_flags.check_only_enabled(GPS_1C, GAL_E6))) { const auto gps_eph_iter = pvt_solver->gps_ephemeris_map.cbegin(); if (gps_eph_iter != pvt_solver->gps_ephemeris_map.cend()) @@ -285,7 +278,7 @@ void Rtcm_Printer::Print_Rtcm_Messages(const Rtklib_Solver* pvt_solver, Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, rx_time, gnss_observables_map, enable_rx_clock_correction, 0, 0, false, false); } } - else if (rtcm_MT1077_enabled && (flags.check_only_enabled(GPS_1C, GPS_2S) || flags.check_only_enabled(GPS_1C, GPS_L5))) + else if (rtcm_MT1077_enabled && (d_flags.check_only_enabled(GPS_1C, GPS_2S) || d_flags.check_only_enabled(GPS_1C, GPS_L5))) { const auto gps_eph_iter = pvt_solver->gps_ephemeris_map.cbegin(); const auto gps_cnav_eph_iter = pvt_solver->gps_cnav_ephemeris_map.cbegin(); @@ -294,7 +287,7 @@ void Rtcm_Printer::Print_Rtcm_Messages(const Rtklib_Solver* pvt_solver, Print_Rtcm_MSM(7, gps_eph_iter->second, gps_cnav_eph_iter->second, {}, {}, rx_time, gnss_observables_map, enable_rx_clock_correction, 0, 0, false, false); } } - else if (rtcm_MT1097_enabled && only_galileo) + else if (rtcm_MT1097_enabled && d_flags.only_galileo) { const auto gal_eph_iter = pvt_solver->galileo_ephemeris_map.cbegin(); if (gal_eph_iter != pvt_solver->galileo_ephemeris_map.cend()) @@ -302,7 +295,7 @@ void Rtcm_Printer::Print_Rtcm_Messages(const Rtklib_Solver* pvt_solver, Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, rx_time, gnss_observables_map, enable_rx_clock_correction, 0, 0, false, false); } } - else if (rtcm_MT1087_enabled && only_glonass) + else if (rtcm_MT1087_enabled && d_flags.only_glonass) { const auto glo_gnav_ephemeris_iter = pvt_solver->glonass_gnav_ephemeris_map.cbegin(); if (glo_gnav_ephemeris_iter != pvt_solver->glonass_gnav_ephemeris_map.cend()) @@ -317,10 +310,10 @@ void Rtcm_Printer::Print_Rtcm_Messages(const Rtklib_Solver* pvt_solver, auto gal_eph_iter = pvt_solver->galileo_ephemeris_map.cend(); auto glonass_gnav_eph_iter = pvt_solver->glonass_gnav_ephemeris_map.cend(); - bool search_gps_nav = flags.check_any_enabled(GPS_1C); - bool search_gps_cnav = !search_gps_nav && flags.check_any_enabled(GPS_2S, GPS_L5); - bool search_gal = has_galileo; - bool search_glo = has_glonass; + bool search_gps_nav = d_flags.check_any_enabled(GPS_1C); + bool search_gps_cnav = !search_gps_nav && d_flags.check_any_enabled(GPS_2S, GPS_L5); + bool search_gal = d_flags.has_galileo; + bool search_glo = d_flags.has_glonass; for (const auto& gnss_observables_iter : gnss_observables_map) { diff --git a/src/algorithms/PVT/libs/rtcm_printer.h b/src/algorithms/PVT/libs/rtcm_printer.h index 6b2b63004..b9998cec7 100644 --- a/src/algorithms/PVT/libs/rtcm_printer.h +++ b/src/algorithms/PVT/libs/rtcm_printer.h @@ -20,6 +20,7 @@ #ifndef GNSS_SDR_RTCM_PRINTER_H #define GNSS_SDR_RTCM_PRINTER_H +#include "signal_enabled_flags.h" #include // for int32_t #include // for std::ofstream #include // for std::map @@ -58,6 +59,7 @@ public: uint16_t rtcm_tcp_port, uint16_t rtcm_station_id, const std::string& rtcm_dump_devname, + uint32_t signal_enabled_flags, bool time_tag_name = true, const std::string& base_path = "."); @@ -72,7 +74,6 @@ public: void Print_Rtcm_Messages(const Rtklib_Solver* pvt_solver, const std::map& gnss_observables_map, double rx_time, - uint32_t signal_enabled_flags, bool rtcm_MSM_enabled, bool rtcm_MT1019_enabled, bool rtcm_MT1020_enabled, @@ -201,6 +202,7 @@ private: uint16_t station_id; bool d_rtcm_has_written_once; bool d_rtcm_file_dump; + const Signal_Enabled_Flags d_flags; }; diff --git a/src/algorithms/PVT/libs/signal_enabled_flags.cc b/src/algorithms/PVT/libs/signal_enabled_flags.cc index 8d6a58b77..0c111b808 100644 --- a/src/algorithms/PVT/libs/signal_enabled_flags.cc +++ b/src/algorithms/PVT/libs/signal_enabled_flags.cc @@ -54,11 +54,19 @@ uint32_t flags_from_config(const ConfigurationInterface* configuration) } // namespace -Signal_Enabled_Flags::Signal_Enabled_Flags(const ConfigurationInterface* configuration) : flags(flags_from_config(configuration)) +Signal_Enabled_Flags::Signal_Enabled_Flags(const ConfigurationInterface* configuration) : Signal_Enabled_Flags(flags_from_config(configuration)) { } -Signal_Enabled_Flags::Signal_Enabled_Flags(uint32_t flags_) : flags(flags_) +Signal_Enabled_Flags::Signal_Enabled_Flags(uint32_t flags_) : flags(flags_), + has_gps(check_any_enabled(GPS_1C, GPS_2S, GPS_L5)), + has_galileo(check_any_enabled(GAL_1B, GAL_E5a, GAL_E5b, GAL_E6)), + has_glonass(check_any_enabled(GLO_1G, GLO_2G)), + has_beidou(check_any_enabled(BDS_B1, BDS_B3)), + only_gps(has_gps && !(has_galileo || has_glonass || has_beidou)), + only_galileo(has_galileo && !(has_gps || has_glonass || has_beidou)), + only_glonass(has_glonass && !(has_gps || has_galileo || has_beidou)), + only_beidou(has_beidou && !(has_gps || has_galileo || has_glonass)) { } diff --git a/src/algorithms/PVT/libs/signal_enabled_flags.h b/src/algorithms/PVT/libs/signal_enabled_flags.h index 8aae82ed4..0a1a8f74b 100644 --- a/src/algorithms/PVT/libs/signal_enabled_flags.h +++ b/src/algorithms/PVT/libs/signal_enabled_flags.h @@ -67,6 +67,16 @@ public: } const uint32_t flags; + + const bool has_gps; + const bool has_galileo; + const bool has_glonass; + const bool has_beidou; + + const bool only_gps; + const bool only_galileo; + const bool only_glonass; + const bool only_beidou; }; #endif // GNSS_SDR_SIGNAL_ENABLED_FLAGS_H diff --git a/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc b/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc index 44465480b..5d8edab2c 100644 --- a/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc +++ b/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc @@ -17,6 +17,7 @@ #include "gnss_sdr_make_unique.h" #include "rtcm_printer.h" +#include "signal_enabled_flags.h" #include @@ -29,7 +30,7 @@ TEST(RtcmPrinterTest, Instantiate) bool rtcm_file_output_enabled = false; unsigned short rtcm_tcp_port = 2101; unsigned short rtcm_station_id = 1234; - auto RTCM_printer = std::make_unique(filename, rtcm_file_output_enabled, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname); + auto RTCM_printer = std::make_unique(filename, rtcm_file_output_enabled, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname, GPS_1C); } @@ -43,7 +44,7 @@ TEST(RtcmPrinterTest, Run) unsigned short rtcm_tcp_port = 2101; unsigned short rtcm_station_id = 1234; - auto RTCM_printer = std::make_unique(filename, rtcm_file_output_enabled, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname); + auto RTCM_printer = std::make_unique(filename, rtcm_file_output_enabled, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname, GPS_1C); std::string reference_msg = "D300133ED7D30202980EDEEF34B4BD62AC0941986F33360B98"; From c53d18c41222700bf82b1c852d56ac3a2b319590 Mon Sep 17 00:00:00 2001 From: Mathieu Favreau Date: Tue, 3 Feb 2026 20:36:53 +0000 Subject: [PATCH 7/8] Some more cleanup --- src/algorithms/PVT/libs/rinex_printer.cc | 35 ++++++++++-------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 232b34eb2..2855dd772 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -457,33 +457,23 @@ std::string getFilePath(const std::string& type, const std::string& base_name, c } -std::string getNavFilePath(uint32_t signal_enabled_flags, int version, const std::string& base_name, const std::string& base_rinex_path) +std::string getNavFilePath(const Signal_Enabled_Flags& flags, int version, const std::string& base_name, const std::string& base_rinex_path) { std::string type; - const Signal_Enabled_Flags flags(signal_enabled_flags); - const auto has_gps = flags.check_any_enabled(GPS_1C, GPS_2S, GPS_L5); - const auto has_galileo = flags.check_any_enabled(GAL_1B, GAL_E5a, GAL_E5b, GAL_E6); - const auto has_glonass = flags.check_any_enabled(GLO_1G, GLO_2G); - const auto has_beidou = flags.check_any_enabled(BDS_B1, BDS_B3); - const auto only_gps = has_gps && !(has_galileo || has_glonass || has_beidou); - const auto only_galileo = has_galileo && !(has_gps || has_glonass || has_beidou); - const auto only_glonass = has_glonass && !(has_gps || has_galileo || has_beidou); - const auto only_beidou = has_beidou && !(has_gps || has_galileo || has_glonass); - - if (only_gps) + if (flags.only_gps) { type = "RINEX_FILE_TYPE_GPS_NAV"; } - else if (only_galileo) + else if (flags.only_galileo) { type = "RINEX_FILE_TYPE_GAL_NAV"; } - else if (only_glonass) + else if (flags.only_glonass) { type = "RINEX_FILE_TYPE_GLO_NAV"; } - else if (only_beidou) + else if (flags.only_beidou) { type = "RINEX_FILE_TYPE_BDS_NAV"; } @@ -1412,6 +1402,7 @@ std::string get_obs_epoch_record_lines(const boost::posix_time::ptime& system_ti return line; } + void add_obs_sat_record_line(const Gnss_Synchro& synchro, std::string& line, bool padding = true) { const int32_t ssi = signal_strength(synchro.CN0_dB_hz); @@ -1441,6 +1432,7 @@ void add_obs_sat_record_line(const Gnss_Synchro& synchro, std::string& line, boo } } + void add_constellation_obs_sat_record_lines(std::fstream& out, const std::string& system, const Constellation_Observables_Map& observables, int version) { const auto system_char = satelliteSystem.at(system); @@ -1474,6 +1466,7 @@ void add_constellation_obs_sat_record_lines(std::fstream& out, const std::string } } + void add_constellation_obs_sat_record_lines(std::fstream& out, const std::vector& systems, const Constellation_Observables_Map& observables, int version) { for (const auto& system : systems) @@ -1482,6 +1475,7 @@ void add_constellation_obs_sat_record_lines(std::fstream& out, const std::vector } } + std::string get_nav_sv_epoch_svclk_line(const boost::posix_time::ptime& p_utc_time, char sys_char, uint32_t prn, double value0, double value1, double value2) { std::string line; @@ -1798,6 +1792,7 @@ void add_obs_glonass_code_phase_bias(std::fstream& out, out << line << '\n'; } + void add_obs_epoch_record(std::fstream& out, const boost::posix_time::ptime& system_time, double seconds, int version, const Constellation_Observables_Map& constel_observables) { std::string line = get_obs_epoch_record_lines(system_time, seconds, version); @@ -1835,6 +1830,7 @@ void add_obs_epoch_record(std::fstream& out, const boost::posix_time::ptime& sys out << line << '\n'; } + struct NavHeaderInfo { std::string prefix; @@ -1842,6 +1838,7 @@ struct NavHeaderInfo std::string new_line; }; + void update_nav_header_from_info(std::fstream& out, const std::string& filename, const std::vector& infos) { std::vector data; @@ -1892,12 +1889,10 @@ void update_nav_header_from_info(std::fstream& out, const std::string& filename, } -int get_version(uint32_t signal_enabled_flags, int version) +int get_version(const Signal_Enabled_Flags& flags, int version) { if (version == 2) { - const Signal_Enabled_Flags flags(signal_enabled_flags); - if (flags.check_only_enabled(GPS_1C) || flags.check_only_enabled(GLO_1G) || flags.check_only_enabled(GPS_1C, GLO_1G)) @@ -1930,13 +1925,13 @@ Rinex_Printer::Rinex_Printer(uint32_t signal_enabled_flags, bool pre_2009_file) : observationType(getObservationTypes()), observationCode(getObservationCodes()), d_flags(signal_enabled_flags), - d_version(get_version(signal_enabled_flags, version)), + d_version(get_version(d_flags, version)), d_stringVersion(d_version == 2 ? "2.11" : "3.02"), // Only version 2.11 and 3.02 d_fake_cnav_iode(1), d_rinex_header_updated(false), d_rinex_header_written(false), d_pre_2009_file(pre_2009_file), - navfilename(getNavFilePath(signal_enabled_flags, d_version, base_name, base_rinex_path)), + navfilename(getNavFilePath(d_flags, d_version, base_name, base_rinex_path)), obsfilename(getFilePath("RINEX_FILE_TYPE_OBS", base_name, base_rinex_path)), navGlofilename(getFilePath("RINEX_FILE_TYPE_GLO_NAV", base_name, base_rinex_path)), output_navfilename({navfilename}) From 22d2a58f9a539063310f4cd4e6c7f1bbdb62736d Mon Sep 17 00:00:00 2001 From: Mathieu Favreau Date: Wed, 4 Feb 2026 18:21:24 +0000 Subject: [PATCH 8/8] Fix clang-tidy CI --- src/algorithms/libs/gps_l2c_signal_replica.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/algorithms/libs/gps_l2c_signal_replica.cc b/src/algorithms/libs/gps_l2c_signal_replica.cc index da5c9b209..6f6a8941d 100644 --- a/src/algorithms/libs/gps_l2c_signal_replica.cc +++ b/src/algorithms/libs/gps_l2c_signal_replica.cc @@ -136,7 +136,7 @@ void gps_l2c_m_code_gen_complex_sampled( for (int32_t i = 0; i < nSamples; i++) { - int32_t slotIndex = + auto slotIndex = static_cast(std::floor(ts * static_cast(i) / tc_used)); // Avoid rounding overflow at last sample