mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 15:23:04 +00:00 
			
		
		
		
	| @@ -396,10 +396,19 @@ bool gps_l1_ca_telemetry_decoder_gs::decode_subframe(double cn0, bool flag_inver | ||||
|                                     const std::shared_ptr<Gps_Utc_Model> tmp_obj = std::make_shared<Gps_Utc_Model>(d_nav.get_utc_model()); | ||||
|                                     this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); | ||||
|                                 } | ||||
|                             if (d_nav.almanac_validation() == true) | ||||
|                                 { | ||||
|                                     const std::shared_ptr<Gps_Almanac> tmp_obj = std::make_shared<Gps_Almanac>(d_nav.get_almanac()); | ||||
|                                     this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); | ||||
|                                 } | ||||
|                             break; | ||||
|                         case 5: | ||||
|                         // get almanac (if available) | ||||
|                         // TODO: implement almanac reader in navigation_message | ||||
|                             if (d_nav.almanac_validation() == true) | ||||
|                                 { | ||||
|                                     const std::shared_ptr<Gps_Almanac> tmp_obj = std::make_shared<Gps_Almanac>(d_nav.get_almanac()); | ||||
|                                     this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); | ||||
|                                 } | ||||
|                             break; | ||||
|                         default: | ||||
|                             break; | ||||
|                         } | ||||
|   | ||||
| @@ -226,6 +226,29 @@ const std::vector<std::pair<int32_t, int32_t>> HEALTH_SV23({{253, 6}}); | ||||
| const std::vector<std::pair<int32_t, int32_t>> HEALTH_SV24({{259, 6}}); | ||||
|  | ||||
|  | ||||
| // Almanac  | ||||
| const std::vector<std::pair<int32_t, int32_t>> ALM_ECC({{69, 16}}); | ||||
| constexpr double ALM_ECC_LSB = TWO_N21; | ||||
| const std::vector<std::pair<int32_t, int32_t>> ALM_TOA({{91, 8}}); | ||||
| constexpr int32_t ALM_TOA_LSB = static_cast<int32_t>(TWO_P12); | ||||
| const std::vector<std::pair<int32_t, int32_t>> ALM_DELTAI({{99, 16}}); | ||||
| constexpr double ALM_DELTAI_LSB = TWO_N19; | ||||
| const std::vector<std::pair<int32_t, int32_t>> ALM_OMEGADOT({{121, 16}}); | ||||
| constexpr double ALM_OMEGADOT_LSB = TWO_N38; | ||||
| const std::vector<std::pair<int32_t, int32_t>> ALM_SVHEALTH({{137, 8}}); | ||||
| const std::vector<std::pair<int32_t, int32_t>> ALM_SQUAREA({{151, 24}}); | ||||
| constexpr double ALM_SQUAREA_LSB = TWO_N11; | ||||
| const std::vector<std::pair<int32_t, int32_t>> ALM_OMEGAZERO({{181, 24}}); | ||||
| constexpr double ALM_OMEGAZERO_LSB = TWO_N23; | ||||
| const std::vector<std::pair<int32_t, int32_t>> ALM_OMEGA({{211, 24}}); | ||||
| constexpr double ALM_OMEGA_LSB = TWO_N23; | ||||
| const std::vector<std::pair<int32_t, int32_t>> ALM_MZERO({{241, 24}}); | ||||
| constexpr double ALM_MZERO_LSB = TWO_N23; | ||||
|  | ||||
| const std::vector<std::pair<int32_t, int32_t>> ALM_AF0({{271, 8}, {290, 3}}); | ||||
| constexpr double ALM_AF0_LSB = TWO_N20; | ||||
| const std::vector<std::pair<int32_t, int32_t>> ALM_AF1({{279, 11}}); | ||||
| constexpr double ALM_AF1_LSB = TWO_N38; | ||||
| /** \} */ | ||||
| /** \} */ | ||||
| #endif  // GNSS_SDR_GPS_L1_CA_H | ||||
|   | ||||
| @@ -201,9 +201,31 @@ int32_t Gps_Navigation_Message::subframe_decoder(const char* subframe) | ||||
|             SV_page = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, SV_PAGE)); | ||||
|             if (SV_page > 24 && SV_page < 33)  // Page 4 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200M) | ||||
|                 { | ||||
|                     //! \TODO read almanac | ||||
|                     if (SV_data_ID != 0) | ||||
|                         { | ||||
|                             a_M_0   = static_cast<double>(read_navigation_signed(subframe_bits, ALM_MZERO)); | ||||
|                             a_M_0   = a_M_0 * ALM_MZERO_LSB; | ||||
|                             a_ecc   = static_cast<double>(read_navigation_unsigned(subframe_bits, ALM_ECC)); | ||||
|                             a_ecc   = a_ecc *ALM_ECC_LSB; | ||||
|                             a_sqrtA = static_cast<double>(read_navigation_unsigned(subframe_bits, ALM_SQUAREA)); | ||||
|                             a_sqrtA = a_sqrtA *ALM_SQUAREA_LSB; | ||||
|                             a_OMEGA_0 = static_cast<double>(read_navigation_signed(subframe_bits, ALM_OMEGAZERO)); | ||||
|                             a_OMEGA_0 = a_OMEGA_0 * ALM_OMEGAZERO_LSB; | ||||
|                             a_omega = static_cast<double>(read_navigation_signed(subframe_bits, ALM_OMEGA)); | ||||
|                             a_omega = a_omega * ALM_OMEGA_LSB; | ||||
|                             a_OMEGAdot = static_cast<double>(read_navigation_signed(subframe_bits, ALM_OMEGADOT)); | ||||
|                             a_OMEGAdot =  a_OMEGAdot *ALM_OMEGADOT_LSB; | ||||
|                             a_delta_i = static_cast<double>(read_navigation_signed(subframe_bits, ALM_DELTAI)); | ||||
|                             a_delta_i = a_delta_i * ALM_DELTAI_LSB; | ||||
|                             a_af0 = static_cast<double>(read_navigation_signed(subframe_bits, ALM_AF0)); | ||||
|                             a_af0 = a_af0 * ALM_AF0_LSB;                             | ||||
|                             a_af1 = static_cast<double>(read_navigation_signed(subframe_bits, ALM_AF1)); | ||||
|                             a_af1 = a_af1* ALM_AF1_LSB; | ||||
|                             a_PRN = SV_page; | ||||
|                             i_Toa = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, ALM_TOA)); | ||||
|                             i_Toa = i_Toa * ALM_TOA_LSB; | ||||
|                              | ||||
|                             flag_almanac_valid = true ; | ||||
|                         } | ||||
|                 } | ||||
|  | ||||
| @@ -276,11 +298,34 @@ int32_t Gps_Navigation_Message::subframe_decoder(const char* subframe) | ||||
|             b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); | ||||
|             SV_data_ID_5 = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, SV_DATA_ID)); | ||||
|             SV_page_5 = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, SV_PAGE)); | ||||
|             if (SV_page_5 < 25) | ||||
|             if ((SV_page_5 > 0) && (SV_page_5 < 25)) | ||||
|                 { | ||||
|                     //! \TODO read almanac | ||||
|                     if (SV_data_ID_5 != 0) | ||||
|                         { | ||||
|                             a_M_0   = static_cast<double>(read_navigation_signed(subframe_bits, ALM_MZERO)); | ||||
|                             a_M_0   = a_M_0 * ALM_MZERO_LSB; | ||||
|                             a_ecc   = static_cast<double>(read_navigation_unsigned(subframe_bits, ALM_ECC)); | ||||
|                             a_ecc   = a_ecc *ALM_ECC_LSB; | ||||
|                             a_sqrtA = static_cast<double>(read_navigation_unsigned(subframe_bits, ALM_SQUAREA)); | ||||
|                             a_sqrtA =  a_sqrtA *ALM_SQUAREA_LSB; | ||||
|                             a_OMEGA_0 = static_cast<double>(read_navigation_signed(subframe_bits, ALM_OMEGAZERO)); | ||||
|                             a_OMEGA_0 = a_OMEGA_0 * ALM_OMEGAZERO_LSB; | ||||
|                             a_omega = static_cast<double>(read_navigation_signed(subframe_bits, ALM_OMEGA)); | ||||
|                             a_omega = a_omega * ALM_OMEGA_LSB; | ||||
|                             a_OMEGAdot = static_cast<double>(read_navigation_signed(subframe_bits, ALM_OMEGADOT)); | ||||
|                             a_OMEGAdot =  a_OMEGAdot *ALM_OMEGADOT_LSB; | ||||
|                             a_delta_i = static_cast<double>(read_navigation_signed(subframe_bits, ALM_DELTAI)); | ||||
|                             a_delta_i = a_delta_i * ALM_DELTAI_LSB; | ||||
|                             a_af0 = static_cast<double>(read_navigation_signed(subframe_bits, ALM_AF0)); | ||||
|                             a_af0 = a_af0 * ALM_AF0_LSB;                             | ||||
|                             a_af1 = static_cast<double>(read_navigation_signed(subframe_bits, ALM_AF1)); | ||||
|                             a_af1 = a_af1* ALM_AF1_LSB; | ||||
|                             a_PRN = SV_page_5; | ||||
|                             i_Toa = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, ALM_TOA)); | ||||
|                             i_Toa = i_Toa * ALM_TOA_LSB; | ||||
|                             SV_Health = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, ALM_SVHEALTH)); | ||||
|                             flag_almanac_valid = true; | ||||
|  | ||||
|                         } | ||||
|                 } | ||||
|             if (SV_page_5 == 51)  // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200M) | ||||
| @@ -288,6 +333,7 @@ int32_t Gps_Navigation_Message::subframe_decoder(const char* subframe) | ||||
|                     i_Toa = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, T_OA)); | ||||
|                     i_Toa = i_Toa * T_OA_LSB; | ||||
|                     i_WN_A = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, WN_A)); | ||||
|                     flag_almanac_week_valid = true; | ||||
|                     almanacHealth[1] = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, HEALTH_SV1)); | ||||
|                     almanacHealth[2] = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, HEALTH_SV2)); | ||||
|                     almanacHealth[3] = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, HEALTH_SV3)); | ||||
| @@ -435,6 +481,27 @@ Gps_Ephemeris Gps_Navigation_Message::get_ephemeris() const | ||||
| } | ||||
|  | ||||
|  | ||||
| Gps_Almanac Gps_Navigation_Message::get_almanac() | ||||
| {   | ||||
|     Gps_Almanac almanac; | ||||
|     almanac.SV_health = SV_Health; | ||||
|     almanac.PRN = a_PRN; | ||||
|     almanac.delta_i = a_delta_i;    | ||||
|     almanac.toa = i_Toa; | ||||
|     almanac.WNa = i_WN_A;       | ||||
|     almanac.M_0 = a_M_0;       | ||||
|     almanac.ecc = a_ecc;       | ||||
|     almanac.sqrtA = a_sqrtA;     | ||||
|     almanac.OMEGA_0 = a_OMEGA_0;    | ||||
|     almanac.omega = a_omega;      | ||||
|     almanac.OMEGAdot = a_OMEGAdot;   | ||||
|     almanac.af0 = a_af0;        | ||||
|     almanac.af1 = a_af1;     | ||||
|     flag_almanac_valid = false; | ||||
|     return almanac; | ||||
| } | ||||
|  | ||||
|  | ||||
| Gps_Iono Gps_Navigation_Message::get_iono() | ||||
| { | ||||
|     Gps_Iono iono; | ||||
| @@ -490,3 +557,9 @@ bool Gps_Navigation_Message::satellite_validation() | ||||
|         } | ||||
|     return flag_data_valid; | ||||
| } | ||||
|  | ||||
|  | ||||
| bool Gps_Navigation_Message::almanac_validation() | ||||
| { | ||||
|     return flag_almanac_valid && (i_WN_A > 0);  | ||||
| } | ||||
|   | ||||
| @@ -22,6 +22,7 @@ | ||||
|  | ||||
| #include "GPS_L1_CA.h" | ||||
| #include "gps_ephemeris.h" | ||||
| #include "gps_almanac.h" | ||||
| #include "gps_iono.h" | ||||
| #include "gps_utc_model.h" | ||||
| #include <bitset> | ||||
| @@ -61,7 +62,12 @@ public: | ||||
|     Gps_Iono get_iono(); | ||||
|  | ||||
|     /*! | ||||
|      * \brief Obtain a GPS UTC model parameters class filled with current SV data | ||||
|      * \brief Obtain a GPS almanac class filled with current SV data | ||||
|      */ | ||||
|     Gps_Almanac get_almanac(); | ||||
|  | ||||
|     /*! | ||||
|      * \brief Obtain a GPS Almanac  model parameters class filled with current SV data | ||||
|      */ | ||||
|     Gps_Utc_Model get_utc_model(); | ||||
|  | ||||
| @@ -133,6 +139,7 @@ public: | ||||
|     } | ||||
|  | ||||
|     bool satellite_validation(); | ||||
|     bool almanac_validation(); | ||||
|  | ||||
| private: | ||||
|     uint64_t read_navigation_unsigned(const std::bitset<GPS_SUBFRAME_BITS>& bits, const std::vector<std::pair<int32_t, int32_t>>& parameter) const; | ||||
| @@ -194,6 +201,17 @@ private: | ||||
|     // Almanac | ||||
|     int32_t i_Toa{};   // Almanac reference time [s] | ||||
|     int32_t i_WN_A{};  // Modulo 256 of the GPS week number to which the almanac reference time (i_Toa) is referenced | ||||
|     int32_t SV_Health{};  // Almanac SV healt | ||||
|     uint32_t a_PRN;       // Almanac PRN | ||||
|     double a_delta_i{};   // Inclination Angle at Reference Time (relative to i_0 = 0.30 semi-circles) | ||||
|     double a_M_0{};       // Mean Anomaly at Reference Time [semi-circles] | ||||
|     double a_ecc{};       // Eccentricity [dimensionless] | ||||
|     double a_sqrtA{};     // Square Root of the Semi-Major Axis [sqrt(m)] | ||||
|     double a_OMEGA_0{};   // Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] | ||||
|     double a_omega{};     // Argument of Perigee [semi-cicles] | ||||
|     double a_OMEGAdot{};  // Rate of Right Ascension [semi-circles/s] | ||||
|     double a_af0{};       // Coefficient 0 of code phase offset model [s] | ||||
|     double a_af1{};       // Coefficient 1 of code phase offset model [s/s] | ||||
|  | ||||
|     // satellite identification info | ||||
|     int32_t i_channel_ID{}; | ||||
| @@ -224,7 +242,8 @@ private: | ||||
|     bool b_valid_ephemeris_set_flag{};  // flag indicating that this ephemeris set have passed the validation check | ||||
|     bool flag_iono_valid{};             // If set, it indicates that the ionospheric parameters are filled (page 18 has arrived and decoded) | ||||
|     bool flag_utc_model_valid{};        // If set, it indicates that the UTC model parameters are filled | ||||
|  | ||||
|     bool flag_almanac_valid{};          // If set, it indicates that the almanac is filled | ||||
|     bool flag_almanac_week_valid{};     // If set, it indicates that the almanac week is valid | ||||
|     /*  If true, enhanced level of integrity assurance. | ||||
|      * | ||||
|      *  If false, indicates that the conveying signal is provided with the legacy level of integrity assurance. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 joebre
					joebre