1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-11-13 13:47:15 +00:00

Integrate unified block for DLL/PLL Tracking

This commit is contained in:
Carles Fernandez
2018-03-29 12:54:03 +02:00
33 changed files with 2891 additions and 735 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -53,7 +53,7 @@ void galileo_e1_code_gen_int(int* _dest, char _Signal[3], signed int _prn)
for (size_t i = 0; i < Galileo_E1_B_PRIMARY_CODE[prn].length(); i++)
{
hex_to_binary_converter(&_dest[index], Galileo_E1_B_PRIMARY_CODE[prn].at(i));
index = index + 4;
index += 4;
}
}
else if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2)
@@ -61,13 +61,9 @@ void galileo_e1_code_gen_int(int* _dest, char _Signal[3], signed int _prn)
for (size_t i = 0; i < Galileo_E1_C_PRIMARY_CODE[prn].length(); i++)
{
hex_to_binary_converter(&_dest[index], Galileo_E1_C_PRIMARY_CODE[prn].at(i));
index = index + 4;
index += 4;
}
}
else
{
return;
}
}
@@ -107,6 +103,18 @@ void galileo_e1_sinboc_61_gen_int(int* _dest, int* _prn, unsigned int _length_ou
}
}
void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], unsigned int _prn)
{
std::string _galileo_signal = _Signal;
unsigned int _codeLength = static_cast<unsigned int>(Galileo_E1_B_CODE_LENGTH_CHIPS);
int primary_code_E1_chips[4092]; // _codeLength not accepted by Clang
galileo_e1_code_gen_int(primary_code_E1_chips, _Signal, _prn); //generate Galileo E1 code, 1 sample per chip
for (unsigned int i = 0; i < _codeLength; i++)
{
_dest[2 * i] = static_cast<float>(primary_code_E1_chips[i]);
_dest[2 * i + 1] = -_dest[2 * i];
}
}
void galileo_e1_gen_float(float* _dest, int* _prn, char _Signal[3])
{
@@ -137,8 +145,6 @@ void galileo_e1_gen_float(float* _dest, int* _prn, char _Signal[3])
beta * static_cast<float>(sinboc_61[i]);
}
}
else
return;
}

View File

@@ -34,6 +34,11 @@
#include <complex>
/*!
* \brief This function generates Galileo E1 code (can select E1B or E1C sinboc).
*
*/
void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], unsigned int _prn);
/*!
* \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc

View File

@@ -71,6 +71,23 @@ void gps_l2c_m_code_gen_complex(std::complex<float>* _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<float>(_code[i]);
}
delete[] _code;
}
/*
* Generates complex GPS L2C M code for the desired SV ID and sampled to specific sampling frequency

View File

@@ -38,7 +38,7 @@
//!Generates complex GPS L2C M code for the desired SV ID
void gps_l2c_m_code_gen_complex(std::complex<float>* _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<float>* _dest, unsigned int _prn, signed int _fs);

View File

@@ -197,6 +197,22 @@ void gps_l5i_code_gen_complex(std::complex<float>* _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<float>(_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<float>* _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<float>(_code[i]);
}
delete[] _code;
}
/*
* Generates complex GPS L5i code for the desired SV ID and sampled to specific sampling frequency
*/

View File

@@ -38,9 +38,11 @@
//!Generates complex GPS L5i M code for the desired SV ID
void gps_l5i_code_gen_complex(std::complex<float>* _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<float>* _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<float>* _dest, unsigned int _prn, signed int _fs);

View File

@@ -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)

View File

@@ -42,8 +42,7 @@
#include <utility>
#include <vector>
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<double> sym_hist;
bool sync_NH;
bool new_sym;

View File

@@ -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", false);
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<float>(FLAGS_pll_bw_hz);
@@ -94,22 +92,44 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking(
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";
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_;
}

View File

@@ -39,6 +39,7 @@
#include "tracking_interface.h"
#include "galileo_e1_dll_pll_veml_tracking_cc.h"
#include "dll_pll_veml_tracking.h"
#include <string>
@@ -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_

View File

