mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 15:23:04 +00:00 
			
		
		
		
	Merge branch next_gps_20ms_corr with next. Removing obsolete code and code cleaning
This commit is contained in:
		| @@ -60,7 +60,9 @@ GpsL1CaDllPllCAidTracking::GpsL1CaDllPllCAidTracking( | ||||
|     std::string dump_filename; | ||||
|     std::string default_item_type = "gr_complex"; | ||||
|     float pll_bw_hz; | ||||
|     float pll_bw_narrow_hz; | ||||
|     float dll_bw_hz; | ||||
|     float dll_bw_narrow_hz; | ||||
|     float early_late_space_chips; | ||||
|     item_type_ = configuration->property(role + ".item_type", default_item_type); | ||||
|     //vector_length = configuration->property(role + ".vector_length", 2048); | ||||
| @@ -69,6 +71,11 @@ GpsL1CaDllPllCAidTracking::GpsL1CaDllPllCAidTracking( | ||||
|     dump = configuration->property(role + ".dump", false); | ||||
|     pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); | ||||
|     dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); | ||||
|     pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 20.0); | ||||
|     dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 2.0); | ||||
|     int extend_correlation_ms; | ||||
|     extend_correlation_ms = configuration->property(role + ".extend_correlation_ms", 1); | ||||
|  | ||||
|     early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); | ||||
|     std::string default_dump_filename = "./track_ch"; | ||||
|     dump_filename = configuration->property(role + ".dump_filename", | ||||
| @@ -88,6 +95,9 @@ GpsL1CaDllPllCAidTracking::GpsL1CaDllPllCAidTracking( | ||||
|                     dump_filename, | ||||
|                     pll_bw_hz, | ||||
|                     dll_bw_hz, | ||||
|                     pll_bw_narrow_hz, | ||||
|                     dll_bw_narrow_hz, | ||||
|                     extend_correlation_ms, | ||||
|                     early_late_space_chips); | ||||
|             DLOG(INFO) << "tracking(" << tracking_cc->unique_id() << ")"; | ||||
|     }else if(item_type_.compare("cshort") == 0) | ||||
| @@ -102,6 +112,8 @@ GpsL1CaDllPllCAidTracking::GpsL1CaDllPllCAidTracking( | ||||
|                 dump_filename, | ||||
|                 pll_bw_hz, | ||||
|                 dll_bw_hz, | ||||
|                 pll_bw_narrow_hz, | ||||
|                 dll_bw_narrow_hz, | ||||
|                 early_late_space_chips); | ||||
|         DLOG(INFO) << "tracking(" << tracking_sc->unique_id() << ")"; | ||||
|     }else | ||||
|   | ||||
| @@ -105,6 +105,8 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc( | ||||
|         gr::block("galileo_e1_dll_pll_veml_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_relative_rate(1.0/vector_length); | ||||
|     // initialize internal vars | ||||
|     d_queue = queue; | ||||
|   | ||||
| @@ -108,6 +108,9 @@ Galileo_E1_Tcp_Connector_Tracking_cc::Galileo_E1_Tcp_Connector_Tracking_cc( | ||||
|         gr::block("Galileo_E1_Tcp_Connector_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_relative_rate(1.0/vector_length); | ||||
|     // initialize internal vars | ||||
|     d_queue = queue; | ||||
|   | ||||
| @@ -108,6 +108,9 @@ Galileo_E5a_Dll_Pll_Tracking_cc::Galileo_E5a_Dll_Pll_Tracking_cc( | ||||
|         gr::block("Galileo_E5a_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 | ||||
| 	this->message_port_register_in(pmt::mp("preamble_timestamp_s")); | ||||
|  | ||||
|     this->set_relative_rate(1.0/vector_length); | ||||
|     // initialize internal vars | ||||
|     d_queue = queue; | ||||
|   | ||||
| @@ -105,6 +105,8 @@ Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc( | ||||
|         gr::block("Gps_L1_Ca_Dll_Fll_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 | ||||
| 	this->message_port_register_in(pmt::mp("preamble_timestamp_s")); | ||||
|     // initialize internal vars | ||||
|     d_queue = queue; | ||||
|     d_dump = dump; | ||||
| @@ -290,16 +292,6 @@ void Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::update_local_code() | ||||
|     memcpy(d_prompt_code,&d_early_code[early_late_spc_samples],d_current_prn_length_samples* sizeof(gr_complex)); | ||||
|     memcpy(d_late_code,&d_early_code[early_late_spc_samples*2],d_current_prn_length_samples* sizeof(gr_complex)); | ||||
|  | ||||
|     //    for (int i=0; i<d_current_prn_length_samples; i++) | ||||
|     //        { | ||||
|     //            associated_chip_index = 1 + round(fmod(tcode_chips - d_early_late_spc_chips, code_length_chips)); | ||||
|     //            d_early_code[i] = d_ca_code[associated_chip_index]; | ||||
|     //            associated_chip_index = 1 + round(fmod(tcode_chips, code_length_chips)); | ||||
|     //            d_prompt_code[i] = d_ca_code[associated_chip_index]; | ||||
|     //            associated_chip_index = 1 + round(fmod(tcode_chips + d_early_late_spc_chips, code_length_chips)); | ||||
|     //            d_late_code[i] = d_ca_code[associated_chip_index]; | ||||
|     //            tcode_chips = tcode_chips + code_phase_step_chips; | ||||
|     //        } | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -555,6 +547,8 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto | ||||
|             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_tracking = true; | ||||
|             current_synchro_data.Flag_valid_symbol_output = true; | ||||
|             current_synchro_data.correlation_length_ms=1; | ||||
|              current_synchro_data.Flag_valid_pseudorange = false; | ||||
|             *out[0] = current_synchro_data; | ||||
|         } | ||||
| @@ -583,6 +577,7 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto | ||||
|  | ||||
|             Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0]; //block output streams pointer | ||||
|             d_acquisition_gnss_synchro->Flag_valid_pseudorange = false; | ||||
|             d_acquisition_gnss_synchro->Flag_valid_symbol_output = false; | ||||
|             *out[0] = *d_acquisition_gnss_synchro; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -34,7 +34,9 @@ | ||||
| #include <memory> | ||||
| #include <sstream> | ||||
| #include <boost/lexical_cast.hpp> | ||||
| #include <boost/bind.hpp> | ||||
| #include <gnuradio/io_signature.h> | ||||
| #include <pmt/pmt.h> | ||||
| #include <volk/volk.h> | ||||
| #include <glog/logging.h> | ||||
| #include "gps_sdr_signal_processing.h" | ||||
| @@ -65,10 +67,13 @@ gps_l1_ca_dll_pll_c_aid_make_tracking_cc( | ||||
|         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 gps_l1_ca_dll_pll_c_aid_tracking_cc_sptr(new gps_l1_ca_dll_pll_c_aid_tracking_cc(if_freq, | ||||
|             fs_in, vector_length, queue, dump, dump_filename, pll_bw_hz, dll_bw_hz, early_late_space_chips)); | ||||
|             fs_in, vector_length, queue, dump, dump_filename, pll_bw_hz, dll_bw_hz,pll_bw_narrow_hz, dll_bw_narrow_hz, extend_correlation_ms, early_late_space_chips)); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -82,6 +87,17 @@ void gps_l1_ca_dll_pll_c_aid_tracking_cc::forecast (int noutput_items, | ||||
|         } | ||||
| } | ||||
|  | ||||
| void gps_l1_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)<< std::endl; | ||||
|   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; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc( | ||||
| @@ -93,10 +109,20 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc( | ||||
|         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("gps_l1_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(&gps_l1_ca_dll_pll_c_aid_tracking_cc::msg_handler_preamble_index, this, _1)); | ||||
|  | ||||
|  | ||||
|     // initialize internal vars | ||||
|     d_queue = queue; | ||||
|     d_dump = dump; | ||||
| @@ -107,8 +133,13 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc( | ||||
|     d_correlation_length_samples = static_cast<int>(d_vector_length); | ||||
|  | ||||
|     // Initialize tracking  ========================================== | ||||
|     d_code_loop_filter.set_DLL_BW(dll_bw_hz); | ||||
|     d_carrier_loop_filter.set_params(10.0, pll_bw_hz,2); | ||||
|     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) | ||||
| @@ -141,7 +172,8 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc( | ||||
|     d_rem_carrier_phase_rad = 0.0; | ||||
|  | ||||
|     // sample synchronization | ||||
|     d_sample_counter = 0; | ||||
|     d_sample_counter = 0; //(from trk to tlm) | ||||
|  | ||||
|     //d_sample_counter_seconds = 0; | ||||
|     d_acq_sample_stamp = 0; | ||||
|  | ||||
| @@ -168,6 +200,7 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc( | ||||
|     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; | ||||
|  | ||||
| @@ -175,6 +208,8 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc( | ||||
|     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; | ||||
|     //set_min_output_buffer((long int)300); | ||||
| } | ||||
|  | ||||
| @@ -258,7 +293,8 @@ void gps_l1_ca_dll_pll_c_aid_tracking_cc::start_tracking() | ||||
|     // 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; | ||||
| @@ -290,13 +326,10 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items, gr_vec | ||||
|     Gnss_Synchro current_synchro_data = Gnss_Synchro(); | ||||
|  | ||||
|     // process vars | ||||
|     double code_error_chips_Ti = 0.0; | ||||
|     double code_error_filt_chips = 0.0; | ||||
|     double code_error_filt_secs_Ti = 0.0; | ||||
|     double CURRENT_INTEGRATION_TIME_S; | ||||
|     double CORRECTED_INTEGRATION_TIME_S; | ||||
|     double CURRENT_INTEGRATION_TIME_S = 0.0; | ||||
|     double CORRECTED_INTEGRATION_TIME_S = 0.0; | ||||
|     double dll_code_error_secs_Ti = 0.0; | ||||
|     double carr_phase_error_secs_Ti = 0.0; | ||||
|     double old_d_rem_code_phase_samples; | ||||
|     if (d_enable_tracking == true) | ||||
|         { | ||||
| @@ -313,6 +346,8 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items, gr_vec | ||||
|                     d_pull_in = false; | ||||
|                     // Fill the acquisition data | ||||
|                     current_synchro_data = *d_acquisition_gnss_synchro; | ||||
|     	            current_synchro_data.correlation_length_ms=1; | ||||
|     	            current_synchro_data.Flag_valid_symbol_output = false; | ||||
|                     *out[0] = current_synchro_data; | ||||
|                     consume_each(samples_offset); //shift input to perform alignment with local replica | ||||
|                     return 1; | ||||
| @@ -326,115 +361,228 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items, gr_vec | ||||
|             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); | ||||
|  | ||||
|             // UPDATE INTEGRATION TIME | ||||
|             CURRENT_INTEGRATION_TIME_S = static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in); | ||||
|             // ####### coherent intergration 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 | ||||
|  | ||||
|             // ################## PLL ########################################################## | ||||
|             // Update PLL discriminator [rads/Ti -> Secs/Ti] | ||||
|             carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / GPS_TWO_PI; //prompt output | ||||
|             // Carrier discriminator filter | ||||
|             // NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan | ||||
|             //d_carrier_doppler_hz = d_acq_carrier_doppler_hz + carr_phase_error_filt_secs_ti/INTEGRATION_TIME; | ||||
|             // Input [s/Ti] -> output [Hz] | ||||
|             d_carrier_doppler_hz = d_carrier_loop_filter.get_carrier_error(0.0, 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) / GPS_L1_FREQ_HZ; | ||||
|             // code Doppler frequency update | ||||
|             d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ); | ||||
|             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(); | ||||
|             } | ||||
|  | ||||
|             // ################## DLL ########################################################## | ||||
|             // DLL discriminator | ||||
|             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 | ||||
|             code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips_Ti); //input [chips/Ti] -> output [chips/second] | ||||
|             code_error_filt_secs_Ti = code_error_filt_chips*CURRENT_INTEGRATION_TIME_S/d_code_freq_chips; // [s/Ti] | ||||
|             // DLL code error estimation [s/Ti] | ||||
|             // 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; | ||||
|             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); | ||||
| 		            } | ||||
|  | ||||
|             // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### | ||||
|             // 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 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_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; | ||||
|             T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in); | ||||
|             K_blk_samples = T_prn_samples + d_rem_code_phase_samples - dll_code_error_secs_Ti * static_cast<double>(d_fs_in); | ||||
| 		            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 extended correlator for CH "<< d_channel <<" : Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) | ||||
| 		            				<<" dll_narrow_bw="<<d_dll_bw_narrow_hz<<" pll_narrow_bw="<<d_pll_bw_narrow_hz<<std::endl; | ||||
|  | ||||
|             d_correlation_length_samples = round(K_blk_samples); //round to a discrete samples | ||||
|             old_d_rem_code_phase_samples=d_rem_code_phase_samples; | ||||
|             d_rem_code_phase_samples = K_blk_samples - static_cast<double>(d_correlation_length_samples); //rounding error < 1 sample | ||||
| 		            } | ||||
| 					// UPDATE INTEGRATION TIME | ||||
| 	            	CURRENT_INTEGRATION_TIME_S = static_cast<double>(d_extend_correlation_ms)*GPS_L1_CA_CODE_PERIOD; | ||||
| 					enable_dll_pll=true; | ||||
|  | ||||
|             // UPDATE REMNANT 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 + GPS_TWO_PI * d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S, GPS_TWO_PI); | ||||
|             // UPDATE CARRIER PHASE ACCUULATOR | ||||
|             //carrier phase accumulator prior to update the PLL estimators (accumulated carrier in this loop depends on the old estimations!) | ||||
|             d_acc_carrier_phase_cycles -= d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S; | ||||
| 				}else{ | ||||
| 					if(d_preamble_synchronized==true) | ||||
| 					{ | ||||
| 						// continue extended coherent correlation | ||||
| 						//remnant carrier phase [rads] | ||||
| 						d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + d_carrier_phase_step_rad * static_cast<double>(d_correlation_length_samples), GPS_TWO_PI); | ||||
|  | ||||
|             //################### 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); | ||||
| 						// Compute the next buffer length based on the period of the PRN sequence and the code phase error estimation | ||||
| 						double T_chip_seconds = 1 / d_code_freq_chips; | ||||
| 						double T_prn_seconds = T_chip_seconds * GPS_L1_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; | ||||
|  | ||||
|             //################### 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)); | ||||
| 						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); | ||||
| 						d_correlation_length_samples = K_prn_samples + d_rem_code_phase_integer_samples; //round to a discrete 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)); | ||||
|  | ||||
|             // ####### 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, GPS_L1_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 < MINIMUM_VALID_CN0) | ||||
|                         { | ||||
|                             d_carrier_lock_fail_counter++; | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; | ||||
|                         } | ||||
|                     if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER) | ||||
|                         { | ||||
|                             std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; | ||||
|                             LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; | ||||
|                             std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory()); | ||||
|                             if (d_queue != gr::msg_queue::sptr()) | ||||
|                                 { | ||||
|                                     d_queue->handle(cmf->GetQueueMessage(d_channel, 2)); | ||||
|                                 } | ||||
|                             d_carrier_lock_fail_counter = 0; | ||||
|                             d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine | ||||
|                         } | ||||
|                 } | ||||
| 						// 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_doppler_hz * CORRECTED_INTEGRATION_TIME_S; | ||||
|  | ||||
|             // ########### 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()); | ||||
|             // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!) | ||||
|             current_synchro_data.Tracking_timestamp_secs = (static_cast<double>(d_sample_counter) + old_d_rem_code_phase_samples) / static_cast<double>(d_fs_in); | ||||
|             // This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, thus, Code_phase_secs=0 | ||||
|             current_synchro_data.Code_phase_secs = 0; | ||||
|             current_synchro_data.Carrier_phase_rads = GPS_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_pseudorange = false; | ||||
|             *out[0] = current_synchro_data; | ||||
| 						// 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(d_correlator_outs[1]) / GPS_TWO_PI; //prompt output | ||||
| 				// Carrier discriminator filter | ||||
| 				// NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan | ||||
| 				//d_carrier_doppler_hz = d_acq_carrier_doppler_hz + carr_phase_error_filt_secs_ti/INTEGRATION_TIME; | ||||
| 				// 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) / GPS_L1_FREQ_HZ; | ||||
| 				// code Doppler frequency update | ||||
| 				d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ); | ||||
|  | ||||
| 				// ################## 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] | ||||
| 				// DLL code error estimation [s/Ti] | ||||
| 				// PLL to DLL assistance is disable due to the use of a fractional resampler that allows the correction of the code Doppler effect. | ||||
| 				dll_code_error_secs_Ti = - code_error_filt_secs_Ti;// + d_pll_to_dll_assist_secs_Ti; | ||||
|  | ||||
| 				// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### | ||||
|  | ||||
| 				// keep alignment parameters for the next input buffer | ||||
| 				double T_chip_seconds; | ||||
| 				double T_prn_seconds; | ||||
| 				double T_prn_samples; | ||||
| 				double K_prn_samples; | ||||
| 				// 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_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; | ||||
| 				T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in); | ||||
| 				K_prn_samples = round(T_prn_samples); | ||||
| 				double K_T_prn_error_samples=K_prn_samples-T_prn_samples; | ||||
|  | ||||
| 				old_d_rem_code_phase_samples=d_rem_code_phase_samples; | ||||
| 				d_rem_code_phase_samples= d_rem_code_phase_samples - K_T_prn_error_samples -dll_code_error_secs_Ti * static_cast<double>(d_fs_in); | ||||
| 				d_rem_code_phase_integer_samples=round(d_rem_code_phase_samples); | ||||
| 				d_correlation_length_samples = K_prn_samples + d_rem_code_phase_integer_samples; //round to a discrete samples | ||||
| 				d_rem_code_phase_samples=d_rem_code_phase_samples-d_rem_code_phase_integer_samples; | ||||
|  | ||||
| 				// 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 + GPS_TWO_PI * d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S, GPS_TWO_PI); | ||||
| 				// UPDATE CARRIER PHASE ACCUULATOR | ||||
| 				//carrier phase accumulator prior to update the PLL estimators (accumulated carrier in this loop depends on the old estimations!) | ||||
| 				d_acc_carrier_phase_cycles -= d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S; | ||||
|  | ||||
| 				//################### 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); | ||||
|  | ||||
| 				//################### 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, GPS_L1_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 < MINIMUM_VALID_CN0) | ||||
| 							{ | ||||
| 								d_carrier_lock_fail_counter++; | ||||
| 							} | ||||
| 						else | ||||
| 							{ | ||||
| 								if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; | ||||
| 							} | ||||
| 						if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER) | ||||
| 							{ | ||||
| 								std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; | ||||
| 								LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; | ||||
| 								std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory()); | ||||
| 								if (d_queue != gr::msg_queue::sptr()) | ||||
| 									{ | ||||
| 										d_queue->handle(cmf->GetQueueMessage(d_channel, 2)); | ||||
| 									} | ||||
| 								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()); | ||||
| 	            // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!) | ||||
| 	            current_synchro_data.Tracking_timestamp_secs = (static_cast<double>(d_sample_counter) + old_d_rem_code_phase_samples) / static_cast<double>(d_fs_in); | ||||
| 	            // This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, thus, Code_phase_secs=0 | ||||
| 	            current_synchro_data.Code_phase_secs = 0; | ||||
| 	            current_synchro_data.Carrier_phase_rads = GPS_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_pseudorange = false; | ||||
| 	            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; | ||||
| 	            } | ||||
| 	            *out[0] = current_synchro_data; | ||||
| 			}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()); | ||||
| 	            // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!) | ||||
| 	            current_synchro_data.Tracking_timestamp_secs = (static_cast<double>(d_sample_counter) + d_rem_code_phase_samples) / static_cast<double>(d_fs_in); | ||||
| 	            // This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, thus, Code_phase_secs=0 | ||||
| 	            current_synchro_data.Code_phase_secs = 0; | ||||
| 	            current_synchro_data.Carrier_phase_rads = GPS_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; | ||||
| 	            current_synchro_data.Flag_valid_pseudorange = false; | ||||
| 	            current_synchro_data.Flag_valid_symbol_output = false; | ||||
| 	            current_synchro_data.correlation_length_ms=1; | ||||
| 	            *out[0] = current_synchro_data; | ||||
| 			} | ||||
|  | ||||
|             // ########## DEBUG OUTPUT | ||||
|             /*! | ||||
| @@ -447,7 +595,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items, gr_vec | ||||
|                         { | ||||
|                             d_last_seg = floor(d_sample_counter / d_fs_in); | ||||
|                             std::cout << "Current input signal time = " << d_last_seg << " [s]" << std::endl; | ||||
|                             DLOG(INFO) << "GPS L1 C/A Tracking CH " << d_channel <<  ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) | ||||
|                             DLOG(INFO)  << "GPS L1 C/A Tracking CH " << d_channel <<  ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) | ||||
|                                               << ", CN0 = " << d_CN0_SNV_dB_Hz << " [dB-Hz]" << std::endl; | ||||
|                             //if (d_last_seg==5) d_carrier_lock_fail_counter=500; //DEBUG: force unlock! | ||||
|                         } | ||||
| @@ -457,7 +605,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items, gr_vec | ||||
|                     if (floor(d_sample_counter / d_fs_in) != d_last_seg) | ||||
|                         { | ||||
|                             d_last_seg = floor(d_sample_counter / d_fs_in); | ||||
|                             DLOG(INFO) << "Tracking CH " << d_channel <<  ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) | ||||
|                             DLOG(INFO)  << "Tracking CH " << d_channel <<  ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) | ||||
|                                                << ", CN0 = " << d_CN0_SNV_dB_Hz << " [dB-Hz]"; | ||||
|                         } | ||||
|                 } | ||||
| @@ -488,6 +636,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items, gr_vec | ||||
|  | ||||
|             current_synchro_data.System = {'G'}; | ||||
|             current_synchro_data.Flag_valid_pseudorange = false; | ||||
|             current_synchro_data.correlation_length_ms=1; | ||||
|             *out[0] = current_synchro_data; | ||||
|         } | ||||
|  | ||||
| @@ -523,19 +672,19 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items, gr_vec | ||||
|                     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_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)); | ||||
|                     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)); | ||||
|  | ||||
|                     // 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)); | ||||
|  | ||||
|                     // AUX vars (for debug purposes) | ||||
|                     tmp_double = d_rem_code_phase_samples; | ||||
|                     tmp_double = d_code_error_chips_Ti*CURRENT_INTEGRATION_TIME_S; | ||||
|                     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)); | ||||
|   | ||||
| @@ -39,13 +39,16 @@ | ||||
|  | ||||
| #include <fstream> | ||||
| #include <map> | ||||
| #include <deque> | ||||
| #include <string> | ||||
| #include <gnuradio/block.h> | ||||
| #include <gnuradio/msg_queue.h> | ||||
| #include <pmt/pmt.h> | ||||
| #include "concurrent_queue.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" | ||||
|  | ||||
| class gps_l1_ca_dll_pll_c_aid_tracking_cc; | ||||
| @@ -62,6 +65,9 @@ gps_l1_ca_dll_pll_c_aid_make_tracking_cc(long if_freq, | ||||
|                                    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); | ||||
|  | ||||
|  | ||||
| @@ -94,6 +100,9 @@ private: | ||||
|             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); | ||||
|  | ||||
|     gps_l1_ca_dll_pll_c_aid_tracking_cc(long if_freq, | ||||
| @@ -104,6 +113,9 @@ private: | ||||
|             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 | ||||
| @@ -130,8 +142,10 @@ private: | ||||
|     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; | ||||
|  | ||||
| @@ -140,6 +154,10 @@ private: | ||||
|     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; | ||||
| @@ -147,6 +165,21 @@ private: | ||||
|     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; | ||||
|     int d_correlation_symbol_counter; | ||||
|     void msg_handler_preamble_index(pmt::pmt_t msg); | ||||
|  | ||||
|     //Integration period in samples | ||||
|     int d_correlation_length_samples; | ||||
|   | ||||
| @@ -66,10 +66,12 @@ gps_l1_ca_dll_pll_c_aid_make_tracking_sc( | ||||
|         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) | ||||
| { | ||||
|     return gps_l1_ca_dll_pll_c_aid_tracking_sc_sptr(new gps_l1_ca_dll_pll_c_aid_tracking_sc(if_freq, | ||||
|             fs_in, vector_length, queue, dump, dump_filename, pll_bw_hz, dll_bw_hz, early_late_space_chips)); | ||||
|             fs_in, vector_length, queue, dump, dump_filename, pll_bw_hz, dll_bw_hz, pll_bw_narrow_hz, dll_bw_narrow_hz, early_late_space_chips)); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -94,10 +96,14 @@ gps_l1_ca_dll_pll_c_aid_tracking_sc::gps_l1_ca_dll_pll_c_aid_tracking_sc( | ||||
|         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) : | ||||
|         gr::block("gps_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")); | ||||
|     // initialize internal vars | ||||
|     d_queue = queue; | ||||
|     d_dump = dump; | ||||
| @@ -108,6 +114,10 @@ gps_l1_ca_dll_pll_c_aid_tracking_sc::gps_l1_ca_dll_pll_c_aid_tracking_sc( | ||||
|     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(dll_bw_hz); | ||||
|     d_carrier_loop_filter.set_params(10.0, pll_bw_hz,2); | ||||
|  | ||||
| @@ -330,17 +340,9 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work (int noutput_items, gr_vec | ||||
|             // ################# CARRIER WIPEOFF AND CORRELATORS ############################## | ||||
|             // perform carrier wipe-off and compute Early, Prompt and Late correlation | ||||
|  | ||||
|             //volk_gnsssdr_32fc_convert_16ic(d_in_16sc,in,d_correlation_length_samples); | ||||
|             //std::cout << std::fixed << std::setw( 11 ) << std::setprecision( 6 ); | ||||
|             //std::cout<<"in="<<in[0]<<std::endl; | ||||
|  | ||||
|             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); | ||||
|  | ||||
|             //std::cout<<"E 16sc="<<d_correlator_outs_16sc[0]<<std::endl; | ||||
|             //std::cout<<"P 16sc="<<d_correlator_outs_16sc[1]<<std::endl; | ||||
|             //std::cout<<"L 16sc="<<d_correlator_outs_16sc[2]<<std::endl; | ||||
|  | ||||
|             //std::cout<<std::endl; | ||||
|             // UPDATE INTEGRATION TIME | ||||
|             CURRENT_INTEGRATION_TIME_S = static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in); | ||||
| @@ -450,6 +452,8 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work (int noutput_items, gr_vec | ||||
|             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_pseudorange = false; | ||||
|             current_synchro_data.Flag_valid_symbol_output = true; | ||||
|             current_synchro_data.correlation_length_ms=1; | ||||
|             *out[0] = current_synchro_data; | ||||
|  | ||||
|             // ########## DEBUG OUTPUT | ||||
| @@ -504,6 +508,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work (int noutput_items, gr_vec | ||||
|  | ||||
|             current_synchro_data.System = {'G'}; | ||||
|             current_synchro_data.Flag_valid_pseudorange = false; | ||||
|             current_synchro_data.Flag_valid_symbol_output = false; | ||||
|             *out[0] = current_synchro_data; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -67,6 +67,8 @@ gps_l1_ca_dll_pll_c_aid_make_tracking_sc(long if_freq, | ||||
|                                    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); | ||||
|  | ||||
|  | ||||
| @@ -99,6 +101,8 @@ private: | ||||
|             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); | ||||
|  | ||||
|     gps_l1_ca_dll_pll_c_aid_tracking_sc(long if_freq, | ||||
| @@ -109,6 +113,8 @@ private: | ||||
|             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); | ||||
|  | ||||
|     // tracking configuration vars | ||||
| @@ -148,6 +154,10 @@ private: | ||||
|     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; | ||||
|   | ||||
| @@ -104,6 +104,8 @@ Gps_L1_Ca_Dll_Pll_Tracking_cc::Gps_L1_Ca_Dll_Pll_Tracking_cc( | ||||
|         gr::block("Gps_L1_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 | ||||
| 	this->message_port_register_in(pmt::mp("preamble_timestamp_s")); | ||||
|     // initialize internal vars | ||||
|     d_queue = queue; | ||||
|     d_dump = dump; | ||||
| @@ -309,8 +311,6 @@ void Gps_L1_Ca_Dll_Pll_Tracking_cc::update_local_carrier() | ||||
|             d_carr_sign[i] = std::complex<float>(cos_f, -sin_f); | ||||
|             phase_rad_i += phase_step_rad_i; | ||||
|         } | ||||
|     //d_rem_carr_phase_rad = fmod(phase_rad, GPS_TWO_PI); | ||||
|     //d_acc_carrier_phase_rad = d_acc_carrier_phase_rad + d_rem_carr_phase_rad; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -362,11 +362,8 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in | ||||
|                     acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; | ||||
|                     acq_trk_shif_correction_samples = d_current_prn_length_samples - fmod(static_cast<float>(acq_to_trk_delay_samples), static_cast<float>(d_current_prn_length_samples)); | ||||
|                     samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); | ||||
|                     // /todo: Check if the sample counter sent to the next block as a time reference should be incremented AFTER sended or BEFORE | ||||
|                     //d_sample_counter_seconds = d_sample_counter_seconds + (((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; | ||||
|                     //std::cout<<" samples_offset="<<samples_offset<<"\r\n"; | ||||
|                     // Fill the acquisition data | ||||
|                     current_synchro_data = *d_acquisition_gnss_synchro; | ||||
|                     *out[0] = current_synchro_data; | ||||
| @@ -493,11 +490,6 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in | ||||
|             current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).real()); | ||||
|             current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).imag()); | ||||
|  | ||||
|             // Tracking_timestamp_secs is aligned with the NEXT PRN start sample (Hybridization problem!) | ||||
|             //compute remnant code phase samples BEFORE the Tracking timestamp | ||||
|             //d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample | ||||
|             //current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + (double)d_current_prn_length_samples + (double)d_rem_code_phase_samples)/static_cast<double>(d_fs_in); | ||||
|  | ||||
|             // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!, but some glitches??) | ||||
|             current_synchro_data.Tracking_timestamp_secs = (static_cast<double>(d_sample_counter) + static_cast<double>(d_rem_code_phase_samples)) / static_cast<double>(d_fs_in); | ||||
|             //compute remnant code phase samples AFTER the Tracking timestamp | ||||
| @@ -510,6 +502,8 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in | ||||
|             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_pseudorange = false; | ||||
|             current_synchro_data.Flag_valid_symbol_output = true; | ||||
|             current_synchro_data.correlation_length_ms=1; | ||||
|             *out[0] = current_synchro_data; | ||||
|  | ||||
|             // ########## DEBUG OUTPUT | ||||
| @@ -563,6 +557,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in | ||||
|  | ||||
|             current_synchro_data.System = {'G'}; | ||||
|             current_synchro_data.Flag_valid_pseudorange = false; | ||||
|             current_synchro_data.Flag_valid_symbol_output = false; | ||||
|             *out[0] = current_synchro_data; | ||||
|         } | ||||
|  | ||||
| @@ -616,7 +611,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in | ||||
|                 tmp_double = static_cast<double>(d_sample_counter + d_current_prn_length_samples); | ||||
|                 d_dump_file.write(reinterpret_cast<char*>(&tmp_double), sizeof(double)); | ||||
|             } | ||||
|             catch (std::ifstream::failure e) | ||||
|             catch (const std::ifstream::failure &e) | ||||
|             { | ||||
|                     LOG(WARNING) << "Exception writing trk dump file " << e.what(); | ||||
|             } | ||||
| @@ -651,7 +646,7 @@ void Gps_L1_Ca_Dll_Pll_Tracking_cc::set_channel(unsigned int channel) | ||||
|                             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 (std::ifstream::failure e) | ||||
|                     catch (const std::ifstream::failure &e) | ||||
|                     { | ||||
|                             LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what() << std::endl; | ||||
|                     } | ||||
|   | ||||
| @@ -99,6 +99,8 @@ Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc( | ||||
|         gr::block("Gps_L1_Ca_Dll_Pll_Tracking_GPU_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")); | ||||
|     // initialize internal vars | ||||
|     d_queue = queue; | ||||
|     d_dump = dump; | ||||
| @@ -451,6 +453,8 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work (int noutput_items, gr_vecto | ||||
|             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_pseudorange = false; | ||||
|             current_synchro_data.Flag_valid_symbol_output = true; | ||||
|             current_synchro_data.correlation_length_ms=1; | ||||
|             *out[0] = current_synchro_data; | ||||
|  | ||||
|             // ########## DEBUG OUTPUT | ||||
| @@ -505,6 +509,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work (int noutput_items, gr_vecto | ||||
|  | ||||
|             current_synchro_data.System = {'G'}; | ||||
|             current_synchro_data.Flag_valid_pseudorange = false; | ||||
|             current_synchro_data.Flag_valid_symbol_output = false; | ||||
|             *out[0] = current_synchro_data; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -1,606 +0,0 @@ | ||||
| /*! | ||||
|  * \file gps_l1_ca_dll_pll_tracking_gpu_cc.cc | ||||
|  * \brief Implementation of a code DLL + carrier PLL tracking block, GPU ACCELERATED | ||||
|  * \author Javier Arribas, 2015. jarribas(at)cttc.es | ||||
|  * | ||||
|  * Code DLL + carrier PLL according to the algorithms described in: | ||||
|  * [1] 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 | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2015  (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 "gps_l1_ca_dll_pll_tracking_gpu_cc.h" | ||||
| #include <cmath> | ||||
| #include <iostream> | ||||
| #include <memory> | ||||
| #include <sstream> | ||||
| #include <boost/lexical_cast.hpp> | ||||
| #include <gnuradio/io_signature.h> | ||||
| #include <glog/logging.h> | ||||
| #include "gnss_synchro.h" | ||||
| #include "gps_sdr_signal_processing.h" | ||||
| #include "tracking_discriminators.h" | ||||
| #include "lock_detectors.h" | ||||
| #include "GPS_L1_CA.h" | ||||
| #include "control_message_factory.h" | ||||
| #include <volk/volk.h> //volk_alignement | ||||
| // includes | ||||
| #include <cuda_profiler_api.h> | ||||
|  | ||||
|  | ||||
| /*! | ||||
|  * \todo Include in definition header file | ||||
|  */ | ||||
| #define CN0_ESTIMATION_SAMPLES 20 | ||||
| #define MINIMUM_VALID_CN0 25 | ||||
| #define MAXIMUM_LOCK_FAIL_COUNTER 50 | ||||
| #define CARRIER_LOCK_THRESHOLD 0.85 | ||||
|  | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| gps_l1_ca_dll_pll_tracking_gpu_cc_sptr | ||||
| gps_l1_ca_dll_pll_make_tracking_gpu_cc( | ||||
|         long if_freq, | ||||
|         long fs_in, | ||||
|         unsigned int vector_length, | ||||
|         boost::shared_ptr<gr::msg_queue> queue, | ||||
|         bool dump, | ||||
|         std::string dump_filename, | ||||
|         float pll_bw_hz, | ||||
|         float dll_bw_hz, | ||||
|         float early_late_space_chips) | ||||
| { | ||||
|     return gps_l1_ca_dll_pll_tracking_gpu_cc_sptr(new Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc(if_freq, | ||||
|             fs_in, vector_length, queue, dump, dump_filename, pll_bw_hz, dll_bw_hz, early_late_space_chips)); | ||||
| } | ||||
|  | ||||
|  | ||||
| void Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::forecast (int noutput_items, | ||||
|         gr_vector_int &ninput_items_required) | ||||
| { | ||||
|     ninput_items_required[0] = static_cast<int>(d_vector_length) * 2; //set the required available samples in each call | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc( | ||||
|         long if_freq, | ||||
|         long fs_in, | ||||
|         unsigned int vector_length, | ||||
|         boost::shared_ptr<gr::msg_queue> queue, | ||||
|         bool dump, | ||||
|         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_GPU_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)), | ||||
|                 gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) | ||||
| { | ||||
|     // initialize internal vars | ||||
|     d_queue = queue; | ||||
|     d_dump = dump; | ||||
|     d_if_freq = if_freq; | ||||
|     d_fs_in = fs_in; | ||||
|     d_vector_length = vector_length; | ||||
|     d_dump_filename = dump_filename; | ||||
|  | ||||
|     // Initialize tracking  ========================================== | ||||
|     d_code_loop_filter.set_DLL_BW(dll_bw_hz); | ||||
|     d_carrier_loop_filter.set_PLL_BW(pll_bw_hz); | ||||
|  | ||||
|     //--- DLL variables -------------------------------------------------------- | ||||
|     d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips) | ||||
|  | ||||
|     // Set GPU flags | ||||
|     cudaSetDeviceFlags(cudaDeviceMapHost); | ||||
|     //allocate host memory | ||||
|     //pinned memory mode - use special function to get OS-pinned memory | ||||
|     int N_CORRELATORS = 3; | ||||
|     // Get space for a vector with the C/A code replica sampled 1x/chip | ||||
|     cudaHostAlloc((void**)&d_ca_code, (GPS_L1_CA_CODE_LENGTH_CHIPS* sizeof(gr_complex)), cudaHostAllocMapped || cudaHostAllocWriteCombined); | ||||
|     // Get space for the resampled early / prompt / late local replicas | ||||
|     cudaHostAlloc((void**)&d_local_code_shift_chips, N_CORRELATORS * sizeof(float),  cudaHostAllocMapped || cudaHostAllocWriteCombined); | ||||
|     cudaHostAlloc((void**)&in_gpu, 2 * d_vector_length * sizeof(gr_complex), cudaHostAllocMapped || cudaHostAllocWriteCombined); | ||||
|     // correlator outputs (scalar) | ||||
|     cudaHostAlloc((void**)&d_corr_outs_gpu ,sizeof(gr_complex)*N_CORRELATORS, cudaHostAllocMapped ||  cudaHostAllocWriteCombined ); | ||||
|  | ||||
|     //map to EPL pointers | ||||
|     d_Early = &d_corr_outs_gpu[0]; | ||||
|     d_Prompt =  &d_corr_outs_gpu[1]; | ||||
|     d_Late = &d_corr_outs_gpu[2]; | ||||
|  | ||||
|     //--- Perform initializations ------------------------------ | ||||
|     multicorrelator_gpu = new cuda_multicorrelator(); | ||||
|     //local code resampler on GPU | ||||
|     multicorrelator_gpu->init_cuda_integrated_resampler(2 * d_vector_length, GPS_L1_CA_CODE_LENGTH_CHIPS, 3); | ||||
|     multicorrelator_gpu->set_input_output_vectors(d_corr_outs_gpu, in_gpu); | ||||
|  | ||||
|     // define initial code frequency basis of NCO | ||||
|     d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ; | ||||
|     // define residual code phase (in chips) | ||||
|     d_rem_code_phase_samples = 0.0; | ||||
|     // define residual carrier phase | ||||
|     d_rem_carr_phase_rad = 0.0; | ||||
|  | ||||
|     // sample synchronization | ||||
|     d_sample_counter = 0; | ||||
|     //d_sample_counter_seconds = 0; | ||||
|     d_acq_sample_stamp = 0; | ||||
|  | ||||
|     d_enable_tracking = false; | ||||
|     d_pull_in = false; | ||||
|     d_last_seg = 0; | ||||
|  | ||||
|     d_current_prn_length_samples = static_cast<int>(d_vector_length); | ||||
|  | ||||
|     // CN0 estimation and lock detector buffers | ||||
|     d_cn0_estimation_counter = 0; | ||||
|     d_Prompt_buffer = new gr_complex[CN0_ESTIMATION_SAMPLES]; | ||||
|     d_carrier_lock_test = 1; | ||||
|     d_CN0_SNV_dB_Hz = 0; | ||||
|     d_carrier_lock_fail_counter = 0; | ||||
|     d_carrier_lock_threshold = CARRIER_LOCK_THRESHOLD; | ||||
|  | ||||
|     systemName["G"] = std::string("GPS"); | ||||
|     systemName["S"] = std::string("SBAS"); | ||||
|  | ||||
|  | ||||
|     set_relative_rate(1.0/((double)d_vector_length*2)); | ||||
|  | ||||
|     d_channel_internal_queue = 0; | ||||
|     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_rad = 0.0; | ||||
|     d_code_phase_samples = 0.0; | ||||
|     d_acc_code_phase_secs = 0.0; | ||||
|     //set_min_output_buffer((long int)300); | ||||
| } | ||||
|  | ||||
|  | ||||
| void Gps_L1_Ca_Dll_Pll_Tracking_GPU_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 | ||||
|     double radial_velocity = (GPS_L1_FREQ_HZ + d_acq_carrier_doppler_hz) / GPS_L1_FREQ_HZ; | ||||
|     // 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; | ||||
|     T_chip_mod_seconds = 1.0/d_code_freq_chips; | ||||
|     T_prn_mod_seconds = T_chip_mod_seconds * GPS_L1_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_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; | ||||
|  | ||||
|     // 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_complex(d_ca_code, d_acquisition_gnss_synchro->PRN, 0); | ||||
|  | ||||
|     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_gpu->set_local_code_and_taps(GPS_L1_CA_CODE_LENGTH_CHIPS, d_ca_code, d_local_code_shift_chips, 3); | ||||
|  | ||||
|     d_carrier_lock_fail_counter = 0; | ||||
|     d_rem_code_phase_samples = 0; | ||||
|     d_rem_carr_phase_rad = 0; | ||||
|     d_acc_carrier_phase_rad = 0; | ||||
|     d_acc_code_phase_secs = 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; | ||||
|  | ||||
|     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; | ||||
| } | ||||
|  | ||||
|  | ||||
| Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::~Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc() | ||||
| { | ||||
|     d_dump_file.close(); | ||||
|     cudaFreeHost(in_gpu); | ||||
|     cudaFreeHost(d_corr_outs_gpu); | ||||
|     cudaFreeHost(d_local_code_shift_chips); | ||||
|     cudaFreeHost(d_ca_code); | ||||
|     multicorrelator_gpu->free_cuda(); | ||||
|     delete(multicorrelator_gpu); | ||||
|     delete[] d_Prompt_buffer; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work (int noutput_items, gr_vector_int &ninput_items, | ||||
|         gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) | ||||
| { | ||||
|     // process vars | ||||
| 	double carr_error_hz=0.0; | ||||
| 	double carr_error_filt_hz=0.0; | ||||
| 	double code_error_chips=0.0; | ||||
| 	double code_error_filt_chips=0.0; | ||||
|  | ||||
|     // Block input data and block output stream pointers | ||||
|     const gr_complex* in = (gr_complex*) input_items[0]; | ||||
|     Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0]; | ||||
|  | ||||
|     // GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder | ||||
|     Gnss_Synchro current_synchro_data = Gnss_Synchro(); | ||||
|  | ||||
|     if (d_enable_tracking == true) | ||||
|         { | ||||
|             // 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_current_prn_length_samples - fmod(static_cast<float>(acq_to_trk_delay_samples), static_cast<float>(d_current_prn_length_samples)); | ||||
| 					samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); | ||||
| 					// /todo: Check if the sample counter sent to the next block as a time reference should be incremented AFTER sended or BEFORE | ||||
| 					//d_sample_counter_seconds = d_sample_counter_seconds + (((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; | ||||
| 					//std::cout<<" samples_offset="<<samples_offset<<"\r\n"; | ||||
| 					// Fill the acquisition data | ||||
| 					current_synchro_data = *d_acquisition_gnss_synchro; | ||||
| 					*out[0] = current_synchro_data; | ||||
| 					consume_each(samples_offset); //shift input to perform alignment with local replica | ||||
| 					return 1; | ||||
|                 } | ||||
|  | ||||
|             // Fill the acquisition data | ||||
|             current_synchro_data = *d_acquisition_gnss_synchro; | ||||
|  | ||||
|             // UPDATE NCO COMMAND | ||||
|             double phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in); | ||||
|  | ||||
|         	//code resampler on GPU (new) | ||||
|             double code_phase_step_chips = d_code_freq_chips / static_cast<double>(d_fs_in); | ||||
|             double rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / d_fs_in); | ||||
|  | ||||
|             std::cout<<"rem_code_phase_chips="<<rem_code_phase_chips<<" d_current_prn_length_samples="<<d_current_prn_length_samples<<std::endl; | ||||
|             memcpy(in_gpu, in, sizeof(gr_complex) * d_current_prn_length_samples); | ||||
|             cudaProfilerStart(); | ||||
|             multicorrelator_gpu->Carrier_wipeoff_multicorrelator_resampler_cuda( static_cast<float>(d_rem_carr_phase_rad), | ||||
|             		static_cast<float>(phase_step_rad), | ||||
|             		static_cast<float>(code_phase_step_chips), | ||||
|             		static_cast<float>(rem_code_phase_chips), | ||||
|             		d_current_prn_length_samples, 3); | ||||
|             cudaProfilerStop(); | ||||
|  | ||||
|             // ################## PLL ########################################################## | ||||
|             // PLL discriminator | ||||
|             carr_error_hz = pll_cloop_two_quadrant_atan(*d_Prompt) / GPS_TWO_PI; | ||||
|             // 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); | ||||
|             //carrier phase accumulator for (K) doppler estimation | ||||
|             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 | ||||
|             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); | ||||
|  | ||||
|             // ################## DLL ########################################################## | ||||
|             // DLL discriminator | ||||
|             code_error_chips = dll_nc_e_minus_l_normalized(*d_Early, *d_Late); //[chips/Ti] | ||||
|             // Code discriminator filter | ||||
|             code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); //[chips/second] | ||||
|             //Code phase accumulator | ||||
|             double code_error_filt_secs; | ||||
|             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; | ||||
|  | ||||
|             // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### | ||||
|             // 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 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 * GPS_L1_CA_CODE_LENGTH_CHIPS; | ||||
|             T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in); | ||||
|             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 samples | ||||
|             //d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample | ||||
|  | ||||
|             // ####### 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_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, GPS_L1_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 < MINIMUM_VALID_CN0) | ||||
|                         { | ||||
|                             d_carrier_lock_fail_counter++; | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; | ||||
|                         } | ||||
|                     if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER) | ||||
|                         { | ||||
|                             std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; | ||||
|                             LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; | ||||
|                             std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory()); | ||||
|                             if (d_queue != gr::msg_queue::sptr()) | ||||
|                                 { | ||||
|                                     d_queue->handle(cmf->GetQueueMessage(d_channel, 2)); | ||||
|                                 } | ||||
|                             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_Prompt).real()); | ||||
|             current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).imag()); | ||||
|  | ||||
|             // Tracking_timestamp_secs is aligned with the NEXT PRN start sample (Hybridization problem!) | ||||
|             //compute remnant code phase samples BEFORE the Tracking timestamp | ||||
|             //d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample | ||||
|             //current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + (double)d_current_prn_length_samples + (double)d_rem_code_phase_samples)/static_cast<double>(d_fs_in); | ||||
|  | ||||
|             // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!, but some glitches??) | ||||
|             current_synchro_data.Tracking_timestamp_secs = (static_cast<double>(d_sample_counter) + d_rem_code_phase_samples) / static_cast<double>(d_fs_in); | ||||
|             //compute remnant code phase samples AFTER the Tracking timestamp | ||||
|             d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample | ||||
|  | ||||
|             //current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter)/static_cast<double>(d_fs_in); | ||||
|             // This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, thus, 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_Doppler_hz = d_carrier_doppler_hz; | ||||
|             current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; | ||||
|             current_synchro_data.Flag_valid_pseudorange = false; | ||||
|             *out[0] = current_synchro_data; | ||||
|  | ||||
|             // ########## DEBUG OUTPUT | ||||
|             /*! | ||||
|              *  \todo The stop timer has to be moved to the signal source! | ||||
|              */ | ||||
|             // debug: Second counter in channel 0 | ||||
|             if (d_channel == 0) | ||||
|                 { | ||||
|                     if (floor(d_sample_counter / d_fs_in) != d_last_seg) | ||||
|                         { | ||||
|                             d_last_seg = floor(d_sample_counter / d_fs_in); | ||||
|                             std::cout << "Current input signal time = " << d_last_seg << " [s]" << std::endl; | ||||
|                             DLOG(INFO) << "GPS L1 C/A Tracking CH " << d_channel <<  ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) | ||||
|                                       << ", CN0 = " << d_CN0_SNV_dB_Hz << " [dB-Hz]" << std::endl; | ||||
|                             //if (d_last_seg==5) d_carrier_lock_fail_counter=500; //DEBUG: force unlock! | ||||
|                         } | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     if (floor(d_sample_counter / d_fs_in) != d_last_seg) | ||||
|                         { | ||||
|                             d_last_seg = floor(d_sample_counter / d_fs_in); | ||||
|                             DLOG(INFO) << "Tracking CH " << d_channel <<  ": Satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) | ||||
|                                        << ", CN0 = " << d_CN0_SNV_dB_Hz << " [dB-Hz]"; | ||||
|                         } | ||||
|                 } | ||||
|         } | ||||
|     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); | ||||
|  | ||||
|                     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_Prompt = gr_complex(0,0); | ||||
|             *d_Late = gr_complex(0,0); | ||||
|  | ||||
|             current_synchro_data.System = {'G'}; | ||||
|             current_synchro_data.Flag_valid_pseudorange = false; | ||||
|             *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_float; | ||||
|             double tmp_double; | ||||
|             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); | ||||
|             try | ||||
|             { | ||||
|  | ||||
|                 // EPR | ||||
|                 d_dump_file.write((char*)&tmp_E, sizeof(float)); | ||||
|                 d_dump_file.write((char*)&tmp_P, sizeof(float)); | ||||
|                 d_dump_file.write((char*)&tmp_L, sizeof(float)); | ||||
|                 // PROMPT I and Q (to analyze navigation symbols) | ||||
|                 d_dump_file.write((char*)&prompt_I, sizeof(float)); | ||||
|                 d_dump_file.write((char*)&prompt_Q, sizeof(float)); | ||||
|                 // PRN start sample stamp | ||||
|                 //tmp_float=(float)d_sample_counter; | ||||
|                 d_dump_file.write((char*)&d_sample_counter, sizeof(unsigned long int)); | ||||
|                 // accumulated carrier phase | ||||
|                 tmp_float = d_acc_carrier_phase_rad; | ||||
|                 d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||
|  | ||||
|                 // carrier and code frequency | ||||
|                 tmp_float = d_carrier_doppler_hz; | ||||
|                 d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||
|                 tmp_float = d_code_freq_chips; | ||||
|                 d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||
|  | ||||
|                 //PLL commands | ||||
|                 tmp_float = carr_error_hz; | ||||
|                 d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||
|                 tmp_float = carr_error_filt_hz; | ||||
|                 d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||
|  | ||||
|                 //DLL commands | ||||
|                 tmp_float = code_error_chips; | ||||
|                 d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||
|                 tmp_float = code_error_filt_chips; | ||||
|                 d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||
|  | ||||
|                 // CN0 and carrier lock test | ||||
|                 tmp_float = d_CN0_SNV_dB_Hz; | ||||
|                 d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||
|                 tmp_float = d_carrier_lock_test; | ||||
|                 d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||
|  | ||||
|                 // AUX vars (for debug purposes) | ||||
|                 tmp_float = d_rem_code_phase_samples; | ||||
|                 d_dump_file.write((char*)&tmp_float, sizeof(float)); | ||||
|                 tmp_double = (double)(d_sample_counter + d_current_prn_length_samples); | ||||
|                 d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||
|             } | ||||
|             catch (std::ifstream::failure e) | ||||
|             { | ||||
|                     LOG(WARNING) << "Exception writing trk dump file " << e.what(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     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 | ||||
|     //LOG(INFO)<<"GPS tracking output end on CH="<<this->d_channel << " SAMPLE STAMP="<<d_sample_counter<<std::endl; | ||||
|     return 1; //output tracking result ALWAYS even in the case of d_enable_tracking==false | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void Gps_L1_Ca_Dll_Pll_Tracking_GPU_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 (std::ifstream::failure e) | ||||
|                     { | ||||
|                             LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what() << std::endl; | ||||
|                     } | ||||
|                 } | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::set_channel_queue(concurrent_queue<int> *channel_internal_queue) | ||||
| { | ||||
|     d_channel_internal_queue = channel_internal_queue; | ||||
| } | ||||
|  | ||||
|  | ||||
| void Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) | ||||
| { | ||||
|     d_acquisition_gnss_synchro = p_gnss_synchro; | ||||
| } | ||||
| @@ -106,6 +106,8 @@ Gps_L1_Ca_Tcp_Connector_Tracking_cc::Gps_L1_Ca_Tcp_Connector_Tracking_cc( | ||||
|         gr::block("Gps_L1_Ca_Tcp_Connector_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")); | ||||
|     // initialize internal vars | ||||
|     d_queue = queue; | ||||
|     d_dump = dump; | ||||
| @@ -434,7 +436,7 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec | ||||
|                     current_synchro_data.CN0_dB_hz = 0.0; | ||||
|                     current_synchro_data.Flag_valid_tracking = false; | ||||
|                     current_synchro_data.Flag_valid_pseudorange = false; | ||||
|  | ||||
|                     current_synchro_data.Flag_valid_symbol_output = true; | ||||
|                     *out[0] = current_synchro_data; | ||||
|  | ||||
|                     return 1; | ||||
| @@ -547,6 +549,8 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec | ||||
|             current_synchro_data.Code_phase_secs = (double)d_code_phase_samples * (1/(float)d_fs_in); | ||||
|             current_synchro_data.CN0_dB_hz = (double)d_CN0_SNV_dB_Hz; | ||||
|             current_synchro_data.Flag_valid_pseudorange = false; | ||||
|             current_synchro_data.Flag_valid_symbol_output = true; | ||||
|             current_synchro_data.correlation_length_ms=1; | ||||
|             *out[0] = current_synchro_data; | ||||
|  | ||||
|             // ########## DEBUG OUTPUT | ||||
|   | ||||
| @@ -102,7 +102,8 @@ gps_l2_m_dll_pll_tracking_cc::gps_l2_m_dll_pll_tracking_cc( | ||||
|         float early_late_space_chips) : | ||||
|         gr::block("gps_l2_m_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 | ||||
| 	this->message_port_register_in(pmt::mp("preamble_timestamp_s")); | ||||
|     // initialize internal vars | ||||
|     d_queue = queue; | ||||
|     d_dump = dump; | ||||
| @@ -311,8 +312,6 @@ void gps_l2_m_dll_pll_tracking_cc::update_local_carrier() | ||||
|             d_carr_sign[i] = gr_complex(cos(phase_rad), -sin(phase_rad)); | ||||
|             phase_rad += phase_step_rad; | ||||
|         } | ||||
|     //d_rem_carr_phase_rad = fmod(phase_rad, GPS_L2_TWO_PI); | ||||
|     //d_acc_carrier_phase_rad = d_acc_carrier_phase_rad + d_rem_carr_phase_rad; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -414,7 +413,7 @@ int gps_l2_m_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_int | ||||
|                     current_synchro_data.CN0_dB_hz = 0.0; | ||||
|                     current_synchro_data.Flag_valid_tracking = false; | ||||
|                     current_synchro_data.Flag_valid_pseudorange = false; | ||||
|  | ||||
|                     current_synchro_data.Flag_valid_symbol_output = false; | ||||
|                     *out[0] = current_synchro_data; | ||||
|  | ||||
|                     return 1; | ||||
| @@ -499,11 +498,6 @@ int gps_l2_m_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_int | ||||
|             current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).real()); | ||||
|             current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).imag()); | ||||
|  | ||||
|             // Tracking_timestamp_secs is aligned with the NEXT PRN start sample (Hybridization problem!) | ||||
|             //compute remnant code phase samples BEFORE the Tracking timestamp | ||||
|             //d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample | ||||
|             //current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + (double)d_current_prn_length_samples + (double)d_rem_code_phase_samples)/static_cast<double>(d_fs_in); | ||||
|  | ||||
|             // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!, but some glitches??) | ||||
|             current_synchro_data.Tracking_timestamp_secs = (static_cast<double>(d_sample_counter) + d_rem_code_phase_samples) / static_cast<double>(d_fs_in); | ||||
|             //compute remnant code phase samples AFTER the Tracking timestamp | ||||
| @@ -516,6 +510,8 @@ int gps_l2_m_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_int | ||||
|             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_tracking = true; | ||||
|             current_synchro_data.Flag_valid_symbol_output = true; | ||||
|             current_synchro_data.correlation_length_ms=1; | ||||
|             *out[0] = current_synchro_data; | ||||
|  | ||||
|             // ########## DEBUG OUTPUT | ||||
| @@ -570,6 +566,7 @@ int gps_l2_m_dll_pll_tracking_cc::general_work (int noutput_items, gr_vector_int | ||||
|             *d_Late = gr_complex(0,0); | ||||
|  | ||||
|             current_synchro_data.Flag_valid_pseudorange = false; | ||||
|             current_synchro_data.Flag_valid_symbol_output = false; | ||||
|             *out[0] = current_synchro_data; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -100,21 +100,23 @@ bool cpu_multicorrelator::set_input_output_vectors(std::complex<float>* corr_out | ||||
|     return true; | ||||
| } | ||||
|  | ||||
|  | ||||
| void cpu_multicorrelator::update_local_code(int correlator_length_samples, float rem_code_phase_chips, float code_phase_step_chips) | ||||
| void cpu_multicorrelator::update_local_code(int correlator_length_samples,float rem_code_phase_chips, float code_phase_step_chips) | ||||
| { | ||||
|     float local_code_chip_index; | ||||
|     int local_code_chip_index; | ||||
|     for (int current_correlator_tap = 0; current_correlator_tap < d_n_correlators; current_correlator_tap++) | ||||
|         { | ||||
|             for (int n = 0; n < correlator_length_samples; n++) | ||||
|                 { | ||||
|                     // resample code for current tap | ||||
|                     local_code_chip_index = std::fmod(code_phase_step_chips * static_cast<float>(n) + d_shifts_chips[current_correlator_tap] - rem_code_phase_chips, d_code_length_chips); | ||||
|                     //Take into account that in multitap correlators, the shifts can be negative! | ||||
|                     if (local_code_chip_index < 0.0) local_code_chip_index += d_code_length_chips; | ||||
|                     d_local_codes_resampled[current_correlator_tap][n] = d_local_code_in[static_cast<int>(round(local_code_chip_index))]; | ||||
|                 } | ||||
|         } | ||||
|  | ||||
| 	{ | ||||
| 		for (int n = 0; n < correlator_length_samples; n++) | ||||
| 		{ | ||||
| 		   // resample code for current tap | ||||
| 		   local_code_chip_index = floor(code_phase_step_chips*static_cast<float>(n) + d_shifts_chips[current_correlator_tap]- rem_code_phase_chips); | ||||
| 		   local_code_chip_index = local_code_chip_index % d_code_length_chips; | ||||
| 		   //Take into account that in multitap correlators, the shifts can be negative! | ||||
| 		   if (local_code_chip_index < 0) local_code_chip_index += d_code_length_chips; | ||||
| 		   d_local_codes_resampled[current_correlator_tap][n] = d_local_code_in[local_code_chip_index]; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -67,21 +67,22 @@ | ||||
|  */ | ||||
| float cn0_svn_estimator(gr_complex* Prompt_buffer, int length, long fs_in, double code_length) | ||||
| { | ||||
|     float SNR = 0; | ||||
|     float SNR_dB_Hz = 0; | ||||
|     float Psig = 0; | ||||
|     float Ptot = 0; | ||||
| 	double SNR = 0; | ||||
| 	double SNR_dB_Hz = 0; | ||||
|     double Psig = 0; | ||||
|     double Ptot = 0; | ||||
|     for (int i=0; i<length; i++) | ||||
|         { | ||||
|             Psig += std::abs(Prompt_buffer[i].real()); | ||||
|             Ptot += Prompt_buffer[i].imag() * Prompt_buffer[i].imag() + Prompt_buffer[i].real() * Prompt_buffer[i].real(); | ||||
|             Psig += std::abs(static_cast<double>(Prompt_buffer[i].real())); | ||||
|             Ptot += static_cast<double>(Prompt_buffer[i].imag()) * static_cast<double>(Prompt_buffer[i].imag()) | ||||
|             		+ static_cast<double>(Prompt_buffer[i].real()) * static_cast<double>(Prompt_buffer[i].real()); | ||||
|         } | ||||
|     Psig = Psig / (float)length; | ||||
|     Psig = Psig / static_cast<double>(length); | ||||
|     Psig = Psig * Psig; | ||||
|     Ptot = Ptot / (float)length; | ||||
|     Ptot = Ptot / static_cast<double>(length); | ||||
|     SNR = Psig / (Ptot - Psig); | ||||
|     SNR_dB_Hz = 10 * log10(SNR) + 10 * log10(fs_in/2) - 10 * log10((float)code_length); | ||||
|     return SNR_dB_Hz; | ||||
|     SNR_dB_Hz = 10 * log10(SNR) + 10 * log10(static_cast<double>(fs_in)/2) - 10 * log10(code_length); | ||||
|     return static_cast<float>(SNR_dB_Hz); | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Javier Arribas
					Javier Arribas