1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-02-14 18:10:10 +00:00

Fixes rounding errors in frequency to period conversion that were

causing tracking losses. Bug spotted by Marc Sales.
This commit is contained in:
Carles Fernandez 2014-07-19 19:29:27 +02:00
parent 767a5122d5
commit 6967fc833e
11 changed files with 152 additions and 155 deletions

View File

@ -7,11 +7,11 @@
* Code DLL + carrier PLL according to the algorithms described in: * Code DLL + carrier PLL according to the algorithms described in:
* [1] K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, * [1] K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency * A Software-Defined GPS and Galileo Receiver. A Single-Frequency
* Approach, Birkha user, 2007 * Approach, Birkhauser, 2007
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -21,7 +21,7 @@
* GNSS-SDR is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* at your option) any later version. * (at your option) any later version.
* *
* GNSS-SDR is distributed in the hope that it will be useful, * GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -37,6 +37,7 @@
#include "galileo_e1_dll_pll_veml_tracking_cc.h" #include "galileo_e1_dll_pll_veml_tracking_cc.h"
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include <memory>
#include <sstream> #include <sstream>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
@ -148,7 +149,7 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc(
//--- Initializations ------------------------------ //--- Initializations ------------------------------
// Initial code frequency basis of NCO // Initial code frequency basis of NCO
d_code_freq_chips = Galileo_E1_CODE_CHIP_RATE_HZ; d_code_freq_chips = (double)Galileo_E1_CODE_CHIP_RATE_HZ;
// Residual code phase (in chips) // Residual code phase (in chips)
d_rem_code_phase_samples = 0.0; d_rem_code_phase_samples = 0.0;
// Residual carrier phase // Residual carrier phase
@ -369,7 +370,7 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items,gr_vect
//carrier phase accumulator for (K) Doppler estimation //carrier phase accumulator for (K) Doppler estimation
d_acc_carrier_phase_rad = d_acc_carrier_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * Galileo_E1_CODE_PERIOD; d_acc_carrier_phase_rad = d_acc_carrier_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * Galileo_E1_CODE_PERIOD;
//remnant carrier phase to prevent overflow in the code NCO //remnant carrier phase to prevent overflow in the code NCO
d_rem_carr_phase_rad = d_rem_carr_phase_rad + GPS_TWO_PI* d_carrier_doppler_hz * Galileo_E1_CODE_PERIOD; d_rem_carr_phase_rad = d_rem_carr_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * Galileo_E1_CODE_PERIOD;
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, GPS_TWO_PI);
// ################## DLL ########################################################## // ################## DLL ##########################################################
@ -385,15 +386,15 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items,gr_vect
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
// keep alignment parameters for the next input buffer // keep alignment parameters for the next input buffer
float T_chip_seconds; double T_chip_seconds;
float T_prn_seconds; double T_prn_seconds;
float T_prn_samples; double T_prn_samples;
float K_blk_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 lenght based in the new period of the PRN sequence and the code phase error estimation
T_chip_seconds = 1 / d_code_freq_chips; T_chip_seconds = 1 / (double)d_code_freq_chips;
T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS; T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS;
T_prn_samples = T_prn_seconds * (float)d_fs_in; T_prn_samples = T_prn_seconds * (double)d_fs_in;
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs*(float)d_fs_in; K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * (double)d_fs_in;
d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples
d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample
@ -427,12 +428,11 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items,gr_vect
{ {
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
ControlMessageFactory* cmf = new ControlMessageFactory(); std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
if (d_queue != gr::msg_queue::sptr()) if (d_queue != gr::msg_queue::sptr())
{ {
d_queue->handle(cmf->GetQueueMessage(d_channel, 2)); d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
} }
delete cmf;
d_carrier_lock_fail_counter = 0; d_carrier_lock_fail_counter = 0;
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
} }

View File

