1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-12-01 14:18:08 +00:00
This commit is contained in:
Carles Fernandez
2018-04-03 11:52:57 +02:00
220 changed files with 20749 additions and 16437 deletions

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)
@@ -27,9 +27,7 @@ if(ENABLE_FPGA)
endif(ENABLE_FPGA)
set(TRACKING_GR_BLOCKS_SOURCES
galileo_e1_dll_pll_veml_tracking_cc.cc
galileo_e1_tcp_connector_tracking_cc.cc
gps_l1_ca_dll_pll_tracking_cc.cc
gps_l1_ca_tcp_connector_tracking_cc.cc
galileo_e5a_dll_pll_tracking_cc.cc
gps_l2_m_dll_pll_tracking_cc.cc

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,11 @@
/*!
* \file galileo_e1_dll_pll_veml_tracking_cc.h
* \brief Implementation of a code DLL + carrier PLL VEML (Very Early
* Minus Late) tracking block for Galileo E1 signals
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
* \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-2017 (see AUTHORS file for a list of contributors)
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
@@ -29,8 +28,8 @@
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_CC_H
#define GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_CC_H
#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"
@@ -39,72 +38,50 @@
#include <gnuradio/block.h>
#include <fstream>
#include <string>
#include <map>
class galileo_e1_dll_pll_veml_tracking_cc;
class dll_pll_veml_tracking;
typedef boost::shared_ptr<galileo_e1_dll_pll_veml_tracking_cc> galileo_e1_dll_pll_veml_tracking_cc_sptr;
typedef boost::shared_ptr<dll_pll_veml_tracking> dll_pll_veml_tracking_sptr;
galileo_e1_dll_pll_veml_tracking_cc_sptr
galileo_e1_dll_pll_veml_make_tracking_cc(long if_freq,
long 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,
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);
int extend_correlation_symbols, bool track_pilot,
char system, char signal[3]);
/*!
* \brief This class implements a code DLL + carrier PLL VEML (Very Early
* Minus Late) tracking block for Galileo E1 signals
* \brief This class implements a code DLL + carrier PLL tracking block.
*/
class galileo_e1_dll_pll_veml_tracking_cc : public gr::block
class dll_pll_veml_tracking : public gr::block
{
public:
~galileo_e1_dll_pll_veml_tracking_cc();
~dll_pll_veml_tracking();
void set_channel(unsigned int channel);
void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro);
void start_tracking();
/*!
* \brief Code DLL + carrier PLL according to the algorithms described in:
* K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency Approach,
* Birkhauser, 2007
*/
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 galileo_e1_dll_pll_veml_tracking_cc_sptr
galileo_e1_dll_pll_veml_make_tracking_cc(long if_freq,
long 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,
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);
int extend_correlation_symbols, bool track_pilot,
char system, char signal[3]);
galileo_e1_dll_pll_veml_tracking_cc(long if_freq,
long fs_in, unsigned int vector_length,
dll_pll_veml_tracking(double fs_in, unsigned int vector_length,
bool dump,
std::string dump_filename,
float pll_bw_hz,
@@ -116,61 +93,74 @@ private:
float early_late_space_narrow_chips,
float very_early_late_space_narrow_chips,
int extend_correlation_symbols,
bool track_pilot);
bool track_pilot,
char system, char signal[3]);
bool cn0_and_tracking_lock_status();
void do_correlation_step(const gr_complex *input_samples);
void run_dll_pll(bool disable_costas_loop);
void update_local_code();
void update_local_carrier();
bool acquire_secondary();
void do_correlation_step(const gr_complex *input_samples);
void run_dll_pll();
void update_tracking_vars();
void clear_tracking_vars();
void log_data();
void save_correlation_results();
void log_data(bool integrating);
int save_matfile();
// tracking configuration vars
unsigned int d_vector_length;
bool d_dump;
Gnss_Synchro *d_acquisition_gnss_synchro;
bool d_veml;
bool d_cloop;
unsigned int d_vector_length;
unsigned int d_channel;
long d_if_freq;
long d_fs_in;
double d_fs_in;
Gnss_Synchro *d_acquisition_gnss_synchro;
//Signal parameters
bool d_secondary;
bool interchange_iq;
double d_signal_carrier_freq;
double d_code_period;
double d_code_chip_rate;
unsigned int d_secondary_code_length;
unsigned int d_code_length_chips;
unsigned int d_code_samples_per_chip; // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled)
int d_symbols_per_bit;
std::string systemName;
std::string signal_type;
std::string *d_secondary_code_string;
//tracking state machine
int d_state;
bool d_synchonizing;
//Integration period in samples
int d_correlation_length_samples;
int d_correlation_length_ms;
int d_n_correlator_taps;
double d_early_late_spc_chips;
double d_very_early_late_spc_chips;
double d_early_late_spc_narrow_chips;
double d_very_early_late_spc_narrow_chips;
float d_early_late_spc_chips;
float d_very_early_late_spc_chips;
float d_early_late_spc_narrow_chips;
float d_very_early_late_spc_narrow_chips;
float *d_tracking_code;
float *d_data_code;
float *d_local_code_shift_chips;
gr_complex *d_correlator_outs;
float *d_prompt_data_shift;
cpu_multicorrelator_real_codes multicorrelator_cpu;
//todo: currently the multicorrelator does not support adding extra correlator
//with different local code, thus we need extra multicorrelator instance.
//Implement this functionality inside multicorrelator class
//as an enhancement to increase the performance
float *d_local_code_data_shift_chips;
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;
bool d_enable_extended_integration;
int d_current_symbol;
gr_complex d_VE_accu;
@@ -178,6 +168,7 @@ private:
gr_complex d_P_accu;
gr_complex d_L_accu;
gr_complex d_VL_accu;
gr_complex d_last_prompt;
bool d_track_pilot;
gr_complex *d_Prompt_Data;
@@ -206,39 +197,34 @@ private:
double d_carr_error_filt_hz;
double d_code_error_chips;
double d_code_error_filt_chips;
double d_K_blk_samples;
double d_code_freq_chips;
double d_carrier_doppler_hz;
double d_acc_carrier_phase_rad;
double d_rem_code_phase_chips;
double d_code_phase_samples;
//PRN period in 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
// processing samples counters
unsigned long int d_sample_counter;
unsigned long int d_acq_sample_stamp;
// CN0 estimation and lock detector
int d_cn0_estimation_counter;
std::deque<gr_complex> d_Prompt_buffer_deque;
gr_complex *d_Prompt_buffer;
int d_carrier_lock_fail_counter;
double d_carrier_lock_test;
double d_CN0_SNV_dB_Hz;
double d_carrier_lock_threshold;
int d_carrier_lock_fail_counter;
std::deque<gr_complex> d_Prompt_buffer_deque;
gr_complex *d_Prompt_buffer;
// file dump
std::string d_dump_filename;
std::ofstream d_dump_file;
std::map<std::string, std::string> systemName;
std::string sys;
int save_matfile();
};
#endif //GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_CC_H
#endif // GNSS_SDR_DLL_PLL_VEML_TRACKING_H

View File

@@ -355,13 +355,13 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attri
code_error_filt_secs = (Galileo_E1_CODE_PERIOD * code_error_filt_chips) / Galileo_E1_CODE_CHIP_RATE_HZ; //[seconds]
d_acc_code_phase_secs = d_acc_code_phase_secs + code_error_filt_secs;
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
// ################## CARRIER AND CODE NCO BUFFER ALIGNMENT #######################
// keep alignment parameters for the next input buffer
double T_chip_seconds;
double T_prn_seconds;
double T_prn_samples;
double K_blk_samples;
// Compute the next buffer lenght based in the new period of the PRN sequence and the code phase error estimation
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
T_chip_seconds = 1 / static_cast<double>(d_code_freq_chips);
T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS;
T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in);
@@ -443,21 +443,18 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attri
// MULTIPLEXED FILE RECORDING - Record results to file
float prompt_I;
float prompt_Q;
float tmp_VE, tmp_E, tmp_P, tmp_L, tmp_VL;
float tmp_E, tmp_P, tmp_L;
float tmp_VE = 0.0;
float tmp_VL = 0.0;
float tmp_float;
tmp_float = 0;
double tmp_double;
prompt_I = (*d_Prompt).real();
prompt_Q = (*d_Prompt).imag();
tmp_VE = std::abs<float>(*d_Very_Early);
tmp_E = std::abs<float>(*d_Early);
tmp_P = std::abs<float>(*d_Prompt);
tmp_L = std::abs<float>(*d_Late);
tmp_VL = std::abs<float>(*d_Very_Late);
prompt_I = d_correlator_outs[1].real();
prompt_Q = d_correlator_outs[1].imag();
tmp_E = std::abs<float>(d_correlator_outs[0]);
tmp_P = std::abs<float>(d_correlator_outs[1]);
tmp_L = std::abs<float>(d_correlator_outs[2]);
try
{
// EPR
// Dump correlators output
d_dump_file.write(reinterpret_cast<char *>(&tmp_VE), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_E), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_P), sizeof(float));
@@ -469,30 +466,33 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attri
// PRN start sample stamp
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(unsigned long int));
// accumulated carrier phase
d_dump_file.write(reinterpret_cast<char *>(&d_acc_carrier_phase_rad), sizeof(float));
tmp_float = d_acc_carrier_phase_rad;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// carrier and code frequency
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&d_code_freq_chips), sizeof(float));
//PLL commands
tmp_float = d_carrier_doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&carr_error_filt_hz), sizeof(float));
//DLL commands
tmp_float = d_code_freq_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// PLL commands
tmp_float = 0.0;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = carr_error_filt_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// DLL commands
tmp_float = 0.0;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = code_error_filt_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&code_error_filt_chips), sizeof(float));
// CN0 and carrier lock test
d_dump_file.write(reinterpret_cast<char *>(&d_CN0_SNV_dB_Hz), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_lock_test), sizeof(float));
// AUX vars (for debug purposes)
tmp_float = d_rem_code_phase_samples;
tmp_float = d_CN0_SNV_dB_Hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_double = static_cast<double>(d_sample_counter + d_current_prn_length_samples);
tmp_float = d_carrier_lock_test;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// AUX vars (for debug purposes)
tmp_float = 0.0;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
double tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
// PRN
unsigned int prn_ = d_acquisition_gnss_synchro->PRN;
d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int));

View File

@@ -38,9 +38,9 @@
#include "glonass_l1_ca_dll_pll_c_aid_tracking_cc.h"
#include "glonass_l1_signal_processing.h"
#include "GLONASS_L1_L2_CA.h"
#include "tracking_discriminators.h"
#include "lock_detectors.h"
#include "GLONASS_L1_CA.h"
#include "gnss_sdr_flags.h"
#include "control_message_factory.h"
#include <boost/lexical_cast.hpp>
@@ -56,6 +56,8 @@
#include <sstream>
#define CN0_ESTIMATION_SAMPLES 10
using google::LogMessage;
glonass_l1_ca_dll_pll_c_aid_tracking_cc_sptr
@@ -605,7 +607,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at
d_code_phase_step_chips,
d_correlation_length_samples);
// ####### coherent intergration extension
// ####### coherent integration extension
// keep the last symbols
d_E_history.push_back(d_correlator_outs[0]); // save early output
d_P_history.push_back(d_correlator_outs[1]); // save prompt output
@@ -720,7 +722,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at
d_code_error_filt_chips_Ti = d_code_error_filt_chips_s * CURRENT_INTEGRATION_TIME_S;
code_error_filt_secs_Ti = d_code_error_filt_chips_Ti / d_code_freq_chips; // [s/Ti]
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
// ################## CARRIER AND CODE NCO BUFFER ALIGNMENT #######################
// keep alignment parameters for the next input buffer
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
double T_chip_seconds = 1.0 / d_code_freq_chips;
@@ -750,7 +752,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at
d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast<double>(d_fs_in));
// ####### CN0 ESTIMATION AND LOCK DETECTORS #######################################
if (d_cn0_estimation_counter < FLAGS_cn0_samples)
if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES)
{
// fill buffer with prompt correlator output values
d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1]; // prompt
@@ -760,9 +762,9 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at
{
d_cn0_estimation_counter = 0;
// Code lock indicator
d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, FLAGS_cn0_samples, d_fs_in, GLONASS_L1_CA_CODE_LENGTH_CHIPS);
d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, GLONASS_L1_CA_CODE_LENGTH_CHIPS);
// Carrier lock indicator
d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, FLAGS_cn0_samples);
d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES);
// Loss of lock detection
if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min)
{
@@ -829,7 +831,9 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at
float prompt_I;
float prompt_Q;
float tmp_E, tmp_P, tmp_L;
double tmp_double;
float tmp_VE = 0.0;
float tmp_VL = 0.0;
float tmp_float;
prompt_I = d_correlator_outs[1].real();
prompt_Q = d_correlator_outs[1].imag();
tmp_E = std::abs<float>(d_correlator_outs[0]);
@@ -837,42 +841,45 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at
tmp_L = std::abs<float>(d_correlator_outs[2]);
try
{
// EPR
// Dump correlators output
d_dump_file.write(reinterpret_cast<char *>(&tmp_VE), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_E), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_P), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_L), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_VL), sizeof(float));
// PROMPT I and Q (to analyze navigation symbols)
d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float));
// PRN start sample stamp
//tmp_float=(float)d_sample_counter;
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(unsigned long int));
// accumulated carrier phase
d_dump_file.write(reinterpret_cast<char *>(&d_acc_carrier_phase_cycles), sizeof(double));
tmp_float = d_acc_carrier_phase_cycles * GLONASS_TWO_PI;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// carrier and code frequency
double if_freq_carrier = d_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * static_cast<double>(GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)));
d_dump_file.write(reinterpret_cast<char *>(&if_freq_carrier), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_code_freq_chips), sizeof(double));
//PLL commands
d_dump_file.write(reinterpret_cast<char *>(&d_carr_phase_error_secs_Ti), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(double));
//DLL commands
d_dump_file.write(reinterpret_cast<char *>(&d_code_error_chips_Ti), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_code_error_filt_chips_Ti), sizeof(double));
tmp_float = d_carrier_doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_freq_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// PLL commands
tmp_float = 1.0 / (d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = 1.0 / (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// DLL commands
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_error_filt_chips_Ti;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// CN0 and carrier lock test
d_dump_file.write(reinterpret_cast<char *>(&d_CN0_SNV_dB_Hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_lock_test), sizeof(double));
tmp_float = d_CN0_SNV_dB_Hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_carrier_lock_test;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// AUX vars (for debug purposes)
tmp_double = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
double tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
// PRN
unsigned int prn_ = d_acquisition_gnss_synchro->PRN;
d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int));

View File