@@ -52,41 +52,64 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking(
//################# CONFIGURATION PARAMETERS ########################
int fs_in;
int vector_length;
int f_if;
bool dump;
std::string dump_filename;
std::string item_type;
std::string default_item_type = "gr_complex";
float pll_bw_hz;
float dll_bw_hz;
float early_late_space_chips;
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", 50.0);
unified_ = configuration->property(role + ".unified", false);
float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0);
if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz);
dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0);
float pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 20.0);
float dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 2.0);
float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0);
if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast<float>(FLAGS_dll_bw_hz);
early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5);
float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5);
float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.5);
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";
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,
early_late_space_chips,
early_late_space_narrow_chips,
early_late_space_narrow_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_;
}

View File

@@ -40,6 +40,7 @@
#include "tracking_interface.h"
#include "gps_l1_ca_dll_pll_tracking_cc.h"
#include "dll_pll_veml_tracking.h"
#include <string>
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_

View File

@@ -19,7 +19,7 @@
if(ENABLE_CUDA)
set(OPT_TRACKING_BLOCKS ${OPT_TRACKING_BLOCKS} gps_l1_ca_dll_pll_tracking_gpu_cc.cc)
set(OPT_TRACKING_INCLUDES ${OPT_TRACKING_INCLUDES} ${CUDA_INCLUDE_DIRS})
set(OPT_TRACKING_LIBRARIES ${OPT_TRACKING_LIBRARIES} ${CUDA_LIBRARIES})
set(OPT_TRACKING_LIBRARIES ${OPT_TRACKING_LIBRARIES} ${CUDA_LIBRARIES})
endif(ENABLE_CUDA)
if(ENABLE_FPGA)
@@ -42,7 +42,8 @@ set(TRACKING_GR_BLOCKS_SOURCES
glonass_l2_ca_dll_pll_tracking_cc.cc
glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc
glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc
${OPT_TRACKING_BLOCKS}
dll_pll_veml_tracking.cc
${OPT_TRACKING_BLOCKS}
)
include_directories(

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,230 @@
/*!
* \file dll_pll_veml_tracking.h
* \brief Implementation of a code DLL + carrier PLL tracking block.
* \author Antonio Ramos, 2018 antonio.ramosdet(at)gmail.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2018 (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 <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_DLL_PLL_VEML_TRACKING_H
#define GNSS_SDR_DLL_PLL_VEML_TRACKING_H
#include "gnss_synchro.h"
#include "tracking_2nd_DLL_filter.h"
#include "tracking_2nd_PLL_filter.h"
#include "cpu_multicorrelator_real_codes.h"
#include <gnuradio/block.h>
#include <fstream>
#include <string>
class dll_pll_veml_tracking;
typedef boost::shared_ptr<dll_pll_veml_tracking> dll_pll_veml_tracking_sptr;
dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(double fs_in, unsigned int vector_length,
bool dump, std::string dump_filename,
float pll_bw_hz, float dll_bw_hz,
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]);
/*!
* \brief This class implements a code DLL + carrier PLL tracking block.
*/
class dll_pll_veml_tracking : public gr::block
{
public:
~dll_pll_veml_tracking();
void set_channel(unsigned int channel);
void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro);
void start_tracking();
int general_work(int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
void forecast(int noutput_items, gr_vector_int &ninput_items_required);
private:
friend dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(double fs_in, unsigned int vector_length,
bool dump, std::string dump_filename,
float pll_bw_hz, float dll_bw_hz, 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]);
dll_pll_veml_tracking(double fs_in, unsigned int vector_length,
bool dump,
std::string dump_filename,
float pll_bw_hz,
float dll_bw_hz,
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 cn0_and_tracking_lock_status();
bool acquire_secondary();
void do_correlation_step(const gr_complex *input_samples);
void run_dll_pll();
void update_tracking_vars();
void clear_tracking_vars();
void save_correlation_results();
void log_data(bool integrating);
int save_matfile();
// tracking configuration vars
bool d_dump;
bool d_veml;
bool d_cloop;
unsigned int d_vector_length;
unsigned int d_channel;
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;
bool d_synchonizing;
//Integration period in samples
int d_correlation_length_ms;
int d_n_correlator_taps;
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_prompt_data_shift;
cpu_multicorrelator_real_codes multicorrelator_cpu;
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;
gr_complex *d_Late;
gr_complex *d_Very_Late;
bool d_enable_extended_integration;
int d_extend_correlation_symbols;
int d_extend_correlation_symbols_count;
int d_current_symbol;
gr_complex d_VE_accu;
gr_complex d_E_accu;
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;
double d_code_phase_step_chips;
double d_carrier_phase_step_rad;
// remaining code phase and carrier phase between tracking loops
double d_rem_code_phase_samples;
double d_rem_carr_phase_rad;
// PLL and DLL filter library
Tracking_2nd_DLL_filter d_code_loop_filter;
Tracking_2nd_PLL_filter d_carrier_loop_filter;
// acquisition
double d_acq_code_phase_samples;
double d_acq_carrier_doppler_hz;
// tracking parameters
float d_dll_bw_hz;
float d_pll_bw_hz;
float d_dll_bw_narrow_hz;
float d_pll_bw_narrow_hz;
// tracking vars
double d_carr_error_hz;
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;
int d_carrier_lock_fail_counter;
double d_carrier_lock_test;
double d_CN0_SNV_dB_Hz;
double d_carrier_lock_threshold;
std::deque<gr_complex> d_Prompt_buffer_deque;
gr_complex *d_Prompt_buffer;
// file dump
std::string d_dump_filename;
std::ofstream d_dump_file;
};
#endif // GNSS_SDR_DLL_PLL_VEML_TRACKING_H

View File

@@ -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, -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<const float**>(d_local_codes_resampled), d_n_correlators, signal_length_samples);
return true;
}

