diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index c5ec7036a..88350e361 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -1,7 +1,7 @@ /*! * \file dll_pll_veml_tracking.cc * \brief Implementation of a code DLL + carrier PLL tracking block. - * \author Antonio Ramos, 2018 antonioramosdet(at)gmail.com + * \author Antonio Ramos, 2018 antonio.ramosdet(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, @@ -112,8 +112,9 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( float pll_bw_narrow_hz, float dll_bw_narrow_hz, float early_late_space_chips, float very_early_late_space_chips, float early_late_space_narrow_chips, float very_early_late_space_narrow_chips, - int extend_correlation_symbols, bool track_pilot, char system, char signal[3]) : gr::block("dll_pll_veml_tracking", gr::io_signature::make(1, 1, sizeof(gr_complex)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) + int extend_correlation_symbols, bool track_pilot, char system, + char signal[3]) : gr::block("dll_pll_veml_tracking", 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")); @@ -145,7 +146,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( d_correlation_length_ms = 1; d_code_samples_per_chip = 1; d_code_length_chips = static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS); - //GPS L1 C/A does not have pilot component nor secondary code + // GPS L1 C/A does not have pilot component nor secondary code d_secondary = false; d_track_pilot = false; interchange_iq = false; @@ -159,7 +160,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( d_symbols_per_bit = GPS_L2_SAMPLES_PER_SYMBOL; d_correlation_length_ms = 20; d_code_samples_per_chip = 1; - //GPS L2 does not have pilot component nor secondary code + // GPS L2 does not have pilot component nor secondary code d_secondary = false; d_track_pilot = false; interchange_iq = false; @@ -173,7 +174,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( d_correlation_length_ms = 1; d_code_samples_per_chip = 1; d_code_length_chips = static_cast(GPS_L5i_CODE_LENGTH_CHIPS); - //GPS L5 does not have pilot secondary code + // GPS L5 does not have pilot secondary code d_secondary = true; if (d_track_pilot) { @@ -191,7 +192,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( else { LOG(WARNING) << "Invalid Signal argument when instantiating tracking blocks"; - std::cout << "Invalid Signal argument when instantiating tracking blocks" << std::endl; + std::cerr << "Invalid Signal argument when instantiating tracking blocks" << std::endl; } } else if (system == 'E') @@ -250,7 +251,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking( else { LOG(WARNING) << "Invalid System argument when instantiating tracking blocks"; - std::cout << "Invalid System argument when instantiating tracking blocks" << std::endl; + std::cerr << "Invalid System argument when instantiating tracking blocks" << std::endl; d_correlation_length_ms = 1; d_secondary = false; interchange_iq = false; @@ -411,12 +412,11 @@ void dll_pll_veml_tracking::start_tracking() 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 = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; + long int acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); double acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / d_fs_in; DLOG(INFO) << "Number of samples between Acquisition and Tracking = " << acq_trk_diff_samples; DLOG(INFO) << "Number of seconds between Acquisition and Tracking = " << acq_trk_diff_seconds; - // Doppler effect - // Fd=(C/(C+Vr))*F + // Doppler effect Fd = (C / (C + Vr)) * F double radial_velocity = (d_signal_carrier_freq + d_acq_carrier_doppler_hz) / d_signal_carrier_freq; // new chip and prn sequence periods based on acq Doppler d_code_freq_chips = radial_velocity * d_code_chip_rate; @@ -604,7 +604,7 @@ dll_pll_veml_tracking::~dll_pll_veml_tracking() bool dll_pll_veml_tracking::acquire_secondary() { - //******* preamble correlation ******** + // ******* preamble correlation ******** int corr_value = 0; for (unsigned int i = 0; i < d_secondary_code_length; i++) { @@ -766,6 +766,7 @@ void dll_pll_veml_tracking::clear_tracking_vars() d_last_prompt = gr_complex(0.0, 0.0); } + void dll_pll_veml_tracking::update_tracking_vars() { T_chip_seconds = 1.0 / d_code_freq_chips; @@ -796,6 +797,7 @@ void dll_pll_veml_tracking::update_tracking_vars() d_rem_code_phase_chips = d_code_freq_chips * d_rem_code_phase_samples / d_fs_in; } + void dll_pll_veml_tracking::save_correlation_results() { if (d_secondary) @@ -960,301 +962,6 @@ void dll_pll_veml_tracking::log_data(bool integrating) } -int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) -{ - gr::thread::scoped_lock l(d_setlock); - const gr_complex *in = reinterpret_cast(input_items[0]); - Gnss_Synchro **out = reinterpret_cast(&output_items[0]); - Gnss_Synchro current_synchro_data = Gnss_Synchro(); - - switch (d_state) - { - case 0: // Standby - Pass Through. Full throttle - { - d_sample_counter += ninput_items[0]; - consume_each(ninput_items[0]); - return 0; - break; - } - case 1: // Pull-in - { - // Signal alignment (skip samples until the incoming signal is aligned with local replica) - // Fill the acquisition data - unsigned long int acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; - double acq_trk_shif_correction_samples = static_cast(d_current_prn_length_samples) - std::fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_current_prn_length_samples)); - int samples_offset = std::round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - if (samples_offset < 0) - { - samples_offset = 0; - } - d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * d_acq_code_phase_samples; - d_state = 2; - d_sample_counter += samples_offset; // count for the processed samples - consume_each(samples_offset); // shift input to perform alignment with local replica - return 0; - } - case 2: // Wide tracking and symbol synchronization - { - do_correlation_step(in); - // Save single correlation step variables - if (d_veml) - { - d_VE_accu = *d_Very_Early; - d_VL_accu = *d_Very_Late; - } - d_E_accu = *d_Early; - d_P_accu = *d_Prompt; - d_L_accu = *d_Late; - - // Check lock status - if (!cn0_and_tracking_lock_status()) - { - clear_tracking_vars(); - d_state = 0; // loss-of-lock detected - } - else - { - bool next_state = false; - // Perform DLL/PLL tracking loop computations. Costas Loop enabled - run_dll_pll(); - update_tracking_vars(); - - // enable write dump file this cycle (valid DLL/PLL cycle) - log_data(false); - if (d_secondary) - { - // ####### SECONDARY CODE LOCK ##### - d_Prompt_buffer_deque.push_back(*d_Prompt); - if (d_Prompt_buffer_deque.size() == d_secondary_code_length) - { - next_state = acquire_secondary(); - if (next_state) - { - std::cout << "Secondary code locked for CH " << d_channel - << " : Satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; - } - - d_Prompt_buffer_deque.pop_front(); - } - } - else //Signal does not have secondary code. Search a bit transition by sign change - { - if (d_synchonizing) - { - if (d_Prompt->real() * d_last_prompt.real() > 0.0) - { - d_current_symbol++; - } - else if (d_current_symbol > d_symbols_per_bit) - { - d_synchonizing = false; - d_current_symbol = 1; - } - else - { - d_current_symbol = 1; - d_last_prompt = *d_Prompt; - } - } - else if (d_last_prompt.real() != 0.0) - { - d_current_symbol++; - if (d_current_symbol == d_symbols_per_bit) next_state = true; - } - else - { - d_last_prompt = *d_Prompt; - d_synchonizing = true; - d_current_symbol = 1; - } - } - if (next_state) - { // reset extended correlator - d_VE_accu = gr_complex(0.0, 0.0); - d_E_accu = gr_complex(0.0, 0.0); - d_P_accu = gr_complex(0.0, 0.0); - d_L_accu = gr_complex(0.0, 0.0); - d_VL_accu = gr_complex(0.0, 0.0); - d_last_prompt = gr_complex(0.0, 0.0); - d_Prompt_buffer_deque.clear(); - d_current_symbol = 0; - d_synchonizing = false; - // Set narrow taps delay values [chips] - d_code_loop_filter.set_DLL_BW(d_dll_bw_narrow_hz); - d_carrier_loop_filter.set_PLL_BW(d_pll_bw_narrow_hz); - if (d_veml) - { - d_local_code_shift_chips[0] = -d_very_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); - d_local_code_shift_chips[1] = -d_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); - d_local_code_shift_chips[3] = d_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); - d_local_code_shift_chips[4] = d_very_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); - } - else - { - d_local_code_shift_chips[0] = -d_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); - d_local_code_shift_chips[2] = d_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); - } - - // UPDATE INTEGRATION TIME - if (d_enable_extended_integration) - { - d_extend_correlation_symbols_count = 0; - float new_correlation_time_s = static_cast(d_extend_correlation_symbols) * static_cast(d_code_period); - d_carrier_loop_filter.set_pdi(new_correlation_time_s); - d_code_loop_filter.set_pdi(new_correlation_time_s); - d_state = 3; // next state is the extended correlator integrator - LOG(INFO) << "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " - << d_channel - << " : Satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN); - std::cout << "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " - << d_channel - << " : Satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; - } - else - { - d_state = 4; - } - } - } - break; - } - case 3: // coherent integration (correlation time extension) - { - // Fill the acquisition data - current_synchro_data = *d_acquisition_gnss_synchro; - // perform a correlation step - do_correlation_step(in); - update_tracking_vars(); - save_correlation_results(); - - // ########### Output the tracking results to Telemetry block ########## - if (interchange_iq) - { - if (d_track_pilot) - { - //Note that data and pilot components are in quadrature. I and Q are interchanged - current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).imag()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).real()); - } - else - { - current_synchro_data.Prompt_I = static_cast((*d_Prompt).imag()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt).real()); - } - } - else - { - if (d_track_pilot) - { - //Note that data and pilot components are in quadrature. I and Q are interchanged - current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); - } - else - { - current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); - } - } - current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; - current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; - 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; - current_synchro_data.correlation_length_ms = d_correlation_length_ms; - d_extend_correlation_symbols_count++; - if (d_extend_correlation_symbols_count == (d_extend_correlation_symbols - 1)) - { - d_extend_correlation_symbols_count = 0; - d_state = 4; - } - log_data(true); - break; - } - case 4: // narrow tracking - { - // Fill the acquisition data - current_synchro_data = *d_acquisition_gnss_synchro; - - // perform a correlation step - do_correlation_step(in); - save_correlation_results(); - - // check lock status - if (!cn0_and_tracking_lock_status()) - { - clear_tracking_vars(); - d_state = 0; // loss-of-lock detected - } - else - { - run_dll_pll(); - update_tracking_vars(); - - // ########### Output the tracking results to Telemetry block ########## - if (interchange_iq) - { - if (d_track_pilot) - { - //Note that data and pilot components are in quadrature. I and Q are interchanged - current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).imag()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).real()); - } - else - { - current_synchro_data.Prompt_I = static_cast((*d_Prompt).imag()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt).real()); - } - } - else - { - if (d_track_pilot) - { - //Note that data and pilot components are in quadrature. I and Q are interchanged - current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); - } - else - { - current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); - current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); - } - } - current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; - current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; - 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; - current_synchro_data.correlation_length_ms = d_correlation_length_ms; - // enable write dump file this cycle (valid DLL/PLL cycle) - log_data(false); - // reset extended correlator - d_VE_accu = gr_complex(0.0, 0.0); - d_E_accu = gr_complex(0.0, 0.0); - d_P_accu = gr_complex(0.0, 0.0); - d_L_accu = gr_complex(0.0, 0.0); - d_VL_accu = gr_complex(0.0, 0.0); - if (d_enable_extended_integration) - { - d_state = 3; //new coherent integration (correlation time extension) cycle - } - } - } - } - consume_each(d_current_prn_length_samples); - d_sample_counter += d_current_prn_length_samples; - if (current_synchro_data.Flag_valid_symbol_output) - { - current_synchro_data.fs = static_cast(d_fs_in); - current_synchro_data.Tracking_sample_counter = d_sample_counter; - *out[0] = current_synchro_data; - return 1; - } - return 0; -} - - int dll_pll_veml_tracking::save_matfile() { // READ DUMP FILE @@ -1510,3 +1217,297 @@ void dll_pll_veml_tracking::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) gr::thread::scoped_lock l(d_setlock); d_acquisition_gnss_synchro = p_gnss_synchro; } + + +int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +{ + gr::thread::scoped_lock l(d_setlock); + const gr_complex *in = reinterpret_cast(input_items[0]); + Gnss_Synchro **out = reinterpret_cast(&output_items[0]); + Gnss_Synchro current_synchro_data = Gnss_Synchro(); + + switch (d_state) + { + case 0: // Standby - Consume samples at full throttle, do nothing + { + d_sample_counter += ninput_items[0]; + consume_each(ninput_items[0]); + return 0; + break; + } + case 1: // Pull-in + { + // Signal alignment (skip samples until the incoming signal is aligned with local replica) + unsigned long int acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; + double acq_trk_shif_correction_samples = static_cast(d_current_prn_length_samples) - std::fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_current_prn_length_samples)); + int samples_offset = std::round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); + if (samples_offset < 0) + { + samples_offset = 0; + } + d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * d_acq_code_phase_samples; + d_state = 2; + d_sample_counter += samples_offset; // count for the processed samples + consume_each(samples_offset); // shift input to perform alignment with local replica + return 0; + } + case 2: // Wide tracking and symbol synchronization + { + do_correlation_step(in); + // Save single correlation step variables + if (d_veml) + { + d_VE_accu = *d_Very_Early; + d_VL_accu = *d_Very_Late; + } + d_E_accu = *d_Early; + d_P_accu = *d_Prompt; + d_L_accu = *d_Late; + + // Check lock status + if (!cn0_and_tracking_lock_status()) + { + clear_tracking_vars(); + d_state = 0; // loss-of-lock detected + } + else + { + bool next_state = false; + // Perform DLL/PLL tracking loop computations. Costas Loop enabled + run_dll_pll(); + update_tracking_vars(); + + // enable write dump file this cycle (valid DLL/PLL cycle) + log_data(false); + if (d_secondary) + { + // ####### SECONDARY CODE LOCK ##### + d_Prompt_buffer_deque.push_back(*d_Prompt); + if (d_Prompt_buffer_deque.size() == d_secondary_code_length) + { + next_state = acquire_secondary(); + if (next_state) + { + std::cout << "Secondary code locked for CH " << d_channel + << " : Satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; + } + + d_Prompt_buffer_deque.pop_front(); + } + } + else // Signal does not have secondary code. Search a bit transition by sign change + { + if (d_synchonizing) + { + if (d_Prompt->real() * d_last_prompt.real() > 0.0) + { + d_current_symbol++; + } + else if (d_current_symbol > d_symbols_per_bit) + { + d_synchonizing = false; + d_current_symbol = 1; + } + else + { + d_current_symbol = 1; + d_last_prompt = *d_Prompt; + } + } + else if (d_last_prompt.real() != 0.0) + { + d_current_symbol++; + if (d_current_symbol == d_symbols_per_bit) next_state = true; + } + else + { + d_last_prompt = *d_Prompt; + d_synchonizing = true; + d_current_symbol = 1; + } + } + if (next_state) + { // reset extended correlator + d_VE_accu = gr_complex(0.0, 0.0); + d_E_accu = gr_complex(0.0, 0.0); + d_P_accu = gr_complex(0.0, 0.0); + d_L_accu = gr_complex(0.0, 0.0); + d_VL_accu = gr_complex(0.0, 0.0); + d_last_prompt = gr_complex(0.0, 0.0); + d_Prompt_buffer_deque.clear(); + d_current_symbol = 0; + d_synchonizing = false; + // Set narrow taps delay values [chips] + d_code_loop_filter.set_DLL_BW(d_dll_bw_narrow_hz); + d_carrier_loop_filter.set_PLL_BW(d_pll_bw_narrow_hz); + if (d_veml) + { + d_local_code_shift_chips[0] = -d_very_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[1] = -d_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[3] = d_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[4] = d_very_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); + } + else + { + d_local_code_shift_chips[0] = -d_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); + d_local_code_shift_chips[2] = d_early_late_spc_narrow_chips * static_cast(d_code_samples_per_chip); + } + + // UPDATE INTEGRATION TIME + if (d_enable_extended_integration) + { + d_extend_correlation_symbols_count = 0; + float new_correlation_time_s = static_cast(d_extend_correlation_symbols) * static_cast(d_code_period); + d_carrier_loop_filter.set_pdi(new_correlation_time_s); + d_code_loop_filter.set_pdi(new_correlation_time_s); + d_state = 3; // next state is the extended correlator integrator + LOG(INFO) << "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " + << d_channel + << " : Satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN); + std::cout << "Enabled " << d_extend_correlation_symbols << " [symbols] extended correlator for CH " + << d_channel + << " : Satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; + } + else + { + d_state = 4; + } + } + } + break; + } + case 3: // coherent integration (correlation time extension) + { + // Fill the acquisition data + current_synchro_data = *d_acquisition_gnss_synchro; + // perform a correlation step + do_correlation_step(in); + update_tracking_vars(); + save_correlation_results(); + + // ########### Output the tracking results to Telemetry block ########## + if (interchange_iq) + { + if (d_track_pilot) + { + // Note that data and pilot components are in quadrature. I and Q are interchanged + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).imag()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).real()); + } + else + { + current_synchro_data.Prompt_I = static_cast((*d_Prompt).imag()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt).real()); + } + } + else + { + if (d_track_pilot) + { + // Note that data and pilot components are in quadrature. I and Q are interchanged + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); + } + else + { + current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); + } + } + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; + 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; + current_synchro_data.correlation_length_ms = d_correlation_length_ms; + d_extend_correlation_symbols_count++; + if (d_extend_correlation_symbols_count == (d_extend_correlation_symbols - 1)) + { + d_extend_correlation_symbols_count = 0; + d_state = 4; + } + log_data(true); + break; + } + case 4: // narrow tracking + { + // Fill the acquisition data + current_synchro_data = *d_acquisition_gnss_synchro; + + // perform a correlation step + do_correlation_step(in); + save_correlation_results(); + + // check lock status + if (!cn0_and_tracking_lock_status()) + { + clear_tracking_vars(); + d_state = 0; // loss-of-lock detected + } + else + { + run_dll_pll(); + update_tracking_vars(); + + // ########### Output the tracking results to Telemetry block ########## + if (interchange_iq) + { + if (d_track_pilot) + { + // Note that data and pilot components are in quadrature. I and Q are interchanged + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).imag()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).real()); + } + else + { + current_synchro_data.Prompt_I = static_cast((*d_Prompt).imag()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt).real()); + } + } + else + { + if (d_track_pilot) + { + // Note that data and pilot components are in quadrature. I and Q are interchanged + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); + } + else + { + current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); + } + } + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; + 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; + current_synchro_data.correlation_length_ms = d_correlation_length_ms; + // enable write dump file this cycle (valid DLL/PLL cycle) + log_data(false); + // reset extended correlator + d_VE_accu = gr_complex(0.0, 0.0); + d_E_accu = gr_complex(0.0, 0.0); + d_P_accu = gr_complex(0.0, 0.0); + d_L_accu = gr_complex(0.0, 0.0); + d_VL_accu = gr_complex(0.0, 0.0); + if (d_enable_extended_integration) + { + d_state = 3; // new coherent integration (correlation time extension) cycle + } + } + } + } + consume_each(d_current_prn_length_samples); + d_sample_counter += d_current_prn_length_samples; + if (current_synchro_data.Flag_valid_symbol_output) + { + current_synchro_data.fs = static_cast(d_fs_in); + current_synchro_data.Tracking_sample_counter = d_sample_counter; + *out[0] = current_synchro_data; + return 1; + } + return 0; +} diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h index 76d4c5fda..1065f44ef 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h @@ -1,7 +1,7 @@ /*! * \file dll_pll_veml_tracking.h * \brief Implementation of a code DLL + carrier PLL tracking block. - * \author Antonio Ramos, 2018 antonioramosdet(at)gmail.com + * \author Antonio Ramos, 2018 antonio.ramosdet(at)gmail.com * * ------------------------------------------------------------------------- * @@ -55,8 +55,7 @@ dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(double fs_in, unsigned int 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 dll_pll_veml_tracking : public gr::block { @@ -67,12 +66,6 @@ public: 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); @@ -214,9 +207,9 @@ private: double T_prn_seconds; double T_prn_samples; double K_blk_samples; - //PRN period in 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; @@ -234,4 +227,4 @@ private: std::ofstream d_dump_file; }; -#endif //GNSS_SDR_DLL_PLL_VEML_TRACKING_H +#endif // GNSS_SDR_DLL_PLL_VEML_TRACKING_H