@@ -39,9 +39,9 @@
#include "glonass_l1_ca_dll_pll_c_aid_tracking_sc.h"
#include "gnss_synchro.h"
#include "glonass_l1_signal_processing.h"
#include "GLONASS_L1_L2_CA.h"
#include "tracking_discriminators.h"
#include "lock_detectors.h"
#include "GLONASS_L1_CA.h"
#include "gnss_sdr_flags.h"
#include "control_message_factory.h"
#include <boost/bind.hpp>
@@ -57,6 +57,7 @@
#include <sstream>
#define CN0_ESTIMATION_SAMPLES 10
using google::LogMessage;
glonass_l1_ca_dll_pll_c_aid_tracking_sc_sptr
@@ -599,7 +600,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at
d_code_phase_step_chips,
d_correlation_length_samples);
// ####### coherent intergration extension
// ####### coherent integration extension
// keep the last symbols
d_E_history.push_back(d_correlator_outs_16sc[0]); // save early output
d_P_history.push_back(d_correlator_outs_16sc[1]); // save prompt output
@@ -712,7 +713,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at
d_code_error_filt_chips_Ti = d_code_error_filt_chips_s * CURRENT_INTEGRATION_TIME_S;
code_error_filt_secs_Ti = d_code_error_filt_chips_Ti / d_code_freq_chips; // [s/Ti]
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
// ################## CARRIER AND CODE NCO BUFFER ALIGNMENT #######################
// keep alignment parameters for the next input buffer
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
double T_chip_seconds = 1.0 / d_code_freq_chips;
@@ -742,7 +743,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at
d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast<double>(d_fs_in));
// ####### CN0 ESTIMATION AND LOCK DETECTORS #######################################
if (d_cn0_estimation_counter < FLAGS_cn0_samples)
if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES)
{
// fill buffer with prompt correlator output values
d_Prompt_buffer[d_cn0_estimation_counter] = lv_cmake(static_cast<float>(d_correlator_outs_16sc[1].real()), static_cast<float>(d_correlator_outs_16sc[1].imag())); // prompt
@@ -752,9 +753,9 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at
{
d_cn0_estimation_counter = 0;
// Code lock indicator
d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, FLAGS_cn0_samples, d_fs_in, GLONASS_L1_CA_CODE_LENGTH_CHIPS);
d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, GLONASS_L1_CA_CODE_LENGTH_CHIPS);
// Carrier lock indicator
d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, FLAGS_cn0_samples);
d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES);
// Loss of lock detection
if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min)
{
@@ -821,49 +822,55 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at
float prompt_I;
float prompt_Q;
float tmp_E, tmp_P, tmp_L;
double tmp_double;
float tmp_VE = 0.0;
float tmp_VL = 0.0;
float tmp_float;
prompt_I = d_correlator_outs_16sc[1].real();
prompt_Q = d_correlator_outs_16sc[1].imag();
tmp_E = std::abs<float>(std::complex<float>(d_correlator_outs_16sc[0].real(), d_correlator_outs_16sc[0].imag()));
tmp_P = std::abs<float>(std::complex<float>(d_correlator_outs_16sc[1].real(), d_correlator_outs_16sc[1].imag()));
tmp_L = std::abs<float>(std::complex<float>(d_correlator_outs_16sc[2].real(), d_correlator_outs_16sc[2].imag()));
tmp_E = std::abs<float>(gr_complex(d_correlator_outs_16sc[0].real(), d_correlator_outs_16sc[0].imag()));
tmp_P = std::abs<float>(gr_complex(d_correlator_outs_16sc[1].real(), d_correlator_outs_16sc[1].imag()));
tmp_L = std::abs<float>(gr_complex(d_correlator_outs_16sc[2].real(), d_correlator_outs_16sc[2].imag()));
try
{
// EPR
// Dump correlators output
d_dump_file.write(reinterpret_cast<char *>(&tmp_VE), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_E), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_P), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_L), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_VL), sizeof(float));
// PROMPT I and Q (to analyze navigation symbols)
d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float));
// PRN start sample stamp
//tmp_float=(float)d_sample_counter;
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(unsigned long int));
// accumulated carrier phase
d_dump_file.write(reinterpret_cast<char *>(&d_acc_carrier_phase_cycles), sizeof(double));
tmp_float = d_acc_carrier_phase_cycles * GLONASS_TWO_PI;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// carrier and code frequency
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_code_freq_chips), sizeof(double));
//PLL commands
d_dump_file.write(reinterpret_cast<char *>(&d_carr_phase_error_secs_Ti), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(double));
//DLL commands
d_dump_file.write(reinterpret_cast<char *>(&d_code_error_chips_Ti), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_code_error_filt_chips_Ti), sizeof(double));
tmp_float = d_carrier_doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_freq_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// PLL commands
tmp_float = 1.0 / (d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = 1.0 / (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// DLL commands
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_error_filt_chips_Ti;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// CN0 and carrier lock test
d_dump_file.write(reinterpret_cast<char *>(&d_CN0_SNV_dB_Hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_lock_test), sizeof(double));
tmp_float = d_CN0_SNV_dB_Hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_carrier_lock_test;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// AUX vars (for debug purposes)
tmp_double = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
double tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
// PRN
unsigned int prn_ = d_acquisition_gnss_synchro->PRN;
d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int));

View File

@@ -38,9 +38,9 @@
#include "glonass_l1_ca_dll_pll_tracking_cc.h"
#include "glonass_l1_signal_processing.h"
#include "GLONASS_L1_L2_CA.h"
#include "tracking_discriminators.h"
#include "lock_detectors.h"
#include "GLONASS_L1_CA.h"
#include "gnss_sdr_flags.h"
#include "control_message_factory.h"
#include <boost/lexical_cast.hpp>
@@ -54,6 +54,7 @@
#include <sstream>
#define CN0_ESTIMATION_SAMPLES 10
using google::LogMessage;
glonass_l1_ca_dll_pll_tracking_cc_sptr
@@ -584,7 +585,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut
double code_error_filt_secs = (T_prn_seconds * code_error_filt_chips * T_chip_seconds); //[seconds]
//double code_error_filt_secs = (GPS_L1_CA_CODE_PERIOD * code_error_filt_chips) / GLONASS_L1_CA_CODE_RATE_HZ; // [seconds]
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
// ################## CARRIER AND CODE NCO BUFFER ALIGNMENT #######################
// keep alignment parameters for the next input buffer
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
//double T_chip_seconds = 1.0 / static_cast<double>(d_code_freq_chips);
@@ -611,7 +612,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut
d_rem_code_phase_chips = d_code_freq_chips * (d_rem_code_phase_samples / static_cast<double>(d_fs_in));
// ####### CN0 ESTIMATION AND LOCK DETECTORS ######
if (d_cn0_estimation_counter < FLAGS_cn0_samples)
if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES)
{
// fill buffer with prompt correlator output values
d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1]; //prompt
@@ -621,9 +622,9 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut
{
d_cn0_estimation_counter = 0;
// Code lock indicator
d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, FLAGS_cn0_samples, d_fs_in, GLONASS_L1_CA_CODE_LENGTH_CHIPS);
d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, GLONASS_L1_CA_CODE_LENGTH_CHIPS);
// Carrier lock indicator
d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, FLAGS_cn0_samples);
d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES);
// Loss of lock detection
if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min)
{
@@ -674,8 +675,9 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut
float prompt_I;
float prompt_Q;
float tmp_E, tmp_P, tmp_L;
double tmp_double;
unsigned long int tmp_long;
float tmp_float;
float tmp_VE = 0.0;
float tmp_VL = 0.0;
prompt_I = d_correlator_outs[1].real();
prompt_Q = d_correlator_outs[1].imag();
tmp_E = std::abs<float>(d_correlator_outs[0]);
@@ -683,41 +685,45 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut
tmp_L = std::abs<float>(d_correlator_outs[2]);
try
{
// EPR
// Dump correlators output
d_dump_file.write(reinterpret_cast<char *>(&tmp_VE), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_E), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_P), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_L), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_VL), sizeof(float));
// PROMPT I and Q (to analyze navigation symbols)
d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float));
// PRN start sample stamp
tmp_long = d_sample_counter + d_current_prn_length_samples;
d_dump_file.write(reinterpret_cast<char *>(&tmp_long), sizeof(unsigned long int));
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(unsigned long int));
// accumulated carrier phase
d_dump_file.write(reinterpret_cast<char *>(&d_acc_carrier_phase_rad), sizeof(double));
tmp_float = d_acc_carrier_phase_rad;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// carrier and code frequency
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_frequency_hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_code_freq_chips), sizeof(double));
tmp_float = d_carrier_doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_freq_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// PLL commands
d_dump_file.write(reinterpret_cast<char *>(&carr_error_hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&carr_error_filt_hz), sizeof(double));
tmp_float = carr_error_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = carr_error_filt_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// DLL commands
d_dump_file.write(reinterpret_cast<char *>(&code_error_chips), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&code_error_filt_chips), sizeof(double));
tmp_float = code_error_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = code_error_filt_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// CN0 and carrier lock test
d_dump_file.write(reinterpret_cast<char *>(&d_CN0_SNV_dB_Hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_lock_test), sizeof(double));
tmp_float = d_CN0_SNV_dB_Hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_carrier_lock_test;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// AUX vars (for debug purposes)
tmp_double = d_rem_code_phase_samples;
tmp_float = d_rem_code_phase_samples;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
double tmp_double = static_cast<double>(d_sample_counter + d_current_prn_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = static_cast<double>(d_sample_counter);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
// PRN
unsigned int prn_ = d_acquisition_gnss_synchro->PRN;
d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int));

View File