@ -16,7 +16,7 @@
* GNSS-SDR is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* at your option) any later version. * (at your option) any later version.
* *
* GNSS-SDR is distributed in the hope that it will be useful, * GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -145,7 +145,7 @@ private:
gr_complex *d_Very_Late; gr_complex *d_Very_Late;
// remaining code phase and carrier phase between tracking loops // remaining code phase and carrier phase between tracking loops
float d_rem_code_phase_samples; double d_rem_code_phase_samples;
float d_rem_carr_phase_rad; float d_rem_carr_phase_rad;
// PLL and DLL filter library // PLL and DLL filter library
@ -160,7 +160,7 @@ private:
Correlator d_correlator; Correlator d_correlator;
// tracking vars // tracking vars
float d_code_freq_chips; double d_code_freq_chips;
float d_carrier_doppler_hz; float d_carrier_doppler_hz;
double d_acc_carrier_phase_rad; double d_acc_carrier_phase_rad;
double d_acc_code_phase_secs; double d_acc_code_phase_secs;

View File

@ -39,6 +39,7 @@
#include "galileo_e1_tcp_connector_tracking_cc.h" #include "galileo_e1_tcp_connector_tracking_cc.h"
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include <memory>
#include <sstream> #include <sstream>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
@ -391,20 +392,20 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_ve
code_error_filt_chips = tcp_data.proc_pack_code_error; code_error_filt_chips = tcp_data.proc_pack_code_error;
//Code phase accumulator //Code phase accumulator
float code_error_filt_secs; float code_error_filt_secs;
code_error_filt_secs=(Galileo_E1_CODE_PERIOD*code_error_filt_chips)/Galileo_E1_CODE_CHIP_RATE_HZ; //[seconds] 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; 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 ALIGNEMENT #######################
// keep alignment parameters for the next input buffer // keep alignment parameters for the next input buffer
float T_chip_seconds; double T_chip_seconds;
float T_prn_seconds; double T_prn_seconds;
float T_prn_samples; double T_prn_samples;
float K_blk_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 lenght based in the new period of the PRN sequence and the code phase error estimation
T_chip_seconds = 1 / d_code_freq_chips; T_chip_seconds = 1 / (double)d_code_freq_chips;
T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS; T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS;
T_prn_samples = T_prn_seconds * (float)d_fs_in; T_prn_samples = T_prn_seconds * (double)d_fs_in;
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs*(float)d_fs_in; K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * (double)d_fs_in;
d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples
d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample
@ -438,12 +439,11 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_ve
{ {
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
ControlMessageFactory* cmf = new ControlMessageFactory(); std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
if (d_queue != gr::msg_queue::sptr()) if (d_queue != gr::msg_queue::sptr())
{ {
d_queue->handle(cmf->GetQueueMessage(d_channel, 2)); d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
} }
delete cmf;
d_carrier_lock_fail_counter = 0; d_carrier_lock_fail_counter = 0;
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
} }
@ -489,23 +489,23 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_ve
} }
else else
{ {
// ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled) // ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled)
/*! /*!
* \todo The stop timer has to be moved to the signal source! * \todo The stop timer has to be moved to the signal source!
*/ */
// stream to collect cout calls to improve thread safety // stream to collect cout calls to improve thread safety
std::stringstream tmp_str_stream; std::stringstream tmp_str_stream;
if (floor(d_sample_counter / d_fs_in) != d_last_seg) if (floor(d_sample_counter / d_fs_in) != d_last_seg)
{ {
d_last_seg = floor(d_sample_counter / d_fs_in); d_last_seg = floor(d_sample_counter / d_fs_in);
if (d_channel == 0) if (d_channel == 0)
{ {
// debug: Second counter in channel 0 // debug: Second counter in channel 0
tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush; tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
std::cout << tmp_str_stream.rdbuf() << std::flush; std::cout << tmp_str_stream.rdbuf() << std::flush;
} }
} }
*d_Early = gr_complex(0,0); *d_Early = gr_complex(0,0);
*d_Prompt = gr_complex(0,0); *d_Prompt = gr_complex(0,0);
*d_Late = gr_complex(0,0); *d_Late = gr_complex(0,0);

View File

@ -23,7 +23,7 @@
* GNSS-SDR is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* at your option) any later version. * (at your option) any later version.
* *
* GNSS-SDR is distributed in the hope that it will be useful, * GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -149,7 +149,7 @@ private:
gr_complex *d_Very_Late; gr_complex *d_Very_Late;
// remaining code phase and carrier phase between tracking loops // remaining code phase and carrier phase between tracking loops
float d_rem_code_phase_samples; double d_rem_code_phase_samples;
float d_next_rem_code_phase_samples; float d_next_rem_code_phase_samples;
float d_rem_carr_phase_rad; float d_rem_carr_phase_rad;
@ -161,7 +161,7 @@ private:
Correlator d_correlator; Correlator d_correlator;
// tracking vars // tracking vars
float d_code_freq_chips; double d_code_freq_chips;
float d_carrier_doppler_hz; float d_carrier_doppler_hz;
float d_acc_carrier_phase_rad; float d_acc_carrier_phase_rad;
float d_acc_code_phase_secs; float d_acc_code_phase_secs;

View File

@ -21,7 +21,7 @@
* GNSS-SDR is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* at your option) any later version. * (at your option) any later version.
* *
* GNSS-SDR is distributed in the hope that it will be useful, * GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -474,12 +474,11 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
{ {
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
ControlMessageFactory* cmf = new ControlMessageFactory(); std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
if (d_queue != gr::msg_queue::sptr()) if (d_queue != gr::msg_queue::sptr())
{ {
d_queue->handle(cmf->GetQueueMessage(d_channel, 2)); d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
} }
delete cmf;
d_carrier_lock_fail_counter = 0; d_carrier_lock_fail_counter = 0;
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
} }
@ -513,12 +512,12 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
double T_prn_seconds; double T_prn_seconds;
double T_prn_samples; double T_prn_samples;
double K_blk_samples; double K_blk_samples;
T_chip_seconds = 1/d_code_freq_hz; T_chip_seconds = 1 / (double)d_code_freq_hz;
T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
T_prn_samples = T_prn_seconds * d_fs_in; T_prn_samples = T_prn_seconds * d_fs_in;
float code_error_filt_samples; float code_error_filt_samples;
code_error_filt_samples = T_prn_seconds*code_error_filt_chips*T_chip_seconds*(float)d_fs_in; //[seconds] code_error_filt_samples = T_prn_seconds * code_error_filt_chips * T_chip_seconds * (double)d_fs_in; //[seconds]
d_acc_code_phase_samples = d_acc_code_phase_samples + code_error_filt_samples; d_acc_code_phase_samples = d_acc_code_phase_samples + code_error_filt_samples;
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_samples; K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_samples;
@ -529,7 +528,7 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
current_synchro_data.Prompt_I = (double)(*d_Prompt).real(); current_synchro_data.Prompt_I = (double)(*d_Prompt).real();
current_synchro_data.Prompt_Q = (double)(*d_Prompt).imag(); current_synchro_data.Prompt_Q = (double)(*d_Prompt).imag();
// Tracking_timestamp_secs is aligned with the PRN start sample // Tracking_timestamp_secs is aligned with the PRN start sample
current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + (double)d_current_prn_length_samples + d_rem_code_phase_samples)/d_fs_in; current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + (double)d_current_prn_length_samples + (double)d_rem_code_phase_samples) / (double)d_fs_in;
// This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, Code_phase_secs=0 // This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, Code_phase_secs=0
current_synchro_data.Code_phase_secs = 0; current_synchro_data.Code_phase_secs = 0;
current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad;