View File

@@ -67,20 +67,20 @@
*/
float cn0_svn_estimator(gr_complex* Prompt_buffer, int length, long fs_in, double code_length)
{
double SNR = 0;
double SNR_dB_Hz = 0;
double Psig = 0;
double Ptot = 0;
double SNR = 0.0;
double SNR_dB_Hz = 0.0;
double Psig = 0.0;
double Ptot = 0.0;
for (int i = 0; i < length; i++)
{
Psig += std::abs(static_cast<double>(Prompt_buffer[i].real()));
Ptot += static_cast<double>(Prompt_buffer[i].imag()) * static_cast<double>(Prompt_buffer[i].imag()) + static_cast<double>(Prompt_buffer[i].real()) * static_cast<double>(Prompt_buffer[i].real());
}
Psig = Psig / static_cast<double>(length);
Psig /= static_cast<double>(length);
Psig = Psig * Psig;
Ptot = Ptot / static_cast<double>(length);
Ptot /= static_cast<double>(length);
SNR = Psig / (Ptot - Psig);
SNR_dB_Hz = 10 * log10(SNR) + 10 * log10(static_cast<double>(fs_in) / 2) - 10 * log10(code_length);
SNR_dB_Hz = 10.0 * log10(SNR) + 10.0 * log10(static_cast<double>(fs_in) / 2.0) - 10.0 * log10(code_length);
return static_cast<float>(SNR_dB_Hz);
}
@@ -96,10 +96,10 @@ float cn0_svn_estimator(gr_complex* Prompt_buffer, int length, long fs_in, doubl
*/
float carrier_lock_detector(gr_complex* Prompt_buffer, int length)
{
float tmp_sum_I = 0;
float tmp_sum_Q = 0;
float NBD = 0;
float NBP = 0;
float tmp_sum_I = 0.0;
float tmp_sum_Q = 0.0;
float NBD = 0.0;
float NBP = 0.0;
for (int i = 0; i < length; i++)
{
tmp_sum_I += Prompt_buffer[i].real();

View File

@@ -41,11 +41,10 @@
void Tracking_2nd_DLL_filter::calculate_lopp_coef(float* tau1, float* tau2, float lbw, float zeta, float k)
{
// Solve natural frequency
float Wn;
Wn = lbw * 8 * zeta / (4 * zeta * zeta + 1);
float Wn = lbw * 8.0 * zeta / (4.0 * zeta * zeta + 1.0);
// solve for t1 & t2
*tau1 = k / (Wn * Wn);
*tau2 = (2.0 * zeta) / Wn;
*tau2 = 2.0 * zeta / Wn;
}
@@ -67,9 +66,7 @@ void Tracking_2nd_DLL_filter::initialize()
float Tracking_2nd_DLL_filter::get_code_nco(float DLL_discriminator)
{
float code_nco;
code_nco = d_old_code_nco + (d_tau2_code / d_tau1_code) * (DLL_discriminator - d_old_code_error) + (DLL_discriminator + d_old_code_error) * (d_pdi_code / (2 * d_tau1_code));
//code_nco = d_old_code_nco + (d_tau2_code/d_tau1_code)*(DLL_discriminator - d_old_code_error) + DLL_discriminator * (d_pdi_code/d_tau1_code);
float code_nco = d_old_code_nco + (d_tau2_code / d_tau1_code) * (DLL_discriminator - d_old_code_error) + (DLL_discriminator + d_old_code_error) * (d_pdi_code / (2.0 * d_tau1_code));
d_old_code_nco = code_nco;
d_old_code_error = DLL_discriminator; //[chips]
return code_nco;

View File

@@ -49,13 +49,13 @@ class Tracking_2nd_DLL_filter
{
private:
// PLL filter parameters
float d_tau1_code = 0;
float d_tau2_code = 0;
float d_pdi_code = 0;
float d_dllnoisebandwidth = 0;
float d_dlldampingratio = 0;
float d_old_code_error = 0;
float d_old_code_nco = 0;
float d_tau1_code = 0.0;
float d_tau2_code = 0.0;
float d_pdi_code = 0.0;
float d_dllnoisebandwidth = 0.0;
float d_dlldampingratio = 0.0;
float d_old_code_error = 0.0;
float d_old_code_nco = 0.0;
void calculate_lopp_coef(float* tau1, float* tau2, float lbw, float zeta, float k);
public:

View File

@@ -40,11 +40,10 @@
void Tracking_2nd_PLL_filter::calculate_lopp_coef(float* tau1, float* tau2, float lbw, float zeta, float k)
{
// Solve natural frequency
float Wn;
Wn = lbw * 8 * zeta / (4 * zeta * zeta + 1);
float Wn = lbw * 8.0 * zeta / (4.0 * zeta * zeta + 1.0);
// solve for t1 & t2
*tau1 = k / (Wn * Wn);
*tau2 = (2.0 * zeta) / Wn;
*tau2 = 2.0 * zeta / Wn;
}
@@ -71,8 +70,7 @@ void Tracking_2nd_PLL_filter::initialize()
*/
float Tracking_2nd_PLL_filter::get_carrier_nco(float PLL_discriminator)
{
float carr_nco;
carr_nco = d_old_carr_nco + (d_tau2_carr / d_tau1_carr) * (PLL_discriminator - d_old_carr_error) + (PLL_discriminator + d_old_carr_error) * (d_pdi_carr / (2 * d_tau1_carr));
float carr_nco = d_old_carr_nco + (d_tau2_carr / d_tau1_carr) * (PLL_discriminator - d_old_carr_error) + (PLL_discriminator + d_old_carr_error) * (d_pdi_carr / (2.0 * d_tau1_carr));
//carr_nco = d_old_carr_nco + (d_tau2_carr/d_tau1_carr)*(PLL_discriminator - d_old_carr_error) + PLL_discriminator * (d_pdi_carr/d_tau1_carr);
d_old_carr_nco = carr_nco;
d_old_carr_error = PLL_discriminator;

View File

@@ -48,15 +48,15 @@ class Tracking_2nd_PLL_filter
{
private:
// PLL filter parameters
float d_tau1_carr = 0;
float d_tau2_carr = 0;
float d_pdi_carr = 0;
float d_tau1_carr = 0.0;
float d_tau2_carr = 0.0;
float d_pdi_carr = 0.0;
float d_pllnoisebandwidth = 0;
float d_plldampingratio = 0;
float d_pllnoisebandwidth = 0.0;
float d_plldampingratio = 0.0;
float d_old_carr_error = 0;
float d_old_carr_nco = 0;
float d_old_carr_error = 0.0;
float d_old_carr_nco = 0.0;
void calculate_lopp_coef(float* tau1, float* tau2, float lbw, float zeta, float k);

View File

@@ -83,7 +83,7 @@ double pll_cloop_two_quadrant_atan(gr_complex prompt_s1)
}
else
{
return 0;
return 0.0;
}
}
@@ -107,7 +107,7 @@ double dll_nc_e_minus_l_normalized(gr_complex early_s1, gr_complex late_s1)
}
else
{
return 0.5 * (P_early - P_late) / ((P_early + P_late));
return 0.5 * (P_early - P_late) / (P_early + P_late);
}
}
@@ -131,6 +131,6 @@ double dll_nc_vemlp_normalized(gr_complex very_early_s1, gr_complex early_s1, gr
}
else
{
return (P_early - P_late) / ((P_early + P_late));
return (P_early - P_late) / (P_early + P_late);
}
}

View File

@@ -37,9 +37,6 @@
#include <glog/logging.h>
#define MAX_LOOP_ORDER 3
#define MAX_HISTORY_LENGTH 4
Tracking_loop_filter::Tracking_loop_filter(float update_interval,
float noise_bandwidth,
int loop_order,
@@ -50,8 +47,8 @@ Tracking_loop_filter::Tracking_loop_filter(float update_interval,
d_noise_bandwidth(noise_bandwidth),
d_update_interval(update_interval)
{
d_inputs.resize(MAX_HISTORY_LENGTH, 0.0);
d_outputs.resize(MAX_HISTORY_LENGTH, 0.0);
d_inputs.resize(MAX_LOOP_HISTORY_LENGTH, 0.0);
d_outputs.resize(MAX_LOOP_HISTORY_LENGTH, 0.0);
update_coefficients();
}
@@ -62,8 +59,8 @@ Tracking_loop_filter::Tracking_loop_filter()
d_noise_bandwidth(15.0),
d_update_interval(0.001)
{
d_inputs.resize(MAX_HISTORY_LENGTH, 0.0);
d_outputs.resize(MAX_HISTORY_LENGTH, 0.0);
d_inputs.resize(MAX_LOOP_HISTORY_LENGTH, 0.0);
d_outputs.resize(MAX_LOOP_HISTORY_LENGTH, 0.0);
update_coefficients();
}
@@ -75,12 +72,12 @@ Tracking_loop_filter::~Tracking_loop_filter()
float Tracking_loop_filter::apply(float current_input)
{
// Now apply the filter coefficients:
float result = 0;
float result = 0.0;
// Hanlde the old outputs first:
for (unsigned int ii = 0; ii < d_output_coefficients.size(); ++ii)
{
result += d_output_coefficients[ii] * d_outputs[(d_current_index + ii) % MAX_HISTORY_LENGTH];
result += d_output_coefficients[ii] * d_outputs[(d_current_index + ii) % MAX_LOOP_HISTORY_LENGTH];
}
// Now update the index to handle the inputs.
@@ -93,7 +90,7 @@ float Tracking_loop_filter::apply(float current_input)
d_current_index--;
if (d_current_index < 0)
{
d_current_index += MAX_HISTORY_LENGTH;
d_current_index += MAX_LOOP_HISTORY_LENGTH;
}
d_inputs[d_current_index] = current_input;
@@ -101,7 +98,7 @@ float Tracking_loop_filter::apply(float current_input)
for (unsigned int ii = 0; ii < d_input_coefficients.size(); ++ii)
{
result += d_input_coefficients[ii] * d_inputs[(d_current_index + ii) % MAX_HISTORY_LENGTH];
result += d_input_coefficients[ii] * d_inputs[(d_current_index + ii) % MAX_LOOP_HISTORY_LENGTH];
}
@@ -122,7 +119,7 @@ void Tracking_loop_filter::update_coefficients(void)
float wn;
float T = d_update_interval;
float zeta = 1 / std::sqrt(2);
float zeta = 1.0 / std::sqrt(2.0);
// The following is based on the bilinear transform approximation of
// the analog integrator. The loop format is from Kaplan & Hegarty
@@ -146,7 +143,7 @@ void Tracking_loop_filter::update_coefficients(void)
d_input_coefficients[1] = g1 * T / 2.0;
d_output_coefficients.resize(1);
d_output_coefficients[0] = 1;
d_output_coefficients[0] = 1.0;
}
else
{
@@ -157,28 +154,28 @@ void Tracking_loop_filter::update_coefficients(void)
}
break;
case 2:
wn = d_noise_bandwidth * (8 * zeta) / (4 * zeta * zeta + 1);
wn = d_noise_bandwidth * (8.0 * zeta) / (4.0 * zeta * zeta + 1.0);
g1 = wn * wn;
g2 = wn * 2 * zeta;
g2 = wn * 2.0 * zeta;
if (d_include_last_integrator)
{
d_input_coefficients.resize(3);
d_input_coefficients[0] = T / 2 * (g1 * T / 2 + g2);
d_input_coefficients[1] = T * T / 2 * g1;
d_input_coefficients[2] = T / 2 * (g1 * T / 2 - g2);
d_input_coefficients[0] = T / 2.0 * (g1 * T / 2.0 + g2);
d_input_coefficients[1] = T * T / 2.0 * g1;
d_input_coefficients[2] = T / 2.0 * (g1 * T / 2.0 - g2);
d_output_coefficients.resize(2);
d_output_coefficients[0] = 2;
d_output_coefficients[1] = -1;
d_output_coefficients[0] = 2.0;
d_output_coefficients[1] = -1.0;
}
else
{
d_input_coefficients.resize(2);
d_input_coefficients[0] = (g1 * T / 2.0 + g2);
d_input_coefficients[1] = g1 * T / 2 - g2;
d_input_coefficients[1] = g1 * T / 2.0 - g2;
d_output_coefficients.resize(1);
d_output_coefficients[0] = 1;
d_output_coefficients[0] = 1.0;
}
break;
@@ -193,27 +190,27 @@ void Tracking_loop_filter::update_coefficients(void)
if (d_include_last_integrator)
{
d_input_coefficients.resize(4);
d_input_coefficients[0] = T / 2 * (g3 + T / 2 * (g2 + T / 2 * g1));
d_input_coefficients[1] = T / 2 * (-g3 + T / 2 * (g2 + 3 * T / 2 * g1));
d_input_coefficients[2] = T / 2 * (-g3 - T / 2 * (g2 - 3 * T / 2 * g1));
d_input_coefficients[3] = T / 2 * (g3 - T / 2 * (g2 - T / 2 * g1));
d_input_coefficients[0] = T / 2.0 * (g3 + T / 2.0 * (g2 + T / 2.0 * g1));
d_input_coefficients[1] = T / 2.0 * (-g3 + T / 2.0 * (g2 + 3.0 * T / 2.0 * g1));
d_input_coefficients[2] = T / 2.0 * (-g3 - T / 2.0 * (g2 - 3.0 * T / 2.0 * g1));
d_input_coefficients[3] = T / 2.0 * (g3 - T / 2.0 * (g2 - T / 2.0 * g1));
d_output_coefficients.resize(3);
d_output_coefficients[0] = 3;
d_output_coefficients[1] = -3;
d_output_coefficients[2] = 1;
d_output_coefficients[0] = 3.0;
d_output_coefficients[1] = -3.0;
d_output_coefficients[2] = 1.0;
}
else
{
d_input_coefficients.resize(3);
d_input_coefficients[0] = g3 + T / 2 * (g2 + T / 2 * g1);
d_input_coefficients[1] = g1 * T * T / 2 - 2 * g3;
d_input_coefficients[2] = g3 + T / 2 * (-g2 + T / 2 * g1);
d_input_coefficients[0] = g3 + T / 2.0 * (g2 + T / 2.0 * g1);
d_input_coefficients[1] = g1 * T * T / 2.0 - 2.0 * g3;
d_input_coefficients[2] = g3 + T / 2.0 * (-g2 + T / 2.0 * g1);
d_output_coefficients.resize(2);
d_output_coefficients[0] = 2;
d_output_coefficients[1] = -1;
d_output_coefficients[0] = 2.0;
d_output_coefficients[1] = -1.0;
}
break;
};
@@ -254,7 +251,7 @@ bool Tracking_loop_filter::get_include_last_integrator(void) const
void Tracking_loop_filter::set_order(int loop_order)
{
if (loop_order < 1 || loop_order > MAX_LOOP_ORDER)
if (loop_order < 1 or loop_order > MAX_LOOP_ORDER)
{
LOG(ERROR) << "Ignoring attempt to set loop order to " << loop_order
<< ". Maximum allowed order is: " << MAX_LOOP_ORDER
@@ -274,7 +271,7 @@ int Tracking_loop_filter::get_order(void) const
void Tracking_loop_filter::initialize(float initial_output)
{
d_inputs.assign(MAX_HISTORY_LENGTH, 0.0);
d_outputs.assign(MAX_HISTORY_LENGTH, initial_output);
d_current_index = MAX_HISTORY_LENGTH - 1;
d_inputs.assign(MAX_LOOP_HISTORY_LENGTH, 0.0);
d_outputs.assign(MAX_LOOP_HISTORY_LENGTH, initial_output);
d_current_index = MAX_LOOP_HISTORY_LENGTH - 1;
}

View File

@@ -33,6 +33,8 @@
#ifndef GNSS_SDR_TRACKING_LOOP_FILTER_H_
#define GNSS_SDR_TRACKING_LOOP_FILTER_H_
#define MAX_LOOP_ORDER 3
#define MAX_LOOP_HISTORY_LENGTH 4
#include <vector>