1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-01-23 07:27:05 +00:00

Add work on reading Galileo Integrity Support Message

This commit is contained in:
Carles Fernandez 2024-04-23 00:55:11 +02:00
parent 4910629a5d
commit 4c8cde1ec7
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
6 changed files with 469 additions and 0 deletions

View File

@ -19,6 +19,7 @@ set(SYSTEM_PARAMETERS_SOURCES
galileo_fnav_message.cc
galileo_has_data.cc
galileo_inav_message.cc
galileo_ism.cc
galileo_reduced_ced.cc
beidou_dnav_navigation_message.cc
beidou_dnav_ephemeris.cc
@ -55,6 +56,7 @@ set(SYSTEM_PARAMETERS_HEADERS
galileo_fnav_message.h
galileo_has_data.h
galileo_inav_message.h
galileo_ism.h
galileo_reduced_ced.h
sbas_ephemeris.h
gps_cnav_ephemeris.h
@ -115,6 +117,7 @@ target_link_libraries(core_system_parameters
Boost::date_time
Boost::serialization
PRIVATE
Boost::headers
Gflags::gflags
Glog::glog
)

View File

@ -274,6 +274,23 @@ constexpr int32_t BITS_IN_OCTET = 8;
constexpr int32_t FIRST_RS_BIT = 7;
constexpr int32_t FIRST_RS_BIT_AFTER_IODNAV = 17;
/* Page 22 */
const std::vector<std::pair<int32_t, int32_t>> ISM_CONSTELLATION_ID_BIT({{7, 3}});
const std::vector<std::pair<int32_t, int32_t>> ISM_SERVICE_LEVEL_ID_BIT({{10, 3}});
const std::vector<std::pair<int32_t, int32_t>> ISM_WN_BIT({{13, 12}});
const std::vector<std::pair<int32_t, int32_t>> ISM_T0_BIT({{25, 9}});
const std::vector<std::pair<int32_t, int32_t>> ISM_MASK_MSB_BIT({{34, 1}});
const std::vector<std::pair<int32_t, int32_t>> ISM_MASK_BIT({{35, 32}});
const std::vector<std::pair<int32_t, int32_t>> ISM_PCONST_BIT({{67, 4}});
const std::vector<std::pair<int32_t, int32_t>> ISM_PSAT_BIT({{71, 4}});
const std::vector<std::pair<int32_t, int32_t>> ISM_URA_BIT({{75, 4}});
const std::vector<std::pair<int32_t, int32_t>> ISM_URE_BIT({{79, 4}});
const std::vector<std::pair<int32_t, int32_t>> ISM_BNOM_BIT({{83, 4}});
const std::vector<std::pair<int32_t, int32_t>> ISM_TVALIDITY_BIT({{87, 4}});
const std::vector<std::pair<int32_t, int32_t>> ISM_CRC_BIT({{97, 32}});
constexpr int32_t GALILEO_ISM_CRC_DATA_BITS = 96;
constexpr int32_t GALILEO_ISM_CRC_DATA_BYTES = 12;
/* Page 0 */
const std::vector<std::pair<int32_t, int32_t>> TIME_0_BIT({{7, 2}});
const std::vector<std::pair<int32_t, int32_t>> WN_0_BIT({{97, 12}});

View File

@ -1315,6 +1315,40 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk)
break;
}
case 22: // Word Type 22: ARAIM Integrity Support Message (ISM)
DLOG(INFO) << "Word type 22 arrived";
ism_constellation_id = read_octet_unsigned(data_jk_bits, ISM_CONSTELLATION_ID_BIT);
ism_service_level_id = read_octet_unsigned(data_jk_bits, ISM_SERVICE_LEVEL_ID_BIT);
ism_crc = static_cast<uint32_t>(read_navigation_unsigned(data_jk_bits, ISM_CRC_BIT));
gal_ism.set_ism_crc(ism_crc);
if (gal_ism.check_ism_crc(data_jk_bits))
{
DLOG(INFO) << "I/NAV ARAIM Integrity Support Message CRC OK";
gal_ism.set_ism_constellation_id(ism_constellation_id);
gal_ism.set_ism_service_level_id(ism_service_level_id);
if (ism_constellation_id == 0)
{
DLOG(INFO) << "I/NAV ARAIM Integrity Support Message in Test";
}
if (ism_constellation_id == 1)
{
if (ism_service_level_id == 2)
{
gal_ism.set_ism_wn(static_cast<uint16_t>(read_navigation_unsigned(data_jk_bits, ISM_WN_BIT)));
gal_ism.set_ism_t0(static_cast<uint16_t>(read_navigation_unsigned(data_jk_bits, ISM_T0_BIT)));
gal_ism.set_ism_mask_msb(read_navigation_bool(data_jk_bits, ISM_MASK_MSB_BIT));
gal_ism.set_ism_mask(static_cast<uint32_t>(read_navigation_unsigned(data_jk_bits, ISM_MASK_BIT)));
gal_ism.set_ism_pconst(read_octet_unsigned(data_jk_bits, ISM_PCONST_BIT));
gal_ism.set_ism_psat(read_octet_unsigned(data_jk_bits, ISM_PSAT_BIT));
gal_ism.set_ism_ura(read_octet_unsigned(data_jk_bits, ISM_URA_BIT));
gal_ism.set_ism_ure(read_octet_unsigned(data_jk_bits, ISM_URE_BIT));
gal_ism.set_ism_bnom(read_octet_unsigned(data_jk_bits, ISM_BNOM_BIT));
gal_ism.set_ism_Tvalidity(read_octet_unsigned(data_jk_bits, ISM_TVALIDITY_BIT));
}
}
}
break;
case 0: // Word type 0: I/NAV Spare Word
Time_0 = static_cast<int32_t>(read_navigation_unsigned(data_jk_bits, TIME_0_BIT));
DLOG(INFO) << "Time_0= " << Time_0;
@ -1336,3 +1370,9 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk)
}
return page_number;
}
Galileo_ISM Galileo_Inav_Message::get_galileo_ism() const
{
return gal_ism;
}

