Fix Glonass carrier phase and time annotations in RINEX files

This commit is contained in:
Carles Fernandez
2026-06-11 07:22:02 +02:00
parent 6584ed5d17
commit 7bd6622e2c
13 changed files with 201 additions and 121 deletions
@@ -165,7 +165,10 @@ void find_obs_record_lines(const std::string& obsfile, const std::string& sat, s
{
line_epoch = line_str;
}
if (line_str.find(sat, 0) != std::string::npos)
// Observation records start with the satellite identifier; header
// lines may also contain it (e.g. GLONASS SLOT / FRQ #), so the
// match is anchored to the beginning of the line
if (line_str.compare(0, sat.size(), sat) == 0)
{
no_more_finds = true;
line_sat = line_str;
@@ -379,23 +382,25 @@ TEST_F(RinexPrinterTest, GlonassObsHeader)
fstr.seekg(0);
std::string line_aux;
std::string line_slot_frq;
std::string line_str;
bool no_more_finds = false;
while (!fstr.eof())
{
std::getline(fstr, line_str);
if (!no_more_finds)
if (line_aux.empty() && line_str.find("SYS / # / OBS TYPES", 59) != std::string::npos)
{
if (line_str.find("SYS / # / OBS TYPES", 59) != std::string::npos)
{
no_more_finds = true;
line_aux = std::string(line_str);
}
line_aux = std::string(line_str);
}
if (line_slot_frq.empty() && line_str.find("GLONASS SLOT / FRQ #", 59) != std::string::npos)
{
line_slot_frq = std::string(line_str);
}
}
std::string expected_str("R 4 C1C L1C D1C S1C SYS / # / OBS TYPES ");
std::string expected_slot_frq(" 27 R01 1 R02 -4 R03 5 R04 6 R05 1 R06 -4 R07 5 R08 6 GLONASS SLOT / FRQ #");
EXPECT_EQ(0, expected_str.compare(line_aux));
EXPECT_EQ(0, expected_slot_frq.compare(line_slot_frq));
fstr.close();
fs::remove(obsfile);
fs::remove(navfile);
@@ -249,3 +249,53 @@ std::string str12("0110010101001100000011110110100110100100010100001000111110000
std::string str13("0110111011100100111110100001000110100010011101001011111110100100101010011010001101001");
std::string str14("0111010101010000000100011000011110100110111100001110110100001000001111001101010000101");
std::string str15("0111101110101010001110101010100111101100001101001011111111100010101010011001010011101");
/*!
* \brief Testing satellite identification fields filled in by the second
* almanac string of the pair (string 7 for satellite slot 6, whose H_n_A
* value of 28 represents carrier frequency channel -4)
*/
TEST(GlonassGnavNavigationMessageTest, String7SetsAlmanacSatelliteInfo)
{
Glonass_Gnav_Navigation_Message gnav_nav_message;
gnav_nav_message.string_decoder(str6);
gnav_nav_message.string_decoder(str7);
Glonass_Gnav_Almanac gnav_almanac = gnav_nav_message.get_almanac(6);
EXPECT_EQ(gnav_almanac.i_satellite_slot_number, 6U);
EXPECT_EQ(gnav_almanac.PRN, 6U);
EXPECT_EQ(gnav_almanac.i_satellite_freq_channel, -4);
}
/*!
* \brief In frames 1-4, string 14 carries almanac data (here for satellite
* slot 10, in frame 2). The frame is known from the almanac slot number
* decoded in a previous string of the same frame
*/
TEST(GlonassGnavNavigationMessageTest, String14AlmanacDecoder)
{
Glonass_Gnav_Navigation_Message gnav_nav_message;
gnav_nav_message.string_decoder(str6); // almanac slot 6 identifies frame 2
gnav_nav_message.string_decoder(str14); // almanac for slot 10, also in frame 2
EXPECT_DOUBLE_EQ(gnav_nav_message.get_almanac(10).d_n_A, 10.0);
}
/*!
* \brief Until the frame being received is identified, string 14 content is
* ambiguous (in frame 5 it carries the B1/B2 UTC parameters instead of
* almanac data), so it must not be decoded as almanac
*/
TEST(GlonassGnavNavigationMessageTest, String14RequiresKnownFrame)
{
Glonass_Gnav_Navigation_Message gnav_nav_message;
gnav_nav_message.string_decoder(str14);
EXPECT_DOUBLE_EQ(gnav_nav_message.get_almanac(10).d_n_A, 0.0);
}