mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 15:23:04 +00:00 
			
		
		
		
	Improving tracking stability of carrier lock detector
This commit is contained in:
		| @@ -444,6 +444,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl | ||||
|     d_carrier_lock_test = 1.0; | ||||
|     d_CN0_SNV_dB_Hz = 0.0; | ||||
|     d_carrier_lock_fail_counter = 0; | ||||
|     d_code_lock_fail_counter = 0; | ||||
|     d_carrier_lock_threshold = trk_parameters.carrier_lock_th; | ||||
|     d_Prompt_Data = static_cast<gr_complex *>(volk_gnsssdr_malloc(sizeof(gr_complex), volk_gnsssdr_get_alignment())); | ||||
|     d_cn0_smoother = Exponential_Smoother(); | ||||
| @@ -451,6 +452,13 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl | ||||
|         { | ||||
|             d_cn0_smoother.set_samples_for_initialization(200 / static_cast<int>(d_code_period * 1000.0)); | ||||
|         } | ||||
|  | ||||
|     d_carrier_lock_test_smoother = Exponential_Smoother(); | ||||
|     d_carrier_lock_test_smoother.set_alpha(0.002); | ||||
|     d_carrier_lock_test_smoother.set_min_value(-1.0); | ||||
|     d_carrier_lock_test_smoother.set_offset(0.0); | ||||
|     d_carrier_lock_test_smoother.set_samples_for_initialization(25); | ||||
|  | ||||
|     d_acquisition_gnss_synchro = nullptr; | ||||
|     d_channel = 0; | ||||
|     d_acq_code_phase_samples = 0.0; | ||||
| @@ -717,6 +725,7 @@ void dll_pll_veml_tracking::start_tracking() | ||||
|     std::fill_n(d_correlator_outs, d_n_correlator_taps, gr_complex(0.0, 0.0)); | ||||
|  | ||||
|     d_carrier_lock_fail_counter = 0; | ||||
|     d_code_lock_fail_counter = 0; | ||||
|     d_rem_code_phase_samples = 0.0; | ||||
|     d_rem_carr_phase_rad = 0.0; | ||||
|     d_rem_code_phase_chips = 0.0; | ||||
| @@ -866,11 +875,13 @@ bool dll_pll_veml_tracking::cn0_and_tracking_lock_status(double coh_integration_ | ||||
|     float d_CN0_SNV_dB_Hz_raw = cn0_svn_estimator(d_Prompt_buffer, trk_parameters.cn0_samples, static_cast<float>(coh_integration_time_s)); | ||||
|     d_CN0_SNV_dB_Hz = d_cn0_smoother.smooth(d_CN0_SNV_dB_Hz_raw); | ||||
|     // Carrier lock indicator | ||||
|     d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, trk_parameters.cn0_samples); | ||||
|     d_carrier_lock_test = d_carrier_lock_test_smoother.smooth(carrier_lock_detector(d_Prompt_buffer, 1)); | ||||
|     //d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, trk_parameters.cn0_samples); | ||||
|     // Loss of lock detection | ||||
|     if (!d_pull_in_transitory) | ||||
|         { | ||||
|             if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < trk_parameters.cn0_min) | ||||
|             //d_carrier_lock_test < d_carrier_lock_threshold or | ||||
|             if (d_carrier_lock_test < d_carrier_lock_threshold) | ||||
|                 { | ||||
|                     d_carrier_lock_fail_counter++; | ||||
|                 } | ||||
| @@ -881,13 +892,28 @@ bool dll_pll_veml_tracking::cn0_and_tracking_lock_status(double coh_integration_ | ||||
|                             d_carrier_lock_fail_counter--; | ||||
|                         } | ||||
|                 } | ||||
|  | ||||
|             if (d_CN0_SNV_dB_Hz < trk_parameters.cn0_min) | ||||
|                 { | ||||
|                     d_code_lock_fail_counter++; | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     if (d_code_lock_fail_counter > 0) | ||||
|                         { | ||||
|                             d_code_lock_fail_counter--; | ||||
|                         } | ||||
|                 } | ||||
|         } | ||||
|     if (d_carrier_lock_fail_counter > trk_parameters.max_lock_fail) | ||||
|     if (d_carrier_lock_fail_counter > trk_parameters.max_carrier_lock_fail or d_code_lock_fail_counter > trk_parameters.max_code_lock_fail) | ||||
|         { | ||||
|             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 | ||||
|                       << " (carrier_lock_fail_counter:" << d_carrier_lock_fail_counter | ||||
|                       << " code_lock_fail_counter : " << d_code_lock_fail_counter << ")"; | ||||
|             this->message_port_pub(pmt::mp("events"), pmt::from_long(3));  // 3 -> loss of lock | ||||
|             d_carrier_lock_fail_counter = 0; | ||||
|             d_code_lock_fail_counter = 0; | ||||
|             return false; | ||||
|         } | ||||
|     return true; | ||||
| @@ -1573,6 +1599,8 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) | ||||
|             if (trk_parameters.pull_in_time_s < (d_sample_counter - d_acq_sample_stamp) / static_cast<int>(trk_parameters.fs_in)) | ||||
|                 { | ||||
|                     d_pull_in_transitory = false; | ||||
|                     d_carrier_lock_fail_counter = 0; | ||||
|                     d_code_lock_fail_counter = 0; | ||||
|                 } | ||||
|         } | ||||
|     switch (d_state) | ||||
| @@ -1606,6 +1634,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) | ||||
|                 d_state = 2; | ||||
|                 d_sample_counter += samples_offset;  // count for the processed samples | ||||
|                 d_cn0_smoother.reset(); | ||||
|                 d_carrier_lock_test_smoother.reset(); | ||||
|  | ||||
|                 DLOG(INFO) << "Number of samples between Acquisition and Tracking = " << acq_trk_diff_samples << " ( " << acq_trk_diff_seconds << " s)"; | ||||
|                 DLOG(INFO) << "PULL-IN Doppler [Hz] = " << d_carrier_doppler_hz | ||||
| @@ -1642,51 +1671,59 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) | ||||
|  | ||||
|                         // enable write dump file this cycle (valid DLL/PLL cycle) | ||||
|                         log_data(false); | ||||
|                         if (d_secondary) | ||||
|  | ||||
|                         if (!d_pull_in_transitory) | ||||
|                             { | ||||
|                                 // ####### SECONDARY CODE LOCK ##### | ||||
|                                 d_Prompt_circular_buffer.push_back(*d_Prompt); | ||||
|                                 if (d_Prompt_circular_buffer.size() == d_secondary_code_length) | ||||
|                                 if (d_secondary) | ||||
|                                     { | ||||
|                                         next_state = acquire_secondary(); | ||||
|                                         if (next_state) | ||||
|                                         // ####### SECONDARY CODE LOCK ##### | ||||
|                                         d_Prompt_circular_buffer.push_back(*d_Prompt); | ||||
|                                         if (d_Prompt_circular_buffer.size() == d_secondary_code_length) | ||||
|                                             { | ||||
|                                                 LOG(INFO) << systemName << " " << signal_pretty_name << " secondary code locked in channel " << d_channel | ||||
|                                                           << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; | ||||
|                                                 std::cout << systemName << " " << signal_pretty_name << " secondary code locked in channel " << d_channel | ||||
|                                                           << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; | ||||
|                                             } | ||||
|                                     } | ||||
|                             } | ||||
|                         else if (d_symbols_per_bit > 1)  //Signal does not have secondary code. Search a bit transition by sign change | ||||
|                             { | ||||
|                                 float current_tracking_time_s = static_cast<float>(d_sample_counter - d_acq_sample_stamp) / trk_parameters.fs_in; | ||||
|                                 if (current_tracking_time_s > 10) | ||||
|                                     { | ||||
|                                         d_symbol_history.push_back(d_Prompt->real()); | ||||
|                                         //******* preamble correlation ******** | ||||
|                                         int32_t corr_value = 0; | ||||
|                                         if ((static_cast<int32_t>(d_symbol_history.size()) == d_preamble_length_symbols))  // and (d_make_correlation or !d_flag_frame_sync)) | ||||
|                                             { | ||||
|                                                 int i = 0; | ||||
|                                                 for (const auto &iter : d_symbol_history) | ||||
|                                                 next_state = acquire_secondary(); | ||||
|                                                 if (next_state) | ||||
|                                                     { | ||||
|                                                         if (iter < 0.0)  // symbols clipping | ||||
|                                                             { | ||||
|                                                                 corr_value -= d_preambles_symbols[i]; | ||||
|                                                             } | ||||
|                                                         else | ||||
|                                                             { | ||||
|                                                                 corr_value += d_preambles_symbols[i]; | ||||
|                                                             } | ||||
|                                                         i++; | ||||
|                                                         LOG(INFO) << systemName << " " << signal_pretty_name << " secondary code locked in channel " << d_channel | ||||
|                                                                   << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; | ||||
|                                                         std::cout << systemName << " " << signal_pretty_name << " secondary code locked in channel " << d_channel | ||||
|                                                                   << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; | ||||
|                                                     } | ||||
|                                             } | ||||
|                                         if (corr_value == d_preamble_length_symbols) | ||||
|                                     } | ||||
|                                 else if (d_symbols_per_bit > 1)  //Signal does not have secondary code. Search a bit transition by sign change | ||||
|                                     { | ||||
|                                         float current_tracking_time_s = static_cast<float>(d_sample_counter - d_acq_sample_stamp) / trk_parameters.fs_in; | ||||
|                                         if (current_tracking_time_s > 10) | ||||
|                                             { | ||||
|                                                 LOG(INFO) << systemName << " " << signal_pretty_name << " tracking preamble detected in channel " << d_channel | ||||
|                                                           << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; | ||||
|                                                 next_state = true; | ||||
|                                                 d_symbol_history.push_back(d_Prompt->real()); | ||||
|                                                 //******* preamble correlation ******** | ||||
|                                                 int32_t corr_value = 0; | ||||
|                                                 if ((static_cast<int32_t>(d_symbol_history.size()) == d_preamble_length_symbols))  // and (d_make_correlation or !d_flag_frame_sync)) | ||||
|                                                     { | ||||
|                                                         int i = 0; | ||||
|                                                         for (const auto &iter : d_symbol_history) | ||||
|                                                             { | ||||
|                                                                 if (iter < 0.0)  // symbols clipping | ||||
|                                                                     { | ||||
|                                                                         corr_value -= d_preambles_symbols[i]; | ||||
|                                                                     } | ||||
|                                                                 else | ||||
|                                                                     { | ||||
|                                                                         corr_value += d_preambles_symbols[i]; | ||||
|                                                                     } | ||||
|                                                                 i++; | ||||
|                                                             } | ||||
|                                                     } | ||||
|                                                 if (corr_value == d_preamble_length_symbols) | ||||
|                                                     { | ||||
|                                                         LOG(INFO) << systemName << " " << signal_pretty_name << " tracking preamble detected in channel " << d_channel | ||||
|                                                                   << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; | ||||
|                                                         next_state = true; | ||||
|                                                     } | ||||
|                                                 else | ||||
|                                                     { | ||||
|                                                         next_state = false; | ||||
|                                                     } | ||||
|                                             } | ||||
|                                         else | ||||
|                                             { | ||||
| @@ -1695,14 +1732,13 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) | ||||
|                                     } | ||||
|                                 else | ||||
|                                     { | ||||
|                                         next_state = false; | ||||
|                                         next_state = true; | ||||
|                                     } | ||||
|                             } | ||||
|                         else | ||||
|                             { | ||||
|                                 next_state = true; | ||||
|                                 next_state = false;  //keep in state 2 during pull-in transitory | ||||
|                             } | ||||
|  | ||||
|                         // ########### Output the tracking results to Telemetry block ########## | ||||
|                         if (interchange_iq) | ||||
|                             { | ||||
| @@ -1837,7 +1873,6 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) | ||||
|                         d_extend_correlation_symbols_count = 0; | ||||
|                         d_state = 4; | ||||
|                     } | ||||
|                 log_data(true); | ||||
|                 break; | ||||
|             } | ||||
|         case 4:  // narrow tracking | ||||
|   | ||||
| @@ -193,13 +193,14 @@ private: | ||||
|     // CN0 estimation and lock detector | ||||
|     int32_t d_cn0_estimation_counter; | ||||
|     int32_t d_carrier_lock_fail_counter; | ||||
|     int32_t d_code_lock_fail_counter; | ||||
|     double d_carrier_lock_test; | ||||
|     double d_CN0_SNV_dB_Hz; | ||||
|     double d_carrier_lock_threshold; | ||||
|     boost::circular_buffer<gr_complex> d_Prompt_circular_buffer; | ||||
|     gr_complex *d_Prompt_buffer; | ||||
|     Exponential_Smoother d_cn0_smoother; | ||||
|  | ||||
|     Exponential_Smoother d_carrier_lock_test_smoother; | ||||
|     // file dump | ||||
|     std::ofstream d_dump_file; | ||||
|     std::string d_dump_filename; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Javier Arribas
					Javier Arribas