@@ -0,0 +1,926 @@
/*!
* \file glonass_l2_ca_dll_pll_c_aid_tracking_cc.h
* \brief Implementation of a code DLL + carrier PLL tracking block
* \author Damian Miralles, 2018. dmiralles2009(at)gmail.com
*
*
* Code DLL + carrier PLL according to the algorithms described in:
* K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency
* Approach, Birkha user, 2007
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2017 (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/>.
*
* -------------------------------------------------------------------------
*/
#include "glonass_l2_ca_dll_pll_c_aid_tracking_cc.h"
#include "glonass_l2_signal_processing.h"
#include "tracking_discriminators.h"
#include "lock_detectors.h"
#include "GLONASS_L1_L2_CA.h"
#include "gnss_sdr_flags.h"
#include "control_message_factory.h"
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include <gnuradio/io_signature.h>
#include <matio.h>
#include <pmt/pmt.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <glog/logging.h>
#include <cmath>
#include <iostream>
#include <memory>
#include <sstream>
#define CN0_ESTIMATION_SAMPLES 10
using google::LogMessage;
glonass_l2_ca_dll_pll_c_aid_tracking_cc_sptr
glonass_l2_ca_dll_pll_c_aid_make_tracking_cc(
long if_freq,
long 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,
int extend_correlation_ms,
float early_late_space_chips)
{
return glonass_l2_ca_dll_pll_c_aid_tracking_cc_sptr(new glonass_l2_ca_dll_pll_c_aid_tracking_cc(if_freq,
fs_in, vector_length, dump, dump_filename, pll_bw_hz, dll_bw_hz, pll_bw_narrow_hz, dll_bw_narrow_hz, extend_correlation_ms, early_late_space_chips));
}
void glonass_l2_ca_dll_pll_c_aid_tracking_cc::forecast(int noutput_items,
gr_vector_int &ninput_items_required)
{
if (noutput_items != 0)
{
ninput_items_required[0] = static_cast<int>(d_vector_length) * 2; //set the required available samples in each call
}
}
void glonass_l2_ca_dll_pll_c_aid_tracking_cc::msg_handler_preamble_index(pmt::pmt_t msg)
{
//pmt::print(msg);
DLOG(INFO) << "Extended correlation enabled for Tracking CH " << d_channel << ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN);
if (d_enable_extended_integration == false) //avoid re-setting preamble indicator
{
d_preamble_timestamp_s = pmt::to_double(msg);
d_enable_extended_integration = true;
d_preamble_synchronized = false;
}
}
glonass_l2_ca_dll_pll_c_aid_tracking_cc::glonass_l2_ca_dll_pll_c_aid_tracking_cc(
long if_freq,
long 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,
int extend_correlation_ms,
float early_late_space_chips) : gr::block("glonass_l2_ca_dll_pll_c_aid_tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{
// Telemetry bit synchronization message port input
this->message_port_register_in(pmt::mp("preamble_timestamp_s"));
this->set_msg_handler(pmt::mp("preamble_timestamp_s"),
boost::bind(&glonass_l2_ca_dll_pll_c_aid_tracking_cc::msg_handler_preamble_index, this, _1));
this->message_port_register_out(pmt::mp("events"));
// initialize internal vars
d_dump = dump;
d_if_freq = if_freq;
d_fs_in = fs_in;
d_vector_length = vector_length;
d_dump_filename = dump_filename;
d_correlation_length_samples = static_cast<int>(d_vector_length);
// Initialize tracking ==========================================
d_pll_bw_hz = pll_bw_hz;
d_dll_bw_hz = dll_bw_hz;
d_pll_bw_narrow_hz = pll_bw_narrow_hz;
d_dll_bw_narrow_hz = dll_bw_narrow_hz;
d_extend_correlation_ms = extend_correlation_ms;
d_code_loop_filter.set_DLL_BW(d_dll_bw_hz);
d_carrier_loop_filter.set_params(10.0, d_pll_bw_hz, 2);
// --- DLL variables --------------------------------------------------------
d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips)
// Initialization of local code replica
// Get space for a vector with the C/A code replica sampled 1x/chip
d_ca_code = static_cast<gr_complex *>(volk_gnsssdr_malloc(static_cast<int>(GLONASS_L2_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
// correlator outputs (scalar)
d_n_correlator_taps = 3; // Early, Prompt, and Late
d_correlator_outs = static_cast<gr_complex *>(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
for (int n = 0; n < d_n_correlator_taps; n++)
{
d_correlator_outs[n] = gr_complex(0, 0);
}
d_local_code_shift_chips = static_cast<float *>(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(float), volk_gnsssdr_get_alignment()));
// Set TAPs delay values [chips]
d_local_code_shift_chips[0] = -d_early_late_spc_chips;
d_local_code_shift_chips[1] = 0.0;
d_local_code_shift_chips[2] = d_early_late_spc_chips;
multicorrelator_cpu.init(2 * d_correlation_length_samples, d_n_correlator_taps);
//--- Perform initializations ------------------------------
// define initial code frequency basis of NCO
d_code_freq_chips = GLONASS_L2_CA_CODE_RATE_HZ;
// define residual code phase (in chips)
d_rem_code_phase_samples = 0.0;
// define residual carrier phase
d_rem_carrier_phase_rad = 0.0;
// sample synchronization
d_sample_counter = 0; //(from trk to tlm)
d_acq_sample_stamp = 0;
d_enable_tracking = false;
d_pull_in = false;
// CN0 estimation and lock detector buffers
d_cn0_estimation_counter = 0;
d_Prompt_buffer = new gr_complex[FLAGS_cn0_samples];
d_carrier_lock_test = 1;
d_CN0_SNV_dB_Hz = 0;
d_carrier_lock_fail_counter = 0;
d_carrier_lock_threshold = FLAGS_carrier_lock_th;
systemName["R"] = std::string("Glonass");
set_relative_rate(1.0 / static_cast<double>(d_vector_length));
d_acquisition_gnss_synchro = 0;
d_channel = 0;
d_acq_code_phase_samples = 0.0;
d_acq_carrier_doppler_hz = 0.0;
d_carrier_doppler_hz = 0.0;
d_code_error_filt_chips_Ti = 0.0;
d_acc_carrier_phase_cycles = 0.0;
d_code_phase_samples = 0.0;
d_pll_to_dll_assist_secs_Ti = 0.0;
d_rem_code_phase_chips = 0.0;
d_code_phase_step_chips = 0.0;
d_carrier_phase_step_rad = 0.0;
d_enable_extended_integration = false;
d_preamble_synchronized = false;
d_rem_code_phase_integer_samples = 0;
d_code_error_chips_Ti = 0.0;
d_code_error_filt_chips_s = 0.0;
d_carr_phase_error_secs_Ti = 0.0;
d_preamble_timestamp_s = 0.0;
d_carrier_frequency_hz = 0.0;
d_carrier_doppler_old_hz = 0.0;
d_glonass_freq_ch = 0;
//set_min_output_buffer((long int)300);
}
void glonass_l2_ca_dll_pll_c_aid_tracking_cc::start_tracking()
{
/*
* correct the code phase according to the delay between acq and trk
*/
d_acq_code_phase_samples = d_acquisition_gnss_synchro->Acq_delay_samples;
d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz;
d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples;
long int acq_trk_diff_samples;
double acq_trk_diff_seconds;
acq_trk_diff_samples = static_cast<long int>(d_sample_counter) - static_cast<long int>(d_acq_sample_stamp); //-d_vector_length;
DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples;
acq_trk_diff_seconds = static_cast<double>(acq_trk_diff_samples) / static_cast<double>(d_fs_in);
// Doppler effect
// Fd=(C/(C+Vr))*F
d_glonass_freq_ch = GLONASS_L2_CA_FREQ_HZ + (DFRQ2_GLO * static_cast<double>(GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)));
double radial_velocity = (d_glonass_freq_ch + d_acq_carrier_doppler_hz) / d_glonass_freq_ch;
// new chip and prn sequence periods based on acq Doppler
double T_chip_mod_seconds;
double T_prn_mod_seconds;
double T_prn_mod_samples;
d_code_freq_chips = radial_velocity * GLONASS_L2_CA_CODE_RATE_HZ;
d_code_phase_step_chips = static_cast<double>(d_code_freq_chips) / static_cast<double>(d_fs_in);
T_chip_mod_seconds = 1.0 / d_code_freq_chips;
T_prn_mod_seconds = T_chip_mod_seconds * GLONASS_L2_CA_CODE_LENGTH_CHIPS;
T_prn_mod_samples = T_prn_mod_seconds * static_cast<double>(d_fs_in);
d_correlation_length_samples = round(T_prn_mod_samples);
double T_prn_true_seconds = GLONASS_L2_CA_CODE_LENGTH_CHIPS / GLONASS_L2_CA_CODE_RATE_HZ;
double T_prn_true_samples = T_prn_true_seconds * static_cast<double>(d_fs_in);
double T_prn_diff_seconds = T_prn_true_seconds - T_prn_mod_seconds;
double N_prn_diff = acq_trk_diff_seconds / T_prn_true_seconds;
double corrected_acq_phase_samples, delay_correction_samples;
corrected_acq_phase_samples = fmod((d_acq_code_phase_samples + T_prn_diff_seconds * N_prn_diff * static_cast<double>(d_fs_in)), T_prn_true_samples);
if (corrected_acq_phase_samples < 0)
{
corrected_acq_phase_samples = T_prn_mod_samples + corrected_acq_phase_samples;
}
delay_correction_samples = d_acq_code_phase_samples - corrected_acq_phase_samples;
d_acq_code_phase_samples = corrected_acq_phase_samples;
// d_carrier_doppler_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ2_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN));
// d_carrier_doppler_hz = d_acq_carrier_doppler_hz;
// d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in);
d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ2_GLO * static_cast<double>(GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)));
d_carrier_doppler_hz = d_acq_carrier_doppler_hz;
d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast<double>(d_fs_in);
// DLL/PLL filter initialization
d_carrier_loop_filter.initialize(d_carrier_frequency_hz); // The carrier loop filter implements the Doppler accumulator
d_code_loop_filter.initialize(); // initialize the code filter
// generate local reference ALWAYS starting at chip 1 (1 sample per chip)
glonass_l2_ca_code_gen_complex(d_ca_code, 0);
multicorrelator_cpu.set_local_code_and_taps(static_cast<int>(GLONASS_L2_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips);
for (int n = 0; n < d_n_correlator_taps; n++)
{
d_correlator_outs[n] = gr_complex(0, 0);
}
d_carrier_lock_fail_counter = 0;
d_rem_code_phase_samples = 0.0;
d_rem_carrier_phase_rad = 0.0;
d_rem_code_phase_chips = 0.0;
d_acc_carrier_phase_cycles = 0.0;
d_pll_to_dll_assist_secs_Ti = 0.0;
d_code_phase_samples = d_acq_code_phase_samples;
std::string sys_ = &d_acquisition_gnss_synchro->System;
sys = sys_.substr(0, 1);
// DEBUG OUTPUT
std::cout << "Tracking start on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl;
LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel;
// enable tracking
d_pull_in = true;
d_enable_tracking = true;
d_enable_extended_integration = false;
d_preamble_synchronized = false;
LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz
<< " Code Phase correction [samples]=" << delay_correction_samples
<< " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples;
}
glonass_l2_ca_dll_pll_c_aid_tracking_cc::~glonass_l2_ca_dll_pll_c_aid_tracking_cc()
{
if (d_dump_file.is_open())
{
try
{
d_dump_file.close();
}
catch (const std::exception &ex)
{
LOG(WARNING) << "Exception in destructor " << ex.what();
}
}
if (d_dump)
{
if (d_channel == 0)
{
std::cout << "Writing .mat files ...";
}
glonass_l2_ca_dll_pll_c_aid_tracking_cc::save_matfile();
if (d_channel == 0)
{
std::cout << " done." << std::endl;
}
}
try
{
volk_gnsssdr_free(d_local_code_shift_chips);
volk_gnsssdr_free(d_correlator_outs);
volk_gnsssdr_free(d_ca_code);
delete[] d_Prompt_buffer;
multicorrelator_cpu.free();
}
catch (const std::exception &ex)
{
LOG(WARNING) << "Exception in destructor " << ex.what();
}
}
int glonass_l2_ca_dll_pll_c_aid_tracking_cc::save_matfile()
{
// READ DUMP FILE
std::ifstream::pos_type size;
int number_of_double_vars = 11;
int number_of_float_vars = 5;
int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars +
sizeof(float) * number_of_float_vars + sizeof(unsigned int);
std::ifstream dump_file;
dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate);
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Problem opening dump file:" << e.what() << std::endl;
return 1;
}
// count number of epochs and rewind
long int num_epoch = 0;
if (dump_file.is_open())
{
size = dump_file.tellg();
num_epoch = static_cast<long int>(size) / static_cast<long int>(epoch_size_bytes);
dump_file.seekg(0, std::ios::beg);
}
else
{
return 1;
}
float *abs_E = new float[num_epoch];
float *abs_P = new float[num_epoch];
float *abs_L = new float[num_epoch];
float *Prompt_I = new float[num_epoch];
float *Prompt_Q = new float[num_epoch];
unsigned long int *PRN_start_sample_count = new unsigned long int[num_epoch];
double *acc_carrier_phase_rad = new double[num_epoch];
double *carrier_doppler_hz = new double[num_epoch];
double *code_freq_chips = new double[num_epoch];
double *carr_error_hz = new double[num_epoch];
double *carr_error_filt_hz = new double[num_epoch];
double *code_error_chips = new double[num_epoch];
double *code_error_filt_chips = new double[num_epoch];
double *CN0_SNV_dB_Hz = new double[num_epoch];
double *carrier_lock_test = new double[num_epoch];
double *aux1 = new double[num_epoch];
double *aux2 = new double[num_epoch];
unsigned int *PRN = new unsigned int[num_epoch];
try
{
if (dump_file.is_open())
{
for (long int i = 0; i < num_epoch; i++)
{
dump_file.read(reinterpret_cast<char *>(&abs_E[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&abs_P[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&abs_L[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&Prompt_I[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&Prompt_Q[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&PRN_start_sample_count[i]), sizeof(unsigned long int));
dump_file.read(reinterpret_cast<char *>(&acc_carrier_phase_rad[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&carrier_doppler_hz[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&code_freq_chips[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&carr_error_hz[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&carr_error_filt_hz[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&code_error_chips[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&code_error_filt_chips[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&CN0_SNV_dB_Hz[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&carrier_lock_test[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&aux1[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&aux2[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&PRN[i]), sizeof(unsigned int));
}
}
dump_file.close();
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Problem reading dump file:" << e.what() << std::endl;
delete[] abs_E;
delete[] abs_P;
delete[] abs_L;
delete[] Prompt_I;
delete[] Prompt_Q;
delete[] PRN_start_sample_count;
delete[] acc_carrier_phase_rad;
delete[] carrier_doppler_hz;
delete[] code_freq_chips;
delete[] carr_error_hz;
delete[] carr_error_filt_hz;
delete[] code_error_chips;
delete[] code_error_filt_chips;
delete[] CN0_SNV_dB_Hz;
delete[] carrier_lock_test;
delete[] aux1;
delete[] aux2;
delete[] PRN;
return 1;
}
// WRITE MAT FILE
mat_t *matfp;
matvar_t *matvar;
std::string filename = d_dump_filename;
filename.erase(filename.length() - 4, 4);
filename.append(".mat");
matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73);
if (reinterpret_cast<long *>(matfp) != NULL)
{
size_t dims[2] = {1, static_cast<size_t>(num_epoch)};
matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, acc_carrier_phase_rad, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_doppler_hz, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("code_freq_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_freq_chips, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("carr_error_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_hz, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_filt_hz, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("code_error_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_chips, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_filt_chips, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, CN0_SNV_dB_Hz, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("carrier_lock_test", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_lock_test, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("aux1", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux1, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
}
Mat_Close(matfp);
delete[] abs_E;
delete[] abs_P;
delete[] abs_L;
delete[] Prompt_I;
delete[] Prompt_Q;
delete[] PRN_start_sample_count;
delete[] acc_carrier_phase_rad;
delete[] carrier_doppler_hz;
delete[] code_freq_chips;
delete[] carr_error_hz;
delete[] carr_error_filt_hz;
delete[] code_error_chips;
delete[] code_error_filt_chips;
delete[] CN0_SNV_dB_Hz;
delete[] carrier_lock_test;
delete[] aux1;
delete[] aux2;
delete[] PRN;
return 0;
}
int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
{
// Block input data and block output stream pointers
const gr_complex *in = reinterpret_cast<const gr_complex *>(input_items[0]); // PRN start block alignment
Gnss_Synchro **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]);
// GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder
Gnss_Synchro current_synchro_data = Gnss_Synchro();
// process vars
double code_error_filt_secs_Ti = 0.0;
double CURRENT_INTEGRATION_TIME_S = 0.0;
double CORRECTED_INTEGRATION_TIME_S = 0.0;
if (d_enable_tracking == true)
{
// Fill the acquisition data
current_synchro_data = *d_acquisition_gnss_synchro;
// Receiver signal alignment
if (d_pull_in == true)
{
int samples_offset;
double acq_trk_shif_correction_samples;
int acq_to_trk_delay_samples;
acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp;
acq_trk_shif_correction_samples = d_correlation_length_samples - fmod(static_cast<double>(acq_to_trk_delay_samples), static_cast<double>(d_correlation_length_samples));
samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples);
current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset;
d_sample_counter += samples_offset; // count for the processed samples
d_pull_in = false;
d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * samples_offset / GLONASS_TWO_PI;
current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_cycles * GLONASS_TWO_PI;
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
current_synchro_data.fs = d_fs_in;
*out[0] = current_synchro_data;
consume_each(samples_offset); // shift input to perform alignment with local replica
return 1;
}
// ################# CARRIER WIPEOFF AND CORRELATORS ##############################
// perform carrier wipe-off and compute Early, Prompt and Late correlation
multicorrelator_cpu.set_input_output_vectors(d_correlator_outs, in);
multicorrelator_cpu.Carrier_wipeoff_multicorrelator_resampler(d_rem_carrier_phase_rad,
d_carrier_phase_step_rad,
d_rem_code_phase_chips,
d_code_phase_step_chips,
d_correlation_length_samples);
// ####### coherent integration extension
// keep the last symbols
d_E_history.push_back(d_correlator_outs[0]); // save early output
d_P_history.push_back(d_correlator_outs[1]); // save prompt output
d_L_history.push_back(d_correlator_outs[2]); // save late output
if (static_cast<int>(d_P_history.size()) > d_extend_correlation_ms)
{
d_E_history.pop_front();
d_P_history.pop_front();
d_L_history.pop_front();
}
bool enable_dll_pll;
if (d_enable_extended_integration == true)
{
long int symbol_diff = round(1000.0 * ((static_cast<double>(d_sample_counter) + d_rem_code_phase_samples) / static_cast<double>(d_fs_in) - d_preamble_timestamp_s));
if (symbol_diff > 0 and symbol_diff % d_extend_correlation_ms == 0)
{
// compute coherent integration and enable tracking loop
// perform coherent integration using correlator output history
// std::cout<<"##### RESET COHERENT INTEGRATION ####"<<std::endl;
d_correlator_outs[0] = gr_complex(0.0, 0.0);
d_correlator_outs[1] = gr_complex(0.0, 0.0);
d_correlator_outs[2] = gr_complex(0.0, 0.0);
for (int n = 0; n < d_extend_correlation_ms; n++)
{
d_correlator_outs[0] += d_E_history.at(n);
d_correlator_outs[1] += d_P_history.at(n);
d_correlator_outs[2] += d_L_history.at(n);
}
if (d_preamble_synchronized == false)
{
d_code_loop_filter.set_DLL_BW(d_dll_bw_narrow_hz);
d_carrier_loop_filter.set_params(10.0, d_pll_bw_narrow_hz, 2);
d_preamble_synchronized = true;
std::cout << "Enabled " << d_extend_correlation_ms << " [ms] extended correlator for CH " << d_channel << " : Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN)
<< " pll_bw = " << d_pll_bw_hz << " [Hz], pll_narrow_bw = " << d_pll_bw_narrow_hz << " [Hz]" << std::endl
<< " dll_bw = " << d_dll_bw_hz << " [Hz], dll_narrow_bw = " << d_dll_bw_narrow_hz << " [Hz]" << std::endl;
}
// UPDATE INTEGRATION TIME
CURRENT_INTEGRATION_TIME_S = static_cast<double>(d_extend_correlation_ms) * GLONASS_L2_CA_CODE_PERIOD;
d_code_loop_filter.set_pdi(CURRENT_INTEGRATION_TIME_S);
enable_dll_pll = true;
}
else
{
if (d_preamble_synchronized == true)
{
// continue extended coherent correlation
// Compute the next buffer length based on the period of the PRN sequence and the code phase error estimation
double T_chip_seconds = 1.0 / d_code_freq_chips;
double T_prn_seconds = T_chip_seconds * GLONASS_L2_CA_CODE_LENGTH_CHIPS;
double T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in);
int K_prn_samples = round(T_prn_samples);
double K_T_prn_error_samples = K_prn_samples - T_prn_samples;
d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples;
d_rem_code_phase_integer_samples = round(d_rem_code_phase_samples); // round to a discrete number of samples
d_correlation_length_samples = K_prn_samples + d_rem_code_phase_integer_samples;
d_rem_code_phase_samples = d_rem_code_phase_samples - d_rem_code_phase_integer_samples;
// code phase step (Code resampler phase increment per sample) [chips/sample]
d_code_phase_step_chips = d_code_freq_chips / static_cast<double>(d_fs_in);
// remnant code phase [chips]
d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast<double>(d_fs_in));
d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + d_carrier_phase_step_rad * static_cast<double>(d_correlation_length_samples), GLONASS_TWO_PI);
// UPDATE ACCUMULATED CARRIER PHASE
CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in));
d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / GLONASS_TWO_PI;
// disable tracking loop and inform telemetry decoder
enable_dll_pll = false;
}
else
{
// perform basic (1ms) correlation
// UPDATE INTEGRATION TIME
CURRENT_INTEGRATION_TIME_S = static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in);
d_code_loop_filter.set_pdi(CURRENT_INTEGRATION_TIME_S);
enable_dll_pll = true;
}
}
}
else
{
// UPDATE INTEGRATION TIME
CURRENT_INTEGRATION_TIME_S = static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in);
enable_dll_pll = true;
}
if (enable_dll_pll == true)
{
// ################## PLL ##########################################################
// Update PLL discriminator [rads/Ti -> Secs/Ti]
d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / GLONASS_TWO_PI; // prompt output
d_carrier_doppler_old_hz = d_carrier_doppler_hz;
// Carrier discriminator filter
// NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan
// Input [s/Ti] -> output [Hz]
d_carrier_doppler_hz = d_carrier_loop_filter.get_carrier_error(0.0, d_carr_phase_error_secs_Ti, CURRENT_INTEGRATION_TIME_S);
// PLL to DLL assistance [Secs/Ti]
d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch;
// code Doppler frequency update
d_code_freq_chips = GLONASS_L2_CA_CODE_RATE_HZ + (((d_carrier_doppler_hz - d_carrier_doppler_old_hz) * GLONASS_L2_CA_CODE_RATE_HZ) / d_glonass_freq_ch);
// ################## 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
// 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;
code_error_filt_secs_Ti = d_code_error_filt_chips_Ti / d_code_freq_chips; // [s/Ti]
// ################## CARRIER AND CODE NCO BUFFER ALIGNMENT #######################
// keep alignment parameters for the next input buffer
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
double T_chip_seconds = 1.0 / d_code_freq_chips;
double T_prn_seconds = T_chip_seconds * GLONASS_L2_CA_CODE_LENGTH_CHIPS;
double T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in);
double K_prn_samples = round(T_prn_samples);
double K_T_prn_error_samples = K_prn_samples - T_prn_samples;
d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples + code_error_filt_secs_Ti * static_cast<double>(d_fs_in); //(code_error_filt_secs_Ti + d_pll_to_dll_assist_secs_Ti) * static_cast<double>(d_fs_in);
d_rem_code_phase_integer_samples = round(d_rem_code_phase_samples); // round to a discrete number of samples
d_correlation_length_samples = K_prn_samples + d_rem_code_phase_integer_samples;
d_rem_code_phase_samples = d_rem_code_phase_samples - d_rem_code_phase_integer_samples;
//################### PLL COMMANDS #################################################
//carrier phase step (NCO phase increment per sample) [rads/sample]
d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in);
d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / GLONASS_TWO_PI;
// UPDATE ACCUMULATED CARRIER PHASE
CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in));
//remnant carrier phase [rad]
d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + GLONASS_TWO_PI * d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S, GLONASS_TWO_PI);
//################### DLL COMMANDS #################################################
//code phase step (Code resampler phase increment per sample) [chips/sample]
d_code_phase_step_chips = d_code_freq_chips / static_cast<double>(d_fs_in);
//remnant code phase [chips]
d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast<double>(d_fs_in));
// ####### CN0 ESTIMATION AND LOCK DETECTORS #######################################
if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES)
{
// fill buffer with prompt correlator output values
d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1]; // prompt
d_cn0_estimation_counter++;
}
else
{
d_cn0_estimation_counter = 0;
// Code lock indicator
d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, GLONASS_L2_CA_CODE_LENGTH_CHIPS);
// Carrier lock indicator
d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES);
// Loss of lock detection
if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min)
{
d_carrier_lock_fail_counter++;
}
else
{
if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--;
}
if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail)
{
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
this->message_port_pub(pmt::mp("events"), pmt::from_long(3)); //3 -> loss of lock
d_carrier_lock_fail_counter = 0;
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
}
}
// ########### Output the tracking data to navigation and PVT ##########
current_synchro_data.Prompt_I = static_cast<double>((d_correlator_outs[1]).real());
current_synchro_data.Prompt_Q = static_cast<double>((d_correlator_outs[1]).imag());
current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples;
current_synchro_data.Code_phase_samples = d_rem_code_phase_samples;
current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles;
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
current_synchro_data.Flag_valid_symbol_output = true;
if (d_preamble_synchronized == true)
{
current_synchro_data.correlation_length_ms = d_extend_correlation_ms;
}
else
{
current_synchro_data.correlation_length_ms = 1;
}
}
else
{
current_synchro_data.Prompt_I = static_cast<double>((d_correlator_outs[1]).real());
current_synchro_data.Prompt_Q = static_cast<double>((d_correlator_outs[1]).imag());
current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples;
current_synchro_data.Code_phase_samples = d_rem_code_phase_samples;
current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles;
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; // todo: project the carrier doppler
current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
}
}
else
{
for (int n = 0; n < d_n_correlator_taps; n++)
{
d_correlator_outs[n] = gr_complex(0, 0);
}
current_synchro_data.System = {'R'};
current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples;
}
//assign the GNURadio block output data
current_synchro_data.fs = d_fs_in;
*out[0] = current_synchro_data;
if (d_dump)
{
// MULTIPLEXED FILE RECORDING - Record results to file
float prompt_I;
float prompt_Q;
float tmp_E, tmp_P, tmp_L;
float tmp_VE = 0.0;
float tmp_VL = 0.0;
float tmp_float;
prompt_I = d_correlator_outs[1].real();
prompt_Q = d_correlator_outs[1].imag();
tmp_E = std::abs<float>(d_correlator_outs[0]);
tmp_P = std::abs<float>(d_correlator_outs[1]);
tmp_L = std::abs<float>(d_correlator_outs[2]);
try
{
// Dump correlators output
d_dump_file.write(reinterpret_cast<char *>(&tmp_VE), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_E), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_P), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_L), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_VL), sizeof(float));
// PROMPT I and Q (to analyze navigation symbols)
d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float));
// PRN start sample stamp
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(unsigned long int));
// accumulated carrier phase
tmp_float = d_acc_carrier_phase_cycles * GLONASS_TWO_PI;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// carrier and code frequency
tmp_float = d_carrier_doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_freq_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// PLL commands
tmp_float = 1.0 / (d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = 1.0 / (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// DLL commands
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_error_filt_chips_Ti;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// CN0 and carrier lock test
tmp_float = d_CN0_SNV_dB_Hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_carrier_lock_test;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// AUX vars (for debug purposes)
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
double tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
// PRN
unsigned int prn_ = d_acquisition_gnss_synchro->PRN;
d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int));
}
catch (const std::ifstream::failure *e)
{
LOG(WARNING) << "Exception writing trk dump file " << e->what();
}
}
consume_each(d_correlation_length_samples); // this is necessary in gr::block derivates
d_sample_counter += d_correlation_length_samples; //count for the processed samples
return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false
}
void glonass_l2_ca_dll_pll_c_aid_tracking_cc::set_channel(unsigned int channel)
{
d_channel = channel;
LOG(INFO) << "Tracking Channel set to " << d_channel;
// ############# ENABLE DATA FILE LOG #################
if (d_dump == true)
{
if (d_dump_file.is_open() == false)
{
try
{
d_dump_filename.append(boost::lexical_cast<std::string>(d_channel));
d_dump_filename.append(".dat");
d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str() << std::endl;
}
catch (const std::ifstream::failure *e)
{
LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e->what() << std::endl;
}
}
}
}
void glonass_l2_ca_dll_pll_c_aid_tracking_cc::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro)
{
d_acquisition_gnss_synchro = p_gnss_synchro;
}

