mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-14 20:20:35 +00:00
Fix normalization in dll_nc_e_minus_l_normalized discriminator (see #333)
This commit is contained in:
parent
7d24203472
commit
bb8416402c
@ -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<uint32_t>(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<uint32_t>(BEIDOU_B1I_SECONDARY_CODE_LENGTH);
|
||||
d_secondary_code_string = const_cast<std::string *>(&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<uint32_t>(BEIDOU_B3I_SECONDARY_CODE_LENGTH);
|
||||
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B3I_SECONDARY_CODE_STR);
|
||||
d_data_secondary_code_length = static_cast<uint32_t>(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<int>(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<float>(d_code_samples_per_chip);
|
||||
d_local_code_shift_chips[4] = trk_parameters.very_early_late_space_narrow_chips * static_cast<float>(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
|
||||
{
|
||||
|
@ -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<uint32_t>(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<int>(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<float>(d_code_samples_per_chip);
|
||||
d_local_code_shift_chips[4] = trk_parameters.very_early_late_space_narrow_chips * static_cast<float>(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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -34,7 +34,6 @@
|
||||
|
||||
#include "tracking_discriminators.h"
|
||||
#include "MATH_CONSTANTS.h"
|
||||
#include <cmath>
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
#define GNSS_SDR_TRACKING_DISCRIMINATORS_H_
|
||||
|
||||
#include <gnuradio/gr_complex.h>
|
||||
#include <cmath>
|
||||
|
||||
/*! 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 <typename Fun>
|
||||
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 <typename Fun>
|
||||
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 <typename Fun>
|
||||
double GetYIntercept(Fun &&f, double x)
|
||||
{
|
||||
double slope = CalculateSlope(f, x);
|
||||
double y1 = f(x);
|
||||
|
||||
return y1 - slope * x;
|
||||
}
|
||||
|
||||
template <typename Fun>
|
||||
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 <int M = 1, int N = M>
|
||||
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<int>(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 <int M = 1, int N = M>
|
||||
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<int>(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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "tracking_discriminators.h"
|
||||
#include <gtest/gtest.h>
|
||||
#include <cmath>
|
||||
//#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
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<gr_complex> complex_amplitude_vector = {{1.0, 0.0}, {-1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}};
|
||||
std::vector<double> spacing_vector = {0.5, 0.25, 0.1, 0.01};
|
||||
std::vector<double> 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<float>(BpskCorrelationFunction(err - spacing));
|
||||
gr_complex L = A * static_cast<float>(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<gr_complex> complex_amplitude_vector = {{1.0, 0.0}, {-1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}};
|
||||
std::vector<double> spacing_vector = {0.75, 0.6666, 5.0 / 12.0, 0.25, 1.0 / 6.0, 0.01};
|
||||
std::vector<double> 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<float>(SinBocCorrelationFunction<1, 1>(err - spacing));
|
||||
gr_complex L = A * static_cast<float>(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<gr_complex> complex_amplitude_vector = {{1.0, 0.0}, {-1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}};
|
||||
std::vector<double> spacing_vector = {0.875, 0.588, 0.1, 0.01};
|
||||
std::vector<double> 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<float>(CosBocCorrelationFunction<1, 1>(err - spacing));
|
||||
gr_complex L = A * static_cast<float>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user