From 9847a45e7849a1bece30fadaaa821425656d72b9 Mon Sep 17 00:00:00 2001 From: Javier Date: Mon, 25 May 2015 17:55:10 +0200 Subject: [PATCH] Added GPS CNAV ephemeris, iono, and utc model objects. Work in progress towards GPS CNAV telemetry decoder. --- src/core/system_parameters/CMakeLists.txt | 3 + src/core/system_parameters/GPS_L2C.h | 4 +- .../system_parameters/gps_cnav_ephemeris.cc | 3 +- .../system_parameters/gps_cnav_ephemeris.h | 9 +- src/core/system_parameters/gps_cnav_iono.cc | 47 +++ src/core/system_parameters/gps_cnav_iono.h | 81 ++++ .../gps_cnav_navigation_message.cc | 382 ++++++++++++++++++ .../gps_cnav_navigation_message.h | 121 ++++++ .../system_parameters/gps_cnav_utc_model.cc | 45 +++ .../system_parameters/gps_cnav_utc_model.h | 85 ++++ 10 files changed, 775 insertions(+), 5 deletions(-) create mode 100644 src/core/system_parameters/gps_cnav_iono.cc create mode 100644 src/core/system_parameters/gps_cnav_iono.h create mode 100644 src/core/system_parameters/gps_cnav_navigation_message.cc create mode 100644 src/core/system_parameters/gps_cnav_navigation_message.h create mode 100644 src/core/system_parameters/gps_cnav_utc_model.cc create mode 100644 src/core/system_parameters/gps_cnav_utc_model.h diff --git a/src/core/system_parameters/CMakeLists.txt b/src/core/system_parameters/CMakeLists.txt index 8fe5b0430..bc6949dff 100644 --- a/src/core/system_parameters/CMakeLists.txt +++ b/src/core/system_parameters/CMakeLists.txt @@ -38,6 +38,9 @@ set(SYSTEM_PARAMETERS_SOURCES sbas_telemetry_data.cc galileo_fnav_message.cc gps_cnav_ephemeris.cc + gps_cnav_navigation_message.cc + gps_cnav_iono.cc + gps_cnav_utc_model.cc ) diff --git a/src/core/system_parameters/GPS_L2C.h b/src/core/system_parameters/GPS_L2C.h index 1e621a95e..ed4c9b2ed 100644 --- a/src/core/system_parameters/GPS_L2C.h +++ b/src/core/system_parameters/GPS_L2C.h @@ -60,7 +60,6 @@ const double GPS_L2_L_CODE_RATE_HZ = 0.5115e6; //!< GPS L2 L code rate [chips/ const int GPS_L2_L_CODE_LENGTH_CHIPS = 767250; //!< GPS L2 L code length [chips] const double GPS_L2_L_PERIOD = 1.5; //!< GPS L2 L code period [seconds] - const int32_t GPS_L2C_M_INIT_REG[115] = {0742417664, 0756014035,0002747144,0066265724, // 1:4 0601403471, 0703232733, 0124510070,0617316361, // 5:8 @@ -97,6 +96,8 @@ const int32_t GPS_L2C_M_INIT_REG[115] = #define GPS_CNAV_PREAMBLE {1, 0, 0, 0, 1, 0, 1, 1} +const int GPS_L2_CNAV_DATA_PAGE_BITS = 300; //!< GPS L2 CNAV page length, including preamble and CRC [bits] + // common to all messages const std::vector > CNAV_PRN( { {9,6} } ); const std::vector > CNAV_MSG_TYPE( { {15,6} } ); @@ -185,6 +186,7 @@ const std::vector > CNAV_ISCL5I({{167,13}}); const double CNAV_ISCL5I_LSB = TWO_N35; const std::vector > CNAV_ISCL5Q({{180,13}}); const double CNAV_ISCL5Q_LSB = TWO_N35; +//Ionospheric parameters const std::vector > CNAV_ALPHA0({{193,8}}); const double CNAV_ALPHA0_LSB = TWO_N30; const std::vector > CNAV_ALPHA1({{201,8}}); diff --git a/src/core/system_parameters/gps_cnav_ephemeris.cc b/src/core/system_parameters/gps_cnav_ephemeris.cc index 569d69815..b58b80160 100644 --- a/src/core/system_parameters/gps_cnav_ephemeris.cc +++ b/src/core/system_parameters/gps_cnav_ephemeris.cc @@ -43,7 +43,8 @@ Gps_CNAV_Ephemeris::Gps_CNAV_Ephemeris() d_e_eccentricity = 0; d_Cus = 0; - d_Toe = 0; + d_Toe1 = 0; + d_Toe2 = 0; d_Toc = 0; d_Cic = 0; d_OMEGA0 = 0; diff --git a/src/core/system_parameters/gps_cnav_ephemeris.h b/src/core/system_parameters/gps_cnav_ephemeris.h index fc0def47d..c4a35e330 100644 --- a/src/core/system_parameters/gps_cnav_ephemeris.h +++ b/src/core/system_parameters/gps_cnav_ephemeris.h @@ -65,7 +65,8 @@ public: double d_e_eccentricity; //!< Eccentricity double d_OMEGA; //!< Argument of Perigee [semi-cicles] double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-cicles] - double d_Toe; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] + double d_Toe1; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] + double d_Toe2; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] double d_DELTA_OMEGA_DOT; //!< Rate of Right Ascension difference [semi-circles/s] double d_i_0; //!< Inclination Angle at Reference Time [semi-circles] double d_IDOT; //!< Rate of Inclination Angle [semi-circles/s] @@ -109,6 +110,7 @@ public: * accompanying alert, is less than 1E-8 per hour. */ bool b_integrity_status_flag; + bool b_l2c_phasing_flag; bool b_alert_flag; //!< If true, indicates that the SV URA may be worse than indicated in d_SV_accuracy, use that SV at our own risk. bool b_antispoofing_flag; //!< If true, the AntiSpoofing mode is ON in that SV @@ -143,8 +145,9 @@ public: archive & make_nvp("d_Cuc", d_Cuc); //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad] archive & make_nvp("d_e_eccentricity", d_e_eccentricity); //!< Eccentricity [dimensionless] archive & make_nvp("d_Cus", d_Cus); //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad] - archive & make_nvp("d_Toe", d_Toe); //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] - archive & make_nvp("d_Toc", d_Toe); //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s] + archive & make_nvp("d_Toe1", d_Toe1); //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] + archive & make_nvp("d_Toe2", d_Toe2); //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] + archive & make_nvp("d_Toc", d_Toc); //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s] archive & make_nvp("d_Cic", d_Cic); //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad] archive & make_nvp("d_OMEGA0", d_OMEGA0); //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] archive & make_nvp("d_Cis", d_Cis); //!< Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination [rad] diff --git a/src/core/system_parameters/gps_cnav_iono.cc b/src/core/system_parameters/gps_cnav_iono.cc new file mode 100644 index 000000000..8a7e3fd03 --- /dev/null +++ b/src/core/system_parameters/gps_cnav_iono.cc @@ -0,0 +1,47 @@ +/*! + * \file gps_cnav_iono.cc + * \brief Interface of a GPS CNAV IONOSPHERIC MODEL storage + * + * See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II + * \author Javier Arribas, 2015. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "gps_cnav_iono.h" + +Gps_CNAV_Iono::Gps_CNAV_Iono() +{ + valid = false; + d_alpha0 = 0.0; + d_alpha1 = 0.0; + d_alpha2 = 0.0; + d_alpha3 = 0.0; + d_beta0 = 0.0; + d_beta1 = 0.0; + d_beta2 = 0.0; + d_beta3 = 0.0; +} + diff --git a/src/core/system_parameters/gps_cnav_iono.h b/src/core/system_parameters/gps_cnav_iono.h new file mode 100644 index 000000000..fb3b5a8d8 --- /dev/null +++ b/src/core/system_parameters/gps_cnav_iono.h @@ -0,0 +1,81 @@ +/*! + * \file gps_cnav_iono.h + * \brief Interface of a GPS CNAV IONOSPHERIC MODEL storage + * \author Javier Arribas, 2015. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GPS_CNAV_IONO_H_ +#define GNSS_SDR_GPS_CNAV_IONO_H_ + +#include "GPS_L2C.h" +#include "boost/assign.hpp" +#include + + +/*! + * \brief This class is a storage for the GPS IONOSPHERIC data as described in IS-GPS-200E + * + * See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II + */ +class Gps_CNAV_Iono +{ +public: + bool valid; //!< Valid flag + // Ionospheric parameters + double d_alpha0; //!< Coefficient 0 of a cubic equation representing the amplitude of the vertical delay [s] + double d_alpha1; //!< Coefficient 1 of a cubic equation representing the amplitude of the vertical delay [s/semi-circle] + double d_alpha2; //!< Coefficient 2 of a cubic equation representing the amplitude of the vertical delay [s(semi-circle)^2] + double d_alpha3; //!< Coefficient 3 of a cubic equation representing the amplitude of the vertical delay [s(semi-circle)^3] + double d_beta0; //!< Coefficient 0 of a cubic equation representing the period of the model [s] + double d_beta1; //!< Coefficient 1 of a cubic equation representing the period of the model [s/semi-circle] + double d_beta2; //!< Coefficient 2 of a cubic equation representing the period of the model [s(semi-circle)^2] + double d_beta3; //!< Coefficient 3 of a cubic equation representing the period of the model [s(semi-circle)^3] + + Gps_CNAV_Iono(); //!< Default constructor + + template + + /*! + * \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the ephemeris data on disk file. + */ + void serialize(Archive& archive, const unsigned int version) + { + using boost::serialization::make_nvp; + if(version){}; + archive & make_nvp("d_alpha0",d_alpha0); + archive & make_nvp("d_alpha1",d_alpha1); + archive & make_nvp("d_alpha2",d_alpha2); + archive & make_nvp("d_alpha3",d_alpha3); + archive & make_nvp("d_beta0",d_beta0); + archive & make_nvp("d_beta1",d_beta1); + archive & make_nvp("d_beta2",d_beta2); + archive & make_nvp("d_beta3",d_beta3); + } +}; + +#endif diff --git a/src/core/system_parameters/gps_cnav_navigation_message.cc b/src/core/system_parameters/gps_cnav_navigation_message.cc new file mode 100644 index 000000000..bac4dc90c --- /dev/null +++ b/src/core/system_parameters/gps_cnav_navigation_message.cc @@ -0,0 +1,382 @@ +/*! + * \file Gps_CNAV_Navigation_Message.cc + * \brief Implementation of a GPS NAV Data message decoder as described in IS-GPS-200E + * + * See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II + * \author Javier Arribas, 2011. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "gps_cnav_navigation_message.h" +#include +#include "boost/date_time/posix_time/posix_time.hpp" + + +void Gps_CNAV_Navigation_Message::reset() +{ + b_valid_ephemeris_set_flag = false; + + // satellite positions + d_satpos_X = 0; + d_satpos_Y = 0; + d_satpos_Z = 0; + + // info + i_channel_ID = 0; + i_satellite_PRN = 0; + + // Satellite velocity + d_satvel_X = 0; + d_satvel_Y = 0; + d_satvel_Z = 0; + + //Plane A (info from http://www.navcen.uscg.gov/?Do=constellationStatus) + satelliteBlock[9] = "IIA"; + satelliteBlock[31] = "IIR-M"; + satelliteBlock[8] = "IIA"; + satelliteBlock[7] = "IIR-M"; + satelliteBlock[27] = "IIA"; + //Plane B + satelliteBlock[16] = "IIR"; + satelliteBlock[25] = "IIF"; + satelliteBlock[28] = "IIR"; + satelliteBlock[12] = "IIR-M"; + satelliteBlock[30] = "IIA"; + //Plane C + satelliteBlock[29] = "IIR-M"; + satelliteBlock[3] = "IIA"; + satelliteBlock[19] = "IIR"; + satelliteBlock[17] = "IIR-M"; + satelliteBlock[6] = "IIA"; + //Plane D + satelliteBlock[2] = "IIR"; + satelliteBlock[1] = "IIF"; + satelliteBlock[21] = "IIR"; + satelliteBlock[4] = "IIA"; + satelliteBlock[11] = "IIR"; + satelliteBlock[24] = "IIA"; // Decommissioned from active service on 04 Nov 2011 + //Plane E + satelliteBlock[20] = "IIR"; + satelliteBlock[22] = "IIR"; + satelliteBlock[5] = "IIR-M"; + satelliteBlock[18] = "IIR"; + satelliteBlock[32] = "IIA"; + satelliteBlock[10] = "IIA"; + //Plane F + satelliteBlock[14] = "IIR"; + satelliteBlock[15] = "IIR-M"; + satelliteBlock[13] = "IIR"; + satelliteBlock[23] = "IIR"; + satelliteBlock[26] = "IIA"; +} + +Gps_CNAV_Navigation_Message::Gps_CNAV_Navigation_Message() +{ + reset(); +} + +void Gps_CNAV_Navigation_Message::print_gps_word_bytes(unsigned int GPS_word) +{ + std::cout << " Word ="; + std::cout << std::bitset<32>(GPS_word); + std::cout << std::endl; +} + +bool Gps_CNAV_Navigation_Message::read_navigation_bool(std::bitset bits, const std::vector> parameter) +{ + bool value; + + if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1) + { + value = true; + } + else + { + value = false; + } + return value; +} + + +unsigned long int Gps_CNAV_Navigation_Message::read_navigation_unsigned(std::bitset bits, const std::vector> parameter) +{ + unsigned long int value = 0; + int num_of_slices = parameter.size(); + for (int i = 0; i < num_of_slices; i++) + { + for (int j = 0; j < parameter[i].second; j++) + { + value <<= 1; //shift left + if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1) + { + value += 1; // insert the bit + } + } + } + return value; +} + + +signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset bits, const std::vector> parameter) +{ + signed long int value = 0; + int num_of_slices = parameter.size(); + // Discriminate between 64 bits and 32 bits compiler + int long_int_size_bytes = sizeof(signed long int); + if (long_int_size_bytes == 8) // if a long int takes 8 bytes, we are in a 64 bits system + { + // read the MSB and perform the sign extension + if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1) + { + value ^= 0xFFFFFFFFFFFFFFFF; //64 bits variable + } + else + { + value &= 0; + } + + for (int i = 0; i < num_of_slices; i++) + { + for (int j = 0; j < parameter[i].second; j++) + { + value <<= 1; //shift left + value &= 0xFFFFFFFFFFFFFFFE; //reset the corresponding bit (for the 64 bits variable) + if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1) + { + value += 1; // insert the bit + } + } + } + } + else // we assume we are in a 32 bits system + { + // read the MSB and perform the sign extension + if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1) + { + value ^= 0xFFFFFFFF; + } + else + { + value &= 0; + } + + for (int i = 0; i < num_of_slices; i++) + { + for (int j = 0; j < parameter[i].second; j++) + { + value <<= 1; //shift left + value &= 0xFFFFFFFE; //reset the corresponding bit + if (bits[GPS_L2_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1) + { + value += 1; // insert the bit + } + } + } + } + return value; +} + + +void Gps_CNAV_Navigation_Message::decode_page(std::string data) +{ + std::bitset data_bits(data); + + int PRN; + int page_type; + double TOW; + bool alert_flag; + + // common to all messages + PRN = static_cast(read_navigation_unsigned(data_bits, CNAV_PRN)); + TOW = static_cast(read_navigation_unsigned(data_bits, CNAV_TOW)); + alert_flag= static_cast(read_navigation_bool(data_bits, CNAV_ALERT_FLAG)); + page_type = static_cast(read_navigation_unsigned(data_bits, CNAV_MSG_TYPE)); + + switch(page_type) + { + case 10: // Ephemeris 1/2 + ephemeris_record.i_GPS_week=static_cast(read_navigation_unsigned(data_bits, CNAV_WN)); + ephemeris_record.i_signal_health=static_cast(read_navigation_unsigned(data_bits, CNAV_HEALTH)); + ephemeris_record.d_Top=static_cast(read_navigation_unsigned(data_bits, CNAV_TOP1)); + ephemeris_record.d_Top=ephemeris_record.d_Top*CNAV_TOP1_LSB; + ephemeris_record.d_URA0=static_cast(read_navigation_signed(data_bits, CNAV_URA)); + ephemeris_record.d_Toe1=static_cast(read_navigation_unsigned(data_bits, CNAV_TOE1)); + ephemeris_record.d_Toe1=ephemeris_record.d_Toe1*CNAV_TOE1_LSB; + ephemeris_record.d_DELTA_A=static_cast(read_navigation_signed(data_bits, CNAV_DELTA_A)); + ephemeris_record.d_DELTA_A=ephemeris_record.d_DELTA_A*CNAV_DELTA_A_LSB; + ephemeris_record.d_A_DOT=static_cast(read_navigation_signed(data_bits, CNAV_A_DOT)); + ephemeris_record.d_A_DOT=ephemeris_record.d_A_DOT*CNAV_A_DOT_LSB; + ephemeris_record.d_Delta_n=static_cast(read_navigation_signed(data_bits, CNAV_DELTA_N0)); + ephemeris_record.d_Delta_n=ephemeris_record.d_Delta_n*CNAV_DELTA_N0_LSB; + ephemeris_record.d_DELTA_DOT_N=static_cast(read_navigation_signed(data_bits, CNAV_DELTA_N0_DOT)); + ephemeris_record.d_DELTA_DOT_N=ephemeris_record.d_DELTA_DOT_N*CNAV_DELTA_N0_DOT_LSB; + ephemeris_record.d_M_0=static_cast(read_navigation_signed(data_bits, CNAV_M0)); + ephemeris_record.d_M_0=ephemeris_record.d_M_0*CNAV_M0_LSB; + ephemeris_record.d_e_eccentricity=static_cast(read_navigation_signed(data_bits, CNAV_E_ECCENTRICITY)); + ephemeris_record.d_e_eccentricity=ephemeris_record.d_e_eccentricity*CNAV_E_ECCENTRICITY_LSB; + ephemeris_record.d_OMEGA=static_cast(read_navigation_signed(data_bits, CNAV_OMEGA)); + ephemeris_record.d_OMEGA=ephemeris_record.d_OMEGA*CNAV_OMEGA_LSB; + + ephemeris_record.b_integrity_status_flag=static_cast(read_navigation_bool(data_bits, CNAV_INTEGRITY_FLAG)); + ephemeris_record.b_l2c_phasing_flag=static_cast(read_navigation_bool(data_bits, CNAV_L2_PHASING_FLAG)); + break; + case 11: // Ephemeris 2/2 + ephemeris_record.d_Toe2=static_cast(read_navigation_unsigned(data_bits, CNAV_TOE2)); + ephemeris_record.d_Toe2=ephemeris_record.d_Toe2*CNAV_TOE2_LSB; + ephemeris_record.d_OMEGA0=static_cast(read_navigation_signed(data_bits, CNAV_OMEGA0)); + ephemeris_record.d_OMEGA0=ephemeris_record.d_OMEGA0*CNAV_OMEGA0_LSB; + ephemeris_record.d_DELTA_OMEGA_DOT=static_cast(read_navigation_signed(data_bits, CNAV_DELTA_OMEGA_DOT)); + ephemeris_record.d_DELTA_OMEGA_DOT=ephemeris_record.d_DELTA_OMEGA_DOT*CNAV_DELTA_OMEGA_DOT_LSB; + ephemeris_record.d_i_0=static_cast(read_navigation_signed(data_bits, CNAV_I0)); + ephemeris_record.d_i_0=ephemeris_record.d_i_0*CNAV_I0_LSB; + ephemeris_record.d_IDOT=static_cast(read_navigation_signed(data_bits, CNAV_I0_DOT)); + ephemeris_record.d_IDOT=ephemeris_record.d_IDOT*CNAV_I0_DOT_LSB; + ephemeris_record.d_Cis=static_cast(read_navigation_signed(data_bits, CNAV_CIS)); + ephemeris_record.d_Cis=ephemeris_record.d_Cis*CNAV_CIS_LSB; + ephemeris_record.d_Cic=static_cast(read_navigation_signed(data_bits, CNAV_CIC)); + ephemeris_record.d_Cic=ephemeris_record.d_Cic*CNAV_CIC_LSB; + ephemeris_record.d_Crs=static_cast(read_navigation_signed(data_bits, CNAV_CRS)); + ephemeris_record.d_Crs=ephemeris_record.d_Crs*CNAV_CRS_LSB; + ephemeris_record.d_Crc=static_cast(read_navigation_signed(data_bits, CNAV_CRC)); + ephemeris_record.d_Cic=ephemeris_record.d_Cic*CNAV_CRC_LSB; + ephemeris_record.d_Cus=static_cast(read_navigation_signed(data_bits, CNAV_CUS)); + ephemeris_record.d_Cus=ephemeris_record.d_Cus*CNAV_CUS_LSB; + ephemeris_record.d_Cuc=static_cast(read_navigation_signed(data_bits, CNAV_CUC)); + ephemeris_record.d_Cuc=ephemeris_record.d_Cuc*CNAV_CUS_LSB; + break; + case 30: // (CLOCK, IONO, GRUP DELAY) + //clock + ephemeris_record.d_Toc=static_cast(read_navigation_unsigned(data_bits, CNAV_TOC)); + ephemeris_record.d_Toc=ephemeris_record.d_Toc*CNAV_TOC_LSB; + ephemeris_record.d_URA0 = static_cast(read_navigation_signed(data_bits, CNAV_URA_NED0)); + ephemeris_record.d_URA1 = static_cast(read_navigation_unsigned(data_bits, CNAV_URA_NED1)); + ephemeris_record.d_URA2 = static_cast(read_navigation_unsigned(data_bits, CNAV_URA_NED2)); + ephemeris_record.d_A_f0=static_cast(read_navigation_signed(data_bits, CNAV_AF0)); + ephemeris_record.d_A_f0=ephemeris_record.d_A_f0*CNAV_AF0_LSB; + ephemeris_record.d_A_f1=static_cast(read_navigation_signed(data_bits, CNAV_AF1)); + ephemeris_record.d_A_f1=ephemeris_record.d_A_f1*CNAV_AF1_LSB; + ephemeris_record.d_A_f2=static_cast(read_navigation_signed(data_bits, CNAV_AF2)); + ephemeris_record.d_A_f2=ephemeris_record.d_A_f2*CNAV_AF2_LSB; + //group delays + ephemeris_record.d_TGD=static_cast(read_navigation_signed(data_bits, CNAV_TGD)); + ephemeris_record.d_TGD=ephemeris_record.d_TGD*CNAV_TGD_LSB; + ephemeris_record.d_ISCL1=static_cast(read_navigation_signed(data_bits, CNAV_ISCL1)); + ephemeris_record.d_ISCL1=ephemeris_record.d_ISCL1*CNAV_ISCL1_LSB; + ephemeris_record.d_ISCL2=static_cast(read_navigation_signed(data_bits, CNAV_ISCL2)); + ephemeris_record.d_ISCL2=ephemeris_record.d_ISCL2*CNAV_ISCL2_LSB; + ephemeris_record.d_ISCL5I=static_cast(read_navigation_signed(data_bits, CNAV_ISCL5I)); + ephemeris_record.d_ISCL5I=ephemeris_record.d_ISCL5I*CNAV_ISCL5I_LSB; + ephemeris_record.d_ISCL5Q=static_cast(read_navigation_signed(data_bits, CNAV_ISCL5Q)); + ephemeris_record.d_ISCL5Q=ephemeris_record.d_ISCL5Q*CNAV_ISCL5Q_LSB; + //iono + iono_record.d_alpha0=static_cast(read_navigation_signed(data_bits, CNAV_ALPHA0)); + iono_record.d_alpha0=iono_record.d_alpha0*CNAV_ALPHA0_LSB; + iono_record.d_alpha1=static_cast(read_navigation_signed(data_bits, CNAV_ALPHA1)); + iono_record.d_alpha1=iono_record.d_alpha1*CNAV_ALPHA1_LSB; + iono_record.d_alpha2=static_cast(read_navigation_signed(data_bits, CNAV_ALPHA2)); + iono_record.d_alpha2=iono_record.d_alpha2*CNAV_ALPHA2_LSB; + iono_record.d_alpha3=static_cast(read_navigation_signed(data_bits, CNAV_ALPHA3)); + iono_record.d_alpha3=iono_record.d_alpha3*CNAV_ALPHA3_LSB; + iono_record.d_beta0=static_cast(read_navigation_signed(data_bits, CNAV_BETA0)); + iono_record.d_beta0=iono_record.d_beta0*CNAV_BETA0_LSB; + iono_record.d_beta1=static_cast(read_navigation_signed(data_bits, CNAV_BETA1)); + iono_record.d_beta1=iono_record.d_beta1*CNAV_BETA1_LSB; + iono_record.d_beta2=static_cast(read_navigation_signed(data_bits, CNAV_BETA2)); + iono_record.d_beta2=iono_record.d_beta2*CNAV_BETA2_LSB; + iono_record.d_beta3=static_cast(read_navigation_signed(data_bits, CNAV_BETA3)); + iono_record.d_beta3=iono_record.d_beta3*CNAV_BETA3_LSB; + break; + default: + break; + } +} +bool Gps_CNAV_Navigation_Message::have_new_ephemeris() //Check if we have a new ephemeris stored in the galileo navigation class +{ +// if ((flag_ephemeris_1 == true) and (flag_ephemeris_2 == true) and (flag_ephemeris_3 == true) and (flag_iono_and_GST == true)) +// { +// //if all ephemeris pages have the same IOD, then they belong to the same block +// if ((FNAV_IODnav_1 == FNAV_IODnav_2) and (FNAV_IODnav_3 == FNAV_IODnav_4) and (FNAV_IODnav_1 == FNAV_IODnav_3)) +// { +// std::cout << "Ephemeris (1, 2, 3) have been received and belong to the same batch" << std::endl; +// flag_ephemeris_1 = false;// clear the flag +// flag_ephemeris_2 = false;// clear the flag +// flag_ephemeris_3 = false;// clear the flag +// flag_all_ephemeris = true; +// IOD_ephemeris = FNAV_IODnav_1; +// std::cout << "Batch number: "<< IOD_ephemeris << std::endl; +// return true; +// } +// else +// { +// return false; +// } +// } +// else + return false; +} + + + + +Gps_CNAV_Ephemeris Gps_CNAV_Navigation_Message::get_ephemeris() +{ + return ephemeris_record; +} + + +Gps_CNAV_Iono Gps_CNAV_Navigation_Message::get_iono() +{ + + //WARNING: We clear flag_utc_model_valid in order to not re-send the same information to the ionospheric parameters queue + flag_iono_valid = false; + return iono_record; +} + + +Gps_CNAV_Utc_Model Gps_CNAV_Navigation_Message::get_utc_model() +{ + return utc_model_record; +} + + +bool Gps_CNAV_Navigation_Message::satellite_validation() +{ + bool flag_data_valid = false; + b_valid_ephemeris_set_flag = false; + + // First Step: + // check Issue Of Ephemeris Data (IODE IODC..) to find a possible interrupted reception + // and check if the data have been filled (!=0) +// if (d_TOW_SF1 != 0 and d_TOW_SF2 != 0 and d_TOW_SF3 != 0) +// { +// if (d_IODE_SF2 == d_IODE_SF3 and d_IODC == d_IODE_SF2 and d_IODC!= -1) +// { +// flag_data_valid = true; +// b_valid_ephemeris_set_flag = true; +// } +// } + return flag_data_valid; +} diff --git a/src/core/system_parameters/gps_cnav_navigation_message.h b/src/core/system_parameters/gps_cnav_navigation_message.h new file mode 100644 index 000000000..2c3ea5601 --- /dev/null +++ b/src/core/system_parameters/gps_cnav_navigation_message.h @@ -0,0 +1,121 @@ +/*! + * \file Gps_CNAV_Navigation_Message.h + * \brief Interface of a GPS NAV Data message decoder + * \author Javier Arribas, 2015. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_Gps_CNAV_Navigation_Message_H_ +#define GNSS_SDR_Gps_CNAV_Navigation_Message_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "boost/assign.hpp" +#include "GPS_L2C.h" +#include "gps_cnav_ephemeris.h" +#include "gps_cnav_iono.h" +#include "gps_cnav_utc_model.h" +//TODO: Create GPS CNAV almanac +//#include "gps_almanac.h" + + + +/*! + * \brief This class decodes a GPS CNAV Data message as described in IS-GPS-200E + * + * See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II + */ +class Gps_CNAV_Navigation_Message +{ +private: + unsigned long int read_navigation_unsigned(std::bitset bits, const std::vector> parameter); + signed long int read_navigation_signed(std::bitset bits, const std::vector> parameter); + bool read_navigation_bool(std::bitset bits, const std::vector> parameter); + void print_gps_word_bytes(unsigned int GPS_word); + + Gps_CNAV_Ephemeris ephemeris_record; + Gps_CNAV_Iono iono_record; + Gps_CNAV_Utc_Model utc_model_record; + +public: + + bool flag_iono_valid; //!< If set, it indicates that the ionospheric parameters are filled (page 18 has arrived and decoded) + bool b_valid_ephemeris_set_flag; // flag indicating that this ephemeris set have passed the validation check + + std::map satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus + + // satellite positions + double d_satpos_X; //!< Earth-fixed coordinate x of the satellite [m]. Intersection of the IERS Reference Meridian (IRM) and the plane passing through the origin and normal to the Z-axis. + double d_satpos_Y; //!< Earth-fixed coordinate y of the satellite [m]. Completes a right-handed, Earth-Centered, Earth-Fixed orthogonal coordinate system. + double d_satpos_Z; //!< Earth-fixed coordinate z of the satellite [m]. The direction of the IERS (International Earth Rotation and Reference Systems Service) Reference Pole (IRP). + + // satellite identification info + int i_channel_ID; + unsigned int i_satellite_PRN; + + // Satellite velocity + double d_satvel_X; //!< Earth-fixed velocity coordinate x of the satellite [m] + double d_satvel_Y; //!< Earth-fixed velocity coordinate y of the satellite [m] + double d_satvel_Z; //!< Earth-fixed velocity coordinate z of the satellite [m] + + // public functions + void reset(); + + void decode_page(std::string data); + /*! + * \brief Obtain a GPS SV Ephemeris class filled with current SV data + */ + Gps_CNAV_Ephemeris get_ephemeris(); + + /*! + * \brief Obtain a GPS ionospheric correction parameters class filled with current SV data + */ + Gps_CNAV_Iono get_iono(); + + /*! + * \brief Obtain a GPS UTC model parameters class filled with current SV data + */ + Gps_CNAV_Utc_Model get_utc_model(); + + + bool satellite_validation(); + + bool have_new_ephemeris(); //Check if we have a new ephemeris stored in the galileo navigation class + + /*! + * Default constructor + */ + Gps_CNAV_Navigation_Message(); +}; + +#endif diff --git a/src/core/system_parameters/gps_cnav_utc_model.cc b/src/core/system_parameters/gps_cnav_utc_model.cc new file mode 100644 index 000000000..7d950c896 --- /dev/null +++ b/src/core/system_parameters/gps_cnav_utc_model.cc @@ -0,0 +1,45 @@ +/* + * \file gps_cnav_utc_model.h + * \brief Interface of a GPS CNAV UTC MODEL storage + * \author Javier Arribas, 2015. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "gps_cnav_utc_model.h" +#include + +Gps_CNAV_Utc_Model::Gps_CNAV_Utc_Model() +{ + valid = false; + d_A1 = 0; + d_A0 = 0; + d_t_OT = 0; + i_WN_T = 0; + d_DeltaT_LS = 0; + i_WN_LSF = 0; + i_DN = 0; + d_DeltaT_LSF = 0; +} diff --git a/src/core/system_parameters/gps_cnav_utc_model.h b/src/core/system_parameters/gps_cnav_utc_model.h new file mode 100644 index 000000000..ca0244b0f --- /dev/null +++ b/src/core/system_parameters/gps_cnav_utc_model.h @@ -0,0 +1,85 @@ +/*! + * \file gps_utc_model.h + * \brief Interface of a GPS UTC MODEL storage + * \author Javier Arribas, 2013. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GPS_CNAV_UTC_MODEL_H_ +#define GNSS_SDR_GPS_CNAV_UTC_MODEL_H_ + +#include "GPS_L2C.h" +#include "boost/assign.hpp" +#include + + +/*! + * \brief This class is a storage for the GPS UTC MODEL data as described in IS-GPS-200E + * + * See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II + */ +class Gps_CNAV_Utc_Model +{ +public: + bool valid; + // UTC parameters + double d_A1; //!< 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s/s] + double d_A0; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s] + double d_t_OT; //!< Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200E) [s] + int i_WN_T; //!< UTC reference week number [weeks] + double d_DeltaT_LS; //!< delta time due to leap seconds [s]. Number of leap seconds since 6-Jan-1980 as transmitted by the GPS almanac. + int i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks] + int i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days] + double d_DeltaT_LSF; //!< Scheduled future or recent past (relative to NAV message upload) value of the delta time due to leap seconds [s] + + /*! + * Default constructor + */ + Gps_CNAV_Utc_Model(); + + template + /* + * \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the ephemeris data on disk file. + */ + void serialize(Archive& archive, const unsigned int version) + { + using boost::serialization::make_nvp; + if(version){}; + archive & make_nvp("valid",valid); + archive & make_nvp("d_A1",d_A1); + archive & make_nvp("d_A0",d_A0); + archive & make_nvp("d_t_OT",d_t_OT); + archive & make_nvp("i_WN_T",i_WN_T); + archive & make_nvp("d_DeltaT_LS",d_DeltaT_LS); + archive & make_nvp("i_WN_LSF",i_WN_LSF); + archive & make_nvp("i_DN",i_DN); + archive & make_nvp("d_DeltaT_LSF",d_DeltaT_LSF); + } + +}; + +#endif