View File

@@ -0,0 +1,203 @@
/*!
* \file glonass_l2_ca_dll_pll_c_aid_tracking_cc.h
* \brief Implementation of a code DLL + carrier PLL tracking block
* \author Damian Miralles, 2018. dmiralles2009(at)gmail.com
*
*
* Code DLL + carrier PLL according to the algorithms described in:
* K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency
* Approach, Birkha user, 2007
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2017 (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_GLONASS_L2_CA_DLL_PLL_C_AID_TRACKING_CC_H
#define GNSS_SDR_GLONASS_L2_CA_DLL_PLL_C_AID_TRACKING_CC_H
#include "gnss_synchro.h"
#include "tracking_2nd_DLL_filter.h"
#include "tracking_FLL_PLL_filter.h"
//#include "tracking_loop_filter.h"
#include "cpu_multicorrelator.h"
#include <gnuradio/block.h>
#include <pmt/pmt.h>
#include <fstream>
#include <map>
#include <deque>
#include <string>
class glonass_l2_ca_dll_pll_c_aid_tracking_cc;
typedef boost::shared_ptr<glonass_l2_ca_dll_pll_c_aid_tracking_cc>
glonass_l2_ca_dll_pll_c_aid_tracking_cc_sptr;
glonass_l2_ca_dll_pll_c_aid_tracking_cc_sptr
glonass_l2_ca_dll_pll_c_aid_make_tracking_cc(long if_freq,
long 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,
int extend_correlation_ms,
float early_late_space_chips);
/*!
* \brief This class implements a DLL + PLL tracking loop block
*/
class glonass_l2_ca_dll_pll_c_aid_tracking_cc : public gr::block
{
public:
~glonass_l2_ca_dll_pll_c_aid_tracking_cc();
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 glonass_l2_ca_dll_pll_c_aid_tracking_cc_sptr
glonass_l2_ca_dll_pll_c_aid_make_tracking_cc(long if_freq,
long 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,
int extend_correlation_ms,
float early_late_space_chips);
glonass_l2_ca_dll_pll_c_aid_tracking_cc(long if_freq,
long 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,
int extend_correlation_ms,
float early_late_space_chips);
// tracking configuration vars
unsigned int d_vector_length;
bool d_dump;
Gnss_Synchro* d_acquisition_gnss_synchro;
unsigned int d_channel;
long d_if_freq;
long d_fs_in;
double d_glonass_freq_ch;
double d_early_late_spc_chips;
int d_n_correlator_taps;
gr_complex* d_ca_code;
float* d_local_code_shift_chips;
gr_complex* d_correlator_outs;
cpu_multicorrelator multicorrelator_cpu;
// remaining code phase and carrier phase between tracking loops
double d_rem_code_phase_samples;
double d_rem_code_phase_chips;
double d_rem_carrier_phase_rad;
int d_rem_code_phase_integer_samples;
// PLL and DLL filter library
//Tracking_2nd_DLL_filter d_code_loop_filter;
Tracking_2nd_DLL_filter d_code_loop_filter;
Tracking_FLL_PLL_filter d_carrier_loop_filter;
// acquisition
double d_acq_code_phase_samples;
double d_acq_carrier_doppler_hz;
// tracking vars
float d_dll_bw_hz;
float d_pll_bw_hz;
float d_dll_bw_narrow_hz;
float d_pll_bw_narrow_hz;
double d_code_freq_chips;
double d_code_phase_step_chips;
double d_carrier_doppler_hz;
double d_carrier_frequency_hz;
double d_carrier_doppler_old_hz;
double d_carrier_phase_step_rad;
double d_acc_carrier_phase_cycles;
double d_code_phase_samples;
double d_pll_to_dll_assist_secs_Ti;
double d_code_error_chips_Ti;
double d_code_error_filt_chips_s;
double d_code_error_filt_chips_Ti;
double d_carr_phase_error_secs_Ti;
// symbol history to detect bit transition
std::deque<gr_complex> d_E_history;
std::deque<gr_complex> d_P_history;
std::deque<gr_complex> d_L_history;
double d_preamble_timestamp_s;
int d_extend_correlation_ms;
bool d_enable_extended_integration;
bool d_preamble_synchronized;
void msg_handler_preamble_index(pmt::pmt_t msg);
//Integration period in samples
int d_correlation_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;
gr_complex* d_Prompt_buffer;
double d_carrier_lock_test;
double d_CN0_SNV_dB_Hz;
double d_carrier_lock_threshold;
int d_carrier_lock_fail_counter;
// control vars
bool d_enable_tracking;
bool d_pull_in;
// file dump
std::string d_dump_filename;
std::ofstream d_dump_file;
std::map<std::string, std::string> systemName;
std::string sys;
int save_matfile();
};
#endif //GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_CC_H

View File