View File

@ -21,7 +21,7 @@
* GNSS-SDR is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* at your option) any later version. * (at your option) any later version.
* *
* GNSS-SDR is distributed in the hope that it will be useful, * GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -36,6 +36,7 @@
#include "gps_l1_ca_dll_pll_optim_tracking_cc.h" #include "gps_l1_ca_dll_pll_optim_tracking_cc.h"
#include <iostream> #include <iostream>
#include <memory>
#include <sstream> #include <sstream>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
@ -396,9 +397,9 @@ int Gps_L1_Ca_Dll_Pll_Optim_Tracking_cc::general_work (int noutput_items, gr_vec
// New code Doppler frequency estimation // 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_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ);
//carrier phase accumulator for (K) doppler estimation //carrier phase accumulator for (K) doppler estimation
d_acc_carrier_phase_rad = d_acc_carrier_phase_rad + GPS_TWO_PI*d_carrier_doppler_hz*GPS_L1_CA_CODE_PERIOD; d_acc_carrier_phase_rad = d_acc_carrier_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * GPS_L1_CA_CODE_PERIOD;
//remnant carrier phase to prevent overflow in the code NCO //remnant carrier phase to prevent overflow in the code NCO
d_rem_carr_phase_rad = d_rem_carr_phase_rad + GPS_TWO_PI*d_carrier_doppler_hz*GPS_L1_CA_CODE_PERIOD; d_rem_carr_phase_rad = d_rem_carr_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * GPS_L1_CA_CODE_PERIOD;
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, GPS_TWO_PI);
// ################## DLL ########################################################## // ################## DLL ##########################################################
@ -408,20 +409,20 @@ int Gps_L1_Ca_Dll_Pll_Optim_Tracking_cc::general_work (int noutput_items, gr_vec
code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); //[chips/second] code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); //[chips/second]
//Code phase accumulator //Code phase accumulator
float code_error_filt_secs; float code_error_filt_secs;
code_error_filt_secs = (GPS_L1_CA_CODE_PERIOD*code_error_filt_chips) / GPS_L1_CA_CODE_RATE_HZ; //[seconds] code_error_filt_secs = (GPS_L1_CA_CODE_PERIOD * code_error_filt_chips) / GPS_L1_CA_CODE_RATE_HZ; //[seconds]
d_acc_code_phase_secs = d_acc_code_phase_secs + code_error_filt_secs; 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 ALIGNEMENT #######################
// keep alignment parameters for the next input buffer // keep alignment parameters for the next input buffer
float T_chip_seconds; double T_chip_seconds;
float T_prn_seconds; double T_prn_seconds;
float T_prn_samples; double T_prn_samples;
float K_blk_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 / d_code_freq_chips; T_chip_seconds = 1 / (double)d_code_freq_chips;
T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
T_prn_samples = T_prn_seconds * (float)d_fs_in; T_prn_samples = T_prn_seconds * (double)d_fs_in;
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs*(float)d_fs_in; K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * (double)d_fs_in;
d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples
d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample
@ -452,12 +453,11 @@ int Gps_L1_Ca_Dll_Pll_Optim_Tracking_cc::general_work (int noutput_items, gr_vec
{ {
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
ControlMessageFactory* cmf = new ControlMessageFactory(); std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
if (d_queue != gr::msg_queue::sptr()) if (d_queue != gr::msg_queue::sptr())
{ {
d_queue->handle(cmf->GetQueueMessage(d_channel, 2)); d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
} }
delete cmf;
d_carrier_lock_fail_counter = 0; d_carrier_lock_fail_counter = 0;
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
} }
@ -499,24 +499,23 @@ int Gps_L1_Ca_Dll_Pll_Optim_Tracking_cc::general_work (int noutput_items, gr_vec
} }
else else
{ {
// ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled)
/*!
* \todo The stop timer has to be moved to the signal source!
*/
// stream to collect cout calls to improve thread safety
std::stringstream tmp_str_stream;
if (floor(d_sample_counter / d_fs_in) != d_last_seg)
{
d_last_seg = floor(d_sample_counter / d_fs_in);
// ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled) if (d_channel == 0)
/*! {
* \todo The stop timer has to be moved to the signal source! // debug: Second counter in channel 0
*/ tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
// stream to collect cout calls to improve thread safety std::cout << tmp_str_stream.rdbuf() << std::flush;
std::stringstream tmp_str_stream; }
if (floor(d_sample_counter / d_fs_in) != d_last_seg) }
{
d_last_seg = floor(d_sample_counter / d_fs_in);
if (d_channel == 0)
{
// debug: Second counter in channel 0
tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
std::cout << tmp_str_stream.rdbuf() << std::flush;
}
}
*d_Early = gr_complex(0,0); *d_Early = gr_complex(0,0);
*d_Prompt = gr_complex(0,0); *d_Prompt = gr_complex(0,0);
*d_Late = gr_complex(0,0); *d_Late = gr_complex(0,0);

View File

@ -21,7 +21,7 @@
* GNSS-SDR is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* at your option) any later version. * (at your option) any later version.
* *
* GNSS-SDR is distributed in the hope that it will be useful, * GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -134,7 +134,7 @@ private:
gr_complex *d_Late; gr_complex *d_Late;
// remaining code phase and carrier phase between tracking loops // remaining code phase and carrier phase between tracking loops
float d_rem_code_phase_samples; double d_rem_code_phase_samples;
float d_rem_carr_phase_rad; float d_rem_carr_phase_rad;
// PLL and DLL filter library // PLL and DLL filter library
@ -148,7 +148,7 @@ private:
Correlator d_correlator; Correlator d_correlator;
// tracking vars // tracking vars
float d_code_freq_chips; double d_code_freq_chips;
float d_carrier_doppler_hz; float d_carrier_doppler_hz;
float d_acc_carrier_phase_rad; float d_acc_carrier_phase_rad;
float d_code_phase_samples; float d_code_phase_samples;

