Merge branch 'glonass-ecc' of https://github.com/vladisslav2011/gnss-sdr into vladisslav2011-glonass-ecc

This commit is contained in:
Carles Fernandez 2022-12-11 15:32:32 +01:00
commit 80c7d56771
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
4 changed files with 105 additions and 7 deletions

View File

@ -238,6 +238,7 @@ const std::vector<int32_t> GLONASS_GNAV_CRC_M_INDEX{20, 21, 22, 23, 24, 25, 26,
const std::vector<int32_t> GLONASS_GNAV_CRC_N_INDEX{35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65};
const std::vector<int32_t> GLONASS_GNAV_CRC_P_INDEX{66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85};
const std::vector<int32_t> GLONASS_GNAV_CRC_Q_INDEX{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, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85};
const std::vector<int32_t> GLONASS_GNAV_ECC_LOCATOR{0, 0, 1, 8, 2, 9, 10, 11, 3, 12, 13, 14, 15, 16, 17, 18, 4, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 5, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 6, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84};
// GLONASS GNAV NAVIGATION MESSAGE STRUCTURE
// NAVIGATION MESSAGE FIELDS POSITIONS

View File

@ -36,7 +36,7 @@ Glonass_Gnav_Navigation_Message::Glonass_Gnav_Navigation_Message()
}
bool Glonass_Gnav_Navigation_Message::CRC_test(const std::bitset<GLONASS_GNAV_STRING_BITS>& bits) const
bool Glonass_Gnav_Navigation_Message::CRC_test(std::bitset<GLONASS_GNAV_STRING_BITS>& bits) const
{
uint32_t sum_bits = 0;
int32_t sum_hamming = 0;
@ -128,7 +128,28 @@ bool Glonass_Gnav_Navigation_Message::CRC_test(const std::bitset<GLONASS_GNAV_ST
return true;
}
// All other conditions are assumed errors. TODO: Add correction for case B
if (C_Sigma && (sum_bits & 1))
{
int32_t syndrome = C1;
syndrome |= (C2 ? 2 : 0);
syndrome |= (C3 ? 4 : 0);
syndrome |= (C4 ? 8 : 0);
syndrome |= (C5 ? 16 : 0);
syndrome |= (C6 ? 32 : 0);
syndrome |= (C7 ? 64 : 0);
if (syndrome < 85)
{
const int32_t locator = GLONASS_GNAV_ECC_LOCATOR[syndrome];
bits[locator] = !bits[locator];
return true;
}
else
{
return false;
}
}
// All other conditions are assumed errors.
return false;
}
@ -238,7 +259,7 @@ int32_t Glonass_Gnav_Navigation_Message::string_decoder(const std::string& frame
uint64_t P_1_tmp = 0;
// Unpack bytes to bits
const std::bitset<GLONASS_GNAV_STRING_BITS> string_bits(frame_string);
std::bitset<GLONASS_GNAV_STRING_BITS> string_bits(frame_string);
// Perform data verification and exit code if error in bit sequence
flag_CRC_test = CRC_test(string_bits);

View File

@ -55,7 +55,7 @@ public:
* \brief Compute CRC for GLONASS GNAV strings
* \param bits Bits of the string message where to compute CRC
*/
bool CRC_test(const std::bitset<GLONASS_GNAV_STRING_BITS>& bits) const;
bool CRC_test(std::bitset<GLONASS_GNAV_STRING_BITS>& bits) const;
/*!
* \brief Computes the frame number being decoded given the satellite slot number

View File

@ -17,15 +17,65 @@
#include "glonass_gnav_navigation_message.h"
#include <bitset>
#include <string>
#include <iostream>
void to_bitset(const uint32_t from[3], std::bitset<GLONASS_GNAV_STRING_BITS> &to)
{
to.reset();
for (int k = 0; k < 3; k++)
{
std::bitset<GLONASS_GNAV_STRING_BITS> tmp(from[k]);
to |= (tmp << (k * 32));
}
}
TEST(GlonassCrcTest, GnssSdrCRCTest)
{
// test data
std::string string1Real_14_18_00("0000100000111001001001000011101010101100010101001000001001011101010101110011110110101");
std::string string1Real_14_18_30("0000100000111001001011000011101010101100010101001000001001011101010101110011100001010");
std::string string1Wrong_14_18_00("0000100000111001001001000011101010101100010101001000001001011101010101110011100001010");
std::string string1Wrong_14_18_00("0000100000111001001001100011101010101100010101001000001001011101010101110011100001010");
const uint32_t test_case_good[][3] = {
/* Test data from libswiftnav (github.com/swift-nav/libswiftnav) */
/* First, simply test one GLO nav message received from Novatel,
* we trust Novatel, so no errors must be */
{0xc90cfb3e, 0x9743a301, 0x010749},
{0xdd39f5fc, 0x24542d0c, 0x021760},
{0x653bc7e9, 0x1e8ead92, 0x038006},
{0x60342dfc, 0x41000002, 0x0481c7},
{0x40000895, 0x00000003, 0x050d10},
{0x530a7ecf, 0x059c4415, 0x06b082},
{0xfd94beb6, 0x7a577e97, 0x070f46},
{0xba02de6f, 0x988e6814, 0x08b101},
{0x12064831, 0x87767698, 0x09e1a6},
{0xaf870be5, 0x54ef2617, 0x0ab286},
{0x0f06ba41, 0x9a3f2698, 0x0b8f7c},
{0x2f012204, 0xf0c3c81a, 0x0cb309},
{0x1c858601, 0x10c47e98, 0x0da065},
{0x5205980b, 0xf49abc1a, 0x0eb40e},
{0x15454437, 0x2504e698, 0x0f8c09},
/* Second, take 1st string from other GLO nav message and introduce an
* error in data bits */
{0xc90cfb81, 0x9743a301, 0x010748}, /* case 15, no errors */
};
const uint32_t test_case_correctable[][3] = {
/* single bit errors are correctable */
{0xc90cfb81, 0x9743a301, 0x110748},
{0xc90cfb81, 0x1743a301, 0x010748},
{0x490cfb81, 0x9743a301, 0x010748},
{0xc90cfb81, 0x9743a300, 0x010748},
{0xc90cfb81, 0x9743a301, 0x010749},
{0xc90cfb81, 0x9743a301, 0x000748},
};
const uint32_t test_case_uncorrectable[][3] = {
/* multiple bit errors are uncorrectable */
{0xc90c3b81, 0x9743a301, 0x010748},
{0xc90cfb81, 0x974fa301, 0x010748},
{0xc90cfb81, 0x9743a301, 0x01074b},
{0xc90cfb81, 0x9743a301, 0x010744},
{0xc90cfb81, 0x9aaaa301, 0x010748},
};
auto gnav_msg = Glonass_Gnav_Navigation_Message();
std::bitset<GLONASS_GNAV_STRING_BITS> bits;
bits = std::bitset<GLONASS_GNAV_STRING_BITS>(string1Real_14_18_00);
@ -34,4 +84,30 @@ TEST(GlonassCrcTest, GnssSdrCRCTest)
ASSERT_TRUE(gnav_msg.CRC_test(bits));
bits = std::bitset<GLONASS_GNAV_STRING_BITS>(string1Wrong_14_18_00);
ASSERT_FALSE(gnav_msg.CRC_test(bits));
bits = std::bitset<GLONASS_GNAV_STRING_BITS>(string1Real_14_18_30);
for (int k = 8; k < 85; k++)
{
std::bitset<GLONASS_GNAV_STRING_BITS> corrupt_bits = bits;
corrupt_bits[k] = corrupt_bits[k] ? false : true;
ASSERT_TRUE(gnav_msg.CRC_test(corrupt_bits));
ASSERT_TRUE(corrupt_bits == bits);
}
for (unsigned k = 0; k < sizeof(test_case_good) / sizeof(test_case_good[0]); k++)
{
to_bitset(test_case_good[k], bits);
ASSERT_TRUE(gnav_msg.CRC_test(bits));
}
for (unsigned k = 0; k < sizeof(test_case_correctable) / sizeof(test_case_correctable[0]); k++)
{
std::bitset<GLONASS_GNAV_STRING_BITS> corrupt_bits;
to_bitset(test_case_correctable[k], corrupt_bits);
ASSERT_TRUE(gnav_msg.CRC_test(corrupt_bits));
ASSERT_TRUE(corrupt_bits == bits);
}
for (unsigned k = 0; k < sizeof(test_case_uncorrectable) / sizeof(test_case_uncorrectable[0]); k++)
{
std::bitset<GLONASS_GNAV_STRING_BITS> corrupt_bits;
to_bitset(test_case_uncorrectable[k], corrupt_bits);
ASSERT_FALSE(gnav_msg.CRC_test(corrupt_bits));
}
}