@@ -0,0 +1,918 @@
/*!
* \file glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc
* \brief Implementation of a code DLL + carrier PLL tracking block
* \author Damian Miralles, 2018. dmiralles2009(at)gmail.com
*
*
* Code DLL + carrier PLL according to the algorithms described in:
* K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency
* Approach, Birkha user, 2007
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2017 (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/>.
*
* -------------------------------------------------------------------------
*/
#include "glonass_l2_ca_dll_pll_c_aid_tracking_sc.h"
#include "gnss_synchro.h"
#include "glonass_l2_signal_processing.h"
#include "tracking_discriminators.h"
#include "lock_detectors.h"
#include "GLONASS_L1_L2_CA.h"
#include "gnss_sdr_flags.h"
#include "control_message_factory.h"
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <gnuradio/io_signature.h>
#include <matio.h>
#include <pmt/pmt.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <glog/logging.h>
#include <cmath>
#include <iostream>
#include <memory>
#include <sstream>
#define CN0_ESTIMATION_SAMPLES 10
using google::LogMessage;
glonass_l2_ca_dll_pll_c_aid_tracking_sc_sptr
glonass_l2_ca_dll_pll_c_aid_make_tracking_sc(
long if_freq,
long 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,
int extend_correlation_ms,
float early_late_space_chips)
{
return glonass_l2_ca_dll_pll_c_aid_tracking_sc_sptr(new glonass_l2_ca_dll_pll_c_aid_tracking_sc(if_freq,
fs_in, vector_length, dump, dump_filename, pll_bw_hz, dll_bw_hz, pll_bw_narrow_hz, dll_bw_narrow_hz, extend_correlation_ms, early_late_space_chips));
}
void glonass_l2_ca_dll_pll_c_aid_tracking_sc::forecast(int noutput_items,
gr_vector_int &ninput_items_required)
{
if (noutput_items != 0)
{
ninput_items_required[0] = static_cast<int>(d_vector_length) * 2; //set the required available samples in each call
}
}
void glonass_l2_ca_dll_pll_c_aid_tracking_sc::msg_handler_preamble_index(pmt::pmt_t msg)
{
//pmt::print(msg);
DLOG(INFO) << "Extended correlation enabled for Tracking CH " << d_channel << ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN);
if (d_enable_extended_integration == false) //avoid re-setting preamble indicator
{
d_preamble_timestamp_s = pmt::to_double(msg);
d_enable_extended_integration = true;
d_preamble_synchronized = false;
}
}
glonass_l2_ca_dll_pll_c_aid_tracking_sc::glonass_l2_ca_dll_pll_c_aid_tracking_sc(
long if_freq,
long 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,
int extend_correlation_ms,
float early_late_space_chips) : gr::block("glonass_l1_ca_dll_pll_c_aid_tracking_sc", gr::io_signature::make(1, 1, sizeof(lv_16sc_t)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{
// Telemetry bit synchronization message port input
this->message_port_register_in(pmt::mp("preamble_timestamp_s"));
this->set_msg_handler(pmt::mp("preamble_timestamp_s"),
boost::bind(&glonass_l2_ca_dll_pll_c_aid_tracking_sc::msg_handler_preamble_index, this, _1));
this->message_port_register_out(pmt::mp("events"));
// initialize internal vars
d_dump = dump;
d_if_freq = if_freq;
d_fs_in = fs_in;
d_vector_length = vector_length;
d_dump_filename = dump_filename;
d_correlation_length_samples = static_cast<int>(d_vector_length);
// Initialize tracking ==========================================
d_pll_bw_hz = pll_bw_hz;
d_dll_bw_hz = dll_bw_hz;
d_pll_bw_narrow_hz = pll_bw_narrow_hz;
d_dll_bw_narrow_hz = dll_bw_narrow_hz;
d_code_loop_filter.set_DLL_BW(d_dll_bw_hz);
d_carrier_loop_filter.set_params(10.0, d_pll_bw_hz, 2);
d_extend_correlation_ms = extend_correlation_ms;
// --- DLL variables --------------------------------------------------------
d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips)
// Initialization of local code replica
// Get space for a vector with the C/A code replica sampled 1x/chip
d_ca_code = static_cast<gr_complex *>(volk_gnsssdr_malloc(static_cast<int>(GLONASS_L2_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
d_ca_code_16sc = static_cast<lv_16sc_t *>(volk_gnsssdr_malloc(static_cast<int>(GLONASS_L2_CA_CODE_LENGTH_CHIPS) * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment()));
// correlator outputs (scalar)
d_n_correlator_taps = 3; // Early, Prompt, and Late
d_correlator_outs_16sc = static_cast<lv_16sc_t *>(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment()));
for (int n = 0; n < d_n_correlator_taps; n++)
{
d_correlator_outs_16sc[n] = lv_cmake(0, 0);
}
d_local_code_shift_chips = static_cast<float *>(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(float), volk_gnsssdr_get_alignment()));
// Set TAPs delay values [chips]
d_local_code_shift_chips[0] = -d_early_late_spc_chips;
d_local_code_shift_chips[1] = 0.0;
d_local_code_shift_chips[2] = d_early_late_spc_chips;
multicorrelator_cpu_16sc.init(2 * d_correlation_length_samples, d_n_correlator_taps);
//--- Perform initializations ------------------------------
// define initial code frequency basis of NCO
d_code_freq_chips = GLONASS_L2_CA_CODE_RATE_HZ;
// define residual code phase (in chips)
d_rem_code_phase_samples = 0.0;
// define residual carrier phase
d_rem_carrier_phase_rad = 0.0;
// sample synchronization
d_sample_counter = 0; //(from trk to tlm)
d_acq_sample_stamp = 0;
d_enable_tracking = false;
d_pull_in = false;
// CN0 estimation and lock detector buffers
d_cn0_estimation_counter = 0;
d_Prompt_buffer = new gr_complex[FLAGS_cn0_samples];
d_carrier_lock_test = 1;
d_CN0_SNV_dB_Hz = 0;
d_carrier_lock_fail_counter = 0;
d_carrier_lock_threshold = FLAGS_carrier_lock_th;
systemName["R"] = std::string("Glonass");
set_relative_rate(1.0 / static_cast<double>(d_vector_length));
d_acquisition_gnss_synchro = 0;
d_channel = 0;
d_acq_code_phase_samples = 0.0;
d_acq_carrier_doppler_hz = 0.0;
d_carrier_doppler_hz = 0.0;
d_acc_carrier_phase_cycles = 0.0;
d_code_phase_samples = 0.0;
d_enable_extended_integration = false;
d_preamble_synchronized = false;
d_rem_code_phase_integer_samples = 0;
d_code_error_chips_Ti = 0.0;
d_pll_to_dll_assist_secs_Ti = 0.0;
d_rem_code_phase_chips = 0.0;
d_code_phase_step_chips = 0.0;
d_carrier_phase_step_rad = 0.0;
d_code_error_filt_chips_s = 0.0;
d_code_error_filt_chips_Ti = 0.0;
d_preamble_timestamp_s = 0.0;
d_carr_phase_error_secs_Ti = 0.0;
d_carrier_frequency_hz = 0.0;
d_carrier_doppler_old_hz = 0.0;
d_glonass_freq_ch = 0;
//set_min_output_buffer((long int)300);
}
void glonass_l2_ca_dll_pll_c_aid_tracking_sc::start_tracking()
{
/*
* correct the code phase according to the delay between acq and trk
*/
d_acq_code_phase_samples = d_acquisition_gnss_synchro->Acq_delay_samples;
d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz;
d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples;
long int acq_trk_diff_samples;
double acq_trk_diff_seconds;
acq_trk_diff_samples = static_cast<long int>(d_sample_counter) - static_cast<long int>(d_acq_sample_stamp); //-d_vector_length;
DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples;
acq_trk_diff_seconds = static_cast<double>(acq_trk_diff_samples) / static_cast<double>(d_fs_in);
// Doppler effect
// Fd=(C/(C+Vr))*F
d_glonass_freq_ch = GLONASS_L2_CA_FREQ_HZ + (GLONASS_L2_CA_FREQ_HZ * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN));
double radial_velocity = (d_glonass_freq_ch + d_acq_carrier_doppler_hz) / d_glonass_freq_ch;
// new chip and prn sequence periods based on acq Doppler
double T_chip_mod_seconds;
double T_prn_mod_seconds;
double T_prn_mod_samples;
d_code_freq_chips = radial_velocity * GLONASS_L2_CA_CODE_RATE_HZ;
d_code_phase_step_chips = static_cast<double>(d_code_freq_chips) / static_cast<double>(d_fs_in);
T_chip_mod_seconds = 1.0 / d_code_freq_chips;
T_prn_mod_seconds = T_chip_mod_seconds * GLONASS_L2_CA_CODE_LENGTH_CHIPS;
T_prn_mod_samples = T_prn_mod_seconds * static_cast<double>(d_fs_in);
d_correlation_length_samples = round(T_prn_mod_samples);
double T_prn_true_seconds = GLONASS_L2_CA_CODE_LENGTH_CHIPS / GLONASS_L2_CA_CODE_RATE_HZ;
double T_prn_true_samples = T_prn_true_seconds * static_cast<double>(d_fs_in);
double T_prn_diff_seconds = T_prn_true_seconds - T_prn_mod_seconds;
double N_prn_diff = acq_trk_diff_seconds / T_prn_true_seconds;
double corrected_acq_phase_samples, delay_correction_samples;
corrected_acq_phase_samples = fmod((d_acq_code_phase_samples + T_prn_diff_seconds * N_prn_diff * static_cast<double>(d_fs_in)), T_prn_true_samples);
if (corrected_acq_phase_samples < 0)
{
corrected_acq_phase_samples = T_prn_mod_samples + corrected_acq_phase_samples;
}
delay_correction_samples = d_acq_code_phase_samples - corrected_acq_phase_samples;
d_acq_code_phase_samples = corrected_acq_phase_samples;
d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ2_GLO * static_cast<double>(GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)));
;
d_carrier_doppler_hz = d_acq_carrier_doppler_hz;
d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast<double>(d_fs_in);
// DLL/PLL filter initialization
d_carrier_loop_filter.initialize(d_carrier_frequency_hz); // The carrier loop filter implements the Doppler accumulator
d_code_loop_filter.initialize(); // initialize the code filter
// generate local reference ALWAYS starting at chip 1 (1 sample per chip)
glonass_l2_ca_code_gen_complex(d_ca_code, 0);
volk_gnsssdr_32fc_convert_16ic(d_ca_code_16sc, d_ca_code, static_cast<int>(GLONASS_L2_CA_CODE_LENGTH_CHIPS));
multicorrelator_cpu_16sc.set_local_code_and_taps(static_cast<int>(GLONASS_L2_CA_CODE_LENGTH_CHIPS), d_ca_code_16sc, d_local_code_shift_chips);
for (int n = 0; n < d_n_correlator_taps; n++)
{
d_correlator_outs_16sc[n] = lv_16sc_t(0, 0);
}
d_carrier_lock_fail_counter = 0;
d_rem_code_phase_samples = 0.0;
d_rem_carrier_phase_rad = 0.0;
d_rem_code_phase_chips = 0.0;
d_acc_carrier_phase_cycles = 0.0;
d_pll_to_dll_assist_secs_Ti = 0.0;
d_code_phase_samples = d_acq_code_phase_samples;
std::string sys_ = &d_acquisition_gnss_synchro->System;
sys = sys_.substr(0, 1);
// DEBUG OUTPUT
std::cout << "Tracking start on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl;
LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel;
// enable tracking
d_pull_in = true;
d_enable_tracking = true;
d_enable_extended_integration = true;
d_preamble_synchronized = true;
LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz
<< " Code Phase correction [samples]=" << delay_correction_samples
<< " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples;
}
int glonass_l2_ca_dll_pll_c_aid_tracking_sc::save_matfile()
{
// READ DUMP FILE
std::ifstream::pos_type size;
int number_of_double_vars = 11;
int number_of_float_vars = 5;
int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars +
sizeof(float) * number_of_float_vars + sizeof(unsigned int);
std::ifstream dump_file;
dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate);
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Problem opening dump file:" << e.what() << std::endl;
return 1;
}
// count number of epochs and rewind
long int num_epoch = 0;
if (dump_file.is_open())
{
size = dump_file.tellg();
num_epoch = static_cast<long int>(size) / static_cast<long int>(epoch_size_bytes);
dump_file.seekg(0, std::ios::beg);
}
else
{
return 1;
}
float *abs_E = new float[num_epoch];
float *abs_P = new float[num_epoch];
float *abs_L = new float[num_epoch];
float *Prompt_I = new float[num_epoch];
float *Prompt_Q = new float[num_epoch];
unsigned long int *PRN_start_sample_count = new unsigned long int[num_epoch];
double *acc_carrier_phase_rad = new double[num_epoch];
double *carrier_doppler_hz = new double[num_epoch];
double *code_freq_chips = new double[num_epoch];
double *carr_error_hz = new double[num_epoch];
double *carr_error_filt_hz = new double[num_epoch];
double *code_error_chips = new double[num_epoch];
double *code_error_filt_chips = new double[num_epoch];
double *CN0_SNV_dB_Hz = new double[num_epoch];
double *carrier_lock_test = new double[num_epoch];
double *aux1 = new double[num_epoch];
double *aux2 = new double[num_epoch];
unsigned int *PRN = new unsigned int[num_epoch];
try
{
if (dump_file.is_open())
{
for (long int i = 0; i < num_epoch; i++)
{
dump_file.read(reinterpret_cast<char *>(&abs_E[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&abs_P[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&abs_L[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&Prompt_I[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&Prompt_Q[i]), sizeof(float));
dump_file.read(reinterpret_cast<char *>(&PRN_start_sample_count[i]), sizeof(unsigned long int));
dump_file.read(reinterpret_cast<char *>(&acc_carrier_phase_rad[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&carrier_doppler_hz[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&code_freq_chips[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&carr_error_hz[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&carr_error_filt_hz[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&code_error_chips[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&code_error_filt_chips[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&CN0_SNV_dB_Hz[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&carrier_lock_test[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&aux1[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&aux2[i]), sizeof(double));
dump_file.read(reinterpret_cast<char *>(&PRN[i]), sizeof(unsigned int));
}
}
dump_file.close();
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Problem reading dump file:" << e.what() << std::endl;
delete[] abs_E;
delete[] abs_P;
delete[] abs_L;
delete[] Prompt_I;
delete[] Prompt_Q;
delete[] PRN_start_sample_count;
delete[] acc_carrier_phase_rad;
delete[] carrier_doppler_hz;
delete[] code_freq_chips;
delete[] carr_error_hz;
delete[] carr_error_filt_hz;
delete[] code_error_chips;
delete[] code_error_filt_chips;
delete[] CN0_SNV_dB_Hz;
delete[] carrier_lock_test;
delete[] aux1;
delete[] aux2;
delete[] PRN;
return 1;
}
// WRITE MAT FILE
mat_t *matfp;
matvar_t *matvar;
std::string filename = d_dump_filename;
filename.erase(filename.length() - 4, 4);
filename.append(".mat");
matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73);
if (reinterpret_cast<long *>(matfp) != NULL)
{
size_t dims[2] = {1, static_cast<size_t>(num_epoch)};
matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, acc_carrier_phase_rad, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_doppler_hz, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("code_freq_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_freq_chips, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("carr_error_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_hz, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_filt_hz, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("code_error_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_chips, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_filt_chips, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, CN0_SNV_dB_Hz, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("carrier_lock_test", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_lock_test, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("aux1", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux1, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
}
Mat_Close(matfp);
delete[] abs_E;
delete[] abs_P;
delete[] abs_L;
delete[] Prompt_I;
delete[] Prompt_Q;
delete[] PRN_start_sample_count;
delete[] acc_carrier_phase_rad;
delete[] carrier_doppler_hz;
delete[] code_freq_chips;
delete[] carr_error_hz;
delete[] carr_error_filt_hz;
delete[] code_error_chips;
delete[] code_error_filt_chips;
delete[] CN0_SNV_dB_Hz;
delete[] carrier_lock_test;
delete[] aux1;
delete[] aux2;
delete[] PRN;
return 0;
}
glonass_l2_ca_dll_pll_c_aid_tracking_sc::~glonass_l2_ca_dll_pll_c_aid_tracking_sc()
{
if (d_dump_file.is_open())
{
try
{
d_dump_file.close();
}
catch (const std::exception &ex)
{
LOG(WARNING) << "Exception in destructor " << ex.what();
}
}
if (d_dump)
{
if (d_channel == 0)
{
std::cout << "Writing .mat files ...";
}
glonass_l2_ca_dll_pll_c_aid_tracking_sc::save_matfile();
if (d_channel == 0)
{
std::cout << " done." << std::endl;
}
}
volk_gnsssdr_free(d_local_code_shift_chips);
volk_gnsssdr_free(d_ca_code);
volk_gnsssdr_free(d_ca_code_16sc);
volk_gnsssdr_free(d_correlator_outs_16sc);
delete[] d_Prompt_buffer;
multicorrelator_cpu_16sc.free();
}
int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
{
// Block input data and block output stream pointers
const lv_16sc_t *in = reinterpret_cast<const lv_16sc_t *>(input_items[0]); // PRN start block alignment
Gnss_Synchro **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]);
// GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder
Gnss_Synchro current_synchro_data = Gnss_Synchro();
// process vars
double code_error_filt_secs_Ti = 0.0;
double CURRENT_INTEGRATION_TIME_S = 0.0;
double CORRECTED_INTEGRATION_TIME_S = 0.0;
if (d_enable_tracking == true)
{
// Fill the acquisition data
current_synchro_data = *d_acquisition_gnss_synchro;
// Receiver signal alignment
if (d_pull_in == true)
{
int samples_offset;
double acq_trk_shif_correction_samples;
int acq_to_trk_delay_samples;
acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp;
acq_trk_shif_correction_samples = d_correlation_length_samples - fmod(static_cast<double>(acq_to_trk_delay_samples), static_cast<double>(d_correlation_length_samples));
samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples);
current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset;
d_sample_counter += samples_offset; // count for the processed samples
d_pull_in = false;
d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * samples_offset / GLONASS_TWO_PI;
current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_cycles * GLONASS_TWO_PI;
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
current_synchro_data.fs = d_fs_in;
*out[0] = current_synchro_data;
consume_each(samples_offset); // shift input to perform alignment with local replica
return 1;
}
// ################# CARRIER WIPEOFF AND CORRELATORS ##############################
// perform carrier wipe-off and compute Early, Prompt and Late correlation
multicorrelator_cpu_16sc.set_input_output_vectors(d_correlator_outs_16sc, in);
multicorrelator_cpu_16sc.Carrier_wipeoff_multicorrelator_resampler(d_rem_carrier_phase_rad,
d_carrier_phase_step_rad,
d_rem_code_phase_chips,
d_code_phase_step_chips,
d_correlation_length_samples);
// ####### coherent integration extension
// keep the last symbols
d_E_history.push_back(d_correlator_outs_16sc[0]); // save early output
d_P_history.push_back(d_correlator_outs_16sc[1]); // save prompt output
d_L_history.push_back(d_correlator_outs_16sc[2]); // save late output
if (static_cast<int>(d_P_history.size()) > d_extend_correlation_ms)
{
d_E_history.pop_front();
d_P_history.pop_front();
d_L_history.pop_front();
}
bool enable_dll_pll;
if (d_enable_extended_integration == true)
{
long int symbol_diff = round(1000.0 * ((static_cast<double>(d_sample_counter) + d_rem_code_phase_samples) / static_cast<double>(d_fs_in) - d_preamble_timestamp_s));
if (symbol_diff > 0 and symbol_diff % d_extend_correlation_ms == 0)
{
// compute coherent integration and enable tracking loop
// perform coherent integration using correlator output history
// std::cout<<"##### RESET COHERENT INTEGRATION ####"<<std::endl;
d_correlator_outs_16sc[0] = lv_cmake(0, 0);
d_correlator_outs_16sc[1] = lv_cmake(0, 0);
d_correlator_outs_16sc[2] = lv_cmake(0, 0);
for (int n = 0; n < d_extend_correlation_ms; n++)
{
d_correlator_outs_16sc[0] += d_E_history.at(n);
d_correlator_outs_16sc[1] += d_P_history.at(n);
d_correlator_outs_16sc[2] += d_L_history.at(n);
}
if (d_preamble_synchronized == false)
{
d_code_loop_filter.set_DLL_BW(d_dll_bw_narrow_hz);
d_carrier_loop_filter.set_params(10.0, d_pll_bw_narrow_hz, 2);
d_preamble_synchronized = true;
std::cout << "Enabled " << d_extend_correlation_ms << " [ms] extended correlator for CH " << d_channel << " : Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN)
<< " pll_bw = " << d_pll_bw_hz << " [Hz], pll_narrow_bw = " << d_pll_bw_narrow_hz << " [Hz]" << std::endl
<< " dll_bw = " << d_dll_bw_hz << " [Hz], dll_narrow_bw = " << d_dll_bw_narrow_hz << " [Hz]" << std::endl;
}
// UPDATE INTEGRATION TIME
CURRENT_INTEGRATION_TIME_S = static_cast<double>(d_extend_correlation_ms) * GLONASS_L2_CA_CODE_PERIOD;
enable_dll_pll = true;
}
else
{
if (d_preamble_synchronized == true)
{
// continue extended coherent correlation
// Compute the next buffer length based on the period of the PRN sequence and the code phase error estimation
double T_chip_seconds = 1.0 / d_code_freq_chips;
double T_prn_seconds = T_chip_seconds * GLONASS_L2_CA_CODE_LENGTH_CHIPS;
double T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in);
int K_prn_samples = round(T_prn_samples);
double K_T_prn_error_samples = K_prn_samples - T_prn_samples;
d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples;
d_rem_code_phase_integer_samples = round(d_rem_code_phase_samples); // round to a discrete number of samples
d_correlation_length_samples = K_prn_samples + d_rem_code_phase_integer_samples;
d_rem_code_phase_samples = d_rem_code_phase_samples - d_rem_code_phase_integer_samples;
// code phase step (Code resampler phase increment per sample) [chips/sample]
d_code_phase_step_chips = d_code_freq_chips / static_cast<double>(d_fs_in);
// remnant code phase [chips]
d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast<double>(d_fs_in));
d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + d_carrier_phase_step_rad * static_cast<double>(d_correlation_length_samples), GLONASS_TWO_PI);
// UPDATE ACCUMULATED CARRIER PHASE
CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in));
d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / GLONASS_TWO_PI;
// disable tracking loop and inform telemetry decoder
enable_dll_pll = false;
}
else
{
// perform basic (1ms) correlation
// UPDATE INTEGRATION TIME
CURRENT_INTEGRATION_TIME_S = static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in);
enable_dll_pll = true;
}
}
}
else
{
// UPDATE INTEGRATION TIME
CURRENT_INTEGRATION_TIME_S = static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in);
enable_dll_pll = true;
}
if (enable_dll_pll == true)
{
// ################## PLL ##########################################################
// Update PLL discriminator [rads/Ti -> Secs/Ti]
d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(std::complex<float>(d_correlator_outs_16sc[1].real(), d_correlator_outs_16sc[1].imag())) / GLONASS_TWO_PI; //prompt output
d_carrier_doppler_old_hz = d_carrier_doppler_hz;
// Carrier discriminator filter
// NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan
// Input [s/Ti] -> output [Hz]
d_carrier_doppler_hz = d_carrier_loop_filter.get_carrier_error(0.0, d_carr_phase_error_secs_Ti, CURRENT_INTEGRATION_TIME_S);
// PLL to DLL assistance [Secs/Ti]
d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch;
// code Doppler frequency update
d_code_freq_chips = GLONASS_L2_CA_CODE_RATE_HZ + (((d_carrier_doppler_hz - d_carrier_doppler_old_hz) * GLONASS_L2_CA_CODE_RATE_HZ) / d_glonass_freq_ch);
// ################## DLL ##########################################################
// DLL discriminator
d_code_error_chips_Ti = dll_nc_e_minus_l_normalized(std::complex<float>(d_correlator_outs_16sc[0].real(), d_correlator_outs_16sc[0].imag()), std::complex<float>(d_correlator_outs_16sc[2].real(), d_correlator_outs_16sc[2].imag())); // [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;
code_error_filt_secs_Ti = d_code_error_filt_chips_Ti / d_code_freq_chips; // [s/Ti]
// ################## CARRIER AND CODE NCO BUFFER ALIGNMENT #######################
// keep alignment parameters for the next input buffer
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
double T_chip_seconds = 1.0 / d_code_freq_chips;
double T_prn_seconds = T_chip_seconds * GLONASS_L2_CA_CODE_LENGTH_CHIPS;
double T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in);
double K_prn_samples = round(T_prn_samples);
double K_T_prn_error_samples = K_prn_samples - T_prn_samples;
d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples + code_error_filt_secs_Ti * static_cast<double>(d_fs_in); //(code_error_filt_secs_Ti + d_pll_to_dll_assist_secs_Ti) * static_cast<double>(d_fs_in);
d_rem_code_phase_integer_samples = round(d_rem_code_phase_samples); // round to a discrete number of samples
d_correlation_length_samples = K_prn_samples + d_rem_code_phase_integer_samples;
d_rem_code_phase_samples = d_rem_code_phase_samples - d_rem_code_phase_integer_samples;
//################### PLL COMMANDS #################################################
//carrier phase step (NCO phase increment per sample) [rads/sample]
d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in);
d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / GLONASS_TWO_PI;
// UPDATE ACCUMULATED CARRIER PHASE
CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in));
//remnant carrier phase [rad]
d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + GLONASS_TWO_PI * d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S, GLONASS_TWO_PI);
//################### DLL COMMANDS #################################################
//code phase step (Code resampler phase increment per sample) [chips/sample]
d_code_phase_step_chips = d_code_freq_chips / static_cast<double>(d_fs_in);
//remnant code phase [chips]
d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast<double>(d_fs_in));
// ####### CN0 ESTIMATION AND LOCK DETECTORS #######################################
if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES)
{
// fill buffer with prompt correlator output values
d_Prompt_buffer[d_cn0_estimation_counter] = lv_cmake(static_cast<float>(d_correlator_outs_16sc[1].real()), static_cast<float>(d_correlator_outs_16sc[1].imag())); // prompt
d_cn0_estimation_counter++;
}
else
{
d_cn0_estimation_counter = 0;
// Code lock indicator
d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, GLONASS_L2_CA_CODE_LENGTH_CHIPS);
// Carrier lock indicator
d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES);
// Loss of lock detection
if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min)
{
d_carrier_lock_fail_counter++;
}
else
{
if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--;
}
if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail)
{
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
this->message_port_pub(pmt::mp("events"), pmt::from_long(3)); //3 -> loss of lock
d_carrier_lock_fail_counter = 0;
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
}
}
// ########### Output the tracking data to navigation and PVT ##########
current_synchro_data.Prompt_I = static_cast<double>((d_correlator_outs_16sc[1]).real());
current_synchro_data.Prompt_Q = static_cast<double>((d_correlator_outs_16sc[1]).imag());
// Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!)
current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples;
current_synchro_data.Code_phase_samples = d_rem_code_phase_samples;
current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles;
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
current_synchro_data.Flag_valid_symbol_output = true;
if (d_preamble_synchronized == true)
{
current_synchro_data.correlation_length_ms = d_extend_correlation_ms;
}
else
{
current_synchro_data.correlation_length_ms = 1;
}
}
else
{
current_synchro_data.Prompt_I = static_cast<double>((d_correlator_outs_16sc[1]).real());
current_synchro_data.Prompt_Q = static_cast<double>((d_correlator_outs_16sc[1]).imag());
current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples;
current_synchro_data.Code_phase_samples = d_rem_code_phase_samples;
current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles;
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; // todo: project the carrier doppler
current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
}
}
else
{
for (int n = 0; n < d_n_correlator_taps; n++)
{
d_correlator_outs_16sc[n] = lv_cmake(0, 0);
}
current_synchro_data.System = {'R'};
current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples;
}
current_synchro_data.fs = d_fs_in;
*out[0] = current_synchro_data;
if (d_dump)
{
// MULTIPLEXED FILE RECORDING - Record results to file
float prompt_I;
float prompt_Q;
float tmp_E, tmp_P, tmp_L;
float tmp_VE = 0.0;
float tmp_VL = 0.0;
float tmp_float;
prompt_I = d_correlator_outs_16sc[1].real();
prompt_Q = d_correlator_outs_16sc[1].imag();
tmp_E = std::abs<float>(gr_complex(d_correlator_outs_16sc[0].real(), d_correlator_outs_16sc[0].imag()));
tmp_P = std::abs<float>(gr_complex(d_correlator_outs_16sc[1].real(), d_correlator_outs_16sc[1].imag()));
tmp_L = std::abs<float>(gr_complex(d_correlator_outs_16sc[2].real(), d_correlator_outs_16sc[2].imag()));
try
{
// Dump correlators output
d_dump_file.write(reinterpret_cast<char *>(&tmp_VE), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_E), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_P), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_L), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_VL), sizeof(float));
// PROMPT I and Q (to analyze navigation symbols)
d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float));
// PRN start sample stamp
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(unsigned long int));
// accumulated carrier phase
tmp_float = d_acc_carrier_phase_cycles * GLONASS_TWO_PI;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// carrier and code frequency
tmp_float = d_carrier_doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_freq_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// PLL commands
tmp_float = 1.0 / (d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = 1.0 / (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// DLL commands
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_error_filt_chips_Ti;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// CN0 and carrier lock test
tmp_float = d_CN0_SNV_dB_Hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_carrier_lock_test;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// AUX vars (for debug purposes)
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
double tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
// PRN
unsigned int prn_ = d_acquisition_gnss_synchro->PRN;
d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int));
}
catch (const std::ifstream::failure *e)
{
LOG(WARNING) << "Exception writing trk dump file " << e->what();
}
}
consume_each(d_correlation_length_samples); // this is necessary in gr::block derivates
d_sample_counter += d_correlation_length_samples; //count for the processed samples
return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false
}
void glonass_l2_ca_dll_pll_c_aid_tracking_sc::set_channel(unsigned int channel)
{
d_channel = channel;
LOG(INFO) << "Tracking Channel set to " << d_channel;
// ############# ENABLE DATA FILE LOG #################
if (d_dump == true)
{
if (d_dump_file.is_open() == false)
{
try
{
d_dump_filename.append(boost::lexical_cast<std::string>(d_channel));
d_dump_filename.append(".dat");
d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str() << std::endl;
}
catch (const std::ifstream::failure *e)
{
LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e->what() << std::endl;
}
}
}
}
void glonass_l2_ca_dll_pll_c_aid_tracking_sc::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro)
{
d_acquisition_gnss_synchro = p_gnss_synchro;
}