View File

@ -23,6 +23,7 @@
#include "galileo_almanac_helper.h"
#include "galileo_ephemeris.h"
#include "galileo_iono.h"
#include "galileo_ism.h"
#include "galileo_utc_model.h"
#include "gnss_sdr_make_unique.h" // for std::unique_ptr in C++11
#include <bitset>
@ -114,6 +115,8 @@ public:
*/
Galileo_Ephemeris get_reduced_ced() const;
Galileo_ISM get_galileo_ism() const;
inline bool get_flag_CRC_test() const
{
return flag_CRC_test;
@ -236,6 +239,7 @@ private:
std::bitset<GALILEO_DATA_JK_BITS> regenerate_page_3(const std::vector<uint8_t>& decoded) const;
std::bitset<GALILEO_DATA_JK_BITS> regenerate_page_4(const std::vector<uint8_t>& decoded) const;
Galileo_ISM gal_ism{};
std::string page_Even{};
std::vector<uint8_t> rs_buffer; // Reed-Solomon buffer
@ -399,6 +403,10 @@ private:
uint8_t IODnav_LSB19{};
uint8_t IODnav_LSB20{};
uint32_t ism_crc{};
uint8_t ism_constellation_id{};
uint8_t ism_service_level_id{};
bool flag_CRC_test{};
bool flag_all_ephemeris{}; // Flag indicating that all words containing ephemeris have been received
bool flag_ephemeris_1{}; // Flag indicating that ephemeris 1/4 (word 1) have been received

View File

@ -0,0 +1,196 @@
/*!
* \file galileo_ism.cc
* \brief Interface of a Galileo Integrity Support Message
* \author Carles Fernandez, 2024. cfernandez(at)cttc.cat
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#include "galileo_ism.h"
#include <boost/crc.hpp>
#include <boost/dynamic_bitset.hpp>
#include <algorithm>
#include <vector>
void Galileo_ISM::set_ism_constellation_id(uint8_t const_id)
{
this->ism_constellation_id = const_id;
}
void Galileo_ISM::set_ism_service_level_id(uint8_t sl_id)
{
this->ism_service_level_id = sl_id;
}
void Galileo_ISM::set_ism_wn(uint16_t wn_ism)
{
this->ism_wn = wn_ism;
}
void Galileo_ISM::set_ism_t0(uint16_t t0)
{
this->ism_t0 = t0;
}
void Galileo_ISM::set_ism_mask_msb(bool mask_msb)
{
this->ism_mask_msb = mask_msb;
}
void Galileo_ISM::set_ism_mask(uint32_t mask)
{
this->ism_mask = mask;
}
void Galileo_ISM::set_ism_pconst(uint8_t pconst)
{
this->ism_pconst = pconst;
}
void Galileo_ISM::set_ism_psat(uint8_t psat)
{
this->ism_psat = psat;
}
void Galileo_ISM::set_ism_ura(uint8_t ura)
{
this->ism_ura = ura;
}
void Galileo_ISM::set_ism_ure(uint8_t ure)
{
this->ism_ure = ure;
}
void Galileo_ISM::set_ism_bnom(uint8_t bnom)
{
this->ism_bnom = bnom;
}
void Galileo_ISM::set_ism_Tvalidity(uint8_t tvalidity)
{
this->ism_Tvalidity = tvalidity;
}
void Galileo_ISM::set_ism_crc(uint32_t crc)
{
this->ism_crc = crc;
}
uint16_t Galileo_ISM::get_WN_ISM() const
{
return this->ism_wn;
}
uint16_t Galileo_ISM::get_t0_ISM() const
{
return (this->ism_t0 * 1800);
}
double Galileo_ISM::get_pconst_value() const
{
auto it = ISM_PCONST_MAP.find(this->ism_pconst);
if (it == ISM_PCONST_MAP.end())
{
return 0.0;
}
return it->second;
}
double Galileo_ISM::get_psat_value() const
{
auto it = ISM_PSAT_MAP.find(this->ism_psat);
if (it == ISM_PSAT_MAP.end())
{
return 0.0;
}
return it->second;
}
float Galileo_ISM::get_ura_m() const
{
auto it = ISM_URA_MAP.find(this->ism_ura);
if (it == ISM_URA_MAP.end())
{
return 0.0;
}
return it->second;
}
float Galileo_ISM::get_ure_m() const
{
auto it = ISM_URE_MAP.find(this->ism_ure);
if (it == ISM_URE_MAP.end())
{
return 0.0;
}
return it->second;
}
float Galileo_ISM::get_bnom_m() const
{
auto it = ISM_BNOM_MAP.find(this->ism_bnom);
if (it == ISM_BNOM_MAP.end())
{
return 5.0; //
}
return it->second;
}
uint16_t Galileo_ISM::get_Tvalidity_hours() const
{
auto it = ISM_TVALIDITY_MAP.find(this->ism_Tvalidity);
if (it == ISM_TVALIDITY_MAP.end())
{
return 0.0;
}
return it->second;
}
bool Galileo_ISM::check_ism_crc(const std::bitset<GALILEO_DATA_JK_BITS>& bits) const
{
boost::dynamic_bitset<unsigned char> frame_bits(bits.to_string().substr(0, GALILEO_ISM_CRC_DATA_BITS));
std::vector<unsigned char> bytes;
boost::to_block_range(frame_bits, std::back_inserter(bytes));
std::reverse(bytes.begin(), bytes.end());
boost::crc_32_type crc32_ism;
crc32_ism.process_bytes(bytes.data(), GALILEO_ISM_CRC_DATA_BYTES);
const uint32_t crc_computed = crc32_ism.checksum();
if (this->ism_crc == crc_computed)
{
return true;
}
return false;
}

View File

@ -0,0 +1,205 @@
/*!
* \file galileo_ism.h
* \brief Interface of a Galileo Integrity Support Message
* \author Carles Fernandez, 2024. 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-2024 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GALILEO_ISM_H
#define GNSS_SDR_GALILEO_ISM_H
#include "Galileo_INAV.h"
#include <bitset>
#include <cstdint>
#include <unordered_map>
/** \addtogroup Core
* \{ */
/** \addtogroup System_Parameters
* \{ */
/*!
* \brief This class is a storage for the GALILEO Integrity Support Message as described
* in Galileo ICD paragraph 5.2
*
* See https://www.gsc-europa.eu/sites/default/files/sites/all/files/Galileo_OS_SIS_ICD_v2.1.pdf
*/
class Galileo_ISM
{
public:
/*!
* Default constructor
*/
Galileo_ISM() = default;
void set_ism_constellation_id(uint8_t const_id);
void set_ism_service_level_id(uint8_t sl_id);
void set_ism_wn(uint16_t wn_ism);
void set_ism_t0(uint16_t t0);
void set_ism_mask_msb(bool mask_msb);
void set_ism_mask(uint32_t mask);
void set_ism_pconst(uint8_t pconst);
void set_ism_psat(uint8_t psat);
void set_ism_ura(uint8_t ura);
void set_ism_ure(uint8_t ure);
void set_ism_bnom(uint8_t bnom);
void set_ism_Tvalidity(uint8_t tvalidity);
void set_ism_crc(uint32_t crc);
bool check_ism_crc(const std::bitset<GALILEO_DATA_JK_BITS>& bits) const;
double get_pconst_value() const;
double get_psat_value() const;
float get_ura_m() const;
float get_ure_m() const;
float get_bnom_m() const;
uint16_t get_WN_ISM() const;
uint16_t get_t0_ISM() const;
uint16_t get_Tvalidity_hours() const;
private:
// ICD 2.1 Table 97
std::unordered_map<uint8_t, double> ISM_PCONST_MAP = {
{0, 1.0e-8},
{1, 1.0e-7},
{2, 1.0e-6},
{3, 3.0e-6},
{4, 6.0e-6},
{5, 8.0e-6},
{6, 1.0e-5},
{7, 2.0e-5},
{8, 4.0e-5},
{9, 6.0e-5},
{10, 8.0e-5},
{11, 1.0e-4},
{12, 1.25e-4},
{13, 1.5e-4},
{14, 1.75e-4},
{15, 2.0e-4}};
// ICD 2.1 Table 98
std::unordered_map<uint8_t, double> ISM_PSAT_MAP = {
{0, 1.0e-7},
{1, 3.0e-7},
{2, 6.0e-7},
{3, 1.0e-6},
{4, 2.0e-6},
{5, 3.0e-6},
{6, 5.0e-6},
{7, 7.0e-6},
{8, 1.0e-5},
{9, 1.2e-5},
{10, 1.4e-5},
{11, 1.7e-5},
{12, 2.05e-5},
{13, 2.4e-5},
{14, 2.8e-5},
{15, 3.0e-5}};
// ICD 2.1 Table 99
std::unordered_map<uint8_t, float> ISM_URA_MAP = {
{0, 0.75},
{1, 1.0},
{2, 1.5},
{3, 2.0},
{4, 2.25},
{5, 2.50},
{6, 2.75},
{7, 3.0},
{8, 3.25},
{9, 3.50},
{10, 3.75},
{11, 4.0},
{12, 4.50},
{13, 5.0},
{14, 5.50},
{15, 6.0}};
// ICD 2.1 Table 100
std::unordered_map<uint8_t, float> ISM_URE_MAP = {
{0, 0.25},
{1, 0.50},
{2, 0.75},
{3, 1.00},
{4, 1.25},
{5, 1.50},
{6, 1.75},
{7, 2.0},
{8, 2.25},
{9, 2.50},
{10, 2.75},
{11, 3.0},
{12, 3.25},
{13, 3.50},
{14, 3.75},
{15, 4.00}};
// ICD 2.1 Table 101
std::unordered_map<uint8_t, float> ISM_BNOM_MAP = {
{0, 0.0},
{1, 0.10},
{2, 0.20},
{3, 0.30},
{4, 0.40},
{5, 0.50},
{6, 0.60},
{7, 0.75},
{8, 0.85},
{9, 1.0},
{10, 1.20},
{11, 1.40},
{12, 1.60},
{13, 1.80},
{14, 2.0},
{15, 2.4}};
// ICD 2.1 Table 102
std::unordered_map<uint8_t, uint16_t> ISM_TVALIDITY_MAP = {
{0, 1},
{1, 2},
{2, 3},
{3, 4},
{4, 6},
{5, 8},
{6, 12},
{7, 18},
{8, 24},
{9, 36},
{10, 48},
{11, 72},
{12, 120},
{13, 168},
{14, 720},
{15, 1440}};
uint32_t ism_crc{};
uint32_t ism_mask{};
uint16_t ism_wn{};
uint16_t ism_t0{};
uint8_t ism_constellation_id{};
uint8_t ism_service_level_id{};
uint8_t ism_pconst{};
uint8_t ism_psat{};
uint8_t ism_ura{};
uint8_t ism_ure{};
uint8_t ism_bnom{};
uint8_t ism_Tvalidity{};
bool ism_mask_msb{};
};
/** \} */
/** \} */
#endif // GNSS_SDR_GALILEO_ISM_H