mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2026-10-09 01:01:50 +00:00
Fix GGTO handling (see ICD 5.1.8)
This commit is contained in:
@@ -2393,7 +2393,10 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver,
|
||||
{
|
||||
iono_lines.emplace_back(get_galileo_iono_alpha_line(pvt_solver->galileo_iono));
|
||||
time_corr_lines.emplace_back(get_galileo_time_corr_line(pvt_solver->galileo_utc_model));
|
||||
time_corr_lines.emplace_back(get_gps_to_galileo_time_corr_line(pvt_solver->galileo_utc_model));
|
||||
if (pvt_solver->galileo_utc_model.flag_GGTO)
|
||||
{
|
||||
time_corr_lines.emplace_back(get_gps_to_galileo_time_corr_line(pvt_solver->galileo_utc_model));
|
||||
}
|
||||
|
||||
if (system_time_str == "GAL")
|
||||
{
|
||||
@@ -2507,7 +2510,10 @@ void Rinex_Printer::print_rinex_annotation(const Rtklib_Solver* pvt_solver,
|
||||
{
|
||||
nav_header_info.emplace_back("GAL", "IONOSPHERIC CORR", get_galileo_iono_alpha_line(pvt_solver->galileo_iono));
|
||||
nav_header_info.emplace_back("GAUT", "TIME SYSTEM CORR", get_galileo_time_corr_line(pvt_solver->galileo_utc_model));
|
||||
nav_header_info.emplace_back("GPGA", "TIME SYSTEM CORR", get_gps_to_galileo_time_corr_line(pvt_solver->galileo_utc_model));
|
||||
if (pvt_solver->galileo_utc_model.flag_GGTO)
|
||||
{
|
||||
nav_header_info.emplace_back("GPGA", "TIME SYSTEM CORR", get_gps_to_galileo_time_corr_line(pvt_solver->galileo_utc_model));
|
||||
}
|
||||
d_rinex_header_galileo_updated = true;
|
||||
|
||||
if (system_time_str == "GAL")
|
||||
|
||||
@@ -649,8 +649,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
|
||||
<< " dB-Hz" << TEXT_RESET << std::endl;
|
||||
}
|
||||
|
||||
d_delta_t = tmp_obj->A_0G + tmp_obj->A_1G * (static_cast<double>(d_TOW_at_current_symbol_ms) / 1000.0 - tmp_obj->t_0G + 604800 * (std::fmod(static_cast<float>(d_inav_nav.get_Galileo_week() - tmp_obj->WN_0G), 64.0)));
|
||||
DLOG(INFO) << "delta_t=" << d_delta_t << "[s]";
|
||||
if (tmp_obj->flag_GGTO)
|
||||
{
|
||||
d_delta_t = tmp_obj->A_0G + tmp_obj->A_1G * (static_cast<double>(d_TOW_at_current_symbol_ms) / 1000.0 - tmp_obj->t_0G + 604800 * (std::fmod(static_cast<float>(d_inav_nav.get_Galileo_week() - tmp_obj->WN_0G), 64.0)));
|
||||
DLOG(INFO) << "delta_t=" << d_delta_t << "[s]";
|
||||
}
|
||||
}
|
||||
|
||||
if (d_inav_nav.have_new_almanac() == true) // flag_almanac_4 tells if W10 available.
|
||||
|
||||
@@ -524,6 +524,7 @@ Galileo_Utc_Model Galileo_Inav_Message::get_utc_model() const
|
||||
utc_model.A_1G = A_1G_10;
|
||||
utc_model.t_0G = t_0G_10;
|
||||
utc_model.WN_0G = WN_0G_10;
|
||||
utc_model.flag_GGTO = get_flag_GGTO();
|
||||
return utc_model;
|
||||
}
|
||||
|
||||
@@ -1243,6 +1244,12 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk)
|
||||
WN_0G_10 = static_cast<int32_t>(read_navigation_unsigned(data_jk_bits, WN_0_G_10_BIT));
|
||||
flag_GGTO_4 = true;
|
||||
DLOG(INFO) << "WN_0G_10= " << WN_0G_10;
|
||||
// OS SIS ICD: GGTO is unavailable only when all four raw fields
|
||||
// are simultaneously encoded as all ones.
|
||||
flag_GGTO_valid = !(read_navigation_unsigned(data_jk_bits, A_0_G_10_BIT) == 0xFFFFU &&
|
||||
read_navigation_unsigned(data_jk_bits, A_1_G_10_BIT) == 0x0FFFU &&
|
||||
read_navigation_unsigned(data_jk_bits, T_0_G_10_BIT) == 0x00FFU &&
|
||||
read_navigation_unsigned(data_jk_bits, WN_0_G_10_BIT) == 0x003FU);
|
||||
flag_almanac_4 = true;
|
||||
DLOG(INFO) << "flag_tow_set" << flag_TOW_set;
|
||||
nav_bits_word_10 = data_jk_bits.to_string().substr(86, 42);
|
||||
|
||||
@@ -230,7 +230,7 @@ public:
|
||||
|
||||
inline bool get_flag_GGTO() const
|
||||
{
|
||||
return (flag_GGTO_1 == true && flag_GGTO_2 == true && flag_GGTO_3 == true && flag_GGTO_4 == true);
|
||||
return (flag_GGTO_1 == true && flag_GGTO_2 == true && flag_GGTO_3 == true && flag_GGTO_4 == true && flag_GGTO_valid == true);
|
||||
}
|
||||
|
||||
inline double get_A0G() const
|
||||
@@ -499,6 +499,7 @@ private:
|
||||
bool flag_GGTO_2{};
|
||||
bool flag_GGTO_3{};
|
||||
bool flag_GGTO_4{};
|
||||
bool flag_GGTO_valid{};
|
||||
|
||||
bool flag_CED{};
|
||||
bool enable_rs{};
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define GNSS_SDR_GALILEO_UTC_MODEL_H
|
||||
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
/** \addtogroup Core
|
||||
@@ -61,6 +62,7 @@ public:
|
||||
int32_t WN_0G{};
|
||||
|
||||
bool flag_utc_model{};
|
||||
bool flag_GGTO{};
|
||||
|
||||
template <class Archive>
|
||||
|
||||
@@ -70,9 +72,6 @@ public:
|
||||
*/
|
||||
inline void serialize(Archive& archive, const unsigned int version)
|
||||
{
|
||||
if (version)
|
||||
{
|
||||
};
|
||||
archive& BOOST_SERIALIZATION_NVP(A0);
|
||||
archive& BOOST_SERIALIZATION_NVP(A1);
|
||||
archive& BOOST_SERIALIZATION_NVP(Delta_tLS);
|
||||
@@ -82,9 +81,28 @@ public:
|
||||
archive& BOOST_SERIALIZATION_NVP(DN);
|
||||
archive& BOOST_SERIALIZATION_NVP(Delta_tLSF);
|
||||
archive& BOOST_SERIALIZATION_NVP(flag_utc_model);
|
||||
if (version > 0)
|
||||
{
|
||||
archive& BOOST_SERIALIZATION_NVP(A_0G);
|
||||
archive& BOOST_SERIALIZATION_NVP(A_1G);
|
||||
archive& BOOST_SERIALIZATION_NVP(t_0G);
|
||||
archive& BOOST_SERIALIZATION_NVP(WN_0G);
|
||||
archive& BOOST_SERIALIZATION_NVP(flag_GGTO);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Version 0 archives predate GGTO persistence.
|
||||
A_0G = 0.0;
|
||||
A_1G = 0.0;
|
||||
t_0G = 0;
|
||||
WN_0G = 0;
|
||||
flag_GGTO = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_CLASS_VERSION(Galileo_Utc_Model, 1)
|
||||
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
|
||||
+72
-6
@@ -70,22 +70,19 @@ uint32_t compute_galileo_inav_crc(const std::string& crc_data)
|
||||
}
|
||||
|
||||
|
||||
std::pair<std::string, std::string> build_inav_page(uint8_t word_type, char page_type, const std::string& osnma_sis)
|
||||
std::pair<std::string, std::string> build_inav_page_from_data(const std::string& data_jk, char page_type, const std::string& osnma_sis)
|
||||
{
|
||||
std::string data_k = to_bit_string(word_type, 6);
|
||||
data_k.append(106, '0');
|
||||
|
||||
std::string even_page;
|
||||
even_page.reserve(114);
|
||||
even_page.push_back('0');
|
||||
even_page.push_back(page_type);
|
||||
even_page += data_k;
|
||||
even_page += data_jk.substr(0, 112);
|
||||
|
||||
std::string odd_page_without_crc;
|
||||
odd_page_without_crc.reserve(82);
|
||||
odd_page_without_crc.push_back('1');
|
||||
odd_page_without_crc.push_back(page_type);
|
||||
odd_page_without_crc.append(16, '0');
|
||||
odd_page_without_crc += data_jk.substr(112, 16);
|
||||
odd_page_without_crc += osnma_sis;
|
||||
odd_page_without_crc.append(22, '0'); // SAR
|
||||
odd_page_without_crc.append(2, '0'); // Spare
|
||||
@@ -101,6 +98,33 @@ std::pair<std::string, std::string> build_inav_page(uint8_t word_type, char page
|
||||
}
|
||||
|
||||
|
||||
std::pair<std::string, std::string> build_inav_page(uint8_t word_type, char page_type, const std::string& osnma_sis)
|
||||
{
|
||||
std::string data_jk = to_bit_string(word_type, 6);
|
||||
data_jk.append(122, '0');
|
||||
return build_inav_page_from_data(data_jk, page_type, osnma_sis);
|
||||
}
|
||||
|
||||
|
||||
void set_inav_field(std::string& data_jk, const std::vector<std::pair<int32_t, int32_t>>& field, uint32_t value)
|
||||
{
|
||||
const auto& range = field.front();
|
||||
data_jk.replace(static_cast<size_t>(range.first - 1), static_cast<size_t>(range.second), to_bit_string(value, static_cast<size_t>(range.second)));
|
||||
}
|
||||
|
||||
|
||||
std::string build_ggto_word(uint32_t a0g, uint32_t a1g, uint32_t t0g, uint32_t wn0g)
|
||||
{
|
||||
std::string data_jk(128, '0');
|
||||
set_inav_field(data_jk, PAGE_TYPE_BIT, 10U);
|
||||
set_inav_field(data_jk, A_0_G_10_BIT, a0g);
|
||||
set_inav_field(data_jk, A_1_G_10_BIT, a1g);
|
||||
set_inav_field(data_jk, T_0_G_10_BIT, t0g);
|
||||
set_inav_field(data_jk, WN_0_G_10_BIT, wn0g);
|
||||
return data_jk;
|
||||
}
|
||||
|
||||
|
||||
std::string build_osnma_sis(uint8_t hkroot, uint32_t mack)
|
||||
{
|
||||
return to_bit_string(hkroot, 8) + to_bit_string(mack, 32);
|
||||
@@ -115,6 +139,14 @@ void feed_inav_page(Galileo_Inav_Message& decoder, uint8_t word_type, char page_
|
||||
}
|
||||
|
||||
|
||||
void feed_inav_data_page(Galileo_Inav_Message& decoder, const std::string& data_jk)
|
||||
{
|
||||
const auto page = build_inav_page_from_data(data_jk, '0', std::string(40, '0'));
|
||||
decoder.split_page(page.first, 0);
|
||||
decoder.split_page(page.second, 1);
|
||||
}
|
||||
|
||||
|
||||
OSNMA_msg decode_osnma_page(uint8_t word_type, char page_type, const std::string& osnma_sis)
|
||||
{
|
||||
Galileo_Inav_Message decoder;
|
||||
@@ -124,6 +156,40 @@ OSNMA_msg decode_osnma_page(uint8_t word_type, char page_type, const std::string
|
||||
} // namespace
|
||||
|
||||
|
||||
TEST(Galileo_INAV_Message_Test, GgtoAllOnesEncodingIsUnavailable)
|
||||
{
|
||||
Galileo_Inav_Message decoder;
|
||||
feed_inav_data_page(decoder, build_ggto_word(0xFFFFU, 0x0FFFU, 0x00FFU, 0x003FU));
|
||||
|
||||
ASSERT_TRUE(decoder.get_flag_CRC_test());
|
||||
EXPECT_FALSE(decoder.get_flag_GGTO());
|
||||
EXPECT_FALSE(decoder.get_utc_model().flag_GGTO);
|
||||
}
|
||||
|
||||
|
||||
TEST(Galileo_INAV_Message_Test, GgtoUnavailableRequiresAllFourAllOnesFields)
|
||||
{
|
||||
const std::array<std::array<uint32_t, 4>, 4> available_encodings{{
|
||||
{{0xFFFEU, 0x0FFFU, 0x00FFU, 0x003FU}},
|
||||
{{0xFFFFU, 0x0FFEU, 0x00FFU, 0x003FU}},
|
||||
{{0xFFFFU, 0x0FFFU, 0x00FEU, 0x003FU}},
|
||||
{{0xFFFFU, 0x0FFFU, 0x00FFU, 0x003EU}},
|
||||
}};
|
||||
|
||||
for (size_t i = 0; i < available_encodings.size(); ++i)
|
||||
{
|
||||
SCOPED_TRACE(i);
|
||||
Galileo_Inav_Message decoder;
|
||||
const auto& fields = available_encodings[i];
|
||||
feed_inav_data_page(decoder, build_ggto_word(fields[0], fields[1], fields[2], fields[3]));
|
||||
|
||||
ASSERT_TRUE(decoder.get_flag_CRC_test());
|
||||
EXPECT_TRUE(decoder.get_flag_GGTO());
|
||||
EXPECT_TRUE(decoder.get_utc_model().flag_GGTO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Galileo_FNAV_INAV_test : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user