diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index 50fc4e57d..6f21adfc2 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -20,6 +20,7 @@ */ #include "gnss_flowgraph.h" +#include "GLONASS_L1_L2_CA.h" #include "GPS_L1_CA.h" #include "GPS_L2C.h" #include "GPS_L5.h" @@ -2029,15 +2030,51 @@ std::vector GNSSFlowgraph::split_string(const std::string& s, char } +void GNSSFlowgraph::keep_one_glonass_slot_per_frequency(std::set& available_prns) +{ + std::set selected_frequency_channels; + std::set unique_frequency_prns; + + for (const auto prn : available_prns) + { + if (prn == 0) + { + LOG(WARNING) << "Ignoring invalid GLONASS slot " << prn << " in Glonass.prns"; + continue; + } + + const auto freq_channel = GLONASS_PRN.find(prn); + if (freq_channel == GLONASS_PRN.cend()) + { + LOG(WARNING) << "Ignoring GLONASS slot " << prn << " without a configured GLONASS frequency channel"; + continue; + } + + if (selected_frequency_channels.insert(freq_channel->second).second) + { + unique_frequency_prns.insert(prn); + } + else + { + LOG(WARNING) << "Ignoring GLONASS slot " << prn + << " because another configured orbital slot already uses frequency channel " + << freq_channel->second; + } + } + + available_prns = std::move(unique_frequency_prns); +} + + void GNSSFlowgraph::set_signals_list() { - // Glonass removing satellites sharing same frequency number(1 and 5, 2 and 6, 3 and 7, 4 and 6, 11 and 15, 12 and 16, 14 and 18, 17 and 21 + // GLONASS uses FDMA, so only one orbital slot per frequency channel is queued for acquisition. std::unordered_map> available_prn_map = { {"GPS", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}}, {"SBAS", {123, 131, 135, 136, 138}}, {"Galileo", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36}}, - {"Glonass", {1, 2, 3, 4, 9, 10, 11, 12, 18, 19, 20, 21, 24}}, + {"Glonass", {1, 2, 3, 4, 9, 10, 11, 12, 18, 19, 20, 21, 26, 27, 28}}, {"Beidou", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, @@ -2092,6 +2129,11 @@ void GNSSFlowgraph::set_signals_list() } } } + + if (gnss_system_str == "Glonass") + { + keep_one_glonass_slot_per_frequency(available_prns); + } } #if CXX_LESS_THAN_17 for (const auto& entry : signal_mapping) @@ -2276,7 +2318,8 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(const std::string& searched_signal { std::list::iterator it2; it2 = std::find_if(std::begin(available_signals), std::end(available_signals), - [&](Gnss_Signal const& sig) { return sig.get_satellite().get_PRN() == current_status.second->PRN; }); + [&](Gnss_Signal const& sig) + { return sig.get_satellite().get_PRN() == current_status.second->PRN; }); if (it2 != available_signals.end()) { diff --git a/src/core/receiver/gnss_flowgraph.h b/src/core/receiver/gnss_flowgraph.h index ee017412a..5bc6cf8a9 100644 --- a/src/core/receiver/gnss_flowgraph.h +++ b/src/core/receiver/gnss_flowgraph.h @@ -39,6 +39,7 @@ #include // for map #include // for for shared_ptr, dynamic_pointer_cast #include // for mutex +#include // for set #include // for string #include // for unordered_map #include // for pair @@ -197,6 +198,8 @@ private: void check_signal_conditioners(); void set_signals_list(); + void keep_one_glonass_slot_per_frequency(std::set& available_prns); + void set_channels_state(); // Initializes the channels state (start acquisition or keep standby) // using the configuration parameters (number of channels and max channels in acquisition) Gnss_Signal search_next_signal(const std::string& searched_signal, diff --git a/src/core/system_parameters/GLONASS_L1_L2_CA.h b/src/core/system_parameters/GLONASS_L1_L2_CA.h index 4c74b9687..7e7c753f0 100644 --- a/src/core/system_parameters/GLONASS_L1_L2_CA.h +++ b/src/core/system_parameters/GLONASS_L1_L2_CA.h @@ -141,7 +141,8 @@ constexpr double GLONASS_LEAP_SECONDS[19][7] = { {1981, 7, 1, 0, 0, 0, -1}, {}}; -//!< GLONASS SV's orbital slots PRN = (orbital_slot - 1) +// GLONASS RINEX satellite numbers are slot numbers. This table maps Rnn slot +// numbers to the corresponding FDMA frequency channel. const std::map GLONASS_PRN = { { 0, @@ -225,7 +226,7 @@ const std::map GLONASS_PRN = { }, // Plane 3 { 20, - -5, + 2, }, // Plane 3 { 21, @@ -238,8 +239,23 @@ const std::map GLONASS_PRN = { { 23, 3, - }, // Plane 3 - {24, 2}}; // Plane 3 + }, // Plane 3 + { + 24, + 2, + }, // Plane 3 + { + 26, + -6, + }, + { + 27, + -5, + }, + { + 28, + 7, + }}; const std::vector GLONASS_GNAV_CRC_I_INDEX{9, 10, 12, 13, 15, 17, 19, 20, 22, 24, 26, 28, 30, 32, 34, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84}; const std::vector GLONASS_GNAV_CRC_J_INDEX{9, 11, 12, 14, 15, 18, 19, 21, 22, 25, 26, 29, 30, 33, 34, 36, 37, 40, 41, 44, 45, 48, 49, 52, 53, 56, 57, 60, 61, 64, 65, 67, 68, 71, 72, 75, 76, 79, 80, 83, 84}; diff --git a/src/core/system_parameters/gnss_satellite.cc b/src/core/system_parameters/gnss_satellite.cc index 5f73fc865..aa5921895 100644 --- a/src/core/system_parameters/gnss_satellite.cc +++ b/src/core/system_parameters/gnss_satellite.cc @@ -15,6 +15,7 @@ */ #include "gnss_satellite.h" +#include "GLONASS_L1_L2_CA.h" #include #if USE_GLOG_AND_GFLAGS @@ -182,14 +183,17 @@ void Gnss_Satellite::update_PRN(uint32_t PRN_) } else { - if (PRN_ < 1 or PRN_ > 24) + if (PRN_ < 1 or PRN_ > 31) { - DLOG(INFO) << "This PRN is not defined"; - // Adjusting for PRN 26, now used in - PRN = PRN_; + DLOG(INFO) << "This GLONASS slot number is not defined"; + PRN = 0; } else { + if (GLONASS_PRN.find(PRN_) == GLONASS_PRN.cend()) + { + DLOG(INFO) << "GLONASS frequency channel for slot " << PRN_ << " is not configured"; + } PRN = PRN_; } } @@ -218,9 +222,9 @@ void Gnss_Satellite::set_PRN(uint32_t PRN_) } else if (system == "Glonass") { - if (PRN_ < 1 or PRN_ > 24) + if (PRN_ == 0 or GLONASS_PRN.find(PRN_) == GLONASS_PRN.cend()) { - DLOG(INFO) << "This PRN is not defined"; + DLOG(INFO) << "This GLONASS slot/frequency channel is not configured"; PRN = 0; } else @@ -446,108 +450,11 @@ std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_ if (system_ == "Glonass") { - // Info from http://www.sdcm.ru/smglo/grupglo?version=eng&site=extern - // See also https://www.glonass-iac.ru/en/GLONASS/ - switch (PRN_) + const auto freq_channel = GLONASS_PRN.find(PRN_); + if (freq_channel != GLONASS_PRN.cend()) { - case 1: - block_ = std::string("1"); // Plane 1 - rf_link = 1; - break; - case 2: - block_ = std::string("-4"); // Plane 1 - rf_link = -4; - break; - case 3: - block_ = std::string("5"); // Plane 1 - rf_link = 5; - break; - case 4: - block_ = std::string("6"); // Plane 1 - rf_link = 6; - break; - case 5: - block_ = std::string("1"); // Plane 1 - rf_link = 1; - break; - case 6: - block_ = std::string("-4"); // Plane 1 - rf_link = -4; - break; - case 7: - block_ = std::string("5"); // Plane 1 - rf_link = 5; - break; - case 8: - block_ = std::string("6"); // Plane 1 - rf_link = 6; - break; - case 9: - block_ = std::string("-2"); // Plane 2 - rf_link = -2; - break; - case 10: - block_ = std::string("-7"); // Plane 2 - rf_link = -7; - break; - case 11: - block_ = std::string("0"); // Plane 2 - rf_link = 0; - break; - case 12: - block_ = std::string("-1"); // Plane 2 - rf_link = -1; - break; - case 13: - block_ = std::string("-2"); // Plane 2 - rf_link = -2; - break; - case 14: - block_ = std::string("-7"); // Plane 2 - rf_link = -7; - break; - case 15: - block_ = std::string("0"); // Plane 2 - rf_link = 0; - break; - case 16: - block_ = std::string("-1"); // Plane 2 - rf_link = -1; - break; - case 17: - block_ = std::string("4"); // Plane 3 - rf_link = 4; - break; - case 18: - block_ = std::string("-3"); // Plane 3 - rf_link = -3; - break; - case 19: - block_ = std::string("3"); // Plane 3 - rf_link = 3; - break; - case 20: - block_ = std::string("2"); // Plane 3 - rf_link = 2; - break; - case 21: - block_ = std::string("4"); // Plane 3 - rf_link = 4; - break; - case 22: - block_ = std::string("-3"); // Plane 3 - rf_link = -3; - break; - case 23: - block_ = std::string("3"); // Plane 3 - rf_link = 3; - break; - case 24: - block_ = std::string("2"); // Plane 3 - rf_link = 2; - break; - default: - block_ = std::string("Unknown"); + rf_link = freq_channel->second; + block_ = std::to_string(freq_channel->second); } } if (system_ == "SBAS") diff --git a/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc b/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc index 4bdc322bd..70060ec7f 100644 --- a/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc +++ b/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc @@ -18,7 +18,28 @@ #include "glonass_gnav_ephemeris.h" +#include "GLONASS_L1_L2_CA.h" #include "gnss_signal_replica.h" +#include "gnss_satellite.h" + + +TEST(GlonassGnavEphemerisTest, SatelliteRfLinkMatchesFrequencyChannelTable) +{ + EXPECT_EQ(2, Gnss_Satellite("Glonass", 20).get_rf_link()); + EXPECT_EQ(-5, Gnss_Satellite("Glonass", 27).get_rf_link()); + EXPECT_EQ(7, Gnss_Satellite("Glonass", 28).get_rf_link()); + + for (const auto& prn_freq : GLONASS_PRN) + { + if (prn_freq.first == 0) + { + continue; + } + + const Gnss_Satellite satellite("Glonass", prn_freq.first); + EXPECT_EQ(prn_freq.second, satellite.get_rf_link()) << "PRN " << prn_freq.first; + } +} TEST(GlonassGnavEphemerisTest, ComputeGlonassTime)