diff --git a/docs/protobuf/monitor_galileo_ephemeris.proto b/docs/protobuf/monitor_galileo_ephemeris.proto new file mode 100644 index 000000000..7880948b5 --- /dev/null +++ b/docs/protobuf/monitor_galileo_ephemeris.proto @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: BSD-3-Clause +// SPDX-FileCopyrightText: 2018-2020 Carles Fernandez-Prades +syntax = "proto3"; + +package gnss_sdr; + +message MonitorGalileoEphemeris { + /* Galileo ephemeris are 16 parameters and here are reported following the ICD order, paragraph 5.1.1. + The number in the name after underscore (_1, _2, _3 and so on) refers to the page were we can find that parameter */ + int32 IOD_ephemeris=1; + int32 IOD_nav_1=2; + double M0_1=3; //!< Mean anomaly at reference time [semi-circles] + double delta_n_3=4; //!< Mean motion difference from computed value [semi-circles/sec] + double e_1=5; //!< Eccentricity + double A_1=6; //!< Square root of the semi-major axis [meters^1/2] + double OMEGA_0_2=7; //!< Longitude of ascending node of orbital plane at weekly epoch [semi-circles] + double i_0_2=8; //!< Inclination angle at reference time [semi-circles] + double omega_2=9; //!< Argument of perigee [semi-circles] + double OMEGA_dot_3=10; //!< Rate of right ascension [semi-circles/sec] + double iDot_2=11; //!< Rate of inclination angle [semi-circles/sec] + double C_uc_3=12; //!< Amplitude of the cosine harmonic correction term to the argument of latitude [radians] + double C_us_3=13; //!< Amplitude of the sine harmonic correction term to the argument of latitude [radians] + double C_rc_3=14; //!< Amplitude of the cosine harmonic correction term to the orbit radius [meters] + double C_rs_3=15; //!< Amplitude of the sine harmonic correction term to the orbit radius [meters] + double C_ic_4=16; //!< Amplitude of the cosine harmonic correction term to the angle of inclination [radians] + double C_is_4=17; //!< Amplitude of the sine harmonic correction term to the angle of inclination [radians] + uint32 d_Toe=18; // Ephemeris reference time + + /*Clock correction parameters*/ + uint32 d_Toc=19; // Clock correction data reference Time of Week + double af0_4=20; //!< SV clock bias correction coefficient [s] + double af1_4=21; //!< SV clock drift correction coefficient [s/s] + double af2_4=22; //!< SV clock drift rate correction coefficient [s/s^2] + + /*GST*/ + // Not belong to ephemeris set (page 1 to 4) + int32 WN_5=23; //!< Week number + int32 TOW_5=24; //!< Time of Week + double Galileo_satClkDrift=25; + double Galileo_dtr=26; //!< relativistic clock correction term + + // SV status + int32 SISA_3=27; + int32 E5a_HS=28; //!< E5a Signal Health Status + int32 E5b_HS_5=29; //!< E5b Signal Health Status + int32 E1B_HS_5=30; //!< E1B Signal Health Status + bool E5a_DVS=31; //!< E5a Data Validity Status + bool E5b_DVS_5=32; //!< E5b Data Validity Status + bool E1B_DVS_5=33; //!< E1B Data Validity Status + + double BGD_E1E5a_5=34; //!< E1-E5a Broadcast Group Delay [s] + double BGD_E1E5b_5=35; //!< E1-E5b Broadcast Group Delay [s] + + int32 i_satellite_PRN=36; //!< SV PRN NUMBER +} diff --git a/docs/protobuf/monitor_gps_ephemeris.proto b/docs/protobuf/monitor_gps_ephemeris.proto new file mode 100644 index 000000000..66896255c --- /dev/null +++ b/docs/protobuf/monitor_gps_ephemeris.proto @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: BSD-3-Clause +// SPDX-FileCopyrightText: 2018-2020 Carles Fernandez-Prades +syntax = "proto3"; + +package gnss_sdr; + +message MonitorGpsEphemeris { + uint32 i_satellite_PRN=1; // SV PRN NUMBER + double d_TOW=2; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s] + double d_Crs=3; //!< Amplitude of the Sine Harmonic Correction Term to the Orbit Radius [m] + double d_Delta_n=4; //!< Mean Motion Difference From Computed Value [semi-circles/s] + double d_M_0=5; //!< Mean Anomaly at Reference Time [semi-circles] + double d_Cuc=6; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad] + double d_e_eccentricity=7; //!< Eccentricity [dimensionless] + double d_Cus=8; //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad] + double d_sqrt_A=9; //!< Square Root of the Semi-Major Axis [sqrt(m)] + uint32 d_Toe=10; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200K) [s] + uint32 d_Toc=11; //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200K) [s] + double d_Cic=12; //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad] + double d_OMEGA0=13; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] + double d_Cis=14; //!< Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination [rad] + double d_i_0=15; //!< Inclination Angle at Reference Time [semi-circles] + double d_Crc=16; //!< Amplitude of the Cosine Harmonic Correction Term to the Orbit Radius [m] + double d_OMEGA=17; //!< Argument of Perigee [semi-cicles] + double d_OMEGA_DOT=18; //!< Rate of Right Ascension [semi-circles/s] + double d_IDOT=19; //!< Rate of Inclination Angle [semi-circles/s] + int32 i_code_on_L2=20; //!< If 1, P code ON in L2; if 2, C/A code ON in L2; + int32 i_GPS_week=21; //!< GPS week number, aka WN [week] + bool b_L2_P_data_flag=22; //!< When true, indicates that the NAV data stream was commanded OFF on the P-code of the L2 channel + int32 i_SV_accuracy=23; //!< User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200K) + int32 i_SV_health=24; + double d_TGD=25; //!< Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s] + double d_IODC=26; //!< Issue of Data, Clock + double d_IODE_SF2=27; //!< Issue of Data, Ephemeris (IODE), subframe 2 + double d_IODE_SF3=28; //!< Issue of Data, Ephemeris(IODE), subframe 3 + int32 i_AODO=29; //!< Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s] + + bool b_fit_interval_flag=30; //!< indicates the curve-fit interval used by the CS (Block II/IIA/IIR/IIR-M/IIF) and SS (Block IIIA) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours. + double d_spare1=31; + double d_spare2=32; + + double d_A_f0=33; //!< Coefficient 0 of code phase offset model [s] + double d_A_f1=34; //!< Coefficient 1 of code phase offset model [s/s] + double d_A_f2=35; //!< Coefficient 2 of code phase offset model [s/s^2] + + bool b_integrity_status_flag=36; + bool b_alert_flag=37; //!< 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=38; //!< If true, the AntiSpoofing mode is ON in that SV +} diff --git a/src/algorithms/PVT/adapters/rtklib_pvt.cc b/src/algorithms/PVT/adapters/rtklib_pvt.cc index 126a0efab..bccb5b0e1 100644 --- a/src/algorithms/PVT/adapters/rtklib_pvt.cc +++ b/src/algorithms/PVT/adapters/rtklib_pvt.cc @@ -804,6 +804,11 @@ Rtklib_Pvt::Rtklib_Pvt(const ConfigurationInterface* configuration, pvt_output_parameters.protobuf_enabled = true; } + // Read EPHEMERIS MONITOR Configuration + pvt_output_parameters.monitor_ephemeris_enabled = configuration->property(role + ".enable_monitor_ephemeris", false); + pvt_output_parameters.udp_eph_addresses = configuration->property(role + ".monitor_ephemeris_client_addresses", std::string("127.0.0.1")); + pvt_output_parameters.udp_eph_port = configuration->property(role + ".monitor_ephemeris_udp_port", 1234); + // Show time in local zone pvt_output_parameters.show_local_time_zone = configuration->property(role + ".show_local_time_zone", false); diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc index cbe340e8e..41e6b4d4c 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc @@ -43,6 +43,7 @@ #include "gps_utc_model.h" #include "gpx_printer.h" #include "kml_printer.h" +#include "monitor_ephemeris_udp_sink.h" #include "monitor_pvt.h" #include "monitor_pvt_udp_sink.h" #include "nmea_printer.h" @@ -396,6 +397,22 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels, d_udp_sink_ptr = nullptr; } + // EPHEMERIS MONITOR + d_flag_monitor_ephemeris_enabled = conf_.monitor_ephemeris_enabled; + if (d_flag_monitor_ephemeris_enabled) + { + std::string address_string = conf_.udp_eph_addresses; + std::vector udp_addr_vec = split_string(address_string, '_'); + std::sort(udp_addr_vec.begin(), udp_addr_vec.end()); + udp_addr_vec.erase(std::unique(udp_addr_vec.begin(), udp_addr_vec.end()), udp_addr_vec.end()); + + d_eph_udp_sink_ptr = std::make_unique(udp_addr_vec, conf_.udp_eph_port, conf_.protobuf_enabled); + } + else + { + d_eph_udp_sink_ptr = nullptr; + } + // Create Sys V message queue d_first_fix = true; d_sysv_msg_key = 1101; @@ -1083,6 +1100,12 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg) new_eph[gps_eph->i_satellite_PRN] = *gps_eph; d_rp->log_rinex_nav_gps_nav(d_type_of_rx, new_eph); } + // todo: Send only new sets of ephemeris (new TOE), not sent to the client + // send the new eph to the eph monitor (if enabled) + if (d_flag_monitor_ephemeris_enabled) + { + d_eph_udp_sink_ptr->write_gps_ephemeris(gps_eph); + } } d_internal_pvt_solver->gps_ephemeris_map[gps_eph->i_satellite_PRN] = *gps_eph; if (d_enable_rx_clock_correction == true) @@ -1211,6 +1234,12 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg) new_gal_eph[galileo_eph->i_satellite_PRN] = *galileo_eph; d_rp->log_rinex_nav_gal_nav(d_type_of_rx, new_gal_eph); } + // todo: Send only new sets of ephemeris (new TOE), not sent to the client + // send the new eph to the eph monitor (if enabled) + if (d_flag_monitor_ephemeris_enabled) + { + d_eph_udp_sink_ptr->write_galileo_ephemeris(galileo_eph); + } } d_internal_pvt_solver->galileo_ephemeris_map[galileo_eph->i_satellite_PRN] = *galileo_eph; if (d_enable_rx_clock_correction == true) diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.h b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.h index 727b9818d..ae8a73b3f 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.h +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.h @@ -52,6 +52,7 @@ class Gps_Ephemeris; class Gpx_Printer; class Kml_Printer; class Monitor_Pvt_Udp_Sink; +class Monitor_Ephemeris_Udp_Sink; class Nmea_Printer; class Pvt_Conf; class Rinex_Printer; @@ -168,6 +169,7 @@ private: std::unique_ptr d_geojson_printer; std::unique_ptr d_rtcm_printer; std::unique_ptr d_udp_sink_ptr; + std::unique_ptr d_eph_udp_sink_ptr; std::chrono::time_point d_start; std::chrono::time_point d_end; @@ -260,6 +262,7 @@ private: bool d_first_fix; bool d_xml_storage; bool d_flag_monitor_pvt_enabled; + bool d_flag_monitor_ephemeris_enabled; bool d_show_local_time_zone; bool d_waiting_obs_block_rx_clock_offset_correction_msg; bool d_enable_rx_clock_correction; diff --git a/src/algorithms/PVT/libs/CMakeLists.txt b/src/algorithms/PVT/libs/CMakeLists.txt index 7149e7a4b..b00e1a9bd 100644 --- a/src/algorithms/PVT/libs/CMakeLists.txt +++ b/src/algorithms/PVT/libs/CMakeLists.txt @@ -5,6 +5,8 @@ # SPDX-License-Identifier: BSD-3-Clause protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${CMAKE_SOURCE_DIR}/docs/protobuf/monitor_pvt.proto) +protobuf_generate_cpp(PROTO_SRCS2 PROTO_HDRS2 ${CMAKE_SOURCE_DIR}/docs/protobuf/monitor_gps_ephemeris.proto) +protobuf_generate_cpp(PROTO_SRCS3 PROTO_HDRS3 ${CMAKE_SOURCE_DIR}/docs/protobuf/monitor_galileo_ephemeris.proto) set(PVT_LIB_SOURCES pvt_conf.cc @@ -18,6 +20,7 @@ set(PVT_LIB_SOURCES rtcm.cc rtklib_solver.cc monitor_pvt_udp_sink.cc + monitor_ephemeris_udp_sink.cc ) set(PVT_LIB_HEADERS @@ -34,6 +37,9 @@ set(PVT_LIB_HEADERS monitor_pvt_udp_sink.h monitor_pvt.h serdes_monitor_pvt.h + serdes_galileo_eph.h + serdes_gps_eph.h + monitor_ephemeris_udp_sink.h ) list(SORT PVT_LIB_HEADERS) @@ -44,14 +50,18 @@ if(USE_CMAKE_TARGET_SOURCES) target_sources(pvt_libs PRIVATE ${PROTO_SRCS} + ${PROTO_SRCS2} + ${PROTO_SRCS3} ${PROTO_HDRS} + ${PROTO_HDRS2} + ${PROTO_HDRS3} ${PVT_LIB_SOURCES} PUBLIC ${PVT_LIB_HEADERS} ) else() - source_group(Headers FILES ${PVT_LIB_HEADERS} ${PROTO_HDRS}) - add_library(pvt_libs ${PVT_LIB_SOURCES} ${PROTO_SRCS} ${PVT_LIB_HEADERS} ${PROTO_HDRS}) + source_group(Headers FILES ${PVT_LIB_HEADERS} ${PROTO_HDRS} ${PROTO_HDRS2} ${PROTO_HDRS3}) + add_library(pvt_libs ${PVT_LIB_SOURCES} ${PROTO_SRCS} ${PROTO_SRCS2} ${PROTO_SRCS3} ${PVT_LIB_HEADERS} ${PROTO_HDRS} ${PROTO_HDRS2} ${PROTO_HDRS3}) endif() target_link_libraries(pvt_libs diff --git a/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.cc b/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.cc new file mode 100644 index 000000000..5e9f45231 --- /dev/null +++ b/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.cc @@ -0,0 +1,111 @@ +/*! + * \file monitor_pvt_udp_sink.cc + * \brief Implementation of a class that sends serialized Monitor_Pvt + * objects over udp to one or multiple endpoints + * \author Álvaro Cebrián Juan, 2019. acebrianjuan(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "monitor_ephemeris_udp_sink.h" +#include +#include +#include + + +Monitor_Ephemeris_Udp_Sink::Monitor_Ephemeris_Udp_Sink(const std::vector& addresses, const uint16_t& port, bool protobuf_enabled) : socket{io_context} +{ + for (const auto& address : addresses) + { + boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(address, error), port); + endpoints.push_back(endpoint); + } + + use_protobuf = protobuf_enabled; + if (use_protobuf) + { + serdes_gal = Serdes_Galileo_Eph(); + serdes_gps = Serdes_Gps_Eph(); + } +} + + +bool Monitor_Ephemeris_Udp_Sink::write_galileo_ephemeris(const std::shared_ptr monitor_gal_eph) +{ + std::string outbound_data; + if (use_protobuf == false) + { + std::ostringstream archive_stream; + boost::archive::binary_oarchive oa{archive_stream}; + oa << *monitor_gal_eph; + outbound_data = archive_stream.str(); + } + else + { + outbound_data = "E"; + outbound_data.append(serdes_gal.createProtobuffer(monitor_gal_eph)); + } + + for (const auto& endpoint : endpoints) + { + socket.open(endpoint.protocol(), error); + socket.connect(endpoint, error); + + try + { + if (socket.send(boost::asio::buffer(outbound_data)) == 0) + { + return false; + } + } + catch (boost::system::system_error const& e) + { + return false; + } + } + return true; +} + +bool Monitor_Ephemeris_Udp_Sink::write_gps_ephemeris(const std::shared_ptr monitor_gps_eph) +{ + std::string outbound_data; + if (use_protobuf == false) + { + std::ostringstream archive_stream; + boost::archive::binary_oarchive oa{archive_stream}; + oa << *monitor_gps_eph; + outbound_data = archive_stream.str(); + } + else + { + outbound_data = "G"; + outbound_data.append(serdes_gps.createProtobuffer(monitor_gps_eph)); + } + + for (const auto& endpoint : endpoints) + { + socket.open(endpoint.protocol(), error); + socket.connect(endpoint, error); + + try + { + if (socket.send(boost::asio::buffer(outbound_data)) == 0) + { + return false; + } + } + catch (boost::system::system_error const& e) + { + return false; + } + } + return true; +} diff --git a/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.h b/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.h new file mode 100644 index 000000000..824797eb7 --- /dev/null +++ b/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.h @@ -0,0 +1,63 @@ +/*! + * \file monitor_pvt_udp_sink.h + * \brief Interface of a class that sends serialized Gps_Ephemeris objects + * over udp to one or multiple endpoints + * \author Álvaro Cebrián Juan, 2019. acebrianjuan(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_MONITOR_EPHEMERIS_UDP_SINK_H +#define GNSS_SDR_MONITOR_EPHEMERIS_UDP_SINK_H + +#include "galileo_ephemeris.h" +#include "gps_ephemeris.h" +#include "serdes_galileo_eph.h" +#include "serdes_gps_eph.h" +#include +#include +#include +#include + +/** \addtogroup PVT + * \{ */ +/** \addtogroup PVT_libs + * \{ */ + + +#if USE_BOOST_ASIO_IO_CONTEXT +using b_io_context = boost::asio::io_context; +#else +using b_io_context = boost::asio::io_service; +#endif + +class Monitor_Ephemeris_Udp_Sink +{ +public: + Monitor_Ephemeris_Udp_Sink(const std::vector& addresses, const uint16_t& port, bool protobuf_enabled); + bool write_gps_ephemeris(const std::shared_ptr monitor_gps_eph); + bool write_galileo_ephemeris(const std::shared_ptr monitor_gal_eph); + + +private: + Serdes_Galileo_Eph serdes_gal; + Serdes_Gps_Eph serdes_gps; + b_io_context io_context; + boost::asio::ip::udp::socket socket; + std::vector endpoints; + boost::system::error_code error; + bool use_protobuf; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_MONITOR_EPHEMERIS_UDP_SINK_H diff --git a/src/algorithms/PVT/libs/pvt_conf.cc b/src/algorithms/PVT/libs/pvt_conf.cc index 75779ca44..d5951940c 100644 --- a/src/algorithms/PVT/libs/pvt_conf.cc +++ b/src/algorithms/PVT/libs/pvt_conf.cc @@ -61,8 +61,10 @@ Pvt_Conf::Pvt_Conf() enable_rx_clock_correction = true; monitor_enabled = false; + monitor_ephemeris_enabled = false; protobuf_enabled = true; udp_port = 0; + udp_eph_port = 0; pre_2009_file = false; show_local_time_zone = false; } diff --git a/src/algorithms/PVT/libs/pvt_conf.h b/src/algorithms/PVT/libs/pvt_conf.h index 5cd584568..147e5109b 100644 --- a/src/algorithms/PVT/libs/pvt_conf.h +++ b/src/algorithms/PVT/libs/pvt_conf.h @@ -48,6 +48,7 @@ public: std::string xml_output_path; std::string rtcm_output_file_path; std::string udp_addresses; + std::string udp_eph_addresses; uint32_t type_of_receiver; int32_t output_rate_ms; @@ -60,6 +61,7 @@ public: int32_t rinexobs_rate_ms; int32_t max_obs_block_rx_clock_offset_ms; int udp_port; + int udp_eph_port; uint16_t rtcm_tcp_port; uint16_t rtcm_station_id; @@ -76,6 +78,7 @@ public: bool xml_output_enabled; bool rtcm_output_file_enabled; bool monitor_enabled; + bool monitor_ephemeris_enabled; bool protobuf_enabled; bool enable_rx_clock_correction; bool show_local_time_zone; diff --git a/src/algorithms/PVT/libs/serdes_galileo_eph.h b/src/algorithms/PVT/libs/serdes_galileo_eph.h new file mode 100644 index 000000000..cea3dcac5 --- /dev/null +++ b/src/algorithms/PVT/libs/serdes_galileo_eph.h @@ -0,0 +1,192 @@ +/*! + * \file serdes_monitor_pvt.h + * \brief Serialization / Deserialization of Monitor_Pvt objects using + * Protocol Buffers + * \author Carles Fernandez-Prades, 2019. 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-2020 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_SERDESGAL_EPH_H +#define GNSS_SDR_SERDESGAL_EPH_H + +#include "galileo_ephemeris.h" +#include "monitor_galileo_ephemeris.pb.h" // file created by Protocol Buffers at compile time +#include +#include +#include + +/** \addtogroup PVT + * \{ */ +/** \addtogroup PVT_libs + * \{ */ + + +/*! + * \brief This class implements serialization and deserialization of + * Monitor_Pvt objects using Protocol Buffers. + */ +class Serdes_Galileo_Eph +{ +public: + Serdes_Galileo_Eph() + { + // Verify that the version of the library that we linked against is + // compatible with the version of the headers we compiled against. + GOOGLE_PROTOBUF_VERIFY_VERSION; + } + + ~Serdes_Galileo_Eph() + { + // google::protobuf::ShutdownProtobufLibrary(); + } + + inline Serdes_Galileo_Eph(const Serdes_Galileo_Eph& other) noexcept //!< Copy constructor + { + this->monitor_ = other.monitor_; + } + + inline Serdes_Galileo_Eph& operator=(const Serdes_Galileo_Eph& rhs) noexcept //!< Copy assignment operator + { + this->monitor_ = rhs.monitor_; + return *this; + } + + inline Serdes_Galileo_Eph(Serdes_Galileo_Eph&& other) noexcept //!< Move constructor + { + this->monitor_ = std::move(other.monitor_); + } + + inline Serdes_Galileo_Eph& operator=(Serdes_Galileo_Eph&& other) noexcept //!< Move assignment operator + { + if (this != &other) + { + this->monitor_ = std::move(other.monitor_); + } + return *this; + } + + inline std::string createProtobuffer(const std::shared_ptr monitor) //!< Serialization into a string + { + monitor_.Clear(); + + std::string data; + + monitor_.set_i_satellite_prn(monitor->i_satellite_PRN); + monitor_.set_iod_ephemeris(monitor->IOD_ephemeris); + monitor_.set_iod_nav_1(monitor->IOD_nav_1); + monitor_.set_m0_1(monitor->M0_1); //!< Mean anomaly at reference time [semi-circles] + monitor_.set_delta_n_3(monitor->delta_n_3); //!< Mean motion difference from computed value [semi-circles/sec] + monitor_.set_e_1(monitor->e_1); //!< Eccentricity + monitor_.set_a_1(monitor->A_1); //!< Square root of the semi-major axis [meters^1/2] + monitor_.set_omega_0_2(monitor->OMEGA_0_2); //!< Longitude of ascending node of orbital plane at weekly epoch [semi-circles] + monitor_.set_i_0_2(monitor->i_0_2); //!< Inclination angle at reference time [semi-circles] + monitor_.set_omega_2(monitor->omega_2); //!< Argument of perigee [semi-circles] + monitor_.set_omega_dot_3(monitor->OMEGA_dot_3); //!< Rate of right ascension [semi-circles/sec] + monitor_.set_idot_2(monitor->iDot_2); //!< Rate of inclination angle [semi-circles/sec] + monitor_.set_c_uc_3(monitor->C_uc_3); //!< Amplitude of the cosine harmonic correction term to the argument of latitude [radians] + monitor_.set_c_us_3(monitor->C_us_3); //!< Amplitude of the sine harmonic correction term to the argument of latitude [radians] + monitor_.set_c_rc_3(monitor->C_rc_3); //!< Amplitude of the cosine harmonic correction term to the orbit radius [meters] + monitor_.set_c_rs_3(monitor->C_rs_3); //!< Amplitude of the sine harmonic correction term to the orbit radius [meters] + monitor_.set_c_ic_4(monitor->C_ic_4); //!< Amplitude of the cosine harmonic correction term to the angle of inclination [radians] + monitor_.set_c_is_4(monitor->C_is_4); //!< Amplitude of the sine harmonic correction term to the angle of inclination [radians] + monitor_.set_d_toe(monitor->t0e_1); // Ephemeris reference time + + /*Clock correction parameters*/ + monitor_.set_d_toc(monitor->t0c_4); // Clock correction data reference Time of Week + monitor_.set_af0_4(monitor->af0_4); //!< SV clock bias correction coefficient [s] + monitor_.set_af1_4(monitor->af1_4); //!< SV clock drift correction coefficient [s/s] + monitor_.set_af2_4(monitor->af2_4); //!< SV clock drift rate correction coefficient [s/s^2] + + /*GST*/ + // Not belong to ephemeris set (page 1 to 4) + monitor_.set_wn_5(monitor->WN_5); //!< Week number + monitor_.set_tow_5(monitor->TOW_5); //!< Time of Week + monitor_.set_galileo_satclkdrift(monitor->Galileo_satClkDrift); + monitor_.set_galileo_dtr(monitor->Galileo_dtr); //!< relativistic clock correction term + + // SV status + monitor_.set_sisa_3(monitor->SISA_3); + monitor_.set_e5a_hs(monitor->E5a_HS); //!< E5a Signal Health Status + monitor_.set_e5b_hs_5(monitor->E5b_HS_5); //!< E5b Signal Health Status + monitor_.set_e1b_hs_5(monitor->E1B_HS_5); //!< E1B Signal Health Status + monitor_.set_e5a_dvs(monitor->E5a_DVS); //!< E5a Data Validity Status + monitor_.set_e5b_dvs_5(monitor->E5b_DVS_5); //!< E5b Data Validity Status + monitor_.set_e1b_dvs_5(monitor->E1B_DVS_5); //!< E1B Data Validity Status + + monitor_.set_bgd_e1e5a_5(monitor->BGD_E1E5a_5); //!< E1-E5a Broadcast Group Delay [s] + monitor_.set_bgd_e1e5b_5(monitor->BGD_E1E5b_5); //!< E1-E5b Broadcast Group Delay [s] + + monitor_.SerializeToString(&data); + return data; + } + + inline Galileo_Ephemeris readProtobuffer(const gnss_sdr::MonitorGalileoEphemeris& mon) const //!< Deserialization + { + Galileo_Ephemeris monitor; + + monitor.i_satellite_PRN = mon.i_satellite_prn(); + + monitor.IOD_ephemeris = mon.iod_ephemeris(); + monitor.IOD_nav_1 = mon.iod_nav_1(); + monitor.M0_1 = mon.m0_1(); //!< Mean anomaly at reference time [semi-circles] + monitor.delta_n_3 = mon.delta_n_3(); //!< Mean motion difference from computed value [semi-circles/sec] + monitor.e_1 = mon.e_1(); //!< Eccentricity + monitor.A_1 = mon.a_1(); //!< Square root of the semi-major axis [meters^1/2] + monitor.OMEGA_0_2 = mon.omega_0_2(); //!< Longitude of ascending node of orbital plane at weekly epoch [semi-circles] + monitor.i_0_2 = mon.i_0_2(); //!< Inclination angle at reference time [semi-circles] + monitor.omega_2 = mon.omega_2(); //!< Argument of perigee [semi-circles] + monitor.OMEGA_dot_3 = mon.omega_dot_3(); //!< Rate of right ascension [semi-circles/sec] + monitor.iDot_2 = mon.idot_2(); //!< Rate of inclination angle [semi-circles/sec] + monitor.C_uc_3 = mon.c_uc_3(); //!< Amplitude of the cosine harmonic correction term to the argument of latitude [radians] + monitor.C_us_3 = mon.c_us_3(); //!< Amplitude of the sine harmonic correction term to the argument of latitude [radians] + monitor.C_rc_3 = mon.c_rc_3(); //!< Amplitude of the cosine harmonic correction term to the orbit radius [meters] + monitor.C_rs_3 = mon.c_rs_3(); //!< Amplitude of the sine harmonic correction term to the orbit radius [meters] + monitor.C_ic_4 = mon.c_ic_4(); //!< Amplitude of the cosine harmonic correction term to the angle of inclination [radians] + monitor.C_is_4 = mon.c_is_4(); //!< Amplitude of the sine harmonic correction term to the angle of inclination [radians] + monitor.t0e_1 = mon.d_toe(); // Ephemeris reference time + + /*Clock correction parameters*/ + monitor.t0c_4 = mon.d_toc(); // Clock correction data reference Time of Week + monitor.af0_4 = mon.af0_4(); //!< SV clock bias correction coefficient [s] + monitor.af1_4 = mon.af1_4(); //!< SV clock drift correction coefficient [s/s] + monitor.af2_4 = mon.af2_4(); //!< SV clock drift rate correction coefficient [s/s^2] + + /*GST*/ + // Not belong to ephemeris set (page 1 to 4) + monitor.WN_5 = mon.wn_5(); //!< Week number + monitor.TOW_5 = mon.tow_5(); //!< Time of Week + monitor.Galileo_satClkDrift = mon.galileo_satclkdrift(); + monitor.Galileo_dtr = mon.galileo_dtr(); //!< relativistic clock correction term + + // SV status + monitor.SISA_3 = mon.sisa_3(); + monitor.E5a_HS = mon.e5a_hs(); //!< E5a Signal Health Status + monitor.E5b_HS_5 = mon.e5b_hs_5(); //!< E5b Signal Health Status + monitor.E1B_HS_5 = mon.e1b_hs_5(); //!< E1B Signal Health Status + monitor.E5a_DVS = mon.e5a_dvs(); //!< E5a Data Validity Status + monitor.E5b_DVS_5 = mon.e5b_dvs_5(); //!< E5b Data Validity Status + monitor.E1B_DVS_5 = mon.e1b_dvs_5(); //!< E1B Data Validity Status + + monitor.BGD_E1E5a_5 = mon.bgd_e1e5a_5(); //!< E1-E5a Broadcast Group Delay [s] + monitor.BGD_E1E5b_5 = mon.bgd_e1e5b_5(); //!< E1-E5b Broadcast Group Delay [s] + + return monitor; + } + +private: + gnss_sdr::MonitorGalileoEphemeris monitor_{}; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_SERDESGAL_EPH_H diff --git a/src/algorithms/PVT/libs/serdes_gps_eph.h b/src/algorithms/PVT/libs/serdes_gps_eph.h new file mode 100644 index 000000000..c3a134649 --- /dev/null +++ b/src/algorithms/PVT/libs/serdes_gps_eph.h @@ -0,0 +1,183 @@ +/*! + * \file serdes_monitor_pvt.h + * \brief Serialization / Deserialization of Monitor_Pvt objects using + * Protocol Buffers + * \author Carles Fernandez-Prades, 2019. 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-2020 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_SERDES_GPS_EPH_H +#define GNSS_SDR_SERDES_GPS_EPH_H + +#include "gps_ephemeris.h" +#include "monitor_gps_ephemeris.pb.h" // file created by Protocol Buffers at compile time +#include +#include +#include + +/** \addtogroup PVT + * \{ */ +/** \addtogroup PVT_libs + * \{ */ + + +/*! + * \brief This class implements serialization and deserialization of + * Monitor_Pvt objects using Protocol Buffers. + */ +class Serdes_Gps_Eph +{ +public: + Serdes_Gps_Eph() + { + // Verify that the version of the library that we linked against is + // compatible with the version of the headers we compiled against. + GOOGLE_PROTOBUF_VERIFY_VERSION; + } + + ~Serdes_Gps_Eph() + { + // google::protobuf::ShutdownProtobufLibrary(); + } + + inline Serdes_Gps_Eph(const Serdes_Gps_Eph& other) noexcept //!< Copy constructor + { + this->monitor_ = other.monitor_; + } + + inline Serdes_Gps_Eph& operator=(const Serdes_Gps_Eph& rhs) noexcept //!< Copy assignment operator + { + this->monitor_ = rhs.monitor_; + return *this; + } + + inline Serdes_Gps_Eph(Serdes_Gps_Eph&& other) noexcept //!< Move constructor + { + this->monitor_ = std::move(other.monitor_); + } + + inline Serdes_Gps_Eph& operator=(Serdes_Gps_Eph&& other) noexcept //!< Move assignment operator + { + if (this != &other) + { + this->monitor_ = std::move(other.monitor_); + } + return *this; + } + + inline std::string createProtobuffer(const std::shared_ptr monitor) //!< Serialization into a string + { + monitor_.Clear(); + std::string data; + monitor_.set_i_satellite_prn(monitor->i_satellite_PRN); // SV PRN NUMBER + monitor_.set_d_tow(monitor->d_TOW); //!< time of gps week of the ephemeris set (taken from subframes tow) [s] + monitor_.set_d_crs(monitor->d_Crs); //!< amplitude of the sine harmonic correction term to the orbit radius [m] + monitor_.set_d_delta_n(monitor->d_Delta_n); //!< mean motion difference from computed value [semi-circles/s] + monitor_.set_d_m_0(monitor->d_M_0); //!< mean anomaly at reference time [semi-circles] + monitor_.set_d_cuc(monitor->d_Cuc); //!< amplitude of the cosine harmonic correction term to the argument of latitude [rad] + monitor_.set_d_e_eccentricity(monitor->d_e_eccentricity); //!< eccentricity [dimensionless] + monitor_.set_d_cus(monitor->d_Cus); //!< amplitude of the sine harmonic correction term to the argument of latitude [rad] + monitor_.set_d_sqrt_a(monitor->d_sqrt_A); //!< square root of the semi-major axis [sqrt(m)] + monitor_.set_d_toe(monitor->d_Toe); //!< ephemeris data reference time of week (ref. 20.3.3.4.3 is-gps-200k) [s] + monitor_.set_d_toc(monitor->d_Toc); //!< clock data reference time (ref. 20.3.3.3.3.1 is-gps-200k) [s] + monitor_.set_d_cic(monitor->d_Cic); //!< amplitude of the cosine harmonic correction term to the angle of inclination [rad] + monitor_.set_d_omega0(monitor->d_OMEGA0); //!< longitude of ascending node of orbit plane at weekly epoch [semi-circles] + monitor_.set_d_cis(monitor->d_Cis); //!< amplitude of the sine harmonic correction term to the angle of inclination [rad] + monitor_.set_d_i_0(monitor->d_i_0); //!< inclination angle at reference time [semi-circles] + monitor_.set_d_crc(monitor->d_Crc); //!< amplitude of the cosine harmonic correction term to the orbit radius [m] + monitor_.set_d_omega(monitor->d_OMEGA); //!< argument of perigee [semi-cicles] + monitor_.set_d_omega_dot(monitor->d_OMEGA_DOT); //!< rate of right ascension [semi-circles/s] + monitor_.set_d_idot(monitor->d_IDOT); //!< rate of inclination angle [semi-circles/s] + monitor_.set_i_code_on_l2(monitor->i_code_on_L2); //!< if 1, p code on in l2; if 2, c/a code on in l2; + monitor_.set_i_gps_week(monitor->i_GPS_week); //!< gps week number, aka wn [week] + monitor_.set_b_l2_p_data_flag(monitor->b_L2_P_data_flag); //!< when true, indicates that the nav data stream was commanded off on the p-code of the l2 channel + monitor_.set_i_sv_accuracy(monitor->i_SV_accuracy); //!< user range accuracy (ura) index of the sv (reference paragraph 6.2.1) for the standard positioning service user (ref 20.3.3.3.1.3 is-gps-200k) + monitor_.set_i_sv_health(monitor->i_SV_health); + monitor_.set_d_tgd(monitor->d_TGD); //!< estimated group delay differential: l1-l2 correction term only for the benefit of "l1 p(y)" or "l2 p(y)" s users [s] + monitor_.set_d_iodc(monitor->d_IODC); //!< issue of data, clock + monitor_.set_d_iode_sf2(monitor->d_IODE_SF2); //!< issue of data, ephemeris (iode), subframe 2 + monitor_.set_d_iode_sf3(monitor->d_IODE_SF3); //!< issue of data, ephemeris(iode), subframe 3 + monitor_.set_i_aodo(monitor->i_AODO); //!< age of data offset (aodo) term for the navigation message correction table (nmct) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s] + + monitor_.set_b_fit_interval_flag(monitor->b_fit_interval_flag); //!< indicates the curve-fit interval used by the cs (block ii/iia/iir/iir-m/iif) and ss (block iiia) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours. + monitor_.set_d_spare1(monitor->d_spare1); + monitor_.set_d_spare2(monitor->d_spare2); + + monitor_.set_d_a_f0(monitor->d_A_f0); //!< coefficient 0 of code phase offset model [s] + monitor_.set_d_a_f1(monitor->d_A_f1); //!< coefficient 1 of code phase offset model [s/s] + monitor_.set_d_a_f2(monitor->d_A_f2); //!< coefficient 2 of code phase offset model [s/s^2] + + monitor_.set_b_integrity_status_flag(monitor->b_integrity_status_flag); + monitor_.set_b_alert_flag(monitor->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. + monitor_.set_b_antispoofing_flag(monitor->b_antispoofing_flag); //!< if true, the antispoofing mode is on in that sv + + monitor_.SerializeToString(&data); + return data; + } + + inline Gps_Ephemeris readProtobuffer(const gnss_sdr::MonitorGpsEphemeris& mon) const //!< Deserialization + { + Gps_Ephemeris monitor; + + monitor.i_satellite_PRN = mon.i_satellite_prn(); // SV PRN NUMBER + monitor.d_TOW = mon.d_tow(); //!< time of gps week of the ephemeris set (taken from subframes tow) [s] + monitor.d_Crs = mon.d_crs(); //!< amplitude of the sine harmonic correction term to the orbit radius [m] + monitor.d_Delta_n = mon.d_delta_n(); //!< mean motion difference from computed value [semi-circles/s] + monitor.d_M_0 = mon.d_m_0(); //!< mean anomaly at reference time [semi-circles] + monitor.d_Cuc = mon.d_cuc(); //!< amplitude of the cosine harmonic correction term to the argument of latitude [rad] + monitor.d_e_eccentricity = mon.d_e_eccentricity(); //!< eccentricity [dimensionless] + monitor.d_Cus = mon.d_cus(); //!< amplitude of the sine harmonic correction term to the argument of latitude [rad] + monitor.d_sqrt_A = mon.d_sqrt_a(); //!< square root of the semi-major axis [sqrt(m)] + monitor.d_Toe = mon.d_toe(); //!< ephemeris data reference time of week (ref. 20.3.3.4.3 is-gps-200k) [s] + monitor.d_Toc = mon.d_toc(); //!< clock data reference time (ref. 20.3.3.3.3.1 is-gps-200k) [s] + monitor.d_Cic = mon.d_cic(); //!< amplitude of the cosine harmonic correction term to the angle of inclination [rad] + monitor.d_OMEGA0 = mon.d_omega0(); //!< longitude of ascending node of orbit plane at weekly epoch [semi-circles] + monitor.d_Cis = mon.d_cis(); //!< amplitude of the sine harmonic correction term to the angle of inclination [rad] + monitor.d_i_0 = mon.d_i_0(); //!< inclination angle at reference time [semi-circles] + monitor.d_Crc = mon.d_crc(); //!< amplitude of the cosine harmonic correction term to the orbit radius [m] + monitor.d_OMEGA = mon.d_omega(); //!< argument of perigee [semi-cicles] + monitor.d_OMEGA_DOT = mon.d_omega_dot(); //!< rate of right ascension [semi-circles/s] + monitor.d_IDOT = mon.d_idot(); //!< rate of inclination angle [semi-circles/s] + monitor.i_code_on_L2 = mon.i_code_on_l2(); //!< if 1, p code on in l2; if 2, c/a code on in l2; + monitor.i_GPS_week = mon.i_gps_week(); //!< gps week number, aka wn [week] + monitor.b_L2_P_data_flag = mon.b_l2_p_data_flag(); //!< when true, indicates that the nav data stream was commanded off on the p-code of the l2 channel + monitor.i_SV_accuracy = mon.i_sv_accuracy(); //!< user range accuracy (ura) index of the sv (reference paragraph 6.2.1) for the standard positioning service user (ref 20.3.3.3.1.3 is-gps-200k) + monitor.i_SV_health = mon.i_sv_health(); + monitor.d_TGD = mon.d_tgd(); //!< estimated group delay differential: l1-l2 correction term only for the benefit of "l1 p(y)" or "l2 p(y)" s users [s] + monitor.d_IODC = mon.d_iodc(); //!< issue of data, clock + monitor.d_IODE_SF2 = mon.d_iode_sf2(); //!< issue of data, ephemeris (iode), subframe 2 + monitor.d_IODE_SF3 = mon.d_iode_sf3(); //!< issue of data, ephemeris(iode), subframe 3 + monitor.i_AODO = mon.i_aodo(); //!< age of data offset (aodo) term for the navigation message correction table (nmct) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s] + + monitor.b_fit_interval_flag = mon.b_fit_interval_flag(); //!< indicates the curve-fit interval used by the cs (block ii/iia/iir/iir-m/iif) and ss (block iiia) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours. + monitor.d_spare1 = mon.d_spare1(); + monitor.d_spare2 = mon.d_spare2(); + + monitor.d_A_f0 = mon.d_a_f0(); //!< coefficient 0 of code phase offset model [s] + monitor.d_A_f1 = mon.d_a_f1(); //!< coefficient 1 of code phase offset model [s/s] + monitor.d_A_f2 = mon.d_a_f2(); //!< coefficient 2 of code phase offset model [s/s^2] + + monitor.b_integrity_status_flag = mon.b_integrity_status_flag(); + monitor.b_alert_flag = mon.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. + monitor.b_antispoofing_flag = mon.b_antispoofing_flag(); //!< if true, the antispoofing mode is on in that sv + + return monitor; + } + +private: + gnss_sdr::MonitorGpsEphemeris monitor_{}; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_SERDES_GPS_EPH_H diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/serdes_monitor_pvt_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/serdes_monitor_pvt_test.cc index 0242d238c..0a653cf97 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/serdes_monitor_pvt_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/serdes_monitor_pvt_test.cc @@ -14,6 +14,7 @@ * ----------------------------------------------------------------------------- */ +#include "serdes_galileo_eph.h" #include "serdes_monitor_pvt.h" #include @@ -29,6 +30,12 @@ TEST(Serdes_Monitor_Pvt_Test, Simpletest) gnss_sdr::MonitorPvt mon; mon.ParseFromString(serialized_data); + serdes.readProtobuffer(mon); + + gnss_sdr::MonitorGalileoEphemeris ephgal; + Serdes_Galileo_Eph gal_serdes = Serdes_Galileo_Eph(); + gal_serdes.readProtobuffer(ephgal); + double read_latitude = mon.latitude(); EXPECT_NEAR(true_latitude, read_latitude, 0.000001); }