diff --git a/src/algorithms/PVT/libs/has_simple_printer.cc b/src/algorithms/PVT/libs/has_simple_printer.cc index a7a87b16a..13692b123 100644 --- a/src/algorithms/PVT/libs/has_simple_printer.cc +++ b/src/algorithms/PVT/libs/has_simple_printer.cc @@ -166,7 +166,7 @@ bool Has_Simple_Printer::print_message(const Galileo_HAS_data* const has_data) d_has_file << "Do not use HAS\n"; break; default: - d_has_file << '\n'; + d_has_file << "Unknown\n"; } d_has_file << "HAS message ID: " << static_cast(has_data->message_id) << "\n\n"; @@ -198,8 +198,39 @@ bool Has_Simple_Printer::print_message(const Galileo_HAS_data* const has_data) Nsat += std::count(sat_mask.begin(), sat_mask.end(), '1'); } - d_has_file << indent << indent << "Satellite Mask: " << print_vector_binary(has_data->satellite_mask, HAS_MSG_SATELLITE_MASK_LENGTH) << " (Nsat = " << Nsat << ")\n"; - d_has_file << indent << indent << "Signal Mask: " << print_vector_binary(has_data->signal_mask, HAS_MSG_SIGNAL_MASK_LENGTH) << " (see Signal Mask table in HAS-SIS-ICD)\n"; + d_has_file << indent << indent << "Satellite Mask: " << print_vector_binary(has_data->satellite_mask, HAS_MSG_SATELLITE_MASK_LENGTH) << '\n'; + d_has_file << indent << indent << " Nsat: " << Nsat << '\n'; + for (uint8_t i = 0; i < has_data->Nsys; i++) + { + std::string system("Reserved"); + if (has_data->gnss_id_mask[i] == 0) + { + system = "GPS"; + } + if (has_data->gnss_id_mask[i] == 2) + { + system = "Galileo"; + } + + d_has_file << indent << indent << " PRN for " << system << ": " << print_vector(has_data->get_PRNs_in_mask(i)) << " (" << has_data->get_PRNs_in_mask(i).size() << " satellites)\n"; + } + + d_has_file << indent << indent << "Signal Mask: " << print_vector_binary(has_data->signal_mask, HAS_MSG_SIGNAL_MASK_LENGTH) << '\n'; + for (uint8_t i = 0; i < has_data->Nsys; i++) + { + std::string system("Reserved"); + if (has_data->gnss_id_mask[i] == 0) + { + system = "GPS"; + } + if (has_data->gnss_id_mask[i] == 2) + { + system = "Galileo"; + } + + d_has_file << indent << indent << " Bias corrections for " << system << " signals: " << print_vector_string(has_data->get_signals_in_mask(i)) << '\n'; + } + d_has_file << indent << indent << "Cell Mask Availability Flag: " << print_vector(has_data->cell_mask_availability_flag) << '\n'; for (uint8_t i = 0; i < has_data->Nsys; i++) { @@ -271,7 +302,8 @@ bool Has_Simple_Printer::print_message(const Galileo_HAS_data* const has_data) Nsatprime += std::count(binary.begin(), binary.end(), '1'); } } - d_has_file << " (Nsat in subset = " << Nsatprime << ")\n"; + d_has_file << '\n'; + d_has_file << " Nsat in subset = " << Nsatprime << '\n'; const std::string text("Delta Clock C0 [m]: "); const std::string filler(indent.length() * 2 + text.length(), ' '); d_has_file << indent << indent << text << print_matrix(has_data->delta_clock_c0_clock_subset, filler, HAS_MSG_DELTA_CLOCK_SCALE_FACTOR); @@ -393,6 +425,26 @@ std::string Has_Simple_Printer::print_matrix(const std::vector>& } +std::string Has_Simple_Printer::print_vector_string(const std::vector& vec) const +{ + std::string msg; + bool first = true; + for (auto el : vec) + { + if (first == true) + { + msg += el; + first = false; + } + else + { + msg += " " + el; + } + } + return msg; +} + + bool Has_Simple_Printer::close_file() { if (d_has_file.is_open()) diff --git a/src/algorithms/PVT/libs/has_simple_printer.h b/src/algorithms/PVT/libs/has_simple_printer.h index 2d14aec3b..11d390218 100644 --- a/src/algorithms/PVT/libs/has_simple_printer.h +++ b/src/algorithms/PVT/libs/has_simple_printer.h @@ -51,6 +51,8 @@ private: template std::string print_matrix(const std::vector>& mat, const std::string& filler, float scale_factor = 1) const; + std::string print_vector_string(const std::vector& vec) const; + bool close_file(); std::mutex d_mutex; diff --git a/src/core/system_parameters/CMakeLists.txt b/src/core/system_parameters/CMakeLists.txt index 0f58d030e..e88306991 100644 --- a/src/core/system_parameters/CMakeLists.txt +++ b/src/core/system_parameters/CMakeLists.txt @@ -16,6 +16,7 @@ set(SYSTEM_PARAMETERS_SOURCES galileo_almanac_helper.cc galileo_cnav_message.cc galileo_fnav_message.cc + galileo_has_data.cc galileo_inav_message.cc galileo_reduced_ced.cc beidou_dnav_navigation_message.cc diff --git a/src/core/system_parameters/galileo_has_data.cc b/src/core/system_parameters/galileo_has_data.cc new file mode 100644 index 000000000..35be32fa2 --- /dev/null +++ b/src/core/system_parameters/galileo_has_data.cc @@ -0,0 +1,384 @@ +/*! + * \file galileo_has_data.cc + * \brief Class for Galileo HAS message type 1 data storage + * \author Carles Fernandez-Prades, 2020-2021 cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "galileo_has_data.h" +#include "Galileo_CNAV.h" +#include +#include + + +std::vector Galileo_HAS_data::get_PRNs_in_mask(uint8_t nsys) const +{ + std::vector prn; + if (nsys < satellite_mask.size()) + { + uint64_t sat_mask = satellite_mask[nsys]; + std::bitset bits(sat_mask); + std::string bit_str = bits.to_string(); + for (int32_t i = 0; i < HAS_MSG_NUMBER_SATELLITE_IDS; i++) + { + if (bit_str[i] == '1') + { + prn.push_back(i + 1); + } + } + } + return prn; +} + + +std::vector Galileo_HAS_data::get_PRNs_in_submask(uint8_t nsys) const +{ + std::vector prn; + std::vector prn_in_submask; + if (nsys < satellite_submask.size()) + { + auto it = std::find(gnss_id_mask.begin(), gnss_id_mask.end(), gnss_id_clock_subset[nsys]); + int index = 0; + if (it != gnss_id_mask.end()) + { + index = it - gnss_id_mask.begin(); + } + else + { + return prn_in_submask; + } + + uint8_t nsys_index_in_mask = gnss_id_mask[index]; + uint64_t sat_mask = satellite_mask[nsys_index_in_mask]; + + std::bitset bits(sat_mask); + std::string mask_bit_str = bits.to_string(); + for (int i = 0; i < HAS_MSG_NUMBER_SATELLITE_IDS; i++) + { + if (mask_bit_str[i] == '1') + { + prn.push_back(i + 1); + } + } + + int number_sats_this_gnss_id = std::count(mask_bit_str.begin(), mask_bit_str.end(), '1'); + uint64_t sat_submask = satellite_submask[nsys]; + // convert into string + std::string sat_submask_str(""); + uint64_t aux = 1; + for (int k = 0; k < number_sats_this_gnss_id - 1; k++) + { + if ((aux & sat_submask) >= 1) + { + sat_submask_str = "1" + sat_submask_str; + } + else + { + sat_submask_str = "0" + sat_submask_str; + } + aux <<= 1; + } + + for (int i = 0; i < number_sats_this_gnss_id; i++) + { + if (sat_submask_str[i] == '1') + { + prn_in_submask.push_back(prn[i]); + } + } + } + + return prn_in_submask; +} + + +std::vector Galileo_HAS_data::get_signals_in_mask(uint8_t nsys) const +{ + std::vector signals_in_mask; + if (signal_mask.size() > nsys) + { + uint16_t sig = signal_mask[nsys]; + std::bitset bits(sig); + std::string bits_str = bits.to_string(); + for (int32_t k = 0; k < HAS_MSG_NUMBER_SIGNAL_MASKS; k++) + { + if (bits_str[k] == '1') + { + uint8_t system = gnss_id_mask[nsys]; + std::string signal; + switch (k) + { + case 0: + if (system == 0) + { + // GPS + signal = "L1 C/A"; + } + else if (system == 2) + { + // Galileo + signal = "E1-B I/NAV OS"; + } + else + { + signal = "Unknown"; + } + break; + case 1: + if (system == 0) + { + // GPS + signal = "Reserved"; + } + else if (system == 2) + { + // Galileo + signal = "E1-C"; + } + else + { + signal = "Unknown"; + } + break; + case 2: + if (system == 0) + { + // GPS + signal = "Reserved"; + } + else if (system == 2) + { + // Galileo + signal = "E1-B + E1-C"; + } + else + { + signal = "Unknown"; + } + break; + case 3: + if (system == 0) + { + // GPS + signal = "L1 L1C(D)"; + } + else if (system == 2) + { + // Galileo + signal = "E5a-I F/NAV OS"; + } + else + { + signal = "Unknown"; + } + break; + case 4: + if (system == 0) + { + // GPS + signal = "L1 L1C(P)"; + } + else if (system == 2) + { + // Galileo + signal = "E5a-Q"; + } + else + { + signal = "Unknown"; + } + break; + case 5: + if (system == 0) + { + // GPS + signal = "L1 L1C(D+P)"; + } + else if (system == 2) + { + // Galileo + signal = "E5a-I+E5a-Q"; + } + else + { + signal = "Unknown"; + } + break; + case 6: + if (system == 0) + { + // GPS + signal = "L2 L2C(M)"; + } + else if (system == 2) + { + // Galileo + signal = "E5b-I I/NAV OS"; + } + else + { + signal = "Unknown"; + } + break; + case 7: + if (system == 0) + { + // GPS + signal = "L2 L2C(L)"; + } + else if (system == 2) + { + // Galileo + signal = "E5b-Q"; + } + else + { + signal = "Unknown"; + } + break; + case 8: + if (system == 0) + { + // GPS + signal = "L2 L2C(M+L)"; + } + else if (system == 2) + { + // Galileo + signal = "E5b-I+E5b-Q"; + } + else + { + signal = "Unknown"; + } + break; + case 9: + if (system == 0) + { + // GPS + signal = "L2 P"; + } + else if (system == 2) + { + // Galileo + signal = "E5-I"; + } + else + { + signal = "Unknown"; + } + break; + case 10: + if (system == 0) + { + // GPS + signal = "Reserved"; + } + else if (system == 2) + { + // Galileo + signal = "E5-Q"; + } + else + { + signal = "Unknown"; + } + break; + case 11: + if (system == 0) + { + // GPS + signal = "L5 I"; + } + else if (system == 2) + { + // Galileo + signal = "E5-I + E5-Q"; + } + else + { + signal = "Unknown"; + } + break; + case 12: + if (system == 0) + { + // GPS + signal = "L5 Q"; + } + else if (system == 2) + { + // Galileo + signal = "E6-B C/NAV HAS"; + } + else + { + signal = "Unknown"; + } + break; + case 13: + if (system == 0) + { + // GPS + signal = "L5 I + L5 Q"; + } + else if (system == 2) + { + // Galileo + signal = "E6-C"; + } + else + { + signal = "Unknown"; + } + break; + case 14: + if (system == 0) + { + // GPS + signal = "Reserved"; + } + else if (system == 2) + { + // Galileo + signal = "E6-B + E6-C"; + } + else + { + signal = "Unknown"; + } + break; + case 15: + if (system == 0) + { + // GPS + signal = "Reserved"; + } + else if (system == 2) + { + // Galileo + signal = "Reserved"; + } + else + { + signal = "Unknown"; + } + break; + default: + signal = "Unknown"; + } + signals_in_mask.push_back(signal); + } + } + } + return signals_in_mask; +} diff --git a/src/core/system_parameters/galileo_has_data.h b/src/core/system_parameters/galileo_has_data.h index 3704b166f..41381767b 100644 --- a/src/core/system_parameters/galileo_has_data.h +++ b/src/core/system_parameters/galileo_has_data.h @@ -1,14 +1,14 @@ /*! * \file galileo_has_data.h - * \brief Class for Galileo HAS message type 1 data storage - * \author Carles Fernandez-Prades, 2020 cfernandez(at)cttc.es + * \brief Class for Galileo HAS message type 1 data storage + * \author Carles Fernandez-Prades, 2020-2021 cfernandez(at)cttc.es * * ----------------------------------------------------------------------------- * * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. * This file is part of GNSS-SDR. * - * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -19,6 +19,7 @@ #define GNSS_SDR_GALILEO_HAS_DATA_H #include +#include #include /** \addtogroup Core @@ -50,6 +51,10 @@ class Galileo_HAS_data public: Galileo_HAS_data() = default; + std::vector get_PRNs_in_mask(uint8_t nsys) const; + std::vector get_PRNs_in_submask(uint8_t nsys) const; + std::vector get_signals_in_mask(uint8_t nsys) const; + mt1_header header; uint8_t has_status; uint8_t message_id;