From d137fda820c5d39361e8d2a77bc972f3a2a031ae Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 13 Sep 2019 13:35:26 +0200 Subject: [PATCH 1/7] Apply clang-tidy --- .../gnuradio_blocks/pcps_opencl_acquisition_cc.cc | 8 ++++---- .../gnuradio_blocks/pcps_opencl_acquisition_cc.h | 6 +++--- .../signal_source/adapters/flexiband_signal_source.cc | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc index c454c0cd5..c9a7188d0 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc @@ -71,7 +71,7 @@ pcps_opencl_acquisition_cc_sptr pcps_make_opencl_acquisition_cc( int samples_per_ms, int samples_per_code, bool bit_transition_flag, bool dump, - std::string dump_filename) + const std::string &dump_filename) { return pcps_opencl_acquisition_cc_sptr( new pcps_opencl_acquisition_cc(sampled_ms, max_dwells, doppler_max, fs_in, samples_per_ms, @@ -88,9 +88,9 @@ pcps_opencl_acquisition_cc::pcps_opencl_acquisition_cc( int samples_per_code, bool bit_transition_flag, bool dump, - std::string dump_filename) : gr::block("pcps_opencl_acquisition_cc", - gr::io_signature::make(1, 1, sizeof(gr_complex) * sampled_ms * samples_per_ms), - gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms)) + const std::string &dump_filename) : gr::block("pcps_opencl_acquisition_cc", + gr::io_signature::make(1, 1, sizeof(gr_complex) * sampled_ms * samples_per_ms), + gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms)) { this->message_port_register_out(pmt::mp("events")); d_sample_counter = 0ULL; // SAMPLE COUNTER diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.h index b86eb040b..87105a2e9 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.h @@ -78,7 +78,7 @@ pcps_opencl_acquisition_cc_sptr pcps_make_opencl_acquisition_cc( int samples_per_code, bool bit_transition_flag, bool dump, - std::string dump_filename); + const std::string& dump_filename); /*! * \brief This class implements a Parallel Code Phase Search Acquisition. @@ -213,14 +213,14 @@ private: int samples_per_ms, int samples_per_code, bool bit_transition_flag, bool dump, - std::string dump_filename); + const std::string& dump_filename); pcps_opencl_acquisition_cc(uint32_t sampled_ms, uint32_t max_dwells, uint32_t doppler_max, int64_t fs_in, int samples_per_ms, int samples_per_code, bool bit_transition_flag, bool dump, - std::string dump_filename); + const std::string& dump_filename); void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift, int doppler_offset); diff --git a/src/algorithms/signal_source/adapters/flexiband_signal_source.cc b/src/algorithms/signal_source/adapters/flexiband_signal_source.cc index e30cbae32..8e28fbb28 100644 --- a/src/algorithms/signal_source/adapters/flexiband_signal_source.cc +++ b/src/algorithms/signal_source/adapters/flexiband_signal_source.cc @@ -82,12 +82,12 @@ FlexibandSignalSource::FlexibandSignalSource(ConfigurationInterface* configurati // create I, Q -> gr_complex type conversion blocks for (int n = 0; n < (n_channels_ * 2); n++) { - char_to_float.push_back(gr::blocks::char_to_float::make()); + char_to_float.emplace_back(gr::blocks::char_to_float::make()); } for (int n = 0; n < n_channels_; n++) { - float_to_complex_.push_back(gr::blocks::float_to_complex::make()); + float_to_complex_.emplace_back(gr::blocks::float_to_complex::make()); null_sinks_.push_back(gr::blocks::null_sink::make(sizeof(gr_complex))); } From b674c0e243308d7884d650b2e3f3ec46d895a422 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 13 Sep 2019 16:30:00 +0200 Subject: [PATCH 2/7] Write RINEX files for triple-band, dual-system receiver --- src/algorithms/PVT/adapters/rtklib_pvt.cc | 8 +++++ .../PVT/gnuradio_blocks/rtklib_pvt_gs.cc | 34 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/algorithms/PVT/adapters/rtklib_pvt.cc b/src/algorithms/PVT/adapters/rtklib_pvt.cc index 603dd3b6a..b507b017d 100644 --- a/src/algorithms/PVT/adapters/rtklib_pvt.cc +++ b/src/algorithms/PVT/adapters/rtklib_pvt.cc @@ -380,6 +380,14 @@ Rtklib_Pvt::Rtklib_Pvt(ConfigurationInterface* configuration, { pvt_output_parameters.type_of_receiver = 603; // Beidou B3I + GPS L2C + GLONASS L2 C/A } + if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0) && (bds_B3_count == 0)) + { + pvt_output_parameters.type_of_receiver = 1000; // GPS L1 + GPS L2C + GPS L5 + } + if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count != 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0) && (bds_B3_count == 0)) + { + pvt_output_parameters.type_of_receiver = 1001; // GPS L1 + Galileo E1B + GPS L2C + GPS L5 + Galileo E5a + } // RTKLIB PVT solver options // Settings 1 diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc index aeb6734e4..5603b4a0f 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc @@ -1107,6 +1107,9 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg) case 33: // L1+E1+E5a rp->log_rinex_nav(rp->navMixFile, new_eph, new_gal_eph); break; + case 1001: // L1+E1+L2+L5+E5a + rp->log_rinex_nav(rp->navMixFile, new_eph, new_gal_eph); + break; default: break; } @@ -1297,6 +1300,9 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg) case 33: // L1+E1+E5a rp->log_rinex_nav(rp->navMixFile, new_eph, new_gal_eph); break; + case 1001: // L1+E1+L2+L5+E5a + rp->log_rinex_nav(rp->navMixFile, new_eph, new_gal_eph); + break; default: break; } @@ -2235,6 +2241,8 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item * 608 | BeiDou B3I + GPS L1 C/A + Galileo E1B + BeiDou B1I * 609 | BeiDou B3I + GPS L1 C/A + Galileo E1B + GLONASS L1 C/A * 610 | BeiDou B3I + GPS L1 C/A + Galileo E1B + GLONASS L1 C/A + BeiDou B1I + * 1000 | GPS L1 C/A + GPS L2C + GPS L5 + * 1001 | GPS L1 C/A + Galileo E1B + GPS L2C + GPS L5 + Galileo E5a */ // ####################### RINEX FILES ################# @@ -2629,6 +2637,18 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item } break; + case 1001: // GPS L1 C/A + Galileo E1B + GPS L2C + GPS L5 + Galileo E5a + if ((galileo_ephemeris_iter != d_user_pvt_solver->galileo_ephemeris_map.cend()) and + (gps_ephemeris_iter != d_user_pvt_solver->gps_ephemeris_map.cend()) and + (gps_cnav_ephemeris_iter != d_user_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + std::string gal_signal("1B 5X"); + std::string gps_signal("1C 2S L5"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gps_signal, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_user_pvt_solver->gps_iono, d_user_pvt_solver->gps_utc_model, gps_ephemeris_iter->second, d_user_pvt_solver->galileo_iono, d_user_pvt_solver->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; default: break; } @@ -2950,6 +2970,20 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item b_rinex_header_updated = true; } break; + case 1001: // GPS L1 C/A + Galileo E1B + GPS L2C + GPS L5 + Galileo E5a + if ((galileo_ephemeris_iter != d_user_pvt_solver->galileo_ephemeris_map.cend()) and + (gps_ephemeris_iter != d_user_pvt_solver->gps_ephemeris_map.cend()) and + (gps_cnav_ephemeris_iter != d_user_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_user_pvt_solver->gps_utc_model.d_A0 != 0) and (d_user_pvt_solver->galileo_utc_model.A0_6 != 0)) + { + rp->update_obs_header(rp->obsFile, d_user_pvt_solver->gps_utc_model); + rp->update_nav_header(rp->navMixFile, d_user_pvt_solver->gps_iono, d_user_pvt_solver->gps_utc_model, gps_ephemeris_iter->second, d_user_pvt_solver->galileo_iono, d_user_pvt_solver->galileo_utc_model); + b_rinex_header_updated = true; + } + break; default: break; } From ad51654fbfd44044ad8289d0958633dc9806e28a Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 13 Sep 2019 16:36:41 +0200 Subject: [PATCH 3/7] Adding global configuration option to specify a custom year in order to postprocess old GNSS captures and avoid wrong week rollover --- src/algorithms/PVT/adapters/rtklib_pvt.cc | 3 + .../PVT/gnuradio_blocks/rtklib_pvt_gs.cc | 3 + src/algorithms/PVT/libs/pvt_conf.cc | 2 +- src/algorithms/PVT/libs/pvt_conf.h | 1 + src/algorithms/PVT/libs/pvt_solution.cc | 6 ++ src/algorithms/PVT/libs/pvt_solution.h | 4 +- src/algorithms/PVT/libs/rtklib_solver.cc | 55 ++++++++++++------- .../libs/rtklib/rtklib_conversions.cc | 20 +++---- .../libs/rtklib/rtklib_conversions.h | 8 +-- src/algorithms/libs/rtklib/rtklib_rtcm2.cc | 8 +-- src/algorithms/libs/rtklib/rtklib_rtcm3.cc | 8 +-- src/algorithms/libs/rtklib/rtklib_rtkcmn.cc | 34 +++++++++--- src/algorithms/libs/rtklib/rtklib_rtkcmn.h | 2 +- src/core/receiver/control_thread.cc | 6 +- src/core/receiver/control_thread.h | 1 + 15 files changed, 105 insertions(+), 56 deletions(-) diff --git a/src/algorithms/PVT/adapters/rtklib_pvt.cc b/src/algorithms/PVT/adapters/rtklib_pvt.cc index 603dd3b6a..35f0512fd 100644 --- a/src/algorithms/PVT/adapters/rtklib_pvt.cc +++ b/src/algorithms/PVT/adapters/rtklib_pvt.cc @@ -68,6 +68,9 @@ Rtklib_Pvt::Rtklib_Pvt(ConfigurationInterface* configuration, pvt_output_parameters.dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); pvt_output_parameters.dump_mat = configuration->property(role + ".dump_mat", true); + //OPTIONAL: specify a custom year to override the system time in order to postprocess old gnss records and avoid wrong week rollover + pvt_output_parameters.custom_year = configuration->property("GNSS-SDR.custom_year", 0); + // output rate pvt_output_parameters.output_rate_ms = bc::lcm(20, configuration->property(role + ".output_rate_ms", 500)); diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc index aeb6734e4..5c7e4465a 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc @@ -467,18 +467,21 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels, // user PVT solver d_user_pvt_solver = std::make_shared(static_cast(nchannels), dump_ls_pvt_filename, d_dump, d_dump_mat, rtk); d_user_pvt_solver->set_averaging_depth(1); + d_user_pvt_solver->set_custom_year(conf_.custom_year); // internal PVT solver, mainly used to estimate the receiver clock rtk_t internal_rtk = rtk; internal_rtk.opt.mode = PMODE_SINGLE; // use single positioning mode in internal PVT solver d_internal_pvt_solver = std::make_shared(static_cast(nchannels), dump_ls_pvt_filename, false, false, internal_rtk); d_internal_pvt_solver->set_averaging_depth(1); + d_internal_pvt_solver->set_custom_year(conf_.custom_year); } else { // only one solver, customized by the user options d_internal_pvt_solver = std::make_shared(static_cast(nchannels), dump_ls_pvt_filename, d_dump, d_dump_mat, rtk); d_internal_pvt_solver->set_averaging_depth(1); + d_internal_pvt_solver->set_custom_year(conf_.custom_year); d_user_pvt_solver = d_internal_pvt_solver; } diff --git a/src/algorithms/PVT/libs/pvt_conf.cc b/src/algorithms/PVT/libs/pvt_conf.cc index d2d144cb3..42c596bba 100644 --- a/src/algorithms/PVT/libs/pvt_conf.cc +++ b/src/algorithms/PVT/libs/pvt_conf.cc @@ -76,6 +76,6 @@ Pvt_Conf::Pvt_Conf() monitor_enabled = false; protobuf_enabled = true; udp_port = 0; - + custom_year = 0; show_local_time_zone = false; } diff --git a/src/algorithms/PVT/libs/pvt_conf.h b/src/algorithms/PVT/libs/pvt_conf.h index ea67a178f..ad79fd2e6 100644 --- a/src/algorithms/PVT/libs/pvt_conf.h +++ b/src/algorithms/PVT/libs/pvt_conf.h @@ -91,6 +91,7 @@ public: bool enable_rx_clock_correction; bool show_local_time_zone; + int custom_year; Pvt_Conf(); }; diff --git a/src/algorithms/PVT/libs/pvt_solution.cc b/src/algorithms/PVT/libs/pvt_solution.cc index b61f985e7..ef53a9a44 100644 --- a/src/algorithms/PVT/libs/pvt_solution.cc +++ b/src/algorithms/PVT/libs/pvt_solution.cc @@ -53,6 +53,7 @@ Pvt_Solution::Pvt_Solution() d_valid_observations = 0; d_rx_pos = arma::zeros(3, 1); d_rx_dt_s = 0.0; + d_custom_year = 0; //disabled by default } @@ -431,3 +432,8 @@ void Pvt_Solution::set_num_valid_observations(int num) { d_valid_observations = num; } + +void Pvt_Solution::set_custom_year(int custom_year) +{ + d_custom_year = custom_year; +} diff --git a/src/algorithms/PVT/libs/pvt_solution.h b/src/algorithms/PVT/libs/pvt_solution.h index df98835d0..2ece97903 100644 --- a/src/algorithms/PVT/libs/pvt_solution.h +++ b/src/algorithms/PVT/libs/pvt_solution.h @@ -49,7 +49,7 @@ class Pvt_Solution { public: Pvt_Solution(); - + void set_custom_year(int custom_year); //!< Set a custom year for the week rollover computation instead of using the system clock, useful in post processing mode double get_time_offset_s() const; //!< Get RX time offset [s] void set_time_offset_s(double offset); //!< Set RX time offset [s] @@ -129,6 +129,8 @@ public: */ int tropo(double *ddr_m, double sinel, double hsta_km, double p_mb, double t_kel, double hum, double hp_km, double htkel_km, double hhum_km); +protected: + int d_custom_year; //custom year to guess the correct week rollover in post processing mode private: double d_rx_dt_s; // RX time offset [s] diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index a6183d854..61085af33 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -496,13 +496,14 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ if (galileo_ephemeris_iter != galileo_ephemeris_map.cend()) { // convert ephemeris from GNSS-SDR class to RTKLIB structure - eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second); + eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second, d_custom_year); // convert observation from GNSS-SDR class to RTKLIB structure obsd_t newobs = {{0, 0}, '0', '0', {}, {}, {}, {}, {}, {}}; obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, galileo_ephemeris_iter->second.WN_5, - 0); + 0, + d_custom_year); valid_obs++; } else // the ephemeris are not available for this SV @@ -526,7 +527,8 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ obs_data[i + glo_valid_obs] = insert_obs_to_rtklib(obs_data[i + glo_valid_obs], gnss_observables_iter->second, galileo_ephemeris_iter->second.WN_5, - 2); // Band 3 (L5/E5) + 2, // Band 3 (L5/E5) + d_custom_year); found_E1_obs = true; break; } @@ -535,7 +537,7 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ { // insert Galileo E5 obs as new obs and also insert its ephemeris // convert ephemeris from GNSS-SDR class to RTKLIB structure - eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second); + eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second, d_custom_year); // convert observation from GNSS-SDR class to RTKLIB structure auto default_code_ = static_cast(CODE_NONE); obsd_t newobs = {{0, 0}, '0', '0', {}, {}, @@ -544,7 +546,8 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, galileo_ephemeris_iter->second.WN_5, - 2); // Band 3 (L5/E5) + 2, // Band 3 (L5/E5) + d_custom_year); valid_obs++; } } @@ -566,13 +569,14 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ if (gps_ephemeris_iter != gps_ephemeris_map.cend()) { // convert ephemeris from GNSS-SDR class to RTKLIB structure - eph_data[valid_obs] = eph_to_rtklib(gps_ephemeris_iter->second); + eph_data[valid_obs] = eph_to_rtklib(gps_ephemeris_iter->second, d_custom_year); // convert observation from GNSS-SDR class to RTKLIB structure obsd_t newobs = {{0, 0}, '0', '0', {}, {}, {}, {}, {}, {}}; obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, gps_ephemeris_iter->second.i_GPS_week, - 0); + 0, + d_custom_year); valid_obs++; } else // the ephemeris are not available for this SV @@ -611,7 +615,7 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ { // 3. If not found, insert the GPS L2 ephemeris and the observation // convert ephemeris from GNSS-SDR class to RTKLIB structure - eph_data[valid_obs] = eph_to_rtklib(gps_cnav_ephemeris_iter->second); + eph_data[valid_obs] = eph_to_rtklib(gps_cnav_ephemeris_iter->second, d_custom_year); // convert observation from GNSS-SDR class to RTKLIB structure auto default_code_ = static_cast(CODE_NONE); obsd_t newobs = {{0, 0}, '0', '0', {}, {}, @@ -620,7 +624,8 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, gps_cnav_ephemeris_iter->second.i_GPS_week, - 1); // Band 2 (L2) + 1, // Band 2 (L2) + d_custom_year); valid_obs++; } } @@ -645,11 +650,12 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ { if (eph_data[i].sat == static_cast(gnss_observables_iter->second.PRN)) { - eph_data[i] = eph_to_rtklib(gps_cnav_ephemeris_iter->second); + eph_data[i] = eph_to_rtklib(gps_cnav_ephemeris_iter->second, d_custom_year); obs_data[i + glo_valid_obs] = insert_obs_to_rtklib(obs_data[i], gnss_observables_iter->second, gps_cnav_ephemeris_iter->second.i_GPS_week, - 2); // Band 3 (L5) + 2, // Band 3 (L5) + d_custom_year); break; } } @@ -658,7 +664,7 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ { // 3. If not found, insert the GPS L5 ephemeris and the observation // convert ephemeris from GNSS-SDR class to RTKLIB structure - eph_data[valid_obs] = eph_to_rtklib(gps_cnav_ephemeris_iter->second); + eph_data[valid_obs] = eph_to_rtklib(gps_cnav_ephemeris_iter->second, d_custom_year); // convert observation from GNSS-SDR class to RTKLIB structure auto default_code_ = static_cast(CODE_NONE); obsd_t newobs = {{0, 0}, '0', '0', {}, {}, @@ -667,7 +673,8 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, gps_cnav_ephemeris_iter->second.i_GPS_week, - 2); // Band 3 (L5) + 2, // Band 3 (L5) + d_custom_year); valid_obs++; } } @@ -695,7 +702,8 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, glonass_gnav_ephemeris_iter->second.d_WN, - 0); // Band 0 (L1) + 0, // Band 0 (L1) + d_custom_year); glo_valid_obs++; } else // the ephemeris are not available for this SV @@ -718,7 +726,8 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ obs_data[i + valid_obs] = insert_obs_to_rtklib(obs_data[i + valid_obs], gnss_observables_iter->second, glonass_gnav_ephemeris_iter->second.d_WN, - 1); // Band 1 (L2) + 1, // Band 1 (L2) + d_custom_year); found_L1_obs = true; break; } @@ -733,7 +742,8 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, glonass_gnav_ephemeris_iter->second.d_WN, - 1); // Band 1 (L2) + 1, // Band 1 (L2) + d_custom_year); glo_valid_obs++; } } @@ -761,7 +771,8 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, beidou_ephemeris_iter->second.i_BEIDOU_week + BEIDOU_DNAV_BDT2GPST_WEEK_NUM_OFFSET, - 0); + 0, + d_custom_year); valid_obs++; } else // the ephemeris are not available for this SV @@ -783,7 +794,8 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ obs_data[i + glo_valid_obs] = insert_obs_to_rtklib(obs_data[i + glo_valid_obs], gnss_observables_iter->second, beidou_ephemeris_iter->second.i_BEIDOU_week + BEIDOU_DNAV_BDT2GPST_WEEK_NUM_OFFSET, - 2); // Band 3 (L2/G2/B3) + 2, // Band 3 (L2/G2/B3) + d_custom_year); found_B1I_obs = true; break; } @@ -801,7 +813,8 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs, gnss_observables_iter->second, beidou_ephemeris_iter->second.i_BEIDOU_week + BEIDOU_DNAV_BDT2GPST_WEEK_NUM_OFFSET, - 2); // Band 2 (L2/G2) + 2, // Band 2 (L2/G2) + d_custom_year); valid_obs++; } } @@ -1025,7 +1038,7 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ // TOW monitor_pvt.TOW_at_current_symbol_ms = gnss_observables_map.begin()->second.TOW_at_current_symbol_ms; // WEEK - monitor_pvt.week = adjgpsweek(nav_data.eph[0].week); + monitor_pvt.week = adjgpsweek(nav_data.eph[0].week, d_custom_year); // PVT GPS time monitor_pvt.RX_time = gnss_observables_map.begin()->second.RX_time; // User clock offset [s] @@ -1083,7 +1096,7 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ tmp_uint32 = gnss_observables_map.begin()->second.TOW_at_current_symbol_ms; d_dump_file.write(reinterpret_cast(&tmp_uint32), sizeof(uint32_t)); // WEEK - tmp_uint32 = adjgpsweek(nav_data.eph[0].week); + tmp_uint32 = adjgpsweek(nav_data.eph[0].week, d_custom_year); d_dump_file.write(reinterpret_cast(&tmp_uint32), sizeof(uint32_t)); // PVT GPS time tmp_double = gnss_observables_map.begin()->second.RX_time; diff --git a/src/algorithms/libs/rtklib/rtklib_conversions.cc b/src/algorithms/libs/rtklib/rtklib_conversions.cc index f26bbd8dd..e58c70db7 100644 --- a/src/algorithms/libs/rtklib/rtklib_conversions.cc +++ b/src/algorithms/libs/rtklib/rtklib_conversions.cc @@ -45,7 +45,7 @@ #include #include -obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs, const Gnss_Synchro& gnss_synchro, int week, int band) +obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs, const Gnss_Synchro& gnss_synchro, int week, int band, int custom_year) { // Get signal type info to adjust code type based on constellation std::string sig_ = gnss_synchro.Signal; @@ -118,7 +118,7 @@ obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs, const Gnss_Synchro& gnss_synchro // rtklib_obs.time = gpst2time(adjgpsweek(week), gnss_synchro.RX_time); // } // - rtklib_obs.time = gpst2time(adjgpsweek(week), gnss_synchro.RX_time); + rtklib_obs.time = gpst2time(adjgpsweek(week, custom_year), gnss_synchro.RX_time); // account for the TOW crossover transitory in the first 18 seconds where the week is not yet updated! if (gnss_synchro.RX_time < 18.0) { @@ -158,19 +158,19 @@ geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const Glona // Time expressed in GPS Time but using RTKLib format glonass_gnav_eph.glot_to_gpst(glonass_gnav_eph.d_t_b, gnav_clock_model.d_tau_c, gnav_clock_model.d_tau_gps, &week, &sec); - adj_week = adjgpsweek(static_cast(week)); + adj_week = adjgpsweek(static_cast(week), 0); rtklib_sat.toe = gpst2time(adj_week, sec); // Time expressed in GPS Time but using RTKLib format glonass_gnav_eph.glot_to_gpst(glonass_gnav_eph.d_t_k, gnav_clock_model.d_tau_c, gnav_clock_model.d_tau_gps, &week, &sec); - adj_week = adjgpsweek(static_cast(week)); + adj_week = adjgpsweek(static_cast(week), 0); rtklib_sat.tof = gpst2time(adj_week, sec); return rtklib_sat; } -eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph) +eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph, int custom_year) { eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0}; @@ -188,7 +188,7 @@ eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph) rtklib_sat.Adot = 0; // only in CNAV; rtklib_sat.ndot = 0; // only in CNAV; - rtklib_sat.week = adjgpsweek(gal_eph.WN_5); /* week of tow */ + rtklib_sat.week = adjgpsweek(gal_eph.WN_5, custom_year); /* week of tow */ rtklib_sat.cic = gal_eph.C_ic_4; rtklib_sat.cis = gal_eph.C_is_4; rtklib_sat.cuc = gal_eph.C_uc_3; @@ -229,7 +229,7 @@ eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph) } -eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph) +eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph, int custom_year) { eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0}; @@ -246,7 +246,7 @@ eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph) rtklib_sat.Adot = 0; // only in CNAV; rtklib_sat.ndot = 0; // only in CNAV; - rtklib_sat.week = adjgpsweek(gps_eph.i_GPS_week); /* week of tow */ + rtklib_sat.week = adjgpsweek(gps_eph.i_GPS_week, custom_year); /* week of tow */ rtklib_sat.cic = gps_eph.d_Cic; rtklib_sat.cis = gps_eph.d_Cis; rtklib_sat.cuc = gps_eph.d_Cuc; @@ -356,7 +356,7 @@ eph_t eph_to_rtklib(const Beidou_Dnav_Ephemeris& bei_eph) } -eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph) +eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph, int custom_year) { eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0}; @@ -377,7 +377,7 @@ eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph) rtklib_sat.Adot = gps_cnav_eph.d_A_DOT; // only in CNAV; rtklib_sat.ndot = gps_cnav_eph.d_DELTA_DOT_N; // only in CNAV; - rtklib_sat.week = adjgpsweek(gps_cnav_eph.i_GPS_week); /* week of tow */ + rtklib_sat.week = adjgpsweek(gps_cnav_eph.i_GPS_week, custom_year); /* week of tow */ rtklib_sat.cic = gps_cnav_eph.d_Cic; rtklib_sat.cis = gps_cnav_eph.d_Cis; rtklib_sat.cuc = gps_cnav_eph.d_Cuc; diff --git a/src/algorithms/libs/rtklib/rtklib_conversions.h b/src/algorithms/libs/rtklib/rtklib_conversions.h index 47cc6c5bb..6621b6ae9 100644 --- a/src/algorithms/libs/rtklib/rtklib_conversions.h +++ b/src/algorithms/libs/rtklib/rtklib_conversions.h @@ -43,9 +43,9 @@ class Gps_Almanac; class Gps_CNAV_Ephemeris; class Gps_Ephemeris; -eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph); -eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph); -eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph); +eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph, int custom_year); +eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph, int custom_year); +eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph, int custom_year); eph_t eph_to_rtklib(const Beidou_Dnav_Ephemeris& bei_eph); alm_t alm_to_rtklib(const Gps_Almanac& gps_alm); @@ -58,6 +58,6 @@ alm_t alm_to_rtklib(const Galileo_Almanac& gal_alm); */ geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const Glonass_Gnav_Utc_Model& gnav_clock_model); -obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs, const Gnss_Synchro& gnss_synchro, int week, int band); +obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs, const Gnss_Synchro& gnss_synchro, int week, int band, int custom_year); #endif /* GNSS_SDR_RTKLIB_CONVERSIONS_H_ */ diff --git a/src/algorithms/libs/rtklib/rtklib_rtcm2.cc b/src/algorithms/libs/rtklib/rtklib_rtcm2.cc index 7bab22997..4eefac11e 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtcm2.cc +++ b/src/algorithms/libs/rtklib/rtklib_rtcm2.cc @@ -192,7 +192,7 @@ int decode_type3(rtcm_t *rtcm) /* decode type 14: gps time of week ------------------------------------------*/ -int decode_type14(rtcm_t *rtcm) +int decode_type14(rtcm_t *rtcm, int custom_year) { double zcnt; int i = 48; @@ -216,7 +216,7 @@ int decode_type14(rtcm_t *rtcm) trace(2, "rtcm2 14 length error: len=%d\n", rtcm->len); return -1; } - week = adjgpsweek(week); + week = adjgpsweek(week, custom_year); rtcm->time = gpst2time(week, hour * 3600.0 + zcnt * 0.6); rtcm->nav.leaps = leaps; return 6; @@ -244,7 +244,7 @@ int decode_type16(rtcm_t *rtcm) /* decode type 17: gps ephemerides -------------------------------------------*/ -int decode_type17(rtcm_t *rtcm) +int decode_type17(rtcm_t *rtcm, int custom_year) { eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, @@ -329,7 +329,7 @@ int decode_type17(rtcm_t *rtcm) } sat = satno(SYS_GPS, prn); eph.sat = sat; - eph.week = adjgpsweek(week); + eph.week = adjgpsweek(week, custom_year); eph.toe = gpst2time(eph.week, eph.toes); eph.toc = gpst2time(eph.week, toc); eph.ttr = rtcm->time; diff --git a/src/algorithms/libs/rtklib/rtklib_rtcm3.cc b/src/algorithms/libs/rtklib/rtklib_rtcm3.cc index 62db7d8ae..623e0d618 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtcm3.cc +++ b/src/algorithms/libs/rtklib/rtklib_rtcm3.cc @@ -1036,7 +1036,7 @@ int decode_type1013(rtcm_t *rtcm __attribute__((unused))) /* decode type 1019: gps ephemerides -----------------------------------------*/ -int decode_type1019(rtcm_t *rtcm) +int decode_type1019(rtcm_t *rtcm, int custom_year) { eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, @@ -1136,7 +1136,7 @@ int decode_type1019(rtcm_t *rtcm) return -1; } eph.sat = sat; - eph.week = adjgpsweek(week); + eph.week = adjgpsweek(week, custom_year); eph.toe = gpst2time(eph.week, eph.toes); eph.toc = gpst2time(eph.week, toc); eph.ttr = rtcm->time; @@ -1535,7 +1535,7 @@ int decode_type1039(rtcm_t *rtcm __attribute__((unused))) /* decode type 1044: qzss ephemerides (ref [15]) -----------------------------*/ -int decode_type1044(rtcm_t *rtcm) +int decode_type1044(rtcm_t *rtcm, int custom_year) { eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, @@ -1628,7 +1628,7 @@ int decode_type1044(rtcm_t *rtcm) return -1; } eph.sat = sat; - eph.week = adjgpsweek(week); + eph.week = adjgpsweek(week, custom_year); eph.toe = gpst2time(eph.week, eph.toes); eph.toc = gpst2time(eph.week, toc); eph.ttr = rtcm->time; diff --git a/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc b/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc index 549e9079b..8df33a3d3 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc +++ b/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc @@ -2114,27 +2114,45 @@ double time2doy(gtime_t t) * args : int week I not-adjusted gps week number * return : adjusted gps week number *-----------------------------------------------------------------------------*/ -int adjgpsweek(int week) +int adjgpsweek(int week, int custom_year) { // int w; // if (week < 512) // { // //assume receiver date > 7 april 2019 - // w = week + 2048; //add weeks from 6-january-1980 to week rollover in 7 april 2019 + // w = week + 2048; //add weeks from 6-january-1980 to week rollover in 6 april 2019 // } // else // { // //assume receiver date < 7 april 2019 - // w = week + 1024; //add weeks from 6-january-1980 to week rollover in 22 august 2019 + // w = week + 1024; //add weeks from 6-january-1980 to week rollover in 21 august 1999 // } int w; - (void)time2gpst(utc2gpst(timeget()), &w); - if (w < 1560) + if (custom_year == 0) { - w = 1560; /* use 2009/12/1 if time is earlier than 2009/12/1 */ + (void)time2gpst(utc2gpst(timeget()), &w); + if (w < 1560) + { + w = 1560; /* use 2009/12/1 if time is earlier than 2009/12/1 */ + } + return week + (w - week + 512) / 1024 * 1024; + } + else + { + if (custom_year >= 2019) + { + w = week + 2048; //add weeks from 6-january-1980 to week rollover in 6 april 2019 + } + else if (custom_year < 2019 and custom_year >= 1999) + { + w = week + 1024; //add weeks from 6-january-1980 to week rollover in 21 august 1999 + } + else + { + w = week; //no rollover + } + return w; } - return week + (w - week + 512) / 1024 * 1024; - // return w; } diff --git a/src/algorithms/libs/rtklib/rtklib_rtkcmn.h b/src/algorithms/libs/rtklib/rtklib_rtkcmn.h index 1e622269c..9eb64207a 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtkcmn.h +++ b/src/algorithms/libs/rtklib/rtklib_rtkcmn.h @@ -189,7 +189,7 @@ double utc2gmst(gtime_t t, double ut1_utc); void time2str(gtime_t t, char *s, int n); char *time_str(gtime_t t, int n); double time2doy(gtime_t t); -int adjgpsweek(int week); +int adjgpsweek(int week, int custom_year); unsigned int tickget(); void sleepms(int ms); void deg2dms(double deg, double *dms, int ndec); diff --git a/src/core/receiver/control_thread.cc b/src/core/receiver/control_thread.cc index 9cb34f999..86f5903a0 100644 --- a/src/core/receiver/control_thread.cc +++ b/src/core/receiver/control_thread.cc @@ -116,6 +116,8 @@ ControlThread::ControlThread(const std::shared_ptr &conf void ControlThread::init() { + //OPTIONAL: specify a custom year to override the system time in order to postprocess old gnss records and avoid wrong week rollover + custom_year_ = configuration_->property("GNSS-SDR.custom_year", 0); // Instantiates a control queue, a GNSS flowgraph, and a control message factory control_queue_ = std::make_shared>(); cmd_interface_.set_msg_queue(control_queue_); // set also the queue pointer for the telecommand thread @@ -942,7 +944,7 @@ std::vector> ControlThread::get_visible_sats(time std::map gps_eph_map = pvt_ptr->get_gps_ephemeris(); for (auto &it : gps_eph_map) { - eph_t rtklib_eph = eph_to_rtklib(it.second); + eph_t rtklib_eph = eph_to_rtklib(it.second, custom_year_); std::array r_sat{}; double clock_bias_s; double sat_pos_variance_m2; @@ -967,7 +969,7 @@ std::vector> ControlThread::get_visible_sats(time std::map gal_eph_map = pvt_ptr->get_galileo_ephemeris(); for (auto &it : gal_eph_map) { - eph_t rtklib_eph = eph_to_rtklib(it.second); + eph_t rtklib_eph = eph_to_rtklib(it.second, custom_year_); std::array r_sat{}; double clock_bias_s; double sat_pos_variance_m2; diff --git a/src/core/receiver/control_thread.h b/src/core/receiver/control_thread.h index 6e1f2ab2f..1069d0b0c 100644 --- a/src/core/receiver/control_thread.h +++ b/src/core/receiver/control_thread.h @@ -171,6 +171,7 @@ private: std::shared_ptr flowgraph_; std::shared_ptr configuration_; std::shared_ptr> control_queue_; + int custom_year_; //to override the system time to postprocess old gnss records and avoid wrong week rollover bool stop_; bool restart_; bool delete_configuration_; From cf3a0e40064823e9bee4bd7de77cf8d6adb610e2 Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 13 Sep 2019 17:35:53 +0200 Subject: [PATCH 4/7] Use GNSS-SDR custom_year config parameter (if set) also in RINEX printers --- .../PVT/gnuradio_blocks/rtklib_pvt_gs.cc | 1 + src/algorithms/PVT/libs/rinex_printer.cc | 47 +++++++++++++++---- src/algorithms/PVT/libs/rinex_printer.h | 3 ++ 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc index 5c7e4465a..309ccc324 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc @@ -347,6 +347,7 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels, if (b_rinex_output_enabled) { rp = std::make_shared(d_rinex_version, conf_.rinex_output_path); + rp->set_custom_year(conf_.custom_year); } else { diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index c74d306ed..ab3c0e270 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -88,6 +88,7 @@ namespace errorlib = boost::system; Rinex_Printer::Rinex_Printer(int32_t conf_version, const std::string& base_path) { + custom_year_ = 0; std::string base_rinex_path = base_path; fs::path full_path(fs::current_path()); const fs::path p(base_rinex_path); @@ -11780,13 +11781,24 @@ boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Gps_Navigation_Me // idea: resolve the ambiguity with the leap second http://www.colorado.edu/geography/gcraft/notes/gps/gpseow.htm const double utc_t = nav_msg.utc_time(nav_msg.d_TOW); boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast((utc_t + 604800 * static_cast(nav_msg.i_GPS_week)) * 1000)); - if (nav_msg.i_GPS_week < 512) + // Handle week rollover + if (custom_year_ == 0 or custom_year_ >= 2009) { - boost::posix_time::ptime p_time(boost::gregorian::date(2019, 4, 7), t); + // Handle week rollover (valid from 2009 to 2029) + if (nav_msg.i_GPS_week < 512) + { + boost::posix_time::ptime p_time(boost::gregorian::date(2019, 4, 7), t); + return p_time; + } + boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); + return p_time; + } + else + { + //assume receiver operating in between 1999 to 2008 + boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); return p_time; } - boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); - return p_time; } @@ -11815,15 +11827,25 @@ boost::posix_time::ptime Rinex_Printer::compute_GPS_time(const Gps_Ephemeris& ep { t += boost::posix_time::seconds(604800); } - // Handle week rollover (valid from 2009 to 2029) - if (eph.i_GPS_week < 512) + + // Handle week rollover + if (custom_year_ == 0 or custom_year_ >= 2009) { - boost::posix_time::ptime p_time(boost::gregorian::date(2019, 4, 7), t); + // Handle week rollover (valid from 2009 to 2029) + if (eph.i_GPS_week < 512) + { + boost::posix_time::ptime p_time(boost::gregorian::date(2019, 4, 7), t); + return p_time; + } + boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); + return p_time; + } + else + { + //assume receiver operating in between 1999 to 2008 + boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); return p_time; } - - boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); - return p_time; } @@ -11933,6 +11955,11 @@ double Rinex_Printer::get_leap_second(const Glonass_Gnav_Ephemeris& eph, const d return leap_second; } +void Rinex_Printer::set_custom_year(int custom_year) +{ + custom_year_ = custom_year; +} + /* diff --git a/src/algorithms/PVT/libs/rinex_printer.h b/src/algorithms/PVT/libs/rinex_printer.h index ca71b51e1..52ec3ebbc 100644 --- a/src/algorithms/PVT/libs/rinex_printer.h +++ b/src/algorithms/PVT/libs/rinex_printer.h @@ -448,9 +448,12 @@ public: std::string navBdsfilename; std::string navMixfilename; + void set_custom_year(int custom_year); + private: int version; // RINEX version (2 for 2.10/2.11 and 3 for 3.01) int numberTypesObservations; // Number of available types of observable in the system. Should be public? + int custom_year_; /* * Generation of RINEX signal strength indicators */ From 24068bdf11b89b6624ca30e31dd49bdee9b079c2 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 13 Sep 2019 17:49:22 +0200 Subject: [PATCH 5/7] Print RINEX files for GPS L1+L2+L5 receiver --- .../PVT/gnuradio_blocks/rtklib_pvt_gs.cc | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc index 5603b4a0f..e92ea77c9 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc @@ -1107,6 +1107,9 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg) case 33: // L1+E1+E5a rp->log_rinex_nav(rp->navMixFile, new_eph, new_gal_eph); break; + case 1000: // L1+L2+L5 + rp->log_rinex_nav(rp->navFile, new_eph); + break; case 1001: // L1+E1+L2+L5+E5a rp->log_rinex_nav(rp->navMixFile, new_eph, new_gal_eph); break; @@ -2637,6 +2640,16 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item } break; + case 1000: // GPS L1 C/A + GPS L2C + GPS L5 + if ((gps_ephemeris_iter != d_user_pvt_solver->gps_ephemeris_map.cend()) and + (gps_cnav_ephemeris_iter != d_user_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + std::string gps_signal("1C 2S L5"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time, gps_signal); + rp->rinex_nav_header(rp->navFile, d_user_pvt_solver->gps_iono, d_user_pvt_solver->gps_utc_model, gps_ephemeris_iter->second); + b_rinex_header_written = true; // do not write header anymore + } + break; case 1001: // GPS L1 C/A + Galileo E1B + GPS L2C + GPS L5 + Galileo E5a if ((galileo_ephemeris_iter != d_user_pvt_solver->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_user_pvt_solver->gps_ephemeris_map.cend()) and @@ -2970,6 +2983,19 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item b_rinex_header_updated = true; } break; + case 1000: // GPS L1 C/A + GPS L2C + GPS L5 + if ((gps_ephemeris_iter != d_user_pvt_solver->gps_ephemeris_map.cend()) and + (gps_cnav_ephemeris_iter != d_user_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_user_pvt_solver->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_user_pvt_solver->gps_utc_model); + rp->update_nav_header(rp->navFile, d_user_pvt_solver->gps_utc_model, d_user_pvt_solver->gps_iono, gps_ephemeris_iter->second); + b_rinex_header_updated = true; + } + break; case 1001: // GPS L1 C/A + Galileo E1B + GPS L2C + GPS L5 + Galileo E5a if ((galileo_ephemeris_iter != d_user_pvt_solver->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_user_pvt_solver->gps_ephemeris_map.cend()) and From d116287dca8e36428598c91d0e239b73a0e0647f Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 13 Sep 2019 18:40:41 +0200 Subject: [PATCH 6/7] Fix RINEX navigation files annotations in some configurations --- src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc index 84091fa18..2d80f5e56 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc @@ -2303,6 +2303,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item { rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time); rp->rinex_nav_header(rp->navGalFile, d_user_pvt_solver->galileo_iono, d_user_pvt_solver->galileo_utc_model); + rp->log_rinex_nav(rp->navGalFile, d_user_pvt_solver->galileo_ephemeris_map); b_rinex_header_written = true; // do not write header anymore } break; @@ -2312,6 +2313,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item std::string signal("5X"); rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, signal); rp->rinex_nav_header(rp->navGalFile, d_user_pvt_solver->galileo_iono, d_user_pvt_solver->galileo_utc_model); + rp->log_rinex_nav(rp->navGalFile, d_user_pvt_solver->galileo_ephemeris_map); b_rinex_header_written = true; // do not write header anymore } break; @@ -2390,6 +2392,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item std::string gal_signal("1B 5X"); rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gal_signal); rp->rinex_nav_header(rp->navGalFile, d_user_pvt_solver->galileo_iono, d_user_pvt_solver->galileo_utc_model); + rp->log_rinex_nav(rp->navGalFile, d_user_pvt_solver->galileo_ephemeris_map); b_rinex_header_written = true; // do not write header anymore } break; @@ -2651,6 +2654,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item std::string gps_signal("1C 2S L5"); rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time, gps_signal); rp->rinex_nav_header(rp->navFile, d_user_pvt_solver->gps_iono, d_user_pvt_solver->gps_utc_model, gps_ephemeris_iter->second); + rp->log_rinex_nav(rp->navFile, d_user_pvt_solver->gps_ephemeris_map); b_rinex_header_written = true; // do not write header anymore } break; @@ -2663,6 +2667,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item std::string gps_signal("1C 2S L5"); rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gps_signal, gal_signal); rp->rinex_nav_header(rp->navMixFile, d_user_pvt_solver->gps_iono, d_user_pvt_solver->gps_utc_model, gps_ephemeris_iter->second, d_user_pvt_solver->galileo_iono, d_user_pvt_solver->galileo_utc_model); + rp->log_rinex_nav(rp->navMixFile, d_user_pvt_solver->gps_ephemeris_map, d_user_pvt_solver->galileo_ephemeris_map); b_rinex_header_written = true; // do not write header anymore } break; From 51cf91425b74a0712b3621b77aaed9ed00960f9a Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 13 Sep 2019 18:58:17 +0200 Subject: [PATCH 7/7] Update changelog --- docs/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/changelog b/docs/changelog index 94815d7e1..3f220156f 100644 --- a/docs/changelog +++ b/docs/changelog @@ -11,6 +11,11 @@ - New PVT parameter enable_rx_clock_correction parameter allows to enable or disable the application of the Time solution correction to the computation of Observables. +### Improvements in Interoperability: + + - Added triple-band configurations RINEX outputs. + + ### Improvements in Maintainability: - New CMake option ENABLE_ARMA_NO_DEBUG defines the macro ARMA_NO_DEBUG, which disables all run-time checks, such as bounds checking, in the Armadillo library. This will result in faster code. This option is disabled by default during development, but automatically set to ON if the option ENABLE_PACKAGING is set to ON. @@ -37,6 +42,7 @@ ### Improvements in Usability: +- A new parameter allows to process raw sample files containing signals dated before year 2009. - Improved DLL-PLL binary dump MATLAB/Octave plot script. Old versions removed. - Simplified RTKLIB error log. - Added a Python 3 plotting script to show relative performance of generic volk_gnsssdr kernels wrt SIMD fastest versions.