View File

@@ -0,0 +1,206 @@
/*!
* \file glonass_l2_ca_dll_pll_c_aid_tracking_sc.h
* \brief Implementation of a code DLL + carrier PLL tracking block
* \author Damian Miralles, 2018. dmiralles2009(at)gmail.com
*
*
* Code DLL + carrier PLL according to the algorithms described in:
* K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency
* Approach, Birkha user, 2007
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2017 (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_GLONASS_L2_CA_DLL_PLL_C_AID_TRACKING_SC_H
#define GNSS_SDR_GLONASS_L2_CA_DLL_PLL_C_AID_TRACKING_SC_H
#include "glonass_l2_signal_processing.h"
#include "gnss_synchro.h"
#include "tracking_2nd_DLL_filter.h"
#include "tracking_FLL_PLL_filter.h"
#include "cpu_multicorrelator_16sc.h"
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <gnuradio/block.h>
#include <volk/volk.h>
#include <fstream>
#include <map>
#include <string>
class glonass_l2_ca_dll_pll_c_aid_tracking_sc;
typedef boost::shared_ptr<glonass_l2_ca_dll_pll_c_aid_tracking_sc>
glonass_l2_ca_dll_pll_c_aid_tracking_sc_sptr;
glonass_l2_ca_dll_pll_c_aid_tracking_sc_sptr
glonass_l2_ca_dll_pll_c_aid_make_tracking_sc(long if_freq,
long 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,
int extend_correlation_ms,
float early_late_space_chips);
/*!
* \brief This class implements a DLL + PLL tracking loop block
*/
class glonass_l2_ca_dll_pll_c_aid_tracking_sc : public gr::block
{
public:
~glonass_l2_ca_dll_pll_c_aid_tracking_sc();
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 glonass_l2_ca_dll_pll_c_aid_tracking_sc_sptr
glonass_l2_ca_dll_pll_c_aid_make_tracking_sc(long if_freq,
long 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,
int extend_correlation_ms,
float early_late_space_chips);
glonass_l2_ca_dll_pll_c_aid_tracking_sc(long if_freq,
long 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,
int extend_correlation_ms,
float early_late_space_chips);
// tracking configuration vars
unsigned int d_vector_length;
bool d_dump;
Gnss_Synchro* d_acquisition_gnss_synchro;
unsigned int d_channel;
long d_if_freq;
long d_fs_in;
long d_glonass_freq_ch;
double d_early_late_spc_chips;
int d_n_correlator_taps;
gr_complex* d_ca_code;
lv_16sc_t* d_ca_code_16sc;
float* d_local_code_shift_chips;
//gr_complex* d_correlator_outs;
lv_16sc_t* d_correlator_outs_16sc;
//cpu_multicorrelator multicorrelator_cpu;
cpu_multicorrelator_16sc multicorrelator_cpu_16sc;
// remaining code phase and carrier phase between tracking loops
double d_rem_code_phase_samples;
double d_rem_code_phase_chips;
double d_rem_carrier_phase_rad;
int d_rem_code_phase_integer_samples;
// PLL and DLL filter library
Tracking_2nd_DLL_filter d_code_loop_filter;
Tracking_FLL_PLL_filter d_carrier_loop_filter;
// acquisition
double d_acq_code_phase_samples;
double d_acq_carrier_doppler_hz;
// tracking vars
float d_dll_bw_hz;
float d_pll_bw_hz;
float d_dll_bw_narrow_hz;
float d_pll_bw_narrow_hz;
double d_code_freq_chips;
double d_code_phase_step_chips;
double d_carrier_doppler_hz;
double d_carrier_frequency_hz;
double d_carrier_doppler_old_hz;
double d_carrier_phase_step_rad;
double d_acc_carrier_phase_cycles;
double d_code_phase_samples;
double d_pll_to_dll_assist_secs_Ti;
double d_carr_phase_error_secs_Ti;
double d_code_error_chips_Ti;
double d_preamble_timestamp_s;
int d_extend_correlation_ms;
bool d_enable_extended_integration;
bool d_preamble_synchronized;
double d_code_error_filt_chips_s;
double d_code_error_filt_chips_Ti;
void msg_handler_preamble_index(pmt::pmt_t msg);
// symbol history to detect bit transition
std::deque<lv_16sc_t> d_E_history;
std::deque<lv_16sc_t> d_P_history;
std::deque<lv_16sc_t> d_L_history;
//Integration period in samples
int d_correlation_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;
gr_complex* d_Prompt_buffer;
double d_carrier_lock_test;
double d_CN0_SNV_dB_Hz;
double d_carrier_lock_threshold;
int d_carrier_lock_fail_counter;
// control vars
bool d_enable_tracking;
bool d_pull_in;
// file dump
std::string d_dump_filename;
std::ofstream d_dump_file;
std::map<std::string, std::string> systemName;
std::string sys;
int save_matfile();
};
#endif //GNSS_SDR_GLONASS_L2_CA_DLL_PLL_C_AID_TRACKING_SC_H

View File