View File

@ -21,7 +21,7 @@
* GNSS-SDR is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* at your option) any later version. * (at your option) any later version.
* *
* GNSS-SDR is distributed in the hope that it will be useful, * GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -37,6 +37,7 @@
#include "gps_l1_ca_dll_pll_tracking_cc.h" #include "gps_l1_ca_dll_pll_tracking_cc.h"
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include <memory>
#include <sstream> #include <sstream>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
@ -408,9 +409,9 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
// New code Doppler frequency estimation // 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_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ);
//carrier phase accumulator for (K) doppler estimation //carrier phase accumulator for (K) doppler estimation
d_acc_carrier_phase_rad = d_acc_carrier_phase_rad + GPS_TWO_PI*d_carrier_doppler_hz*GPS_L1_CA_CODE_PERIOD; d_acc_carrier_phase_rad = d_acc_carrier_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * GPS_L1_CA_CODE_PERIOD;
//remanent carrier phase to prevent overflow in the code NCO //remanent carrier phase to prevent overflow in the code NCO
d_rem_carr_phase_rad = d_rem_carr_phase_rad+GPS_TWO_PI*d_carrier_doppler_hz*GPS_L1_CA_CODE_PERIOD; d_rem_carr_phase_rad = d_rem_carr_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * GPS_L1_CA_CODE_PERIOD;
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, GPS_TWO_PI);
// ################## DLL ########################################################## // ################## DLL ##########################################################
@ -420,20 +421,20 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); //[chips/second] code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); //[chips/second]
//Code phase accumulator //Code phase accumulator
float code_error_filt_secs; float code_error_filt_secs;
code_error_filt_secs = (GPS_L1_CA_CODE_PERIOD*code_error_filt_chips)/GPS_L1_CA_CODE_RATE_HZ; //[seconds] code_error_filt_secs = (GPS_L1_CA_CODE_PERIOD * code_error_filt_chips) / GPS_L1_CA_CODE_RATE_HZ; //[seconds]
d_acc_code_phase_secs = d_acc_code_phase_secs + code_error_filt_secs; 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 ALIGNEMENT #######################
// keep alignment parameters for the next input buffer // keep alignment parameters for the next input buffer
float T_chip_seconds; double T_chip_seconds;
float T_prn_seconds; double T_prn_seconds;
float T_prn_samples; double T_prn_samples;
float K_blk_samples; double K_blk_samples;
// Compute the next buffer length 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 / d_code_freq_chips; T_chip_seconds = 1 / (double)d_code_freq_chips;
T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
T_prn_samples = T_prn_seconds * (float)d_fs_in; T_prn_samples = T_prn_seconds * (double)d_fs_in;
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs*(float)d_fs_in; K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * (double)d_fs_in;
d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples
d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample
@ -464,12 +465,11 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
{ {
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
ControlMessageFactory* cmf = new ControlMessageFactory(); std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
if (d_queue != gr::msg_queue::sptr()) if (d_queue != gr::msg_queue::sptr())
{ {
d_queue->handle(cmf->GetQueueMessage(d_channel, 2)); d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
} }
delete cmf;
d_carrier_lock_fail_counter = 0; d_carrier_lock_fail_counter = 0;
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
} }
@ -515,23 +515,23 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
} }
else else
{ {
// ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled) // ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled)
/*! /*!
* \todo The stop timer has to be moved to the signal source! * \todo The stop timer has to be moved to the signal source!
*/ */
// stream to collect cout calls to improve thread safety // stream to collect cout calls to improve thread safety
std::stringstream tmp_str_stream; std::stringstream tmp_str_stream;
if (floor(d_sample_counter / d_fs_in) != d_last_seg) if (floor(d_sample_counter / d_fs_in) != d_last_seg)
{ {
d_last_seg = floor(d_sample_counter / d_fs_in); d_last_seg = floor(d_sample_counter / d_fs_in);
if (d_channel == 0) if (d_channel == 0)
{ {
// debug: Second counter in channel 0 // debug: Second counter in channel 0
tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush; tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
std::cout << tmp_str_stream.rdbuf() << std::flush; std::cout << tmp_str_stream.rdbuf() << std::flush;
} }
} }
*d_Early = gr_complex(0,0); *d_Early = gr_complex(0,0);
*d_Prompt = gr_complex(0,0); *d_Prompt = gr_complex(0,0);
*d_Late = gr_complex(0,0); *d_Late = gr_complex(0,0);

View File

@ -21,7 +21,7 @@
* GNSS-SDR is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* at your option) any later version. * (at your option) any later version.
* *
* GNSS-SDR is distributed in the hope that it will be useful, * GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -138,7 +138,7 @@ private:
gr_complex *d_Late; gr_complex *d_Late;
// remaining code phase and carrier phase between tracking loops // remaining code phase and carrier phase between tracking loops
float d_rem_code_phase_samples; double d_rem_code_phase_samples;
float d_rem_carr_phase_rad; float d_rem_carr_phase_rad;
// PLL and DLL filter library // PLL and DLL filter library
@ -152,7 +152,7 @@ private:
Correlator d_correlator; Correlator d_correlator;
// tracking vars // tracking vars
float d_code_freq_chips; double d_code_freq_chips;
float d_carrier_doppler_hz; float d_carrier_doppler_hz;
float d_acc_carrier_phase_rad; float d_acc_carrier_phase_rad;
float d_code_phase_samples; float d_code_phase_samples;

View File

@ -457,19 +457,19 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec
// sampling frequency (fixed) // sampling frequency (fixed)
d_code_phase_step_chips = d_code_freq_hz / (float)d_fs_in; //[chips] d_code_phase_step_chips = d_code_freq_hz / (float)d_fs_in; //[chips]
// variable code PRN sample block size // variable code PRN sample block size
float T_chip_seconds; double T_chip_seconds;
float T_prn_seconds; double T_prn_seconds;
float T_prn_samples; double T_prn_samples;
float K_blk_samples; double K_blk_samples;
T_chip_seconds = 1 / d_code_freq_hz; T_chip_seconds = 1 / (double)d_code_freq_hz;
T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
T_prn_samples = T_prn_seconds * d_fs_in; T_prn_samples = T_prn_seconds * (double)d_fs_in;
d_rem_code_phase_samples = d_next_rem_code_phase_samples; d_rem_code_phase_samples = d_next_rem_code_phase_samples;
K_blk_samples = T_prn_samples + d_rem_code_phase_samples;//-code_error*(float)d_fs_in; K_blk_samples = T_prn_samples + d_rem_code_phase_samples;//-code_error*(double)d_fs_in;
// Update the current PRN delay (code phase in samples) // Update the current PRN delay (code phase in samples)
float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS / GPS_L1_CA_CODE_RATE_HZ; double T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS / GPS_L1_CA_CODE_RATE_HZ;
float T_prn_true_samples = T_prn_true_seconds * (float)d_fs_in; double T_prn_true_samples = T_prn_true_seconds * (double)d_fs_in;
d_code_phase_samples = d_code_phase_samples + T_prn_samples - T_prn_true_samples; d_code_phase_samples = d_code_phase_samples + T_prn_samples - T_prn_true_samples;
if (d_code_phase_samples < 0) if (d_code_phase_samples < 0)
{ {
@ -509,11 +509,10 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec
{ {
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
ControlMessageFactory* cmf = new ControlMessageFactory(); std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
if (d_queue != gr::msg_queue::sptr()) { if (d_queue != gr::msg_queue::sptr()) {
d_queue->handle(cmf->GetQueueMessage(d_channel, 2)); d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
} }
delete cmf;
d_carrier_lock_fail_counter = 0; d_carrier_lock_fail_counter = 0;
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
@ -558,23 +557,23 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec
} }
else else
{ {
// ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled) // ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled)
/*! /*!
* \todo The stop timer has to be moved to the signal source! * \todo The stop timer has to be moved to the signal source!
*/ */
// stream to collect cout calls to improve thread safety // stream to collect cout calls to improve thread safety
std::stringstream tmp_str_stream; std::stringstream tmp_str_stream;
if (floor(d_sample_counter / d_fs_in) != d_last_seg) if (floor(d_sample_counter / d_fs_in) != d_last_seg)
{ {
d_last_seg = floor(d_sample_counter / d_fs_in); d_last_seg = floor(d_sample_counter / d_fs_in);
if (d_channel == 0) if (d_channel == 0)
{ {
// debug: Second counter in channel 0 // debug: Second counter in channel 0
tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush; tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
std::cout << tmp_str_stream.rdbuf() << std::flush; std::cout << tmp_str_stream.rdbuf() << std::flush;
} }
} }
*d_Early = gr_complex(0,0); *d_Early = gr_complex(0,0);
*d_Prompt = gr_complex(0,0); *d_Prompt = gr_complex(0,0);
*d_Late = gr_complex(0,0); *d_Late = gr_complex(0,0);

View File

@ -21,7 +21,7 @@
* GNSS-SDR is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* at your option) any later version. * (at your option) any later version.
* *
* GNSS-SDR is distributed in the hope that it will be useful, * GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -132,9 +132,9 @@ private:
long d_if_freq; long d_if_freq;
long d_fs_in; long d_fs_in;
float d_early_late_spc_chips; double d_early_late_spc_chips;
float d_code_phase_step_chips; double d_code_phase_step_chips;
gr_complex* d_ca_code; gr_complex* d_ca_code;
@ -148,8 +148,8 @@ private:
gr_complex *d_Late; gr_complex *d_Late;
// remaining code phase and carrier phase between tracking loops // remaining code phase and carrier phase between tracking loops
float d_rem_code_phase_samples; double d_rem_code_phase_samples;
float d_next_rem_code_phase_samples; double d_next_rem_code_phase_samples;
float d_rem_carr_phase_rad; float d_rem_carr_phase_rad;
// PLL and DLL filter library // PLL and DLL filter library
@ -163,10 +163,10 @@ private:
Correlator d_correlator; Correlator d_correlator;
// tracking vars // tracking vars
float d_code_freq_hz; double d_code_freq_hz;
float d_carrier_doppler_hz; double d_carrier_doppler_hz;
float d_acc_carrier_phase_rad; double d_acc_carrier_phase_rad;
float d_code_phase_samples; double d_code_phase_samples;
size_t d_port_ch0; size_t d_port_ch0;
size_t d_port; size_t d_port;
int d_listen_connection; int d_listen_connection;