From 7d2420347293fb91efa5b6d28b549cbb504b570f Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 8 Nov 2019 18:37:56 +0100 Subject: [PATCH 1/5] Apply new interface of dll_nc_e_minus_l_normalized --- .../gnuradio_blocks/dll_pll_veml_tracking.cc | 20 +++++++++++++++++-- .../dll_pll_veml_tracking_fpga.cc | 15 +++++++++++++- ...glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc | 2 +- ...glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc | 2 +- .../glonass_l1_ca_dll_pll_tracking_cc.cc | 2 +- ...glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc | 2 +- ...glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc | 2 +- .../glonass_l2_ca_dll_pll_tracking_cc.cc | 2 +- .../gps_l1_ca_dll_pll_tracking_gpu_cc.cc | 2 +- .../gps_l1_ca_kf_tracking_cc.cc | 2 +- src/algorithms/tracking/libs/dll_pll_conf.cc | 2 ++ src/algorithms/tracking/libs/dll_pll_conf.h | 2 ++ .../tracking/libs/dll_pll_conf_fpga.cc | 2 ++ .../tracking/libs/dll_pll_conf_fpga.h | 2 ++ 14 files changed, 48 insertions(+), 11 deletions(-) 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 1dabf6b84..06c4916ee 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -145,6 +145,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl // GPS L1 C/A does not have pilot component nor secondary code d_secondary = false; trk_parameters.track_pilot = false; + trk_parameters.slope = 1.0; + trk_parameters.spc = trk_parameters.early_late_space_chips; // symbol integration: 20 trk symbols (20 ms) = 1 tlm bit // set the preamble in the secondary code acquisition to obtain tlm symbol synchronization d_secondary_code_length = static_cast(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); @@ -164,6 +166,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl // GPS L2 does not have pilot component nor secondary code d_secondary = false; trk_parameters.track_pilot = false; + trk_parameters.slope = 1.0; + trk_parameters.spc = trk_parameters.early_late_space_chips; } else if (signal_type == "L5") { @@ -176,6 +180,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_code_samples_per_chip = 1; d_code_length_chips = static_cast(GPS_L5I_CODE_LENGTH_CHIPS); d_secondary = true; + trk_parameters.slope = 1.0; + trk_parameters.spc = trk_parameters.early_late_space_chips; if (trk_parameters.track_pilot) { // synchronize pilot secondary code @@ -224,6 +230,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl 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; + trk_parameters.slope = 3.0; + trk_parameters.spc = trk_parameters.early_late_space_chips; if (trk_parameters.track_pilot) { d_secondary = true; @@ -248,6 +256,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_code_samples_per_chip = 1; d_code_length_chips = static_cast(GALILEO_E5A_CODE_LENGTH_CHIPS); d_secondary = true; + trk_parameters.slope = 1.0; + trk_parameters.spc = trk_parameters.early_late_space_chips; if (trk_parameters.track_pilot) { // synchronize pilot secondary code @@ -294,6 +304,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_code_samples_per_chip = 1; d_secondary = true; trk_parameters.track_pilot = false; + trk_parameters.slope = 1.0; + trk_parameters.spc = trk_parameters.early_late_space_chips; // synchronize and remove data secondary code d_secondary_code_length = static_cast(BEIDOU_B1I_SECONDARY_CODE_LENGTH); d_secondary_code_string = const_cast(&BEIDOU_B1I_SECONDARY_CODE_STR); @@ -312,6 +324,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_code_samples_per_chip = 1; d_secondary = false; trk_parameters.track_pilot = false; + trk_parameters.slope = 1.0; + trk_parameters.spc = trk_parameters.early_late_space_chips; d_secondary_code_length = static_cast(BEIDOU_B3I_SECONDARY_CODE_LENGTH); d_secondary_code_string = const_cast(&BEIDOU_B3I_SECONDARY_CODE_STR); d_data_secondary_code_length = static_cast(BEIDOU_B3I_SECONDARY_CODE_LENGTH); @@ -976,7 +990,7 @@ void dll_pll_veml_tracking::run_dll_pll() } else { - d_code_error_chips = dll_nc_e_minus_l_normalized(d_E_accu, d_L_accu); // [chips/Ti] + d_code_error_chips = dll_nc_e_minus_l_normalized(d_E_accu, d_L_accu, trk_parameters.spc, trk_parameters.slope); // [chips/Ti] } // Code discriminator filter d_code_error_filt_chips = d_code_loop_filter.apply(d_code_error_chips); // [chips/second] @@ -1632,7 +1646,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) d_E_accu = *d_Early; d_P_accu = *d_Prompt; d_L_accu = *d_Late; - + trk_parameters.spc = trk_parameters.early_late_space_chips; // fail-safe: check if the secondary code or bit synchronization has not succeeded in a limited time period if (trk_parameters.bit_synchronization_time_limit_s < (d_sample_counter - d_acq_sample_stamp) / static_cast(trk_parameters.fs_in)) { @@ -1733,11 +1747,13 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) d_local_code_shift_chips[1] = -trk_parameters.early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[3] = trk_parameters.early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[4] = trk_parameters.very_early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); + trk_parameters.spc = trk_parameters.early_late_space_narrow_chips; } else { d_local_code_shift_chips[0] = -trk_parameters.early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[2] = trk_parameters.early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); + trk_parameters.spc = trk_parameters.early_late_space_narrow_chips; } } else diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc index 0e91a47de..350032d83 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc @@ -140,6 +140,8 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & // GPS L1 C/A does not have pilot component nor secondary code d_secondary = false; trk_parameters.track_pilot = false; + trk_parameters.slope = 1.0; + trk_parameters.spc = trk_parameters.early_late_space_chips; // symbol integration: 20 trk symbols (20 ms) = 1 tlm bit // set the preamble in the secondary code acquisition to obtain tlm symbol synchronization d_secondary_code_length = static_cast(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); @@ -154,6 +156,8 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & // GPS L2C has 1 trk symbol (20 ms) per tlm bit, no symbol integration required d_symbols_per_bit = GPS_L2_SAMPLES_PER_SYMBOL; d_correlation_length_ms = 20; + trk_parameters.slope = 1.0; + trk_parameters.spc = trk_parameters.early_late_space_chips; // GPS L2 does not have pilot component nor secondary code d_secondary = false; trk_parameters.track_pilot = false; @@ -167,6 +171,8 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & d_symbols_per_bit = GPS_L5_SAMPLES_PER_SYMBOL; d_correlation_length_ms = 1; d_secondary = true; + trk_parameters.slope = 1.0; + trk_parameters.spc = trk_parameters.early_late_space_chips; if (d_extended_correlation_in_fpga == true) { if (trk_parameters.extend_correlation_symbols > 1) @@ -218,6 +224,8 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & d_symbols_per_bit = 1; d_correlation_length_ms = 4; d_veml = true; + trk_parameters.slope = 3.0; + trk_parameters.spc = trk_parameters.early_late_space_chips; if (trk_parameters.track_pilot) { d_secondary = true; @@ -240,6 +248,8 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & d_symbols_per_bit = 20; d_correlation_length_ms = 1; d_secondary = true; + trk_parameters.slope = 1.0; + trk_parameters.spc = trk_parameters.early_late_space_chips; if (d_extended_correlation_in_fpga == true) { if (trk_parameters.extend_correlation_symbols > 1) @@ -729,7 +739,7 @@ void dll_pll_veml_tracking_fpga::run_dll_pll() } else { - d_code_error_chips = dll_nc_e_minus_l_normalized(d_E_accu, d_L_accu); // [chips/Ti] + d_code_error_chips = dll_nc_e_minus_l_normalized(d_E_accu, d_L_accu, trk_parameters.spc, trk_parameters.slope); // [chips/Ti] } // Code discriminator filter d_code_error_filt_chips = d_code_loop_filter.apply(d_code_error_chips); // [chips/second] @@ -1592,6 +1602,7 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un d_E_accu = *d_Early; d_P_accu = *d_Prompt; d_L_accu = *d_Late; + trk_parameters.spc = trk_parameters.early_late_space_chips; // fail-safe: check if the secondary code or bit synchronization has not succeeded in a limited time period if (trk_parameters.bit_synchronization_time_limit_s < (d_sample_counter - d_acq_sample_stamp) / static_cast(trk_parameters.fs_in)) @@ -1734,11 +1745,13 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un d_local_code_shift_chips[1] = -trk_parameters.early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[3] = trk_parameters.early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[4] = trk_parameters.very_early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); + trk_parameters.spc = trk_parameters.early_late_space_narrow_chips; } else { d_local_code_shift_chips[0] = -trk_parameters.early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[2] = trk_parameters.early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); + trk_parameters.spc = trk_parameters.early_late_space_narrow_chips; } } else diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc index e87e15d23..54bf7188d 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -708,7 +708,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at // ################## DLL ########################################################## // DLL discriminator - d_code_error_chips_Ti = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); // [chips/Ti] //early and late + d_code_error_chips_Ti = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2], d_early_late_spc_chips, 1.0); // [chips/Ti] //early and late // Code discriminator filter d_code_error_filt_chips_s = d_code_loop_filter.get_code_nco(d_code_error_chips_Ti); // input [chips/Ti] -> output [chips/second] d_code_error_filt_chips_Ti = d_code_error_filt_chips_s * CURRENT_INTEGRATION_TIME_S; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc index cd712c5b6..390f93c7c 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc @@ -705,7 +705,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at // ################## DLL ########################################################## // DLL discriminator - d_code_error_chips_Ti = dll_nc_e_minus_l_normalized(std::complex(d_correlator_outs_16sc[0].real(), d_correlator_outs_16sc[0].imag()), std::complex(d_correlator_outs_16sc[2].real(), d_correlator_outs_16sc[2].imag())); // [chips/Ti] //early and late + d_code_error_chips_Ti = dll_nc_e_minus_l_normalized(std::complex(d_correlator_outs_16sc[0].real(), d_correlator_outs_16sc[0].imag()), std::complex(d_correlator_outs_16sc[2].real(), d_correlator_outs_16sc[2].imag()), d_early_late_spc_chips, 1.0); // [chips/Ti] //early and late // Code discriminator filter d_code_error_filt_chips_s = d_code_loop_filter.get_code_nco(d_code_error_chips_Ti); // input [chips/Ti] -> output [chips/second] d_code_error_filt_chips_Ti = d_code_error_filt_chips_s * CURRENT_INTEGRATION_TIME_S; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc index ac1ad9a91..fd235c659 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc @@ -567,7 +567,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut // ################## DLL ########################################################## // DLL discriminator - code_error_chips = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); // [chips/Ti] //early and late + code_error_chips = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2], d_early_late_spc_chips, 1.0); // [chips/Ti] //early and late // Code discriminator filter code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); // [chips/second] double T_chip_seconds = 1.0 / static_cast(d_code_freq_chips); diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc index 1e8445b73..818f2da78 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc @@ -704,7 +704,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at // ################## DLL ########################################################## // DLL discriminator - d_code_error_chips_Ti = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); // [chips/Ti] //early and late + d_code_error_chips_Ti = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2], d_early_late_spc_chips, 1.0); // [chips/Ti] //early and late // Code discriminator filter d_code_error_filt_chips_s = d_code_loop_filter.get_code_nco(d_code_error_chips_Ti); // input [chips/Ti] -> output [chips/second] d_code_error_filt_chips_Ti = d_code_error_filt_chips_s * CURRENT_INTEGRATION_TIME_S; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc index 4a8609aa5..47cbbae5b 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc @@ -703,7 +703,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at // ################## DLL ########################################################## // DLL discriminator - d_code_error_chips_Ti = dll_nc_e_minus_l_normalized(std::complex(d_correlator_outs_16sc[0].real(), d_correlator_outs_16sc[0].imag()), std::complex(d_correlator_outs_16sc[2].real(), d_correlator_outs_16sc[2].imag())); // [chips/Ti] //early and late + d_code_error_chips_Ti = dll_nc_e_minus_l_normalized(std::complex(d_correlator_outs_16sc[0].real(), d_correlator_outs_16sc[0].imag()), std::complex(d_correlator_outs_16sc[2].real(), d_correlator_outs_16sc[2].imag()), d_early_late_spc_chips, 1.0); // [chips/Ti] //early and late // Code discriminator filter d_code_error_filt_chips_s = d_code_loop_filter.get_code_nco(d_code_error_chips_Ti); // input [chips/Ti] -> output [chips/second] d_code_error_filt_chips_Ti = d_code_error_filt_chips_s * CURRENT_INTEGRATION_TIME_S; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc index 53d6a2d81..a2f5b8caa 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc @@ -567,7 +567,7 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut // ################## DLL ########################################################## // DLL discriminator - code_error_chips = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); // [chips/Ti] //early and late + code_error_chips = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2], d_early_late_spc_chips, 1.0); // [chips/Ti] //early and late // Code discriminator filter code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); // [chips/second] double T_chip_seconds = 1.0 / static_cast(d_code_freq_chips); diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc index 09e7c4f0b..45f20c898 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc @@ -384,7 +384,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work(int noutput_items __attribut // ################## DLL ########################################################## // DLL discriminator - code_error_chips_Ti = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); // [chips/Ti] // early and late + code_error_chips_Ti = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2], d_early_late_spc_chips, 1.0); // [chips/Ti] // early and late // Code discriminator filter code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips_Ti); // input [chips/Ti] -> output [chips/second] code_error_filt_secs_Ti = code_error_filt_chips * CURRENT_INTEGRATION_TIME_S / d_code_freq_chips; // [s/Ti] diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.cc index c0ab52ddc..62ec9644b 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.cc @@ -748,7 +748,7 @@ int Gps_L1_Ca_Kf_Tracking_cc::general_work(int noutput_items __attribute__((unus // New code Doppler frequency estimation based on carrier frequency estimation d_code_freq_chips = GPS_L1_CA_CODE_RATE_CPS + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_CPS) / GPS_L1_FREQ_HZ); // DLL discriminator - code_error_chips = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); // [chips/Ti] early and late + code_error_chips = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2], d_early_late_spc_chips, 1.0); // [chips/Ti] early and late // Code discriminator filter code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); // [chips/second] double T_chip_seconds = 1.0 / static_cast(d_code_freq_chips); diff --git a/src/algorithms/tracking/libs/dll_pll_conf.cc b/src/algorithms/tracking/libs/dll_pll_conf.cc index 1cf6569ca..7027bb522 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf.cc +++ b/src/algorithms/tracking/libs/dll_pll_conf.cc @@ -61,6 +61,8 @@ Dll_Pll_Conf::Dll_Pll_Conf() very_early_late_space_chips = 0.5; early_late_space_narrow_chips = 0.1; very_early_late_space_narrow_chips = 0.1; + slope = 1.0; + spc = 0.5; extend_correlation_symbols = 5; cn0_samples = FLAGS_cn0_samples; cn0_smoother_samples = 200; diff --git a/src/algorithms/tracking/libs/dll_pll_conf.h b/src/algorithms/tracking/libs/dll_pll_conf.h index 9b2b6a773..b36efda26 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf.h +++ b/src/algorithms/tracking/libs/dll_pll_conf.h @@ -63,6 +63,8 @@ public: float very_early_late_space_chips; float early_late_space_narrow_chips; float very_early_late_space_narrow_chips; + float slope; + float spc; int32_t extend_correlation_symbols; bool high_dyn; int32_t cn0_samples; diff --git a/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc b/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc index 7d1361a4e..36682e927 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc +++ b/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc @@ -63,6 +63,8 @@ Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga() very_early_late_space_chips = 0.5; early_late_space_narrow_chips = 0.1; very_early_late_space_narrow_chips = 0.1; + slope = 1.0; + spc = 0.5; extend_correlation_symbols = 5; cn0_samples = FLAGS_cn0_samples; cn0_smoother_samples = 200; diff --git a/src/algorithms/tracking/libs/dll_pll_conf_fpga.h b/src/algorithms/tracking/libs/dll_pll_conf_fpga.h index dcc3f9847..545e82c36 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf_fpga.h +++ b/src/algorithms/tracking/libs/dll_pll_conf_fpga.h @@ -67,6 +67,8 @@ public: float very_early_late_space_chips; float early_late_space_narrow_chips; float very_early_late_space_narrow_chips; + float slope; + float spc; int32_t extend_correlation_symbols; bool high_dyn; int32_t cn0_samples; From bb8416402c6ed728d7e71dd8d42c3e30aa65c595 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 7 Feb 2020 10:58:33 +0100 Subject: [PATCH 2/5] Fix normalization in dll_nc_e_minus_l_normalized discriminator (see #333) --- .../gnuradio_blocks/dll_pll_veml_tracking.cc | 21 +- .../dll_pll_veml_tracking_fpga.cc | 16 +- src/algorithms/tracking/libs/dll_pll_conf.cc | 1 + src/algorithms/tracking/libs/dll_pll_conf.h | 1 + .../tracking/libs/dll_pll_conf_fpga.cc | 1 + .../tracking/libs/dll_pll_conf_fpga.h | 1 + .../tracking/libs/tracking_discriminators.cc | 5 +- .../tracking/libs/tracking_discriminators.h | 90 ++++++++- src/tests/test_main.cc | 4 +- .../tracking/discriminator_test.cc | 189 ++++++++++++++++++ 10 files changed, 320 insertions(+), 9 deletions(-) create mode 100644 src/tests/unit-tests/signal-processing-blocks/tracking/discriminator_test.cc 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 06c4916ee..8f2506c50 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -147,6 +147,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl trk_parameters.track_pilot = false; trk_parameters.slope = 1.0; trk_parameters.spc = trk_parameters.early_late_space_chips; + trk_parameters.y_intercept = 1.0; // symbol integration: 20 trk symbols (20 ms) = 1 tlm bit // set the preamble in the secondary code acquisition to obtain tlm symbol synchronization d_secondary_code_length = static_cast(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); @@ -168,6 +169,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl trk_parameters.track_pilot = false; trk_parameters.slope = 1.0; trk_parameters.spc = trk_parameters.early_late_space_chips; + trk_parameters.y_intercept = 1.0; } else if (signal_type == "L5") { @@ -182,6 +184,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_secondary = true; trk_parameters.slope = 1.0; trk_parameters.spc = trk_parameters.early_late_space_chips; + trk_parameters.y_intercept = 1.0; if (trk_parameters.track_pilot) { // synchronize pilot secondary code @@ -230,8 +233,9 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl 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; - trk_parameters.slope = 3.0; trk_parameters.spc = trk_parameters.early_late_space_chips; + trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); if (trk_parameters.track_pilot) { d_secondary = true; @@ -258,6 +262,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_secondary = true; trk_parameters.slope = 1.0; trk_parameters.spc = trk_parameters.early_late_space_chips; + trk_parameters.y_intercept = 1.0; if (trk_parameters.track_pilot) { // synchronize pilot secondary code @@ -306,6 +311,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl trk_parameters.track_pilot = false; trk_parameters.slope = 1.0; trk_parameters.spc = trk_parameters.early_late_space_chips; + trk_parameters.y_intercept = 1.0; // synchronize and remove data secondary code d_secondary_code_length = static_cast(BEIDOU_B1I_SECONDARY_CODE_LENGTH); d_secondary_code_string = const_cast(&BEIDOU_B1I_SECONDARY_CODE_STR); @@ -326,6 +332,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl trk_parameters.track_pilot = false; trk_parameters.slope = 1.0; trk_parameters.spc = trk_parameters.early_late_space_chips; + trk_parameters.y_intercept = 1.0; d_secondary_code_length = static_cast(BEIDOU_B3I_SECONDARY_CODE_LENGTH); d_secondary_code_string = const_cast(&BEIDOU_B3I_SECONDARY_CODE_STR); d_data_secondary_code_length = static_cast(BEIDOU_B3I_SECONDARY_CODE_LENGTH); @@ -990,7 +997,7 @@ void dll_pll_veml_tracking::run_dll_pll() } else { - d_code_error_chips = dll_nc_e_minus_l_normalized(d_E_accu, d_L_accu, trk_parameters.spc, trk_parameters.slope); // [chips/Ti] + d_code_error_chips = dll_nc_e_minus_l_normalized(d_E_accu, d_L_accu, trk_parameters.spc, trk_parameters.slope, trk_parameters.y_intercept); // [chips/Ti] } // Code discriminator filter d_code_error_filt_chips = d_code_loop_filter.apply(d_code_error_chips); // [chips/second] @@ -1647,6 +1654,11 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) d_P_accu = *d_Prompt; d_L_accu = *d_Late; trk_parameters.spc = trk_parameters.early_late_space_chips; + if (std::string(trk_parameters.signal) == "E1") + { + trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + } // fail-safe: check if the secondary code or bit synchronization has not succeeded in a limited time period if (trk_parameters.bit_synchronization_time_limit_s < (d_sample_counter - d_acq_sample_stamp) / static_cast(trk_parameters.fs_in)) { @@ -1748,6 +1760,11 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) d_local_code_shift_chips[3] = trk_parameters.early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[4] = trk_parameters.very_early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); trk_parameters.spc = trk_parameters.early_late_space_narrow_chips; + if (std::string(trk_parameters.signal) == "E1") + { + trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + } } else { diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc index 350032d83..4ba8a1a17 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc @@ -142,6 +142,7 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & trk_parameters.track_pilot = false; trk_parameters.slope = 1.0; trk_parameters.spc = trk_parameters.early_late_space_chips; + trk_parameters.y_intercept = 1.0; // symbol integration: 20 trk symbols (20 ms) = 1 tlm bit // set the preamble in the secondary code acquisition to obtain tlm symbol synchronization d_secondary_code_length = static_cast(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); @@ -158,6 +159,7 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & d_correlation_length_ms = 20; trk_parameters.slope = 1.0; trk_parameters.spc = trk_parameters.early_late_space_chips; + trk_parameters.y_intercept = 1.0; // GPS L2 does not have pilot component nor secondary code d_secondary = false; trk_parameters.track_pilot = false; @@ -173,6 +175,7 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & d_secondary = true; trk_parameters.slope = 1.0; trk_parameters.spc = trk_parameters.early_late_space_chips; + trk_parameters.y_intercept = 1.0; if (d_extended_correlation_in_fpga == true) { if (trk_parameters.extend_correlation_symbols > 1) @@ -224,8 +227,9 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & d_symbols_per_bit = 1; d_correlation_length_ms = 4; d_veml = true; - trk_parameters.slope = 3.0; trk_parameters.spc = trk_parameters.early_late_space_chips; + trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); if (trk_parameters.track_pilot) { d_secondary = true; @@ -250,6 +254,7 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & d_secondary = true; trk_parameters.slope = 1.0; trk_parameters.spc = trk_parameters.early_late_space_chips; + trk_parameters.y_intercept = 1.0; if (d_extended_correlation_in_fpga == true) { if (trk_parameters.extend_correlation_symbols > 1) @@ -739,7 +744,7 @@ void dll_pll_veml_tracking_fpga::run_dll_pll() } else { - d_code_error_chips = dll_nc_e_minus_l_normalized(d_E_accu, d_L_accu, trk_parameters.spc, trk_parameters.slope); // [chips/Ti] + d_code_error_chips = dll_nc_e_minus_l_normalized(d_E_accu, d_L_accu, trk_parameters.spc, trk_parameters.slope, trk_parameters.y_intercept); // [chips/Ti] } // Code discriminator filter d_code_error_filt_chips = d_code_loop_filter.apply(d_code_error_chips); // [chips/second] @@ -1603,6 +1608,11 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un d_P_accu = *d_Prompt; d_L_accu = *d_Late; trk_parameters.spc = trk_parameters.early_late_space_chips; + if (std::string(trk_parameters.signal) == "E1") + { + trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + } // fail-safe: check if the secondary code or bit synchronization has not succeeded in a limited time period if (trk_parameters.bit_synchronization_time_limit_s < (d_sample_counter - d_acq_sample_stamp) / static_cast(trk_parameters.fs_in)) @@ -1746,6 +1756,8 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un d_local_code_shift_chips[3] = trk_parameters.early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[4] = trk_parameters.very_early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); trk_parameters.spc = trk_parameters.early_late_space_narrow_chips; + trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); } else { diff --git a/src/algorithms/tracking/libs/dll_pll_conf.cc b/src/algorithms/tracking/libs/dll_pll_conf.cc index 7027bb522..dcc0194d7 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf.cc +++ b/src/algorithms/tracking/libs/dll_pll_conf.cc @@ -63,6 +63,7 @@ Dll_Pll_Conf::Dll_Pll_Conf() very_early_late_space_narrow_chips = 0.1; slope = 1.0; spc = 0.5; + y_intercept = 1.0; extend_correlation_symbols = 5; cn0_samples = FLAGS_cn0_samples; cn0_smoother_samples = 200; diff --git a/src/algorithms/tracking/libs/dll_pll_conf.h b/src/algorithms/tracking/libs/dll_pll_conf.h index b36efda26..ef9eb8495 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf.h +++ b/src/algorithms/tracking/libs/dll_pll_conf.h @@ -65,6 +65,7 @@ public: float very_early_late_space_narrow_chips; float slope; float spc; + float y_intercept; int32_t extend_correlation_symbols; bool high_dyn; int32_t cn0_samples; diff --git a/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc b/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc index 36682e927..f806332d7 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc +++ b/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc @@ -65,6 +65,7 @@ Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga() very_early_late_space_narrow_chips = 0.1; slope = 1.0; spc = 0.5; + y_intercept = 1.0; extend_correlation_symbols = 5; cn0_samples = FLAGS_cn0_samples; cn0_smoother_samples = 200; diff --git a/src/algorithms/tracking/libs/dll_pll_conf_fpga.h b/src/algorithms/tracking/libs/dll_pll_conf_fpga.h index 545e82c36..8097a6c71 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf_fpga.h +++ b/src/algorithms/tracking/libs/dll_pll_conf_fpga.h @@ -69,6 +69,7 @@ public: float very_early_late_space_narrow_chips; float slope; float spc; + float y_intercept; int32_t extend_correlation_symbols; bool high_dyn; int32_t cn0_samples; diff --git a/src/algorithms/tracking/libs/tracking_discriminators.cc b/src/algorithms/tracking/libs/tracking_discriminators.cc index 6c5e9dbb5..718216713 100644 --- a/src/algorithms/tracking/libs/tracking_discriminators.cc +++ b/src/algorithms/tracking/libs/tracking_discriminators.cc @@ -34,7 +34,6 @@ #include "tracking_discriminators.h" #include "MATH_CONSTANTS.h" -#include // All the outputs are in RADIANS @@ -130,7 +129,7 @@ double pll_cloop_two_quadrant_atan(gr_complex prompt_s1) * where \f$E=\sqrt{I_{ES}^2+Q_{ES}^2}\f$ is the Early correlator output absolute value and * \f$L=\sqrt{I_{LS}^2+Q_{LS}^2}\f$ is the Late correlator output absolute value. The output is in [chips]. */ -double dll_nc_e_minus_l_normalized(gr_complex early_s1, gr_complex late_s1) +double dll_nc_e_minus_l_normalized(gr_complex early_s1, gr_complex late_s1, float spc, float slope, float y_intercept) { double P_early = std::abs(early_s1); double P_late = std::abs(late_s1); @@ -139,7 +138,7 @@ double dll_nc_e_minus_l_normalized(gr_complex early_s1, gr_complex late_s1) { return 0.0; } - return 0.5 * (P_early - P_late) / E_plus_L; + return ((y_intercept - slope * spc) / slope) * (P_early - P_late) / E_plus_L; } diff --git a/src/algorithms/tracking/libs/tracking_discriminators.h b/src/algorithms/tracking/libs/tracking_discriminators.h index 350d31fd6..0d0a82274 100644 --- a/src/algorithms/tracking/libs/tracking_discriminators.h +++ b/src/algorithms/tracking/libs/tracking_discriminators.h @@ -39,6 +39,7 @@ #define GNSS_SDR_TRACKING_DISCRIMINATORS_H_ #include +#include /*! brief FLL four quadrant arctan discriminator * @@ -99,7 +100,7 @@ double pll_cloop_two_quadrant_atan(gr_complex prompt_s1); * where \f$E=\sqrt{I_{ES}^2+Q_{ES}^2}\f$ is the Early correlator output absolute value and * \f$L=\sqrt{I_{LS}^2+Q_{LS}^2}\f$ is the Late correlator output absolute value. The output is in [chips]. */ -double dll_nc_e_minus_l_normalized(gr_complex early_s1, gr_complex late_s1); +double dll_nc_e_minus_l_normalized(gr_complex early_s1, gr_complex late_s1, float spc = 0.5, float slope = 1.0, float y_intercept = 1.0); /*! \brief DLL Noncoherent Very Early Minus Late Power (VEMLP) normalized discriminator @@ -115,4 +116,91 @@ double dll_nc_e_minus_l_normalized(gr_complex early_s1, gr_complex late_s1); double dll_nc_vemlp_normalized(gr_complex very_early_s1, gr_complex early_s1, gr_complex late_s1, gr_complex very_late_s1); +template +double CalculateSlope(Fun &&f, double x) +{ + static constexpr double dx = 1e-6; + + return (f(x + dx / 2.0) - f(x - dx / 2.0)) / dx; +} + +template +double CalculateSlopeAbs(Fun &&f, double x) +{ + static constexpr double dx = 1e-6; + + return (std::abs(f(x + dx / 2.0)) - std::abs(f(x - dx / 2.0))) / dx; +} + +template +double GetYIntercept(Fun &&f, double x) +{ + double slope = CalculateSlope(f, x); + double y1 = f(x); + + return y1 - slope * x; +} + +template +double GetYInterceptAbs(Fun &&f, double x) +{ + double slope = CalculateSlopeAbs(f, x); + double y1 = std::abs(f(x)); + return y1 - slope * x; +} + +// SinBocCorrelationFunction and CosBocCorrelationFunction from +// Sousa, F. and Nunes, F., "New Expressions for the Autocorrelation +// Function of BOC GNSS Signals", NAVIGATION - Journal of the Institute +// of Navigation, March 2013. +// +template +double SinBocCorrelationFunction(double offset_in_chips) +{ + static constexpr int TWO_P = 2 * M / N; + + double abs_tau = std::abs(offset_in_chips); + + if (abs_tau > 1.0) + { + return 0.0; + } + + int k = static_cast(std::ceil(TWO_P * abs_tau)); + + double sgn = ((k & 0x01) == 0 ? 1.0 : -1.0); // (-1)^k + + return sgn * (2.0 * (k * k - k * TWO_P - k) / TWO_P + 1.0 + + (2 * TWO_P - 2 * k + 1) * abs_tau); +} + + +template +double CosBocCorrelationFunction(double offset_in_chips) +{ + static constexpr int TWO_P = 2 * M / N; + + double abs_tau = std::abs(offset_in_chips); + + if (abs_tau > 1.0) + { + return 0.0; + } + + int k = static_cast(std::floor(2.0 * TWO_P * abs_tau)); + + if ((k & 0x01) == 0) // k is even + { + double sgn = ((k >> 1) & 0x01 ? -1.0 : 1.0); // (-1)^(k/2) + + return sgn * ((2 * k * TWO_P + 2 * TWO_P - k * k) / (2.0 * TWO_P) + (-2 * TWO_P + k - 1) * abs_tau); + } + else + { + double sgn = (((k + 1) >> 1) & 0x01 ? -1.0 : 1.0); // (-1)^((k+1)/2) + + return sgn * ((k * k + 2 * k - 2 * k * TWO_P + 1) / (2.0 * TWO_P) + (2 * TWO_P - k - 2) * abs_tau); + } +} + #endif diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index 64acede83..693750cc2 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -105,19 +105,21 @@ DECLARE_string(log_dir); #endif #include "unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc" #include "unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_test.cc" +#include "unit-tests/signal-processing-blocks/tracking/discriminator_test.cc" #include "unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc" + #if CUDA_BLOCKS_TEST #include "unit-tests/signal-processing-blocks/tracking/gpu_multicorrelator_test.cc" #endif #if FPGA_BLOCKS_TEST -#include "unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc" #include "unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc" +#include "unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc" #endif diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/discriminator_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/discriminator_test.cc new file mode 100644 index 000000000..d4c1086d4 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/discriminator_test.cc @@ -0,0 +1,189 @@ +/*! + * \file discriminator_test.cc + * \brief This file implements tests for the tracking discriminators + * \author Cillian O'Driscoll, 2019. cillian.odriscoll(at)gmail.com + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "tracking_discriminators.h" +#include +#include +//#include +#include + +double BpskCorrelationFunction(double offset_in_chips) +{ + double abs_tau = std::abs(offset_in_chips); + + if (abs_tau > 1.0) + { + return 0.0; + } + return 1.0 - abs_tau; +} + + +TEST(DllNcEMinusLNormalizedTest, Bpsk) +{ + std::vector complex_amplitude_vector = {{1.0, 0.0}, {-1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}}; + std::vector spacing_vector = {0.5, 0.25, 0.1, 0.01}; + std::vector error_vector = {0.0, 0.01, 0.1, 0.25, -0.25, -0.1, -0.01}; + + for (auto A : complex_amplitude_vector) + { + for (auto spacing : spacing_vector) + { + for (auto err : error_vector) + { + gr_complex E = A * static_cast(BpskCorrelationFunction(err - spacing)); + gr_complex L = A * static_cast(BpskCorrelationFunction(err + spacing)); + + double disc_out = dll_nc_e_minus_l_normalized(E, L, spacing); + + if (std::abs(err) < 2.0 * spacing) + { + EXPECT_NEAR(disc_out, err, 1e-4) << " Spacing: " << spacing; + } + else + { + EXPECT_TRUE(err * disc_out >= 0.0); + } + + if (spacing != 0.5 and err != 0.0) + { + double disc_out_old = dll_nc_e_minus_l_normalized(E, L); + + EXPECT_NE(disc_out_old, err); + } + } + } + } +} + + +TEST(DllNcEMinusLNormalizedTest, SinBoc11) +{ + std::vector complex_amplitude_vector = {{1.0, 0.0}, {-1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}}; + std::vector spacing_vector = {0.75, 0.6666, 5.0 / 12.0, 0.25, 1.0 / 6.0, 0.01}; + std::vector error_vector = {0.0, 0.01, 0.1, 0.25, -0.25, -0.1, -0.01}; + + for (auto A : complex_amplitude_vector) + { + for (auto spacing : spacing_vector) + { + double corr_slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, spacing); + double y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, spacing); + + for (auto err : error_vector) + { + gr_complex E = A * static_cast(SinBocCorrelationFunction<1, 1>(err - spacing)); + gr_complex L = A * static_cast(SinBocCorrelationFunction<1, 1>(err + spacing)); + + double disc_out = dll_nc_e_minus_l_normalized(E, L, spacing, corr_slope, y_intercept); + double corr_slope_at_err = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, spacing + err); + double corr_slope_at_neg_err = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, spacing - err); + + bool in_linear_region = (std::abs(err) < spacing) and (std::abs(corr_slope_at_err - corr_slope_at_neg_err) < 0.01); + double norm_factor = (y_intercept - corr_slope * spacing) / spacing; + + if (in_linear_region) + { + EXPECT_NEAR(disc_out, err, 1e-4) << " Spacing: " << spacing << ", slope : " << corr_slope << ", y_intercept: " << y_intercept << ", norm: " << norm_factor << " E: " << E << ", L: " << L; + if (norm_factor != 0.5 and err != 0.0) + { + double disc_out_old = dll_nc_e_minus_l_normalized(E, L); + EXPECT_NE(disc_out_old, err) << " Spacing: " << spacing << ", slope : " << corr_slope << ", y_intercept: " << y_intercept << ", norm: " << norm_factor << " E: " << E << ", L: " << L; + } + } + } + } + } +} + + +TEST(CosBocCorrelationFunction, FixedPoints) +{ + double res = CosBocCorrelationFunction<1, 1>(0.0); + EXPECT_NEAR(res, 1.0, 1e-4); + res = CosBocCorrelationFunction<1, 1>(0.2); + EXPECT_NEAR(res, 0.0, 1e-4); + res = CosBocCorrelationFunction<1, 1>(0.25); + EXPECT_NEAR(res, -0.25, 1e-4); + res = CosBocCorrelationFunction<1, 1>(0.5); + EXPECT_NEAR(res, -0.5, 1e-4); + res = CosBocCorrelationFunction<1, 1>(0.75); + EXPECT_NEAR(res, 0.25, 1e-4); + res = CosBocCorrelationFunction<1, 1>(1.0); + EXPECT_NEAR(res, 0.0, 1e-4); + res = CosBocCorrelationFunction<1, 1>(-0.2); + EXPECT_NEAR(res, 0.0, 1e-4); + res = CosBocCorrelationFunction<1, 1>(-0.5); + EXPECT_NEAR(res, -0.5, 1e-4); + res = CosBocCorrelationFunction<1, 1>(-0.75); + EXPECT_NEAR(res, 0.25, 1e-4); + res = CosBocCorrelationFunction<1, 1>(-1.0); + EXPECT_NEAR(res, 0.0, 1e-4); +} + + +TEST(DllNcEMinusLNormalizedTest, CosBoc11) +{ + std::vector complex_amplitude_vector = {{1.0, 0.0}, {-1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}}; + std::vector spacing_vector = {0.875, 0.588, 0.1, 0.01}; + std::vector error_vector = {0.0, 0.01, 0.1, 0.25, -0.25, -0.1, -0.01}; + + for (auto A : complex_amplitude_vector) + { + for (auto spacing : spacing_vector) + { + double corr_slope = -CalculateSlopeAbs(&CosBocCorrelationFunction<1, 1>, spacing); + double y_intercept = GetYInterceptAbs(&CosBocCorrelationFunction<1, 1>, spacing); + for (auto err : error_vector) + { + gr_complex E = A * static_cast(CosBocCorrelationFunction<1, 1>(err - spacing)); + gr_complex L = A * static_cast(CosBocCorrelationFunction<1, 1>(err + spacing)); + + double disc_out = dll_nc_e_minus_l_normalized(E, L, spacing, corr_slope, y_intercept); + double corr_slope_at_err = -CalculateSlopeAbs(&CosBocCorrelationFunction<1, 1>, spacing + err); + double corr_slope_at_neg_err = -CalculateSlopeAbs(&CosBocCorrelationFunction<1, 1>, spacing - err); + + bool in_linear_region = (std::abs(err) < spacing) and (std::abs(corr_slope_at_err - corr_slope_at_neg_err) < 0.01); + double norm_factor = (y_intercept - corr_slope * spacing) / spacing; + + if (in_linear_region) + { + EXPECT_NEAR(disc_out, err, 1e-4) << " Spacing: " << spacing << ", slope : " << corr_slope << ", y_intercept: " << y_intercept << ", norm: " << norm_factor << " E: " << E << ", L: " << L; + if (norm_factor != 0.5 and err != 0.0) + { + double disc_out_old = dll_nc_e_minus_l_normalized(E, L); + EXPECT_NE(disc_out_old, err) << " Spacing: " << spacing << ", slope : " << corr_slope << ", y_intercept: " << y_intercept << ", norm: " << norm_factor << " E: " << E << ", L: " << L; + } + } + } + } + } +} From bdc8c71e315d228c208cc715035deb6691ba12b0 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 8 Feb 2020 18:39:21 +0100 Subject: [PATCH 3/5] Add SPDX license id in header --- .../tracking/discriminator_test.cc | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/discriminator_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/discriminator_test.cc index d4c1086d4..efdc5a220 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/discriminator_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/discriminator_test.cc @@ -13,18 +13,7 @@ * * This file is part of GNSS-SDR. * - * GNSS-SDR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNSS-SDR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . + * SPDX-License-Identifier: GPL-3.0-or-later * * ------------------------------------------------------------------------- */ @@ -32,7 +21,6 @@ #include "tracking_discriminators.h" #include #include -//#include #include double BpskCorrelationFunction(double offset_in_chips) From 52b9dfb8c058f85d3ca6d7e84f7f9010357323ec Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 13 Feb 2020 18:45:57 +0100 Subject: [PATCH 4/5] Do not add extra work for nothing --- .../gnuradio_blocks/dll_pll_veml_tracking.cc | 21 ++++++++++--------- .../dll_pll_veml_tracking_fpga.cc | 14 ++++++------- 2 files changed, 18 insertions(+), 17 deletions(-) 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 bd16fe9d3..3d159fd69 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -1643,11 +1643,12 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) d_P_accu = *d_Prompt; d_L_accu = *d_Late; trk_parameters.spc = trk_parameters.early_late_space_chips; - if (std::string(trk_parameters.signal) == "E1") - { - trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); - trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); - } + // if (std::string(trk_parameters.signal) == "E1") + // { + // trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + // trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + // } + // fail-safe: check if the secondary code or bit synchronization has not succeeded in a limited time period if (trk_parameters.bit_synchronization_time_limit_s < (d_sample_counter - d_acq_sample_stamp) / static_cast(trk_parameters.fs_in)) { @@ -1749,11 +1750,11 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) d_local_code_shift_chips[3] = trk_parameters.early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[4] = trk_parameters.very_early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); trk_parameters.spc = trk_parameters.early_late_space_narrow_chips; - if (std::string(trk_parameters.signal) == "E1") - { - trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); - trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); - } + // if (std::string(trk_parameters.signal) == "E1") + // { + // trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + // trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + // } } else { diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc index d2682bf10..c7f341d6f 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc @@ -1597,11 +1597,11 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un d_P_accu = *d_Prompt; d_L_accu = *d_Late; trk_parameters.spc = trk_parameters.early_late_space_chips; - if (std::string(trk_parameters.signal) == "E1") - { - trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); - trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); - } + // if (std::string(trk_parameters.signal) == "E1") + // { + // trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + // trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + // } // fail-safe: check if the secondary code or bit synchronization has not succeeded in a limited time period if (trk_parameters.bit_synchronization_time_limit_s < (d_sample_counter - d_acq_sample_stamp) / static_cast(trk_parameters.fs_in)) @@ -1745,8 +1745,8 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un d_local_code_shift_chips[3] = trk_parameters.early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[4] = trk_parameters.very_early_late_space_narrow_chips * static_cast(d_code_samples_per_chip); trk_parameters.spc = trk_parameters.early_late_space_narrow_chips; - trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); - trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + // trk_parameters.slope = -CalculateSlopeAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); + // trk_parameters.y_intercept = GetYInterceptAbs(&SinBocCorrelationFunction<1, 1>, trk_parameters.spc); } else { From d477c8ee280cdf724e76568ad3cdc91279cff36d Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 14 Feb 2020 19:00:42 +0100 Subject: [PATCH 5/5] Document change in discriminator implementation --- src/algorithms/tracking/libs/tracking_discriminators.cc | 2 +- src/algorithms/tracking/libs/tracking_discriminators.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms/tracking/libs/tracking_discriminators.cc b/src/algorithms/tracking/libs/tracking_discriminators.cc index ca54bd5b0..448e7713f 100644 --- a/src/algorithms/tracking/libs/tracking_discriminators.cc +++ b/src/algorithms/tracking/libs/tracking_discriminators.cc @@ -113,7 +113,7 @@ double pll_cloop_two_quadrant_atan(gr_complex prompt_s1) /* * DLL Noncoherent Early minus Late envelope normalized discriminator: * \f{equation} - * error=\frac{1}{2}\frac{E-L}{E+L}, + * error = \frac{y_{intercept} - \text{slope} * \epsilon}{\text{slope}} \frac{E-L}{E+L}, * \f} * where \f$E=\sqrt{I_{ES}^2+Q_{ES}^2}\f$ is the Early correlator output absolute value and * \f$L=\sqrt{I_{LS}^2+Q_{LS}^2}\f$ is the Late correlator output absolute value. The output is in [chips]. diff --git a/src/algorithms/tracking/libs/tracking_discriminators.h b/src/algorithms/tracking/libs/tracking_discriminators.h index a797ff863..fcba833b8 100644 --- a/src/algorithms/tracking/libs/tracking_discriminators.h +++ b/src/algorithms/tracking/libs/tracking_discriminators.h @@ -84,7 +84,7 @@ double pll_cloop_two_quadrant_atan(gr_complex prompt_s1); * * DLL Noncoherent Early minus Late envelope normalized discriminator: * \f{equation} - * error=\frac{E-L}{E+L}, + * error = \frac{y_{intercept} - \text{slope} * \epsilon}{\text{slope}} \frac{E-L}{E+L}, * \f} * where \f$E=\sqrt{I_{ES}^2+Q_{ES}^2}\f$ is the Early correlator output absolute value and * \f$L=\sqrt{I_{LS}^2+Q_{LS}^2}\f$ is the Late correlator output absolute value. The output is in [chips].