@@ -1,17 +1,19 @@
/*!
* \file gps_l1_ca_dll_pll_tracking_cc.cc
* \brief Implementation of a code DLL + carrier PLL tracking block
* \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
* Javier Arribas, 2011. jarribas(at)cttc.es
* \file glonass_l2_ca_dll_pll_tracking_cc.cc
* \brief Implementation of a code DLL + carrier PLL tracking block
* \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com
* \author Luis Esteve, 2017. luis(at)epsilon-formacion.com
* \author Damian Miralles, 2017. dmiralles2009(at)gmail.com
*
*
* Code DLL + carrier PLL according to the algorithms described in:
* [1] K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
* K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency
* Approach, Birkhauser, 2007
* Approach, Birkha user, 2007
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
@@ -34,28 +36,29 @@
* -------------------------------------------------------------------------
*/
#include "gps_l1_ca_dll_pll_tracking_cc.h"
#include "gps_sdr_signal_processing.h"
#include "glonass_l2_ca_dll_pll_tracking_cc.h"
#include "glonass_l2_signal_processing.h"
#include "tracking_discriminators.h"
#include "lock_detectors.h"
#include "GLONASS_L1_L2_CA.h"
#include "gnss_sdr_flags.h"
#include "GPS_L1_CA.h"
#include "control_message_factory.h"
#include <boost/lexical_cast.hpp>
#include <gnuradio/io_signature.h>
#include <glog/logging.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <matio.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <cmath>
#include <iostream>
#include <memory>
#include <sstream>
#define CN0_ESTIMATION_SAMPLES 10
using google::LogMessage;
gps_l1_ca_dll_pll_tracking_cc_sptr
gps_l1_ca_dll_pll_make_tracking_cc(
glonass_l2_ca_dll_pll_tracking_cc_sptr
glonass_l2_ca_dll_pll_make_tracking_cc(
long if_freq,
long fs_in,
unsigned int vector_length,
@@ -65,12 +68,12 @@ gps_l1_ca_dll_pll_make_tracking_cc(
float dll_bw_hz,
float early_late_space_chips)
{
return gps_l1_ca_dll_pll_tracking_cc_sptr(new Gps_L1_Ca_Dll_Pll_Tracking_cc(if_freq,
return glonass_l2_ca_dll_pll_tracking_cc_sptr(new Glonass_L2_Ca_Dll_Pll_Tracking_cc(if_freq,
fs_in, vector_length, dump, dump_filename, pll_bw_hz, dll_bw_hz, early_late_space_chips));
}
void Gps_L1_Ca_Dll_Pll_Tracking_cc::forecast(int noutput_items,
void Glonass_L2_Ca_Dll_Pll_Tracking_cc::forecast(int noutput_items,
gr_vector_int &ninput_items_required)
{
if (noutput_items != 0)
@@ -80,7 +83,7 @@ void Gps_L1_Ca_Dll_Pll_Tracking_cc::forecast(int noutput_items,
}
Gps_L1_Ca_Dll_Pll_Tracking_cc::Gps_L1_Ca_Dll_Pll_Tracking_cc(
Glonass_L2_Ca_Dll_Pll_Tracking_cc::Glonass_L2_Ca_Dll_Pll_Tracking_cc(
long if_freq,
long fs_in,
unsigned int vector_length,
@@ -88,7 +91,7 @@ Gps_L1_Ca_Dll_Pll_Tracking_cc::Gps_L1_Ca_Dll_Pll_Tracking_cc(
std::string dump_filename,
float pll_bw_hz,
float dll_bw_hz,
float early_late_space_chips) : gr::block("Gps_L1_Ca_Dll_Pll_Tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)),
float early_late_space_chips) : gr::block("Glonass_L2_Ca_Dll_Pll_Tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{
// Telemetry bit synchronization message port input
@@ -113,7 +116,7 @@ Gps_L1_Ca_Dll_Pll_Tracking_cc::Gps_L1_Ca_Dll_Pll_Tracking_cc(
// Initialization of local code replica
// Get space for a vector with the C/A code replica sampled 1x/chip
d_ca_code = static_cast<float *>(volk_gnsssdr_malloc(static_cast<int>(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment()));
d_ca_code = static_cast<gr_complex *>(volk_gnsssdr_malloc(static_cast<int>(GLONASS_L2_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
// correlator outputs (scalar)
d_n_correlator_taps = 3; // Early, Prompt, and Late
@@ -132,7 +135,7 @@ Gps_L1_Ca_Dll_Pll_Tracking_cc::Gps_L1_Ca_Dll_Pll_Tracking_cc(
//--- Perform initializations ------------------------------
// define initial code frequency basis of NCO
d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ;
d_code_freq_chips = GLONASS_L2_CA_CODE_RATE_HZ;
// define residual code phase (in chips)
d_rem_code_phase_samples = 0.0;
// define residual carrier phase
@@ -154,27 +157,29 @@ Gps_L1_Ca_Dll_Pll_Tracking_cc::Gps_L1_Ca_Dll_Pll_Tracking_cc(
d_carrier_lock_fail_counter = 0;
d_carrier_lock_threshold = FLAGS_carrier_lock_th;
systemName["G"] = std::string("GPS");
systemName["S"] = std::string("SBAS");
systemName["R"] = std::string("Glonass");
d_acquisition_gnss_synchro = 0;
d_channel = 0;
d_acq_code_phase_samples = 0.0;
d_acq_carrier_doppler_hz = 0.0;
d_carrier_doppler_hz = 0.0;
d_carrier_doppler_phase_step_rad = 0.0;
d_carrier_frequency_hz = 0.0;
d_acc_carrier_phase_rad = 0.0;
d_code_phase_samples = 0.0;
d_rem_code_phase_chips = 0.0;
d_code_phase_step_chips = 0.0;
d_carrier_phase_step_rad = 0.0;
d_glonass_freq_ch = 0;
set_relative_rate(1.0 / static_cast<double>(d_vector_length));
}
void Gps_L1_Ca_Dll_Pll_Tracking_cc::start_tracking()
void Glonass_L2_Ca_Dll_Pll_Tracking_cc::start_tracking()
{
gr::thread::scoped_lock lk(d_setlock);
/*
* correct the code phase according to the delay between acq and trk
*/
@@ -185,24 +190,25 @@ void Gps_L1_Ca_Dll_Pll_Tracking_cc::start_tracking()
long int acq_trk_diff_samples;
double acq_trk_diff_seconds;
acq_trk_diff_samples = static_cast<long int>(d_sample_counter) - static_cast<long int>(d_acq_sample_stamp); //-d_vector_length;
DLOG(INFO) << "Number of samples between Acquisition and Tracking = " << acq_trk_diff_samples;
DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples;
acq_trk_diff_seconds = static_cast<float>(acq_trk_diff_samples) / static_cast<float>(d_fs_in);
// Doppler effect
// Fd=(C/(C+Vr))*F
double radial_velocity = (GPS_L1_FREQ_HZ + d_acq_carrier_doppler_hz) / GPS_L1_FREQ_HZ;
d_glonass_freq_ch = GLONASS_L2_CA_FREQ_HZ + (DFRQ2_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN));
double radial_velocity = (d_glonass_freq_ch + d_acq_carrier_doppler_hz) / d_glonass_freq_ch;
// new chip and prn sequence periods based on acq Doppler
double T_chip_mod_seconds;
double T_prn_mod_seconds;
double T_prn_mod_samples;
d_code_freq_chips = radial_velocity * GPS_L1_CA_CODE_RATE_HZ;
d_code_freq_chips = radial_velocity * GLONASS_L2_CA_CODE_RATE_HZ;
d_code_phase_step_chips = static_cast<double>(d_code_freq_chips) / static_cast<double>(d_fs_in);
T_chip_mod_seconds = 1 / d_code_freq_chips;
T_prn_mod_seconds = T_chip_mod_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
T_prn_mod_seconds = T_chip_mod_seconds * GLONASS_L2_CA_CODE_LENGTH_CHIPS;
T_prn_mod_samples = T_prn_mod_seconds * static_cast<double>(d_fs_in);
d_current_prn_length_samples = round(T_prn_mod_samples);
double T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS / GPS_L1_CA_CODE_RATE_HZ;
double T_prn_true_seconds = GLONASS_L2_CA_CODE_LENGTH_CHIPS / GLONASS_L2_CA_CODE_RATE_HZ;
double T_prn_true_samples = T_prn_true_seconds * static_cast<double>(d_fs_in);
double T_prn_diff_seconds = T_prn_true_seconds - T_prn_mod_seconds;
double N_prn_diff = acq_trk_diff_seconds / T_prn_true_seconds;
@@ -216,17 +222,19 @@ void Gps_L1_Ca_Dll_Pll_Tracking_cc::start_tracking()
d_acq_code_phase_samples = corrected_acq_phase_samples;
d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ2_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN));
d_carrier_doppler_hz = d_acq_carrier_doppler_hz;
d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in);
d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast<double>(d_fs_in);
d_carrier_doppler_phase_step_rad = GLONASS_TWO_PI * (d_carrier_doppler_hz) / static_cast<double>(d_fs_in);
// DLL/PLL filter initialization
d_carrier_loop_filter.initialize(); // initialize the carrier filter
d_code_loop_filter.initialize(); // initialize the code filter
// generate local reference ALWAYS starting at chip 1 (1 sample per chip)
gps_l1_ca_code_gen_float(d_ca_code, d_acquisition_gnss_synchro->PRN, 0);
glonass_l2_ca_code_gen_complex(d_ca_code, 0);
multicorrelator_cpu.set_local_code_and_taps(static_cast<int>(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips);
multicorrelator_cpu.set_local_code_and_taps(static_cast<int>(GLONASS_L2_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips);
for (int n = 0; n < d_n_correlator_taps; n++)
{
d_correlator_outs[n] = gr_complex(0, 0);
@@ -244,20 +252,60 @@ void Gps_L1_Ca_Dll_Pll_Tracking_cc::start_tracking()
sys = sys_.substr(0, 1);
// DEBUG OUTPUT
std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl;
std::cout << "Tracking of GLONASS L2 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl;
LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel;
// enable tracking
d_pull_in = true;
d_enable_tracking = true;
LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz
LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_frequency_hz
<< " Code Phase correction [samples]=" << delay_correction_samples
<< " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples;
}
int Gps_L1_Ca_Dll_Pll_Tracking_cc::save_matfile()
Glonass_L2_Ca_Dll_Pll_Tracking_cc::~Glonass_L2_Ca_Dll_Pll_Tracking_cc()
{
if (d_dump_file.is_open())
{
try
{
d_dump_file.close();
}
catch (const std::exception &ex)
{
LOG(WARNING) << "Exception in destructor " << ex.what();
}
}
if (d_dump)
{
if (d_channel == 0)
{
std::cout << "Writing .mat files ...";
}
Glonass_L2_Ca_Dll_Pll_Tracking_cc::save_matfile();
if (d_channel == 0)
{
std::cout << " done." << std::endl;
}
}
try
{
volk_gnsssdr_free(d_local_code_shift_chips);
volk_gnsssdr_free(d_correlator_outs);
volk_gnsssdr_free(d_ca_code);
delete[] d_Prompt_buffer;
multicorrelator_cpu.free();
}
catch (const std::exception &ex)
{
LOG(WARNING) << "Exception in destructor " << ex.what();
}
}
int Glonass_L2_Ca_Dll_Pll_Tracking_cc::save_matfile()
{
// READ DUMP FILE
std::ifstream::pos_type size;
@@ -464,52 +512,9 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::save_matfile()
}
Gps_L1_Ca_Dll_Pll_Tracking_cc::~Gps_L1_Ca_Dll_Pll_Tracking_cc()
{
if (d_dump_file.is_open())
{
try
{
d_dump_file.close();
}
catch (const std::exception &ex)
{
LOG(WARNING) << "Exception in destructor " << ex.what();
}
}
if (d_dump)
{
if (d_channel == 0)
{
std::cout << "Writing .mat files ...";
}
Gps_L1_Ca_Dll_Pll_Tracking_cc::save_matfile();
if (d_channel == 0)
{
std::cout << " done." << std::endl;
}
}
try
{
volk_gnsssdr_free(d_local_code_shift_chips);
volk_gnsssdr_free(d_correlator_outs);
volk_gnsssdr_free(d_ca_code);
delete[] d_Prompt_buffer;
multicorrelator_cpu.free();
}
catch (const std::exception &ex)
{
LOG(WARNING) << "Exception in destructor " << ex.what();
}
}
int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
int Glonass_L2_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
{
gr::thread::scoped_lock lk(d_setlock);
// process vars
double carr_error_hz = 0.0;
double carr_error_filt_hz = 0.0;
@@ -517,7 +522,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribute__(
double code_error_filt_chips = 0.0;
// Block input data and block output stream pointers
const gr_complex *in = reinterpret_cast<const gr_complex *>(input_items[0]);
const gr_complex *in = reinterpret_cast<const gr_complex *>(input_items[0]); // PRN start block alignment
Gnss_Synchro **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]);
// GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder
@@ -540,13 +545,14 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribute__(
d_sample_counter = d_sample_counter + samples_offset; // count for the processed samples
d_pull_in = false;
// take into account the carrier cycles accumulated in the pull in signal alignment
d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * samples_offset;
d_acc_carrier_phase_rad -= d_carrier_doppler_phase_step_rad * samples_offset;
current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad;
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
current_synchro_data.fs = d_fs_in;
current_synchro_data.correlation_length_ms = 1;
*out[0] = current_synchro_data;
consume_each(samples_offset); // shift input to perform alignment with local replica
return 0;
return 1;
}
// ################# CARRIER WIPEOFF AND CORRELATORS ##############################
@@ -561,13 +567,13 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribute__(
// ################## PLL ##########################################################
// PLL discriminator
// Update PLL discriminator [rads/Ti -> Secs/Ti]
carr_error_hz = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / GPS_TWO_PI; // prompt output
carr_error_hz = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / GLONASS_TWO_PI; // prompt output
// Carrier discriminator filter
carr_error_filt_hz = d_carrier_loop_filter.get_carrier_nco(carr_error_hz);
// New carrier Doppler frequency estimation
d_carrier_doppler_hz = d_acq_carrier_doppler_hz + carr_error_filt_hz;
// New code Doppler frequency estimation
d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ);
d_carrier_frequency_hz += carr_error_filt_hz;
d_carrier_doppler_hz += carr_error_filt_hz;
d_code_freq_chips = GLONASS_L2_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GLONASS_L2_CA_CODE_RATE_HZ) / d_glonass_freq_ch);
// ################## DLL ##########################################################
// DLL discriminator
@@ -575,27 +581,28 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribute__(
// 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<double>(d_code_freq_chips);
double T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
double T_prn_seconds = T_chip_seconds * GLONASS_L2_CA_CODE_LENGTH_CHIPS;
double code_error_filt_secs = (T_prn_seconds * code_error_filt_chips * T_chip_seconds); //[seconds]
//double code_error_filt_secs = (GPS_L1_CA_CODE_PERIOD * code_error_filt_chips) / GPS_L1_CA_CODE_RATE_HZ; // [seconds]
//double code_error_filt_secs = (GPS_L1_CA_CODE_PERIOD * code_error_filt_chips) / GLONASS_L1_CA_CODE_RATE_HZ; // [seconds]
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
// ################## CARRIER AND CODE NCO BUFFER ALIGNMENT #######################
// keep alignment parameters for the next input buffer
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
//double T_chip_seconds = 1.0 / static_cast<double>(d_code_freq_chips);
//double T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
//double T_prn_seconds = T_chip_seconds * GLONASS_L1_CA_CODE_LENGTH_CHIPS;
double T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in);
double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast<double>(d_fs_in);
d_current_prn_length_samples = round(K_blk_samples); // round to a discrete number of samples
//################### PLL COMMANDS #################################################
// carrier phase step (NCO phase increment per sample) [rads/sample]
d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in);
d_carrier_doppler_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in);
d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast<double>(d_fs_in);
// remnant carrier phase to prevent overflow in the code NCO
d_rem_carr_phase_rad = d_rem_carr_phase_rad + d_carrier_phase_step_rad * d_current_prn_length_samples;
d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, GPS_TWO_PI);
d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, GLONASS_TWO_PI);
// carrier phase accumulator
d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * d_current_prn_length_samples;
d_acc_carrier_phase_rad -= d_carrier_doppler_phase_step_rad * d_current_prn_length_samples;
//################### DLL COMMANDS #################################################
// code phase step (Code resampler phase increment per sample) [chips/sample]
@@ -605,7 +612,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribute__(
d_rem_code_phase_chips = d_code_freq_chips * (d_rem_code_phase_samples / static_cast<double>(d_fs_in));
// ####### CN0 ESTIMATION AND LOCK DETECTORS ######
if (d_cn0_estimation_counter < FLAGS_cn0_samples)
if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES)
{
// fill buffer with prompt correlator output values
d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1]; //prompt
@@ -615,9 +622,9 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribute__(
{
d_cn0_estimation_counter = 0;
// Code lock indicator
d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, FLAGS_cn0_samples, d_fs_in, GPS_L1_CA_CODE_LENGTH_CHIPS);
d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES, d_fs_in, GLONASS_L2_CA_CODE_LENGTH_CHIPS);
// Carrier lock indicator
d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, FLAGS_cn0_samples);
d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES);
// Loss of lock detection
if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min)
{
@@ -655,7 +662,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribute__(
}
current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples;
current_synchro_data.System = {'G'};
current_synchro_data.System = {'R'};
current_synchro_data.correlation_length_ms = 1;
}
@@ -668,8 +675,9 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribute__(
float prompt_I;
float prompt_Q;
float tmp_E, tmp_P, tmp_L;
double tmp_double;
unsigned long int tmp_long;
float tmp_float;
float tmp_VE = 0.0;
float tmp_VL = 0.0;
prompt_I = d_correlator_outs[1].real();
prompt_Q = d_correlator_outs[1].imag();
tmp_E = std::abs<float>(d_correlator_outs[0]);
@@ -677,41 +685,45 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribute__(
tmp_L = std::abs<float>(d_correlator_outs[2]);
try
{
// EPR
// Dump correlators output
d_dump_file.write(reinterpret_cast<char *>(&tmp_VE), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_E), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_P), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_L), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_VL), sizeof(float));
// PROMPT I and Q (to analyze navigation symbols)
d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float));
// PRN start sample stamp
tmp_long = d_sample_counter + d_current_prn_length_samples;
d_dump_file.write(reinterpret_cast<char *>(&tmp_long), sizeof(unsigned long int));
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(unsigned long int));
// accumulated carrier phase
d_dump_file.write(reinterpret_cast<char *>(&d_acc_carrier_phase_rad), sizeof(double));
tmp_float = d_acc_carrier_phase_rad;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// carrier and code frequency
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_code_freq_chips), sizeof(double));
tmp_float = d_carrier_doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_freq_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// PLL commands
d_dump_file.write(reinterpret_cast<char *>(&carr_error_hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&carr_error_filt_hz), sizeof(double));
tmp_float = carr_error_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = carr_error_filt_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// DLL commands
d_dump_file.write(reinterpret_cast<char *>(&code_error_chips), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&code_error_filt_chips), sizeof(double));
tmp_float = code_error_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = code_error_filt_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// CN0 and carrier lock test
d_dump_file.write(reinterpret_cast<char *>(&d_CN0_SNV_dB_Hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_lock_test), sizeof(double));
tmp_float = d_CN0_SNV_dB_Hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_carrier_lock_test;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// AUX vars (for debug purposes)
tmp_double = d_rem_code_phase_samples;
tmp_float = d_rem_code_phase_samples;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
double tmp_double = static_cast<double>(d_sample_counter + d_current_prn_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = static_cast<double>(d_sample_counter);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
// PRN
unsigned int prn_ = d_acquisition_gnss_synchro->PRN;
d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int));
@@ -724,19 +736,11 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribute__(
consume_each(d_current_prn_length_samples); // this is necessary in gr::block derivates
d_sample_counter += d_current_prn_length_samples; // count for the processed samples
if (current_synchro_data.Flag_valid_symbol_output)
{
return 1;
}
else
{
return 0;
}
return 1; // output tracking result ALWAYS even in the case of d_enable_tracking==false
}
void Gps_L1_Ca_Dll_Pll_Tracking_cc::set_channel(unsigned int channel)
void Glonass_L2_Ca_Dll_Pll_Tracking_cc::set_channel(unsigned int channel)
{
d_channel = channel;
LOG(INFO) << "Tracking Channel set to " << d_channel;
@@ -762,7 +766,7 @@ void Gps_L1_Ca_Dll_Pll_Tracking_cc::set_channel(unsigned int channel)
}
void Gps_L1_Ca_Dll_Pll_Tracking_cc::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro)
void Glonass_L2_Ca_Dll_Pll_Tracking_cc::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro)
{
d_acquisition_gnss_synchro = p_gnss_synchro;
}

View File

@@ -1,18 +1,17 @@
/*!
* \file gps_l1_ca_dll_pll_tracking_cc.h
* \brief Interface of a code DLL + carrier PLL tracking block
* \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
* Javier Arribas, 2011. jarribas(at)cttc.es
* Cillian O'Driscoll, 2017. cillian.odriscoll(at)gmail.com
* \file glonass_l2_ca_dll_pll_tracking_cc.h
* \brief Implementation of a code DLL + carrier PLL tracking block
* \author Damian Miralles, 2018. dmiralles2009(at)gmail.com
*
*
* Code DLL + carrier PLL according to the algorithms described in:
* K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency Approach,
* Birkhauser, 2007
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency
* Approach, Birkha user, 2007
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
@@ -35,25 +34,25 @@
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_CC_H
#define GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_CC_H
#ifndef GNSS_SDR_GLONASS_L2_CA_DLL_PLL_TRACKING_CC_H
#define GNSS_SDR_GLONASS_L2_CA_DLL_PLL_TRACKING_CC_H
#include "gnss_synchro.h"
#include "tracking_2nd_DLL_filter.h"
#include "tracking_2nd_PLL_filter.h"
#include "cpu_multicorrelator_real_codes.h"
#include "cpu_multicorrelator.h"
#include <gnuradio/block.h>
#include <fstream>
#include <map>
#include <string>
class Gps_L1_Ca_Dll_Pll_Tracking_cc;
class Glonass_L2_Ca_Dll_Pll_Tracking_cc;
typedef boost::shared_ptr<Gps_L1_Ca_Dll_Pll_Tracking_cc>
gps_l1_ca_dll_pll_tracking_cc_sptr;
typedef boost::shared_ptr<Glonass_L2_Ca_Dll_Pll_Tracking_cc>
glonass_l2_ca_dll_pll_tracking_cc_sptr;
gps_l1_ca_dll_pll_tracking_cc_sptr
gps_l1_ca_dll_pll_make_tracking_cc(long if_freq,
glonass_l2_ca_dll_pll_tracking_cc_sptr
glonass_l2_ca_dll_pll_make_tracking_cc(long if_freq,
long fs_in, unsigned int vector_length,
bool dump,
std::string dump_filename,
@@ -65,10 +64,10 @@ gps_l1_ca_dll_pll_make_tracking_cc(long if_freq,
/*!
* \brief This class implements a DLL + PLL tracking loop block
*/
class Gps_L1_Ca_Dll_Pll_Tracking_cc : public gr::block
class Glonass_L2_Ca_Dll_Pll_Tracking_cc : public gr::block
{
public:
~Gps_L1_Ca_Dll_Pll_Tracking_cc();
~Glonass_L2_Ca_Dll_Pll_Tracking_cc();
void set_channel(unsigned int channel);
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro);
@@ -80,8 +79,8 @@ public:
void forecast(int noutput_items, gr_vector_int& ninput_items_required);
private:
friend gps_l1_ca_dll_pll_tracking_cc_sptr
gps_l1_ca_dll_pll_make_tracking_cc(long if_freq,
friend glonass_l2_ca_dll_pll_tracking_cc_sptr
glonass_l2_ca_dll_pll_make_tracking_cc(long if_freq,
long fs_in, unsigned int vector_length,
bool dump,
std::string dump_filename,
@@ -89,7 +88,7 @@ private:
float dll_bw_hz,
float early_late_space_chips);
Gps_L1_Ca_Dll_Pll_Tracking_cc(long if_freq,
Glonass_L2_Ca_Dll_Pll_Tracking_cc(long if_freq,
long fs_in, unsigned int vector_length,
bool dump,
std::string dump_filename,
@@ -97,7 +96,6 @@ private:
float dll_bw_hz,
float early_late_space_chips);
int save_matfile();
// tracking configuration vars
unsigned int d_vector_length;
bool d_dump;
@@ -107,6 +105,7 @@ private:
long d_if_freq;
long d_fs_in;
long d_glonass_freq_ch;
double d_early_late_spc_chips;
@@ -124,15 +123,18 @@ private:
double d_acq_carrier_doppler_hz;
// correlator
int d_n_correlator_taps;
float* d_ca_code;
gr_complex* d_ca_code;
float* d_local_code_shift_chips;
gr_complex* d_correlator_outs;
cpu_multicorrelator_real_codes multicorrelator_cpu;
cpu_multicorrelator multicorrelator_cpu;
// tracking vars
double d_code_freq_chips;
double d_code_phase_step_chips;
double d_carrier_doppler_hz;
double d_carrier_doppler_phase_step_rad;
double d_carrier_frequency_hz;
double d_carrier_phase_step_rad;
double d_acc_carrier_phase_rad;
double d_code_phase_samples;
@@ -162,6 +164,8 @@ private:
std::map<std::string, std::string> systemName;
std::string sys;
int save_matfile();
};
#endif //GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_CC_H
#endif //GNSS_SDR_GLONASS_L2_CA_DLL_PLL_TRACKING_CC_H

View File

@@ -587,7 +587,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib
d_code_phase_step_chips,
d_correlation_length_samples);
// ####### coherent intergration extension
// ####### coherent integration extension
// keep the last symbols
d_E_history.push_back(d_correlator_outs[0]); // save early output
d_P_history.push_back(d_correlator_outs[1]); // save prompt output
@@ -701,7 +701,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib
d_code_error_filt_chips_Ti = d_code_error_filt_chips_s * CURRENT_INTEGRATION_TIME_S;
code_error_filt_secs_Ti = d_code_error_filt_chips_Ti / d_code_freq_chips; // [s/Ti]
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
// ################## CARRIER AND CODE NCO BUFFER ALIGNMENT #######################
// keep alignment parameters for the next input buffer
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
double T_chip_seconds = 1.0 / d_code_freq_chips;
@@ -810,7 +810,9 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib
float prompt_I;
float prompt_Q;
float tmp_E, tmp_P, tmp_L;
double tmp_double;
float tmp_VE = 0.0;
float tmp_VL = 0.0;
float tmp_float;
prompt_I = d_correlator_outs[1].real();
prompt_Q = d_correlator_outs[1].imag();
tmp_E = std::abs<float>(d_correlator_outs[0]);
@@ -818,41 +820,45 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib
tmp_L = std::abs<float>(d_correlator_outs[2]);
try
{
// EPR
// Dump correlators output
d_dump_file.write(reinterpret_cast<char *>(&tmp_VE), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_E), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_P), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_L), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_VL), sizeof(float));
// PROMPT I and Q (to analyze navigation symbols)
d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float));
// PRN start sample stamp
//tmp_float=(float)d_sample_counter;
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(unsigned long int));
// accumulated carrier phase
d_dump_file.write(reinterpret_cast<char *>(&d_acc_carrier_phase_cycles), sizeof(double));
tmp_float = d_acc_carrier_phase_cycles * GPS_TWO_PI;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// carrier and code frequency
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_code_freq_chips), sizeof(double));
//PLL commands
d_dump_file.write(reinterpret_cast<char *>(&d_carr_phase_error_secs_Ti), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(double));
//DLL commands
d_dump_file.write(reinterpret_cast<char *>(&d_code_error_chips_Ti), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_code_error_filt_chips_Ti), sizeof(double));
tmp_float = d_carrier_doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_freq_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// PLL commands
tmp_float = 1.0 / (d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = 1.0 / (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S);;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// DLL commands
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_error_filt_chips_Ti;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// CN0 and carrier lock test
d_dump_file.write(reinterpret_cast<char *>(&d_CN0_SNV_dB_Hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_lock_test), sizeof(double));
tmp_float = d_CN0_SNV_dB_Hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_carrier_lock_test;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// AUX vars (for debug purposes)
tmp_double = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
double tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
// PRN
unsigned int prn_ = d_acquisition_gnss_synchro->PRN;
d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int));

