From e4a3a060eef609393784b9d92ce819e0489a98d6 Mon Sep 17 00:00:00 2001 From: Vladislav P Date: Fri, 26 Aug 2022 16:27:01 +0300 Subject: [PATCH 1/2] Implement GLONASS string error correction Signed-off-by: Vladislav P --- src/core/system_parameters/GLONASS_L1_L2_CA.h | 1 + .../glonass_gnav_navigation_message.cc | 27 ++++++++++++++++--- .../glonass_gnav_navigation_message.h | 2 +- .../glonass_gnav_crc_test.cc | 12 +++++++-- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/core/system_parameters/GLONASS_L1_L2_CA.h b/src/core/system_parameters/GLONASS_L1_L2_CA.h index e893f7df7..042754742 100644 --- a/src/core/system_parameters/GLONASS_L1_L2_CA.h +++ b/src/core/system_parameters/GLONASS_L1_L2_CA.h @@ -238,6 +238,7 @@ const std::vector GLONASS_GNAV_CRC_M_INDEX{20, 21, 22, 23, 24, 25, 26, const std::vector 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 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 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 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 diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.cc b/src/core/system_parameters/glonass_gnav_navigation_message.cc index 3f1bcd12e..94ddd9073 100644 --- a/src/core/system_parameters/glonass_gnav_navigation_message.cc +++ b/src/core/system_parameters/glonass_gnav_navigation_message.cc @@ -36,7 +36,7 @@ Glonass_Gnav_Navigation_Message::Glonass_Gnav_Navigation_Message() } -bool Glonass_Gnav_Navigation_Message::CRC_test(const std::bitset& bits) const +bool Glonass_Gnav_Navigation_Message::CRC_test(std::bitset& 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 string_bits(frame_string); + std::bitset string_bits(frame_string); // Perform data verification and exit code if error in bit sequence flag_CRC_test = CRC_test(string_bits); diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.h b/src/core/system_parameters/glonass_gnav_navigation_message.h index fcad9c79f..c51264ad8 100644 --- a/src/core/system_parameters/glonass_gnav_navigation_message.h +++ b/src/core/system_parameters/glonass_gnav_navigation_message.h @@ -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& bits) const; + bool CRC_test(std::bitset& bits) const; /*! * \brief Computes the frame number being decoded given the satellite slot number diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_crc_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_crc_test.cc index 88fc61e04..2280219d1 100644 --- a/src/tests/unit-tests/system-parameters/glonass_gnav_crc_test.cc +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_crc_test.cc @@ -17,14 +17,14 @@ #include "glonass_gnav_navigation_message.h" #include -#include +#include 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"); auto gnav_msg = Glonass_Gnav_Navigation_Message(); std::bitset bits; @@ -34,4 +34,12 @@ TEST(GlonassCrcTest, GnssSdrCRCTest) ASSERT_TRUE(gnav_msg.CRC_test(bits)); bits = std::bitset(string1Wrong_14_18_00); ASSERT_FALSE(gnav_msg.CRC_test(bits)); + bits = std::bitset(string1Real_14_18_30); + for (int k = 8; k < 85; k++) + { + std::bitset corrupt_bits = bits; + corrupt_bits[k] = corrupt_bits[k] ? false : true; + ASSERT_TRUE(gnav_msg.CRC_test(corrupt_bits)); + ASSERT_TRUE(corrupt_bits == bits); + } } From 4e625b03d1b1fb44e6804155b638fb79e1ab9203 Mon Sep 17 00:00:00 2001 From: Vladislav P Date: Thu, 8 Sep 2022 00:19:03 +0300 Subject: [PATCH 2/2] Add test data from libswitnav Signed-off-by: Vladislav P --- .../glonass_gnav_crc_test.cc | 70 ++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_crc_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_crc_test.cc index 2280219d1..a6863d5b2 100644 --- a/src/tests/unit-tests/system-parameters/glonass_gnav_crc_test.cc +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_crc_test.cc @@ -19,13 +19,63 @@ #include #include +void to_bitset(const uint32_t from[3], std::bitset &to) +{ + to.reset(); + for (int k = 0; k < 3; k++) + { + std::bitset 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("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 bits; bits = std::bitset(string1Real_14_18_00); @@ -42,4 +92,22 @@ TEST(GlonassCrcTest, GnssSdrCRCTest) 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 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 corrupt_bits; + to_bitset(test_case_uncorrectable[k], corrupt_bits); + ASSERT_FALSE(gnav_msg.CRC_test(corrupt_bits)); + } }