From bdce8b6a6628f928310b44801ab017880e34d1fa Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Tue, 13 Mar 2018 12:38:33 +0100 Subject: [PATCH] Add float code generation in some signals --- src/algorithms/libs/gps_l2c_signal.cc | 17 + src/algorithms/libs/gps_l2c_signal.h | 2 +- src/algorithms/libs/gps_l5_signal.cc | 31 + src/algorithms/libs/gps_l5_signal.h | 2 + .../gps_l5_telemetry_decoder_cc.cc | 10 +- .../gps_l5_telemetry_decoder_cc.h | 5 +- .../galileo_e1_dll_pll_veml_tracking.cc | 85 +- .../galileo_e1_dll_pll_veml_tracking.h | 3 + .../adapters/gps_l1_ca_dll_pll_tracking.cc | 74 +- .../adapters/gps_l1_ca_dll_pll_tracking.h | 3 + .../gnuradio_blocks/dll_pll_veml_tracking.cc | 732 ++++++++++-------- .../gnuradio_blocks/dll_pll_veml_tracking.h | 80 +- .../libs/cpu_multicorrelator_real_codes.cc | 2 +- src/core/system_parameters/GPS_L5.h | 9 +- src/core/system_parameters/gnss_synchro.h | 14 +- 15 files changed, 654 insertions(+), 415 deletions(-) diff --git a/src/algorithms/libs/gps_l2c_signal.cc b/src/algorithms/libs/gps_l2c_signal.cc index 68fb7c024..a0d266ab7 100644 --- a/src/algorithms/libs/gps_l2c_signal.cc +++ b/src/algorithms/libs/gps_l2c_signal.cc @@ -71,6 +71,23 @@ void gps_l2c_m_code_gen_complex(std::complex* _dest, unsigned int _prn) delete[] _code; } +void gps_l2c_m_code_gen_float(float* _dest, unsigned int _prn) +{ + int32_t* _code = new int32_t[GPS_L2_M_CODE_LENGTH_CHIPS]; + + if (_prn > 0 and _prn < 51) + { + gps_l2c_m_code(_code, _prn); + } + + for (signed int i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++) + { + _dest[i] = 1.0 - 2.0 * static_cast(_code[i]); + } + + delete[] _code; +} + /* * Generates complex GPS L2C M code for the desired SV ID and sampled to specific sampling frequency diff --git a/src/algorithms/libs/gps_l2c_signal.h b/src/algorithms/libs/gps_l2c_signal.h index a5f48a230..627588355 100644 --- a/src/algorithms/libs/gps_l2c_signal.h +++ b/src/algorithms/libs/gps_l2c_signal.h @@ -38,7 +38,7 @@ //!Generates complex GPS L2C M code for the desired SV ID void gps_l2c_m_code_gen_complex(std::complex* _dest, unsigned int _prn); - +void gps_l2c_m_code_gen_float(float* _dest, unsigned int _prn); //! Generates complex GPS L2C M code for the desired SV ID, and sampled to specific sampling frequency void gps_l2c_m_code_gen_complex_sampled(std::complex* _dest, unsigned int _prn, signed int _fs); diff --git a/src/algorithms/libs/gps_l5_signal.cc b/src/algorithms/libs/gps_l5_signal.cc index 7a443d20f..0bacbea7b 100644 --- a/src/algorithms/libs/gps_l5_signal.cc +++ b/src/algorithms/libs/gps_l5_signal.cc @@ -197,6 +197,22 @@ void gps_l5i_code_gen_complex(std::complex* _dest, unsigned int _prn) delete[] _code; } +void gps_l5i_code_gen_float(float* _dest, unsigned int _prn) +{ + int32_t* _code = new int32_t[GPS_L5i_CODE_LENGTH_CHIPS]; + + if (_prn > 0 and _prn < 51) + { + make_l5i(_code, _prn - 1); + } + + for (signed int i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++) + { + _dest[i] = 1.0 - 2.0 * static_cast(_code[i]); + } + + delete[] _code; +} /* * Generates complex GPS L5i code for the desired SV ID and sampled to specific sampling frequency @@ -264,7 +280,22 @@ void gps_l5q_code_gen_complex(std::complex* _dest, unsigned int _prn) delete[] _code; } +void gps_l5q_code_gen_float(float* _dest, unsigned int _prn) +{ + int32_t* _code = new int32_t[GPS_L5q_CODE_LENGTH_CHIPS]; + if (_prn > 0 and _prn < 51) + { + make_l5q(_code, _prn - 1); + } + + for (signed int i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++) + { + _dest[i] = 1.0 - 2.0 * static_cast(_code[i]); + } + + delete[] _code; +} /* * Generates complex GPS L5i code for the desired SV ID and sampled to specific sampling frequency */ diff --git a/src/algorithms/libs/gps_l5_signal.h b/src/algorithms/libs/gps_l5_signal.h index e9fee4e4b..928180e9a 100644 --- a/src/algorithms/libs/gps_l5_signal.h +++ b/src/algorithms/libs/gps_l5_signal.h @@ -38,9 +38,11 @@ //!Generates complex GPS L5i M code for the desired SV ID void gps_l5i_code_gen_complex(std::complex* _dest, unsigned int _prn); +void gps_l5i_code_gen_float(float* _dest, unsigned int _prn); //!Generates complex GPS L5q M code for the desired SV ID void gps_l5q_code_gen_complex(std::complex* _dest, unsigned int _prn); +void gps_l5q_code_gen_float(float* _dest, unsigned int _prn); //! Generates complex GPS L5i M code for the desired SV ID, and sampled to specific sampling frequency void gps_l5i_code_gen_complex_sampled(std::complex* _dest, unsigned int _prn, signed int _fs); diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc index 79b0fdb07..af9666c03 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc @@ -70,9 +70,9 @@ gps_l5_telemetry_decoder_cc::gps_l5_telemetry_decoder_cc( d_TOW_at_Preamble = 0.0; //initialize the CNAV frame decoder (libswiftcnav) cnav_msg_decoder_init(&d_cnav_decoder); - for (int aux = 0; aux < GPS_L5_NH_CODE_LENGTH; aux++) + for (int aux = 0; aux < GPS_L5i_NH_CODE_LENGTH; aux++) { - if (GPS_L5_NH_CODE[aux] == 0) + if (GPS_L5i_NH_CODE[aux] == 0) { bits_NH[aux] = -1.0; } @@ -119,9 +119,9 @@ int gps_l5_telemetry_decoder_cc::general_work(int noutput_items __attribute__((u int symbol_value = 0; //Search correlation with Neuman-Hofman Code (see IS-GPS-705D) - if (sym_hist.size() == GPS_L5_NH_CODE_LENGTH) + if (sym_hist.size() == GPS_L5i_NH_CODE_LENGTH) { - for (int i = 0; i < GPS_L5_NH_CODE_LENGTH; i++) + for (int i = 0; i < GPS_L5i_NH_CODE_LENGTH; i++) { if ((bits_NH[i] * sym_hist.at(i)) > 0.0) { @@ -132,7 +132,7 @@ int gps_l5_telemetry_decoder_cc::general_work(int noutput_items __attribute__((u corr_NH -= 1; } } - if (abs(corr_NH) == GPS_L5_NH_CODE_LENGTH) + if (abs(corr_NH) == GPS_L5i_NH_CODE_LENGTH) { sync_NH = true; if (corr_NH > 0) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h index c13c2832b..59f0bf108 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h @@ -42,8 +42,7 @@ #include #include -extern "C" -{ +extern "C" { #include "cnav_msg.h" #include "edc.h" #include "bits.h" @@ -91,7 +90,7 @@ private: bool d_flag_valid_word; Gps_CNAV_Navigation_Message d_CNAV_Message; - double bits_NH[GPS_L5_NH_CODE_LENGTH]; + double bits_NH[GPS_L5i_NH_CODE_LENGTH]; std::deque sym_hist; bool sync_NH; bool new_sym; diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc index acae5564a..6ad7b940d 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc @@ -51,7 +51,6 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( //################# CONFIGURATION PARAMETERS ######################## int fs_in; int vector_length; - int f_if; bool dump; std::string dump_filename; std::string item_type; @@ -64,11 +63,10 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( float very_early_late_space_chips; float early_late_space_narrow_chips; float very_early_late_space_narrow_chips; - + unified_ = configuration->property(role + ".unified", true); item_type = configuration->property(role + ".item_type", default_item_type); int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); - f_if = configuration->property(role + ".if", 0); dump = configuration->property(role + ".dump", false); pll_bw_hz = configuration->property(role + ".pll_bw_hz", 5.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); @@ -93,23 +91,45 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( //################# MAKE TRACKING GNURadio object ################### if (item_type.compare("gr_complex") == 0) { - item_size_ = sizeof(gr_complex); - tracking_ = galileo_e1_dll_pll_veml_make_tracking_cc( - f_if, - fs_in, - vector_length, - dump, - dump_filename, - pll_bw_hz, - dll_bw_hz, - pll_bw_narrow_hz, - dll_bw_narrow_hz, - early_late_space_chips, - very_early_late_space_chips, - early_late_space_narrow_chips, - very_early_late_space_narrow_chips, - extend_correlation_symbols, - track_pilot); + if (unified_) + { + char sig_[3] = "1B"; + item_size_ = sizeof(gr_complex); + tracking_unified_ = dll_pll_veml_make_tracking( + fs_in, + vector_length, + dump, + dump_filename, + pll_bw_hz, + dll_bw_hz, + pll_bw_narrow_hz, + dll_bw_narrow_hz, + early_late_space_chips, + very_early_late_space_chips, + early_late_space_narrow_chips, + very_early_late_space_narrow_chips, + extend_correlation_symbols, + track_pilot, 'E', sig_); + } + else + { + tracking_ = galileo_e1_dll_pll_veml_make_tracking_cc( + 0, + fs_in, + vector_length, + dump, + dump_filename, + pll_bw_hz, + dll_bw_hz, + pll_bw_narrow_hz, + dll_bw_narrow_hz, + early_late_space_chips, + very_early_late_space_chips, + early_late_space_narrow_chips, + very_early_late_space_narrow_chips, + extend_correlation_symbols, + track_pilot); + } } else { @@ -130,7 +150,10 @@ GalileoE1DllPllVemlTracking::~GalileoE1DllPllVemlTracking() void GalileoE1DllPllVemlTracking::start_tracking() { - tracking_->start_tracking(); + if (unified_) + tracking_unified_->start_tracking(); + else + tracking_->start_tracking(); } @@ -140,13 +163,19 @@ void GalileoE1DllPllVemlTracking::start_tracking() void GalileoE1DllPllVemlTracking::set_channel(unsigned int channel) { channel_ = channel; - tracking_->set_channel(channel); + if (unified_) + tracking_unified_->set_channel(channel); + else + tracking_->set_channel(channel); } void GalileoE1DllPllVemlTracking::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) { - tracking_->set_gnss_synchro(p_gnss_synchro); + if (unified_) + tracking_unified_->set_gnss_synchro(p_gnss_synchro); + else + tracking_->set_gnss_synchro(p_gnss_synchro); } @@ -170,11 +199,17 @@ void GalileoE1DllPllVemlTracking::disconnect(gr::top_block_sptr top_block) gr::basic_block_sptr GalileoE1DllPllVemlTracking::get_left_block() { - return tracking_; + if (unified_) + return tracking_unified_; + else + return tracking_; } gr::basic_block_sptr GalileoE1DllPllVemlTracking::get_right_block() { - return tracking_; + if (unified_) + return tracking_unified_; + else + return tracking_; } diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.h b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.h index e702ff14d..2d3dfd221 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.h +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.h @@ -39,6 +39,7 @@ #include "tracking_interface.h" #include "galileo_e1_dll_pll_veml_tracking_cc.h" +#include "dll_pll_veml_tracking.h" #include @@ -95,11 +96,13 @@ public: private: galileo_e1_dll_pll_veml_tracking_cc_sptr tracking_; + dll_pll_veml_tracking_sptr tracking_unified_; size_t item_size_; unsigned int channel_; std::string role_; unsigned int in_streams_; unsigned int out_streams_; + bool unified_; }; #endif // GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_H_ diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc index d58329575..4f3fc3e53 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc @@ -52,7 +52,6 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( //################# CONFIGURATION PARAMETERS ######################## int fs_in; int vector_length; - int f_if; bool dump; std::string dump_filename; std::string item_type; @@ -63,8 +62,8 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( item_type = configuration->property(role + ".item_type", default_item_type); int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); - f_if = configuration->property(role + ".if", 0); dump = configuration->property(role + ".dump", false); + unified_ = configuration->property(role + ".unified", true); pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); @@ -73,20 +72,44 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( std::string default_dump_filename = "./track_ch"; dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); //unused! vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); - + int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1); + if (symbols_extended_correlator < 1) symbols_extended_correlator = 1; //################# MAKE TRACKING GNURadio object ################### if (item_type.compare("gr_complex") == 0) { - item_size_ = sizeof(gr_complex); - tracking_ = gps_l1_ca_dll_pll_make_tracking_cc( - f_if, - fs_in, - vector_length, - dump, - dump_filename, - pll_bw_hz, - dll_bw_hz, - early_late_space_chips); + if (unified_) + { + char sig_[3] = "1C"; + item_size_ = sizeof(gr_complex); + tracking_unified_ = dll_pll_veml_make_tracking( + fs_in, + vector_length, + dump, + dump_filename, + pll_bw_hz, + dll_bw_hz, + pll_bw_hz, + dll_bw_hz, + early_late_space_chips, + early_late_space_chips, + early_late_space_chips, + early_late_space_chips, + symbols_extended_correlator, + false, + 'G', sig_); + } + else + { + tracking_ = gps_l1_ca_dll_pll_make_tracking_cc( + 0, + fs_in, + vector_length, + dump, + dump_filename, + pll_bw_hz, + dll_bw_hz, + early_late_space_chips); + } } else { @@ -105,7 +128,10 @@ GpsL1CaDllPllTracking::~GpsL1CaDllPllTracking() void GpsL1CaDllPllTracking::start_tracking() { - tracking_->start_tracking(); + if (unified_) + tracking_unified_->start_tracking(); + else + tracking_->start_tracking(); } @@ -115,13 +141,19 @@ void GpsL1CaDllPllTracking::start_tracking() void GpsL1CaDllPllTracking::set_channel(unsigned int channel) { channel_ = channel; - tracking_->set_channel(channel); + if (unified_) + tracking_unified_->set_channel(channel); + else + tracking_->set_channel(channel); } void GpsL1CaDllPllTracking::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) { - tracking_->set_gnss_synchro(p_gnss_synchro); + if (unified_) + tracking_unified_->set_gnss_synchro(p_gnss_synchro); + else + tracking_->set_gnss_synchro(p_gnss_synchro); } @@ -145,11 +177,17 @@ void GpsL1CaDllPllTracking::disconnect(gr::top_block_sptr top_block) gr::basic_block_sptr GpsL1CaDllPllTracking::get_left_block() { - return tracking_; + if (unified_) + return tracking_unified_; + else + return tracking_; } gr::basic_block_sptr GpsL1CaDllPllTracking::get_right_block() { - return tracking_; + if (unified_) + return tracking_unified_; + else + return tracking_; } diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.h b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.h index ff5a91899..5bf34abfc 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.h @@ -40,6 +40,7 @@ #include "tracking_interface.h" #include "gps_l1_ca_dll_pll_tracking_cc.h" +#include "dll_pll_veml_tracking.h" #include class ConfigurationInterface; @@ -93,11 +94,13 @@ public: private: gps_l1_ca_dll_pll_tracking_cc_sptr tracking_; + dll_pll_veml_tracking_sptr tracking_unified_; size_t item_size_; unsigned int channel_; std::string role_; unsigned int in_streams_; unsigned int out_streams_; + bool unified_; }; #endif // GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_H_ diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index 7456bf3c1..2e469bb6d 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -35,6 +35,22 @@ */ #include "dll_pll_veml_tracking.h" +#include "tracking_discriminators.h" +#include "lock_detectors.h" +#include "control_message_factory.h" +#include "MATH_CONSTANTS.h" + +#include "Galileo_E1.h" +#include "galileo_e1_signal_processing.h" +#include "Galileo_E5a.h" +#include "galileo_e5_signal_processing.h" +#include "GPS_L1_CA.h" +#include "gps_sdr_signal_processing.h" +#include "GPS_L2C.h" +#include "gps_l2c_signal.h" +#include "GPS_L5.h" +#include "gps_l5_signal.h" + #include #include #include @@ -44,16 +60,7 @@ #include #include #include -#include "tracking_discriminators.h" -#include "lock_detectors.h" -#include "control_message_factory.h" -#include "Galileo_E1.h" -#include "galileo_e1_signal_processing.h" -#include "Galileo_E5a.h" -#include "GPS_L1_CA.h" -#include "GPS_L2C.h" -#include "GPS_L5.h" using google::LogMessage; @@ -72,7 +79,7 @@ dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking( float very_early_late_space_narrow_chips, int extend_correlation_symbols, bool track_pilot, - char system, char signal[3], bool veml) + char system, char signal[3]) { return dll_pll_veml_tracking_sptr(new dll_pll_veml_tracking( fs_in, @@ -88,7 +95,7 @@ dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking( early_late_space_narrow_chips, very_early_late_space_narrow_chips, extend_correlation_symbols, - track_pilot, system, signal, veml)); + track_pilot, system, signal)); } @@ -108,8 +115,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( float pll_bw_narrow_hz, float dll_bw_narrow_hz, float early_late_space_chips, float very_early_late_space_chips, float early_late_space_narrow_chips, float very_early_late_space_narrow_chips, - int extend_correlation_symbols, bool track_pilot, char system, char signal[3], bool veml) : gr::block("dll_pll_veml_tracking", gr::io_signature::make(1, 1, sizeof(gr_complex)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) + int extend_correlation_symbols, bool track_pilot, char system, char signal[3]) : gr::block("dll_pll_veml_tracking", gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { // Telemetry bit synchronization message port input this->message_port_register_in(pmt::mp("preamble_timestamp_s")); @@ -118,19 +125,14 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( // initialize internal vars d_dump = dump; - d_veml = veml; + d_veml = false; d_track_pilot = track_pilot; d_fs_in = fs_in; d_vector_length = vector_length; d_dump_filename = dump_filename; - d_code_period = 0.0; d_code_chip_rate = 0.0; - d_signal_carrier_freq = 0.0; - d_code_length_chips = 0; - d_secondary = false; d_secondary_code_length = 0; d_secondary_code_string = nullptr; - d_correlation_length_ms = 0; signal_type = std::string(signal); if (system == 'G') { @@ -140,10 +142,14 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( d_signal_carrier_freq = GPS_L1_FREQ_HZ; d_code_period = GPS_L1_CA_CODE_PERIOD; d_code_chip_rate = GPS_L1_CA_CODE_RATE_HZ; + d_symbols_per_bit = GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; d_correlation_length_ms = 1; + d_code_samples_per_chip = 1; d_code_length_chips = static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS); + //GPS L1 C/A does not have pilot component nor secondary code d_secondary = false; d_track_pilot = false; + interchange_iq = false; } else if (signal_type.compare("2S") == 0) { @@ -151,18 +157,37 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( d_code_period = GPS_L2_M_PERIOD; d_code_chip_rate = GPS_L2_M_CODE_RATE_HZ; d_code_length_chips = static_cast(GPS_L2_M_CODE_LENGTH_CHIPS); + d_symbols_per_bit = GPS_L2_SAMPLES_PER_SYMBOL; d_correlation_length_ms = 20; + d_code_samples_per_chip = 1; + //GPS L2 does not have pilot component nor secondary code d_secondary = false; d_track_pilot = false; + interchange_iq = false; } else if (signal_type.compare("L5") == 0) { d_signal_carrier_freq = GPS_L5_FREQ_HZ; d_code_period = GPS_L5i_PERIOD; d_code_chip_rate = GPS_L5i_CODE_RATE_HZ; + d_symbols_per_bit = GPS_L5_SAMPLES_PER_SYMBOL; d_correlation_length_ms = 1; + d_code_samples_per_chip = 1; d_code_length_chips = static_cast(GPS_L5i_CODE_LENGTH_CHIPS); - d_secondary = false; + //GPS L5 does not have pilot secondary code + d_secondary = true; + if (d_track_pilot) + { + d_secondary_code_length = static_cast(GPS_L5q_NH_CODE_LENGTH); + d_secondary_code_string = const_cast(&GPS_L5q_NH_CODE_STR); + interchange_iq = true; + } + else + { + d_secondary_code_length = static_cast(GPS_L5i_NH_CODE_LENGTH); + d_secondary_code_string = const_cast(&GPS_L5i_NH_CODE_STR); + interchange_iq = false; + } } else { @@ -179,32 +204,33 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( d_code_period = Galileo_E1_CODE_PERIOD; d_code_chip_rate = Galileo_E1_CODE_CHIP_RATE_HZ; d_code_length_chips = static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS); + d_symbols_per_bit = 1; d_correlation_length_ms = 4; + d_code_samples_per_chip = 2; // CBOC disabled: 2 samples per chip. CBOC enabled: 12 samples per chip + d_veml = true; d_secondary = true; - if (d_track_pilot) - { - d_secondary_code_length = static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH); - d_secondary_code_string = const_cast(&Galileo_E1_C_SECONDARY_CODE); - } - else - { - d_secondary = false; - } + d_secondary_code_length = static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH); + d_secondary_code_string = const_cast(&Galileo_E1_C_SECONDARY_CODE); + interchange_iq = false; // Note that E1-B and E1-C are in anti-phase, NOT IN QUADRATURE. See Galileo ICD. } else if (signal_type.compare("5X") == 0) { d_signal_carrier_freq = Galileo_E5a_FREQ_HZ; d_code_period = GALILEO_E5a_CODE_PERIOD; d_code_chip_rate = Galileo_E5a_CODE_CHIP_RATE_HZ; + d_symbols_per_bit = 20; d_correlation_length_ms = 1; + d_code_samples_per_chip = 1; d_code_length_chips = static_cast(Galileo_E5a_CODE_LENGTH_CHIPS); d_secondary = true; if (d_track_pilot) { + interchange_iq = true; d_secondary_code_length = static_cast(Galileo_E5a_Q_SECONDARY_CODE_LENGTH); } else { + interchange_iq = false; d_secondary_code_length = static_cast(Galileo_E5a_I_SECONDARY_CODE_LENGTH); d_secondary_code_string = const_cast(&Galileo_E5a_I_SECONDARY_CODE); } @@ -220,10 +246,10 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( LOG(WARNING) << "Invalid System argument when instantiating tracking blocks"; std::cout << "Invalid System argument when instantiating tracking blocks" << std::endl; } - - - d_code_loop_filter = Tracking_2nd_DLL_filter(d_code_period); - d_carrier_loop_filter = Tracking_2nd_PLL_filter(d_code_period); + T_chip_seconds = 0.0; + T_prn_seconds = 0.0; + T_prn_samples = 0.0; + K_blk_samples = 0.0; // Initialize tracking ========================================== @@ -235,6 +261,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( d_code_loop_filter.set_DLL_BW(d_dll_bw_hz); d_carrier_loop_filter.set_PLL_BW(d_pll_bw_hz); + d_code_loop_filter = Tracking_2nd_DLL_filter(static_cast(d_code_period)); + d_carrier_loop_filter = Tracking_2nd_PLL_filter(static_cast(d_code_period)); // Correlator spacing d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips) @@ -245,7 +273,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( // Initialization of local code replica // Get space for a vector with the sinboc(1,1) replica sampled 2x/chip d_tracking_code = static_cast(volk_gnsssdr_malloc(2 * d_code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); - + std::fill_n(d_tracking_code, 2 * d_code_length_chips, 0.0); // correlator outputs (scalar) if (d_veml) { @@ -270,12 +298,12 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( d_Prompt = &d_correlator_outs[2]; d_Late = &d_correlator_outs[3]; d_Very_Late = &d_correlator_outs[4]; - d_local_code_shift_chips[0] = -d_very_early_late_spc_chips; - d_local_code_shift_chips[1] = -d_early_late_spc_chips; + d_local_code_shift_chips[0] = -d_very_early_late_spc_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[1] = -d_early_late_spc_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[2] = 0.0; - d_local_code_shift_chips[3] = d_early_late_spc_chips; - d_local_code_shift_chips[4] = d_very_early_late_spc_chips; - d_null_shift = &d_local_code_shift_chips[2]; + d_local_code_shift_chips[3] = d_early_late_spc_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[4] = d_very_early_late_spc_chips * static_cast(d_code_samples_per_chip); + d_prompt_data_shift = &d_local_code_shift_chips[2]; } else { @@ -284,38 +312,34 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( d_Prompt = &d_correlator_outs[1]; d_Late = &d_correlator_outs[2]; d_Very_Late = nullptr; - d_local_code_shift_chips[0] = -d_early_late_spc_chips; + d_local_code_shift_chips[0] = -d_early_late_spc_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[1] = 0.0; - d_local_code_shift_chips[2] = d_early_late_spc_chips; - d_null_shift = &d_local_code_shift_chips[1]; + d_local_code_shift_chips[2] = d_early_late_spc_chips * static_cast(d_code_samples_per_chip); + d_prompt_data_shift = &d_local_code_shift_chips[1]; } - d_correlation_length_samples = d_vector_length; - multicorrelator_cpu.init(2 * d_correlation_length_samples, d_n_correlator_taps); + multicorrelator_cpu.init(2 * d_vector_length, d_n_correlator_taps); - d_extend_correlation_symbols = extend_correlation_symbols; - // Enable Data component prompt correlator (slave to Pilot prompt) if tracking uses Pilot signal - if (d_track_pilot) + if (extend_correlation_symbols > 1) { - // extended integration control - if (d_extend_correlation_symbols > 1) - { - d_enable_extended_integration = true; - } - else - { - d_enable_extended_integration = false; - } - // Extra correlator for the data component - correlator_data_cpu.init(2 * d_correlation_length_samples, 1); - d_Prompt_Data = static_cast(volk_gnsssdr_malloc(sizeof(gr_complex), volk_gnsssdr_get_alignment())); - d_Prompt_Data[0] = gr_complex(0.0, 0.0); - d_data_code = static_cast(volk_gnsssdr_malloc(2 * d_code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); + d_enable_extended_integration = true; + d_extend_correlation_symbols = extend_correlation_symbols; } else { - // Disable extended integration if data component tracking is selected d_enable_extended_integration = false; + d_extend_correlation_symbols = 1; + } + + // Enable Data component prompt correlator (slave to Pilot prompt) if tracking uses Pilot signal + if (d_track_pilot) + { + // Extra correlator for the data component + correlator_data_cpu.init(2 * d_vector_length, 1); + d_Prompt_Data = static_cast(volk_gnsssdr_malloc(sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_Prompt_Data[0] = gr_complex(0.0, 0.0); + d_data_code = static_cast(volk_gnsssdr_malloc(2 * d_code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); + std::fill_n(d_data_code, 2 * d_code_length_chips, 0.0); } //--- Initializations ---// @@ -355,7 +379,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( d_rem_code_phase_chips = 0.0; d_K_blk_samples = 0.0; d_code_phase_samples = 0.0; - + d_last_prompt = gr_complex(0.0, 0.0); d_state = 0; // initial state: standby } @@ -371,14 +395,15 @@ void dll_pll_veml_tracking::start_tracking() d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; long int acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; - DLOG(INFO) << "Number of samples between Acquisition and Tracking = " << acq_trk_diff_samples; double acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / d_fs_in; + DLOG(INFO) << "Number of samples between Acquisition and Tracking = " << acq_trk_diff_samples; + DLOG(INFO) << "Number of seconds between Acquisition and Tracking = " << acq_trk_diff_seconds; // Doppler effect // Fd=(C/(C+Vr))*F double radial_velocity = (d_signal_carrier_freq + d_acq_carrier_doppler_hz) / d_signal_carrier_freq; // new chip and prn sequence periods based on acq Doppler d_code_freq_chips = radial_velocity * d_code_chip_rate; - d_code_phase_step_chips = static_cast(d_code_freq_chips) / static_cast(d_fs_in); + d_code_phase_step_chips = d_code_freq_chips / d_fs_in; double T_chip_mod_seconds = 1.0 / d_code_freq_chips; double T_prn_mod_seconds = T_chip_mod_seconds * static_cast(d_code_length_chips); double T_prn_mod_samples = T_prn_mod_seconds * d_fs_in; @@ -399,29 +424,89 @@ void dll_pll_veml_tracking::start_tracking() d_acq_code_phase_samples = corrected_acq_phase_samples; d_carrier_doppler_hz = d_acq_carrier_doppler_hz; - d_carrier_phase_step_rad = GALILEO_TWO_PI * d_carrier_doppler_hz / d_fs_in; + d_carrier_phase_step_rad = PI_2 * d_carrier_doppler_hz / d_fs_in; // DLL/PLL filter initialization d_carrier_loop_filter.initialize(); // initialize the carrier filter d_code_loop_filter.initialize(); // initialize the code filter - if (d_track_pilot) + if (systemName.compare("GPS") == 0 and signal_type.compare("1C") == 0) { - char pilot_signal[3] = "1C"; - galileo_e1_code_gen_float_sampled(d_tracking_code, pilot_signal, false, - d_acquisition_gnss_synchro->PRN, Galileo_E1_CODE_CHIP_RATE_HZ, 0); - galileo_e1_code_gen_float_sampled(d_data_code, d_acquisition_gnss_synchro->Signal, false, - d_acquisition_gnss_synchro->PRN, Galileo_E1_CODE_CHIP_RATE_HZ, 0); - d_Prompt_Data[0] = gr_complex(0.0, 0.0); - correlator_data_cpu.set_local_code_and_taps(d_code_length_chips, d_data_code, d_null_shift); + gps_l1_ca_code_gen_float(d_tracking_code, d_acquisition_gnss_synchro->PRN, 0); } - else + else if (systemName.compare("GPS") == 0 and signal_type.compare("2S") == 0) { - galileo_e1_code_gen_float_sampled(d_tracking_code, d_acquisition_gnss_synchro->Signal, false, - d_acquisition_gnss_synchro->PRN, Galileo_E1_CODE_CHIP_RATE_HZ, 0); + gps_l2c_m_code_gen_float(d_tracking_code, d_acquisition_gnss_synchro->PRN); + } + else if (systemName.compare("GPS") == 0 and signal_type.compare("L5") == 0) + { + if (d_track_pilot) + { + gps_l5q_code_gen_float(d_tracking_code, d_acquisition_gnss_synchro->PRN); + gps_l5i_code_gen_float(d_data_code, d_acquisition_gnss_synchro->PRN); + d_Prompt_Data[0] = gr_complex(0.0, 0.0); + correlator_data_cpu.set_local_code_and_taps(d_code_length_chips, d_data_code, d_prompt_data_shift); + } + else + { + gps_l5i_code_gen_float(d_tracking_code, d_acquisition_gnss_synchro->PRN); + } + } + else if (systemName.compare("Galileo") == 0 and signal_type.compare("1B") == 0) + { + if (d_track_pilot) + { + char pilot_signal[3] = "1C"; + galileo_e1_code_gen_float_sampled(d_tracking_code, + pilot_signal, + false, //CBOC disabled + d_acquisition_gnss_synchro->PRN, + Galileo_E1_CODE_CHIP_RATE_HZ, + 0); + galileo_e1_code_gen_float_sampled(d_data_code, + d_acquisition_gnss_synchro->Signal, + false, //CBOC disabled + d_acquisition_gnss_synchro->PRN, + Galileo_E1_CODE_CHIP_RATE_HZ, + 0); + d_Prompt_Data[0] = gr_complex(0.0, 0.0); + correlator_data_cpu.set_local_code_and_taps(d_code_samples_per_chip * d_code_length_chips, d_data_code, d_prompt_data_shift); + } + else + { + galileo_e1_code_gen_float_sampled(d_tracking_code, + d_acquisition_gnss_synchro->Signal, + false, //CBOC disabled + d_acquisition_gnss_synchro->PRN, + Galileo_E1_CODE_CHIP_RATE_HZ, + 0); + } + } + else if (systemName.compare("Galileo") == 0 and signal_type.compare("5X") == 0) + { + gr_complex aux_code[d_code_length_chips]; + galileo_e5_a_code_gen_complex_primary(aux_code, d_acquisition_gnss_synchro->PRN, const_cast(signal_type.c_str())); + if (d_track_pilot) + { + d_secondary_code_string = const_cast(&Galileo_E5a_Q_SECONDARY_CODE[d_acquisition_gnss_synchro->PRN - 1]); + for (unsigned int i = 0; i < d_code_length_chips; i++) + { + d_tracking_code[i] = aux_code[i].imag(); + d_data_code[i] = aux_code[i].real(); + } + d_Prompt_Data[0] = gr_complex(0.0, 0.0); + correlator_data_cpu.set_local_code_and_taps(d_code_length_chips, d_data_code, d_prompt_data_shift); + } + else + { + for (unsigned int i = 0; i < d_code_length_chips; i++) + { + d_tracking_code[i] = aux_code[i].real(); + } + } } - multicorrelator_cpu.set_local_code_and_taps(d_code_length_chips, d_tracking_code, d_local_code_shift_chips); + multicorrelator_cpu.set_local_code_and_taps(d_code_samples_per_chip * d_code_length_chips, d_tracking_code, d_local_code_shift_chips); std::fill_n(d_correlator_outs, d_n_correlator_taps, gr_complex(0.0, 0.0)); d_carrier_lock_fail_counter = 0; @@ -429,8 +514,28 @@ void dll_pll_veml_tracking::start_tracking() d_rem_carr_phase_rad = 0.0; d_rem_code_phase_chips = 0.0; d_acc_carrier_phase_rad = 0.0; + d_cn0_estimation_counter = 0; + d_carrier_lock_test = 1.0; + d_CN0_SNV_dB_Hz = 0.0; + + if (d_veml) + { + d_local_code_shift_chips[0] = -d_very_early_late_spc_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[1] = -d_early_late_spc_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[3] = d_early_late_spc_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[4] = d_very_early_late_spc_chips * static_cast(d_code_samples_per_chip); + } + else + { + d_local_code_shift_chips[0] = -d_early_late_spc_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[2] = d_early_late_spc_chips * static_cast(d_code_samples_per_chip); + } d_code_phase_samples = d_acq_code_phase_samples; + d_code_loop_filter.set_DLL_BW(d_dll_bw_hz); + d_carrier_loop_filter.set_PLL_BW(d_pll_bw_hz); + d_carrier_loop_filter.set_pdi(static_cast(d_code_period)); + d_code_loop_filter.set_pdi(static_cast(d_code_period)); // DEBUG OUTPUT std::cout << "Tracking of " << systemName << " " << signal_type << " signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; @@ -438,10 +543,11 @@ void dll_pll_veml_tracking::start_tracking() // enable tracking pull-in d_state = 1; - - LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz - << " Code Phase correction [samples]=" << delay_correction_samples - << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; + d_Prompt_buffer_deque.clear(); + d_last_prompt = gr_complex(0.0, 0.0); + LOG(INFO) << "PULL-IN Doppler [Hz] = " << d_carrier_doppler_hz + << ". Code Phase correction [samples] = " << delay_correction_samples + << ". PULL-IN Code Phase [samples] = " << d_acq_code_phase_samples; } @@ -546,7 +652,7 @@ bool dll_pll_veml_tracking::cn0_and_tracking_lock_status() { d_cn0_estimation_counter = 0; // Code lock indicator - d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, DLL_PLL_CN0_ESTIMATION_SAMPLES, d_fs_in, static_cast(d_code_length_chips)); + d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, DLL_PLL_CN0_ESTIMATION_SAMPLES, static_cast(d_fs_in), static_cast(d_code_length_chips)); // Carrier lock indicator d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, DLL_PLL_CN0_ESTIMATION_SAMPLES); // Loss of lock detection @@ -587,9 +693,9 @@ void dll_pll_veml_tracking::do_correlation_step(const gr_complex *input_samples) multicorrelator_cpu.Carrier_wipeoff_multicorrelator_resampler( d_rem_carr_phase_rad, d_carrier_phase_step_rad, - d_rem_code_phase_chips, - d_code_phase_step_chips, - d_correlation_length_samples); + d_rem_code_phase_chips * static_cast(d_code_samples_per_chip), + d_code_phase_step_chips * static_cast(d_code_samples_per_chip), + d_vector_length); // DATA CORRELATOR (if tracking tracks the pilot signal) if (d_track_pilot) @@ -598,26 +704,26 @@ void dll_pll_veml_tracking::do_correlation_step(const gr_complex *input_samples) correlator_data_cpu.Carrier_wipeoff_multicorrelator_resampler( d_rem_carr_phase_rad, d_carrier_phase_step_rad, - d_rem_code_phase_chips, - d_code_phase_step_chips, - d_correlation_length_samples); + d_rem_code_phase_chips * static_cast(d_code_samples_per_chip), + d_code_phase_step_chips * static_cast(d_code_samples_per_chip), + d_vector_length); } } -void dll_pll_veml_tracking::run_dll_pll(bool disable_costas_loop) +void dll_pll_veml_tracking::run_dll_pll(bool enable_costas_loop) { // ################## PLL ########################################################## // PLL discriminator - if (disable_costas_loop == true) + if (enable_costas_loop) { - // Secondary code acquired. No symbols transition should be present in the signal - d_carr_error_hz = pll_four_quadrant_atan(d_P_accu) / GALILEO_TWO_PI; + // Costas loop discriminator, insensitive to 180 deg phase transitions + d_carr_error_hz = pll_cloop_two_quadrant_atan(d_P_accu) / PI_2; } else { - // Costas loop discriminator, insensitive to 180 deg phase transitions - d_carr_error_hz = pll_cloop_two_quadrant_atan(d_P_accu) / GALILEO_TWO_PI; + // Secondary code acquired. No symbols transition should be present in the signal + d_carr_error_hz = pll_four_quadrant_atan(d_P_accu) / PI_2; } // Carrier discriminator filter @@ -625,11 +731,18 @@ void dll_pll_veml_tracking::run_dll_pll(bool disable_costas_loop) // New carrier Doppler frequency estimation d_carrier_doppler_hz = d_acq_carrier_doppler_hz + d_carr_error_filt_hz; // New code Doppler frequency estimation - d_code_freq_chips = (1.0 + d_carrier_doppler_hz / d_signal_carrier_freq) * d_code_chip_rate; + d_code_freq_chips = (1.0 + (d_carrier_doppler_hz / d_signal_carrier_freq)) * d_code_chip_rate; // ################## DLL ########################################################## // DLL discriminator - d_code_error_chips = dll_nc_vemlp_normalized(d_VE_accu, d_E_accu, d_L_accu, d_VL_accu); // [chips/Ti] + if (d_veml) + { + d_code_error_chips = dll_nc_vemlp_normalized(d_VE_accu, d_E_accu, d_L_accu, d_VL_accu); // [chips/Ti] + } + else + { + d_code_error_chips = dll_nc_e_minus_l_normalized(d_E_accu, d_L_accu); // [chips/Ti] + } // Code discriminator filter d_code_error_filt_chips = d_code_loop_filter.get_code_nco(d_code_error_chips); // [chips/second] } @@ -638,11 +751,87 @@ void dll_pll_veml_tracking::run_dll_pll(bool disable_costas_loop) void dll_pll_veml_tracking::clear_tracking_vars() { std::fill_n(d_correlator_outs, d_n_correlator_taps, gr_complex(0.0, 0.0)); + if (d_track_pilot) *d_Prompt_Data = gr_complex(0.0, 0.0); d_carr_error_hz = 0.0; d_carr_error_filt_hz = 0.0; d_code_error_chips = 0.0; d_code_error_filt_chips = 0.0; d_current_symbol = 0; + d_Prompt_buffer_deque.clear(); + d_last_prompt = gr_complex(0.0, 0.0); +} + +void dll_pll_veml_tracking::update_tracking_vars() +{ + T_chip_seconds = 1.0 / d_code_freq_chips; + T_prn_seconds = T_chip_seconds * static_cast(d_code_length_chips); + double code_error_filt_secs = T_prn_seconds * d_code_error_filt_chips * T_chip_seconds; //[seconds] + + // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### + // keep alignment parameters for the next input buffer + // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation + T_prn_samples = T_prn_seconds * d_fs_in; + K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * d_fs_in; + d_current_prn_length_samples = static_cast(round(K_blk_samples)); // round to a discrete number of samples + + //################### PLL COMMANDS ################################################# + // carrier phase step (NCO phase increment per sample) [rads/sample] + d_carrier_phase_step_rad = PI_2 * d_carrier_doppler_hz / d_fs_in; + // remnant carrier phase to prevent overflow in the code NCO + d_rem_carr_phase_rad += d_carrier_phase_step_rad * static_cast(d_current_prn_length_samples); + d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, PI_2); + // carrier phase accumulator + d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * static_cast(d_current_prn_length_samples); + + //################### DLL COMMANDS ################################################# + // code phase step (Code resampler phase increment per sample) [chips/sample] + d_code_phase_step_chips = d_code_freq_chips / d_fs_in; + // remnant code phase [chips] + d_rem_code_phase_samples = K_blk_samples - static_cast(d_current_prn_length_samples); // rounding error < 1 sample + d_rem_code_phase_chips = d_code_freq_chips * d_rem_code_phase_samples / d_fs_in; +} + +void dll_pll_veml_tracking::save_correlation_results() +{ + if (d_secondary) + { + if (d_secondary_code_string->at(d_current_symbol) == '0') + { + if (d_veml) + { + d_VE_accu += *d_Very_Early; + d_VL_accu += *d_Very_Late; + } + d_E_accu += *d_Early; + d_P_accu += *d_Prompt; + d_L_accu += *d_Late; + } + else + { + if (d_veml) + { + d_VE_accu -= *d_Very_Early; + d_VL_accu -= *d_Very_Late; + } + d_E_accu -= *d_Early; + d_P_accu -= *d_Prompt; + d_L_accu -= *d_Late; + } + d_current_symbol++; + // secondary code roll-up + d_current_symbol %= d_secondary_code_length; + } + else + { + if (d_veml) + { + d_VE_accu += *d_Very_Early; + d_VL_accu += *d_Very_Late; + } + d_E_accu += *d_Early; + d_P_accu += *d_Prompt; + d_L_accu += *d_Late; + } } @@ -656,10 +845,16 @@ void dll_pll_veml_tracking::log_data() float tmp_VE, tmp_E, tmp_P, tmp_L, tmp_VL; float tmp_float; double tmp_double; - - prompt_I = static_cast(d_P_accu.real()); - prompt_Q = static_cast(d_P_accu.imag()); - + if (d_track_pilot) + { + prompt_I = d_Prompt_Data->real(); + prompt_Q = d_Prompt_Data->imag(); + } + else + { + prompt_I = d_Prompt->real(); + prompt_Q = d_Prompt->imag(); + } if (d_veml) { tmp_VE = std::abs(d_VE_accu); @@ -727,7 +922,7 @@ void dll_pll_veml_tracking::log_data() } -int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), +int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { gr::thread::scoped_lock l(d_setlock); @@ -737,8 +932,11 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) switch (d_state) { - case 0: // Standby - Pass Through + case 0: // Standby - Pass Through. Full throttle { + d_sample_counter += ninput_items[0]; + consume_each(ninput_items[0]); + return 0; break; } case 1: // Pull-in @@ -746,22 +944,20 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) // Signal alignment (skip samples until the incoming signal is aligned with local replica) // Fill the acquisition data int acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; - double acq_trk_shif_correction_samples = d_current_prn_length_samples - std::fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_current_prn_length_samples)); + double acq_trk_shif_correction_samples = static_cast(d_current_prn_length_samples) - std::fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_current_prn_length_samples)); int samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); + if (samples_offset < 0) + { + samples_offset = 0; + } + d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * static_cast(samples_offset); + d_state = 2; d_sample_counter += samples_offset; // count for the processed samples consume_each(samples_offset); // shift input to perform alignment with local replica - d_state = 2; // next state is the symbol synchronization return 0; } case 2: // Wide tracking and symbol synchronization { - // Fill the acquisition data - current_synchro_data = *d_acquisition_gnss_synchro; - // Current NCO and code generator parameters - d_carrier_phase_step_rad = GALILEO_TWO_PI * d_carrier_doppler_hz / d_fs_in; - d_code_phase_step_chips = d_code_freq_chips / d_fs_in; - d_rem_code_phase_chips = d_rem_code_phase_samples * d_code_phase_step_chips; - // Perform a correlation step do_correlation_step(in); // Save single correlation step variables if (d_veml) @@ -781,103 +977,89 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) } else { - // Perform DLL/PLL tracking loop computations - run_dll_pll(false); - - // ################## PLL COMMANDS ################################################# - // carrier phase accumulator for (K) Doppler estimation- - d_acc_carrier_phase_rad -= GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / d_fs_in; - // remanent carrier phase to prevent overflow in the code NCO - d_rem_carr_phase_rad = d_rem_carr_phase_rad + GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / d_fs_in; - d_rem_carr_phase_rad = std::fmod(d_rem_carr_phase_rad, GALILEO_TWO_PI); - - // ################## DLL COMMANDS ################################################# - // Code error from DLL - double code_error_filt_secs = d_code_period * d_code_error_filt_chips / d_code_chip_rate; // [seconds] - - // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### - // keep alignment parameters for the next input buffer - // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation - double T_chip_seconds = 1.0 / d_code_freq_chips; - double T_prn_seconds = T_chip_seconds * static_cast(d_code_length_chips); - double T_prn_samples = T_prn_seconds * d_fs_in; - double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * d_fs_in; - d_current_prn_length_samples = round(K_blk_samples); // round to a discrete number of samples - - // ########### Output the tracking results to Telemetry block ########## - if (d_track_pilot) - { - current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); - } - else - { - current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); - } - current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; - // compute remnant code phase samples AFTER the Tracking timestamp - d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; // rounding error < 1 sample - current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; - current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; - current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; - current_synchro_data.Flag_valid_symbol_output = true; - current_synchro_data.correlation_length_ms = d_correlation_length_ms; + bool next_state = false; + // Perform DLL/PLL tracking loop computations. Costas Loop enabled + run_dll_pll(true); + update_tracking_vars(); // enable write dump file this cycle (valid DLL/PLL cycle) log_data(); - - if (d_enable_extended_integration) + if (d_secondary) { // ####### SECONDARY CODE LOCK ##### d_Prompt_buffer_deque.push_back(*d_Prompt); if (d_Prompt_buffer_deque.size() == d_secondary_code_length) { - if (acquire_secondary()) - { - d_extend_correlation_symbols_count = 0; - // reset extended correlator - d_VE_accu = gr_complex(0.0, 0.0); - d_E_accu = gr_complex(0.0, 0.0); - d_P_accu = gr_complex(0.0, 0.0); - d_L_accu = gr_complex(0.0, 0.0); - d_VL_accu = gr_complex(0.0, 0.0); - d_Prompt_buffer_deque.clear(); - d_current_symbol = 0; - d_code_loop_filter.set_DLL_BW(d_dll_bw_narrow_hz); - d_carrier_loop_filter.set_PLL_BW(d_pll_bw_narrow_hz); - - // Set narrow taps delay values [chips] - if (d_veml) - { - d_local_code_shift_chips[0] = -d_very_early_late_spc_narrow_chips; - d_local_code_shift_chips[1] = -d_early_late_spc_narrow_chips; - d_local_code_shift_chips[3] = d_early_late_spc_narrow_chips; - d_local_code_shift_chips[4] = d_very_early_late_spc_narrow_chips; - } - else - { - d_local_code_shift_chips[0] = -d_early_late_spc_narrow_chips; - d_local_code_shift_chips[2] = d_early_late_spc_narrow_chips; - } - LOG(INFO) << "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " - << d_channel - << " : Satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN); - std::cout << "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " - << d_channel - << " : Satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; - - // UPDATE INTEGRATION TIME - float new_correlation_time_s = static_cast(d_extend_correlation_symbols) * static_cast(d_code_period); - d_carrier_loop_filter.set_pdi(new_correlation_time_s); - d_code_loop_filter.set_pdi(new_correlation_time_s); - - d_state = 3; // next state is the extended correlator integrator - } - + next_state = acquire_secondary(); d_Prompt_buffer_deque.pop_front(); } } + else //Signal does not have secondary code. Search a bit transition by sign change + { + if (d_current_symbol == (d_symbols_per_bit - 1)) + { + next_state = true; + } + else if (d_current_symbol > 0) + { + d_current_symbol++; + } + else if (d_last_prompt.real() != 0.0) + { + if (d_Prompt->real() * d_last_prompt.real() < 0.0) + { + d_current_symbol = 1; + } + } + d_last_prompt = *d_Prompt; + } + if (next_state) + { // reset extended correlator + d_VE_accu = gr_complex(0.0, 0.0); + d_E_accu = gr_complex(0.0, 0.0); + d_P_accu = gr_complex(0.0, 0.0); + d_L_accu = gr_complex(0.0, 0.0); + d_VL_accu = gr_complex(0.0, 0.0); + d_last_prompt = gr_complex(0.0, 0.0); + d_Prompt_buffer_deque.clear(); + d_current_symbol = 0; + d_code_loop_filter.set_DLL_BW(d_dll_bw_narrow_hz); + d_carrier_loop_filter.set_PLL_BW(d_pll_bw_narrow_hz); + + // Set narrow taps delay values [chips] + if (d_veml) + { + d_local_code_shift_chips[0] = -d_very_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[1] = -d_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[3] = d_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[4] = d_very_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); + } + else + { + d_local_code_shift_chips[0] = -d_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[2] = d_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); + } + + // UPDATE INTEGRATION TIME + if (d_enable_extended_integration) + { + d_extend_correlation_symbols_count = 0; + float new_correlation_time_s = static_cast(d_extend_correlation_symbols) * static_cast(d_code_period); + d_carrier_loop_filter.set_pdi(new_correlation_time_s); + d_code_loop_filter.set_pdi(new_correlation_time_s); + d_state = 3; // next state is the extended correlator integrator + LOG(INFO) << "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " + << d_channel + << " : Satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN); + std::cout << "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " + << d_channel + << " : Satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; + } + else + { + d_state = 4; + } + } } break; } @@ -885,73 +1067,31 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) { // Fill the acquisition data current_synchro_data = *d_acquisition_gnss_synchro; - // Current NCO and code generator parameters - d_carrier_phase_step_rad = GALILEO_TWO_PI * d_carrier_doppler_hz / d_fs_in; - d_code_phase_step_chips = d_code_freq_chips / d_fs_in; - d_rem_code_phase_chips = d_rem_code_phase_samples * d_code_freq_chips / d_fs_in; // perform a correlation step do_correlation_step(in); - // correct the integration sign using the current symbol of the secondary code - if (d_secondary_code_string->at(d_current_symbol) == '0') + update_tracking_vars(); + save_correlation_results(); + + // ########### Output the tracking results to Telemetry block ########## + if (interchange_iq) { - if (d_veml) - { - d_VE_accu += *d_Very_Early; - d_VL_accu += *d_Very_Late; - } - d_E_accu += *d_Early; - d_P_accu += *d_Prompt; - d_L_accu += *d_Late; + //Note that data and pilot components are in quadrature. I and Q are interchanged + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).imag()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).real()); } else { - if (d_veml) - { - d_VE_accu -= *d_Very_Early; - d_VL_accu -= *d_Very_Late; - } - d_E_accu -= *d_Early; - d_P_accu -= *d_Prompt; - d_L_accu -= *d_Late; + current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); } - d_current_symbol++; - // secondary code roll-up - d_current_symbol %= d_secondary_code_length; - - // PLL/DLL not enabled, we are in the middle of a coherent integration - // keep alignment parameters for the next input buffer - // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation - - // ################## PLL ########################################################## - // carrier phase accumulator for (K) Doppler estimation- - d_acc_carrier_phase_rad -= GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / d_fs_in; - // remnant carrier phase to prevent overflow in the code NCO - d_rem_carr_phase_rad = d_rem_carr_phase_rad + GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / d_fs_in; - d_rem_carr_phase_rad = std::fmod(d_rem_carr_phase_rad, GALILEO_TWO_PI); - - // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### - // keep alignment parameters for the next input buffer - // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation - double T_chip_seconds = 1.0 / d_code_freq_chips; - double T_prn_seconds = T_chip_seconds * static_cast(d_code_length_chips); - double T_prn_samples = T_prn_seconds * d_fs_in; - double K_blk_samples = T_prn_samples + d_rem_code_phase_samples; - d_current_prn_length_samples = static_cast(round(K_blk_samples)); //round to a discrete samples - - // ########### Output the tracking results to Telemetry block ########## - current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; - // compute remnant code phase samples AFTER the Tracking timestamp - d_rem_code_phase_samples = K_blk_samples - static_cast(d_current_prn_length_samples); //rounding error < 1 sample current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; current_synchro_data.Flag_valid_symbol_output = true; current_synchro_data.correlation_length_ms = d_correlation_length_ms; - d_extend_correlation_symbols_count++; - if (d_extend_correlation_symbols_count >= (d_extend_correlation_symbols - 1)) + if (d_extend_correlation_symbols_count == (d_extend_correlation_symbols - 1)) { d_extend_correlation_symbols_count = 0; d_state = 4; @@ -962,35 +1102,10 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) { // Fill the acquisition data current_synchro_data = *d_acquisition_gnss_synchro; + // perform a correlation step do_correlation_step(in); - - // correct the integration using the current symbol - if (d_secondary_code_string->at(d_current_symbol) == '0') - { - if (d_veml) - { - d_VE_accu += *d_Very_Early; - d_VL_accu += *d_Very_Late; - } - d_E_accu += *d_Early; - d_P_accu += *d_Prompt; - d_L_accu += *d_Late; - } - else - { - if (d_veml) - { - d_VE_accu -= *d_Very_Early; - d_VL_accu -= *d_Very_Late; - } - d_E_accu -= *d_Early; - d_P_accu -= *d_Prompt; - d_L_accu -= *d_Late; - } - d_current_symbol++; - // secondary code roll-up - d_current_symbol %= d_secondary_code_length; + save_correlation_results(); // check lock status if (!cn0_and_tracking_lock_status()) @@ -1000,34 +1115,32 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) } else { - run_dll_pll(true); // Costas loop disabled, use four quadrant atan - - // ################## PLL ########################################################## - // carrier phase accumulator for (K) Doppler estimation- - d_acc_carrier_phase_rad -= GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / d_fs_in; - // remnant carrier phase to prevent overflow in the code NCO - d_rem_carr_phase_rad = d_rem_carr_phase_rad + GALILEO_TWO_PI * d_carrier_doppler_hz * static_cast(d_current_prn_length_samples) / d_fs_in; - d_rem_carr_phase_rad = std::fmod(d_rem_carr_phase_rad, GALILEO_TWO_PI); - - // ################## DLL ########################################################## - // Code phase accumulator - double code_error_filt_secs = d_code_period * d_code_error_filt_chips / d_code_chip_rate; //[seconds] - - // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### - // keep alignment parameters for the next input buffer - // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation - double T_chip_seconds = 1.0 / d_code_freq_chips; - double T_prn_seconds = T_chip_seconds * static_cast(d_code_length_chips); - double T_prn_samples = T_prn_seconds * d_fs_in; - double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * d_fs_in; - d_current_prn_length_samples = static_cast(round(K_blk_samples)); // round to a discrete number of samples + run_dll_pll(!d_secondary); + //EQUIVALENT TO THE LINE ABOVE if (d_secondary) + //{ + // //If secondary code is locked, disable Costas Loop + // run_dll_pll(false); + //} + //else + //{ + // //The signal does not have secondary code, enable Costas Loop + // run_dll_pll(true); + //} + update_tracking_vars(); // ########### Output the tracking results to Telemetry block ########## - current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); + if (interchange_iq) + { + //Note that data and pilot components are in quadrature. I and Q are interchanged + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).imag()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).real()); + } + else + { + current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); + } current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; - // compute remnant code phase samples AFTER the Tracking timestamp - d_rem_code_phase_samples = K_blk_samples - static_cast(d_current_prn_length_samples); //rounding error < 1 sample current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; @@ -1041,20 +1154,15 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) d_P_accu = gr_complex(0.0, 0.0); d_L_accu = gr_complex(0.0, 0.0); d_VL_accu = gr_complex(0.0, 0.0); - d_state = 3; //new coherent integration (correlation time extension) cycle + if (d_enable_extended_integration) + { + d_state = 3; //new coherent integration (correlation time extension) cycle + } } } } - - //assign the GNURadio block output data - // current_synchro_data.System = {'E'}; - // std::string str_aux = "1B"; - // const char * str = str_aux.c_str(); // get a C style null terminated string - // std::memcpy(static_cast(current_synchro_data.Signal), str, 3); - consume_each(d_current_prn_length_samples); d_sample_counter += d_current_prn_length_samples; - if (current_synchro_data.Flag_valid_symbol_output) { current_synchro_data.fs = static_cast(d_fs_in); diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h index 6538de571..a91d041f8 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h @@ -37,13 +37,14 @@ #define DLL_PLL_MAXIMUM_LOCK_FAIL_COUNTER 50 #define DLL_PLL_CARRIER_LOCK_THRESHOLD 0.85 -#include -#include -#include #include "gnss_synchro.h" #include "tracking_2nd_DLL_filter.h" #include "tracking_2nd_PLL_filter.h" #include "cpu_multicorrelator_real_codes.h" +#include +#include +#include + class dll_pll_veml_tracking; @@ -57,7 +58,7 @@ dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(double fs_in, unsigned int float early_late_space_narrow_chips, float very_early_late_space_narrow_chips, int extend_correlation_symbols, bool track_pilot, - char system, char signal[3], bool veml); + char system, char signal[3]); /*! * \brief This class implements a code DLL + carrier PLL VEML (Very Early @@ -91,7 +92,7 @@ private: float very_early_late_space_chips, float early_late_space_narrow_chips, float very_early_late_space_narrow_chips, int extend_correlation_symbols, bool track_pilot, - char system, char signal[3], bool veml); + char system, char signal[3]); dll_pll_veml_tracking(double fs_in, unsigned int vector_length, bool dump, @@ -106,62 +107,63 @@ private: float very_early_late_space_narrow_chips, int extend_correlation_symbols, bool track_pilot, - char system, char signal[3], bool veml); + char system, char signal[3]); bool cn0_and_tracking_lock_status(); + bool acquire_secondary(); void do_correlation_step(const gr_complex *input_samples); void run_dll_pll(bool disable_costas_loop); - void update_local_code(); - void update_local_carrier(); - bool acquire_secondary(); - + void update_tracking_vars(); void clear_tracking_vars(); - + void save_correlation_results(); void log_data(); + int save_matfile(); // tracking configuration vars bool d_dump; bool d_veml; - bool d_secondary; - unsigned int d_secondary_code_length; - std::string *d_secondary_code_string; - Gnss_Synchro *d_acquisition_gnss_synchro; unsigned int d_vector_length; unsigned int d_channel; - // long d_fs_in; double d_fs_in; - + Gnss_Synchro *d_acquisition_gnss_synchro; //Signal parameters + bool d_secondary; + bool interchange_iq; double d_signal_carrier_freq; double d_code_period; double d_code_chip_rate; + unsigned int d_secondary_code_length; unsigned int d_code_length_chips; + unsigned int d_code_samples_per_chip; // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled) + int d_symbols_per_bit; + std::string systemName; + std::string signal_type; + std::string *d_secondary_code_string; //tracking state machine int d_state; //Integration period in samples - int d_correlation_length_samples; int d_correlation_length_ms; int d_n_correlator_taps; - double d_early_late_spc_chips; - double d_very_early_late_spc_chips; - double d_early_late_spc_narrow_chips; - double d_very_early_late_spc_narrow_chips; + float d_early_late_spc_chips; + float d_very_early_late_spc_chips; + float d_early_late_spc_narrow_chips; + float d_very_early_late_spc_narrow_chips; float *d_tracking_code; float *d_data_code; float *d_local_code_shift_chips; - float *d_null_shift; - gr_complex *d_correlator_outs; + float *d_prompt_data_shift; cpu_multicorrelator_real_codes multicorrelator_cpu; - //TODO: currently the multicorrelator does not support adding extra correlator - //with different local code, thus we need extra multicorrelator instance. - //Implement this functionality inside multicorrelator class - //as an enhancement to increase the performance cpu_multicorrelator_real_codes correlator_data_cpu; //for data channel - + /* TODO: currently the multicorrelator does not support adding extra correlator + with different local code, thus we need extra multicorrelator instance. + Implement this functionality inside multicorrelator class + as an enhancement to increase the performance + */ + gr_complex *d_correlator_outs; gr_complex *d_Very_Early; gr_complex *d_Early; gr_complex *d_Prompt; @@ -178,6 +180,7 @@ private: gr_complex d_P_accu; gr_complex d_L_accu; gr_complex d_VL_accu; + gr_complex d_last_prompt; bool d_track_pilot; gr_complex *d_Prompt_Data; @@ -206,39 +209,34 @@ private: double d_carr_error_filt_hz; double d_code_error_chips; double d_code_error_filt_chips; - double d_K_blk_samples; - double d_code_freq_chips; double d_carrier_doppler_hz; double d_acc_carrier_phase_rad; double d_rem_code_phase_chips; double d_code_phase_samples; - + double T_chip_seconds; + double T_prn_seconds; + double T_prn_samples; + double K_blk_samples; //PRN period in samples int d_current_prn_length_samples; - //processing samples counters unsigned long int d_sample_counter; unsigned long int d_acq_sample_stamp; // CN0 estimation and lock detector int d_cn0_estimation_counter; - std::deque d_Prompt_buffer_deque; - gr_complex *d_Prompt_buffer; + int d_carrier_lock_fail_counter; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; double d_carrier_lock_threshold; - int d_carrier_lock_fail_counter; + std::deque d_Prompt_buffer_deque; + gr_complex *d_Prompt_buffer; // file dump std::string d_dump_filename; std::ofstream d_dump_file; - - std::string systemName; - std::string signal_type; - - int save_matfile(); }; #endif //GNSS_SDR_DLL_PLL_VEML_TRACKING_H diff --git a/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.cc b/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.cc index 4c7735aa2..6fa82351c 100644 --- a/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.cc +++ b/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.cc @@ -122,7 +122,7 @@ bool cpu_multicorrelator_real_codes::Carrier_wipeoff_multicorrelator_resampler( lv_32fc_t phase_offset_as_complex[1]; phase_offset_as_complex[0] = lv_cmake(std::cos(rem_carrier_phase_in_rad), -std::sin(rem_carrier_phase_in_rad)); // call VOLK_GNSSSDR kernel - volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn(d_corr_out, d_sig_in, std::exp(lv_32fc_t(0.0, -phase_step_rad)), phase_offset_as_complex, (const float**)d_local_codes_resampled, d_n_correlators, signal_length_samples); + volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn(d_corr_out, d_sig_in, std::exp(lv_32fc_t(0.0, -phase_step_rad)), phase_offset_as_complex, const_cast(d_local_codes_resampled), d_n_correlators, signal_length_samples); return true; } diff --git a/src/core/system_parameters/GPS_L5.h b/src/core/system_parameters/GPS_L5.h index af317cfc3..ff7ded0d4 100644 --- a/src/core/system_parameters/GPS_L5.h +++ b/src/core/system_parameters/GPS_L5.h @@ -36,6 +36,7 @@ #include "GPS_CNAV.h" #include "MATH_CONSTANTS.h" #include +#include // Physical constants @@ -181,7 +182,11 @@ const int GPS_L5_SYMBOLS_PER_BIT = 2; const int GPS_L5_SAMPLES_PER_SYMBOL = 10; const int GPS_L5_CNAV_DATA_PAGE_SYMBOLS = 600; const int GPS_L5_CNAV_DATA_PAGE_DURATION_S = 6; -const int GPS_L5_NH_CODE_LENGTH = 10; -const int GPS_L5_NH_CODE[10] = {0, 0, 0, 0, 1, 1, 0, 1, 0, 1}; +const int GPS_L5i_NH_CODE_LENGTH = 10; +const int GPS_L5i_NH_CODE[10] = {0, 0, 0, 0, 1, 1, 0, 1, 0, 1}; +const std::string GPS_L5i_NH_CODE_STR = "0000110101"; +const int GPS_L5q_NH_CODE_LENGTH = 20; +const int GPS_L5q_NH_CODE[20] = {0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0}; +const std::string GPS_L5q_NH_CODE_STR = "00000100110101001110"; #endif /* GNSS_SDR_GPS_L5_H_ */ diff --git a/src/core/system_parameters/gnss_synchro.h b/src/core/system_parameters/gnss_synchro.h index 267df4557..8f4c4d880 100644 --- a/src/core/system_parameters/gnss_synchro.h +++ b/src/core/system_parameters/gnss_synchro.h @@ -50,7 +50,7 @@ public: double Acq_delay_samples; //!< Set by Acquisition processing block double Acq_doppler_hz; //!< Set by Acquisition processing block unsigned long int Acq_samplestamp_samples; //!< Set by Acquisition processing block - bool Flag_valid_acquisition; //!< Set by Acquisition processing block + bool Flag_valid_acquisition = false; //!< Set by Acquisition processing block //Tracking long int fs; //!< Set by Tracking processing block double Prompt_I; //!< Set by Tracking processing block @@ -61,17 +61,17 @@ public: double Code_phase_samples; //!< Set by Tracking processing block unsigned long int Tracking_sample_counter; //!< Set by Tracking processing block - bool Flag_valid_symbol_output; //!< Set by Tracking processing block - int correlation_length_ms; //!< Set by Tracking processing block + bool Flag_valid_symbol_output = false; //!< Set by Tracking processing block + int correlation_length_ms; //!< Set by Tracking processing block //Telemetry Decoder - bool Flag_valid_word; //!< Set by Telemetry Decoder processing block + bool Flag_valid_word = false; //!< Set by Telemetry Decoder processing block double TOW_at_current_symbol_s; //!< Set by Telemetry Decoder processing block // Observables - double Pseudorange_m; //!< Set by Observables processing block - double RX_time; //!< Set by Observables processing block - bool Flag_valid_pseudorange; //!< Set by Observables processing block + double Pseudorange_m; //!< Set by Observables processing block + double RX_time; //!< Set by Observables processing block + bool Flag_valid_pseudorange = false; //!< Set by Observables processing block }; #endif