View File

@@ -387,7 +387,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work(
d_rem_code_phase_chips, d_code_phase_step_chips,
d_correlation_length_samples);
// ####### coherent intergration extension
// ####### coherent integration extension
// keep the last symbols
d_E_history.push_back(d_correlator_outs_16sc[0]); // save early output
d_P_history.push_back(d_correlator_outs_16sc[1]); // save prompt output
@@ -517,7 +517,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work(
d_code_error_filt_chips_Ti = d_code_error_filt_chips_s * CURRENT_INTEGRATION_TIME_S;
code_error_filt_secs_Ti = d_code_error_filt_chips_Ti / d_code_freq_chips; // [s/Ti]
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
// ################## CARRIER AND CODE NCO BUFFER ALIGNMENT #######################
// keep alignment parameters for the next input buffer
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
double T_chip_seconds = 1.0 / d_code_freq_chips;
@@ -632,49 +632,55 @@ int gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc::general_work(
float prompt_I;
float prompt_Q;
float tmp_E, tmp_P, tmp_L;
double tmp_double;
float tmp_VE = 0.0;
float tmp_VL = 0.0;
float tmp_float;
prompt_I = d_correlator_outs_16sc[1].real();
prompt_Q = d_correlator_outs_16sc[1].imag();
tmp_E = std::abs<float>(std::complex<float>(d_correlator_outs_16sc[0].real(), d_correlator_outs_16sc[0].imag()));
tmp_P = std::abs<float>(std::complex<float>(d_correlator_outs_16sc[1].real(), d_correlator_outs_16sc[1].imag()));
tmp_L = std::abs<float>(std::complex<float>(d_correlator_outs_16sc[2].real(), d_correlator_outs_16sc[2].imag()));
tmp_E = std::abs<float>(gr_complex(d_correlator_outs_16sc[0].real(), d_correlator_outs_16sc[0].imag()));
tmp_P = std::abs<float>(gr_complex(d_correlator_outs_16sc[1].real(), d_correlator_outs_16sc[1].imag()));
tmp_L = std::abs<float>(gr_complex(d_correlator_outs_16sc[2].real(), d_correlator_outs_16sc[2].imag()));
try
{
// EPR
// Dump correlators output
d_dump_file.write(reinterpret_cast<char *>(&tmp_VE), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_E), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_P), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_L), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_VL), sizeof(float));
// PROMPT I and Q (to analyze navigation symbols)
d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float));
// PRN start sample stamp
//tmp_float=(float)d_sample_counter;
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(unsigned long int));
// accumulated carrier phase
d_dump_file.write(reinterpret_cast<char *>(&d_acc_carrier_phase_cycles), sizeof(double));
tmp_float = d_acc_carrier_phase_cycles * GPS_TWO_PI;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// carrier and code frequency
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_code_freq_chips), sizeof(double));
//PLL commands
d_dump_file.write(reinterpret_cast<char *>(&d_carr_phase_error_secs_Ti), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(double));
//DLL commands
d_dump_file.write(reinterpret_cast<char *>(&d_code_error_chips_Ti), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_code_error_filt_chips_Ti), sizeof(double));
tmp_float = d_carrier_doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_freq_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// PLL commands
tmp_float = 1.0 / (d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = 1.0 / (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// DLL commands
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_error_filt_chips_Ti;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// CN0 and carrier lock test
d_dump_file.write(reinterpret_cast<char *>(&d_CN0_SNV_dB_Hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_lock_test), sizeof(double));
tmp_float = d_CN0_SNV_dB_Hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_carrier_lock_test;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// AUX vars (for debug purposes)
tmp_double = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
double tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
// PRN
unsigned int prn_ = d_acquisition_gnss_synchro->PRN;
d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int));

View File

@@ -590,7 +590,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attrib
d_code_phase_step_chips,
d_correlation_length_samples);
// ####### coherent intergration extension
// ####### coherent integration extension
// keep the last symbols
d_E_history.push_back(d_correlator_outs_16sc[0]); // save early output
d_P_history.push_back(d_correlator_outs_16sc[1]); // save prompt output
@@ -703,7 +703,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attrib
d_code_error_filt_chips_Ti = d_code_error_filt_chips_s * CURRENT_INTEGRATION_TIME_S;
code_error_filt_secs_Ti = d_code_error_filt_chips_Ti / d_code_freq_chips; // [s/Ti]
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
// ################## CARRIER AND CODE NCO BUFFER ALIGNMENT #######################
// keep alignment parameters for the next input buffer
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
double T_chip_seconds = 1.0 / d_code_freq_chips;
@@ -812,49 +812,55 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attrib
float prompt_I;
float prompt_Q;
float tmp_E, tmp_P, tmp_L;
double tmp_double;
float tmp_VE = 0.0;
float tmp_VL = 0.0;
float tmp_float;
prompt_I = d_correlator_outs_16sc[1].real();
prompt_Q = d_correlator_outs_16sc[1].imag();
tmp_E = std::abs<float>(std::complex<float>(d_correlator_outs_16sc[0].real(), d_correlator_outs_16sc[0].imag()));
tmp_P = std::abs<float>(std::complex<float>(d_correlator_outs_16sc[1].real(), d_correlator_outs_16sc[1].imag()));
tmp_L = std::abs<float>(std::complex<float>(d_correlator_outs_16sc[2].real(), d_correlator_outs_16sc[2].imag()));
tmp_E = std::abs<float>(gr_complex(d_correlator_outs_16sc[0].real(), d_correlator_outs_16sc[0].imag()));
tmp_P = std::abs<float>(gr_complex(d_correlator_outs_16sc[1].real(), d_correlator_outs_16sc[1].imag()));
tmp_L = std::abs<float>(gr_complex(d_correlator_outs_16sc[2].real(), d_correlator_outs_16sc[2].imag()));
try
{
// EPR
// Dump correlators output
d_dump_file.write(reinterpret_cast<char *>(&tmp_VE), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_E), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_P), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_L), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_VL), sizeof(float));
// PROMPT I and Q (to analyze navigation symbols)
d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float));
// PRN start sample stamp
//tmp_float=(float)d_sample_counter;
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(unsigned long int));
// accumulated carrier phase
d_dump_file.write(reinterpret_cast<char *>(&d_acc_carrier_phase_cycles), sizeof(double));
tmp_float = d_acc_carrier_phase_cycles * GPS_TWO_PI;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// carrier and code frequency
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_code_freq_chips), sizeof(double));
//PLL commands
d_dump_file.write(reinterpret_cast<char *>(&d_carr_phase_error_secs_Ti), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(double));
//DLL commands
d_dump_file.write(reinterpret_cast<char *>(&d_code_error_chips_Ti), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_code_error_filt_chips_Ti), sizeof(double));
tmp_float = d_carrier_doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_freq_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// PLL commands
tmp_float = 1.0 / (d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = 1.0 / (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// DLL commands
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_error_filt_chips_Ti;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// CN0 and carrier lock test
d_dump_file.write(reinterpret_cast<char *>(&d_CN0_SNV_dB_Hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_lock_test), sizeof(double));
tmp_float = d_CN0_SNV_dB_Hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_carrier_lock_test;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// AUX vars (for debug purposes)
tmp_double = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
double tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
// PRN
unsigned int prn_ = d_acquisition_gnss_synchro->PRN;
d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int));

View File

@@ -368,7 +368,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work(int noutput_items __attribut
// TODO: PLL carrier aid to DLL is disabled. Re-enable it and measure performance
dll_code_error_secs_Ti = -code_error_filt_secs_Ti + d_pll_to_dll_assist_secs_Ti;
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
// ################## CARRIER AND CODE NCO BUFFER ALIGNMENT #######################
// keep alignment parameters for the next input buffer
double T_chip_seconds;
double T_prn_seconds;
@@ -468,7 +468,9 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work(int noutput_items __attribut
float prompt_I;
float prompt_Q;
float tmp_E, tmp_P, tmp_L;
double tmp_double;
float tmp_VE = 0.0;
float tmp_VL = 0.0;
float tmp_float;
prompt_I = d_correlator_outs[1].real();
prompt_Q = d_correlator_outs[1].imag();
tmp_E = std::abs<float>(d_correlator_outs[0]);
@@ -476,41 +478,45 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work(int noutput_items __attribut
tmp_L = std::abs<float>(d_correlator_outs[2]);
try
{
// EPR
// Dump correlators output
d_dump_file.write(reinterpret_cast<char *>(&tmp_VE), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_E), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_P), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_L), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_VL), sizeof(float));
// PROMPT I and Q (to analyze navigation symbols)
d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float));
// PRN start sample stamp
//tmp_float=(float)d_sample_counter;
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(unsigned long int));
// accumulated carrier phase
d_dump_file.write(reinterpret_cast<char *>(&d_acc_carrier_phase_cycles), sizeof(double));
tmp_float = d_acc_carrier_phase_cycles * GPS_TWO_PI;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// carrier and code frequency
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_code_freq_chips), sizeof(double));
//PLL commands
d_dump_file.write(reinterpret_cast<char *>(&carr_phase_error_secs_Ti), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(double));
//DLL commands
d_dump_file.write(reinterpret_cast<char *>(&code_error_chips_Ti), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&code_error_filt_chips), sizeof(double));
tmp_float = d_carrier_doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_freq_chips;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// PLL commands
tmp_float = 1.0 / (d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = 1.0 / (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S);
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// DLL commands
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_error_filt_chips_Ti;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// CN0 and carrier lock test
d_dump_file.write(reinterpret_cast<char *>(&d_CN0_SNV_dB_Hz), sizeof(double));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_lock_test), sizeof(double));
tmp_float = d_CN0_SNV_dB_Hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_carrier_lock_test;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// AUX vars (for debug purposes)
tmp_double = d_rem_code_phase_samples;
tmp_float = d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
double tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
// PRN
unsigned int prn_ = d_acquisition_gnss_synchro->PRN;
d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int));

View File

@@ -333,7 +333,7 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attrib
d_sample_counter_seconds = d_sample_counter_seconds + (static_cast<double>(samples_offset) / static_cast<double>(d_fs_in));
d_sample_counter = d_sample_counter + samples_offset; //count for the processed samples
d_pull_in = false;
consume_each(samples_offset); //shift input to perform alignement with local replica
consume_each(samples_offset); //shift input to perform alignment with local replica
return 1;
}
@@ -482,48 +482,55 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attrib
float prompt_I;
float prompt_Q;
float tmp_E, tmp_P, tmp_L;
float tmp_VE = 0.0;
float tmp_VL = 0.0;
float tmp_float;
prompt_I = (*d_Prompt).real();
prompt_Q = (*d_Prompt).imag();
tmp_E = std::abs<float>(*d_Early);
tmp_P = std::abs<float>(*d_Prompt);
tmp_L = std::abs<float>(*d_Late);
prompt_I = d_correlator_outs[1].real();
prompt_Q = d_correlator_outs[1].imag();
tmp_E = std::abs<float>(d_correlator_outs[0]);
tmp_P = std::abs<float>(d_correlator_outs[1]);
tmp_L = std::abs<float>(d_correlator_outs[2]);
try
{
// EPR
// Dump correlators output
d_dump_file.write(reinterpret_cast<char *>(&tmp_VE), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_E), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_P), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_L), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&tmp_VL), sizeof(float));
// PROMPT I and Q (to analyze navigation symbols)
d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float));
// PRN start sample stamp
//tmp_float=(float)d_sample_counter;
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(unsigned long int));
// accumulated carrier phase
d_dump_file.write(reinterpret_cast<char *>(&d_acc_carrier_phase_rad), sizeof(float));
// carrier and code frequency
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&d_code_freq_hz), sizeof(float));
//PLL commands
d_dump_file.write(reinterpret_cast<char *>(&carr_error), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&carr_nco), sizeof(float));
//DLL commands
d_dump_file.write(reinterpret_cast<char *>(&code_error), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&code_nco), sizeof(float));
// CN0 and carrier lock test
d_dump_file.write(reinterpret_cast<char *>(&d_CN0_SNV_dB_Hz), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&d_carrier_lock_test), sizeof(float));
// AUX vars (for debug purposes)
tmp_float = 0;
tmp_float = d_acc_carrier_phase_rad;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter_seconds), sizeof(double));
// carrier and code frequency
tmp_float = d_carrier_doppler_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_code_freq_hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// PLL commands
tmp_float = 0.0;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = carr_error;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// DLL commands
tmp_float = 0.0;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = code_error;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// CN0 and carrier lock test
tmp_float = d_CN0_SNV_dB_Hz;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
tmp_float = d_carrier_lock_test;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
// AUX vars (for debug purposes)
tmp_float = 0.0;
d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float));
double tmp_double = static_cast<double>(d_sample_counter + d_correlation_length_samples);
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
// PRN
unsigned int prn_ = d_acquisition_gnss_synchro->PRN;
d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int));

View File

@@ -579,7 +579,7 @@ int gps_l2_m_dll_pll_tracking_cc::general_work(int noutput_items __attribute__((
double code_error_filt_secs = (T_prn_seconds * code_error_filt_chips * T_chip_seconds); //[seconds]
//double code_error_filt_secs = (GPS_L2_M_PERIOD * code_error_filt_chips) / GPS_L2_M_CODE_RATE_HZ; //[seconds]
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
// ################## CARRIER AND CODE NCO BUFFER ALIGNMENT #######################
// keep alignment parameters for the next input buffer
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
double T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in);

View File

@@ -580,7 +580,7 @@ int gps_l5i_dll_pll_tracking_cc::general_work(int noutput_items __attribute__((u
double code_error_filt_secs = (T_prn_seconds * code_error_filt_chips * T_chip_seconds); //[seconds]
//double code_error_filt_secs = (GPS_L5i_PERIOD * code_error_filt_chips) / GPS_L5i_CODE_RATE_HZ; //[seconds]
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
// ################## CARRIER AND CODE NCO BUFFER ALIGNMENT #######################
// keep alignment parameters for the next input buffer
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
double T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in);