mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 07:13:03 +00:00 
			
		
		
		
	Add KF test, some KF implementation fixes, use flags in tests
This commit is contained in:
		| @@ -37,17 +37,17 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| #include "gps_l1_ca_kf_tracking.h" | #include "gps_l1_ca_kf_tracking.h" | ||||||
| #include <glog/logging.h> | #include "gnss_sdr_flags.h" | ||||||
| #include "GPS_L1_CA.h" | #include "GPS_L1_CA.h" | ||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
|  | #include <glog/logging.h> | ||||||
|  |  | ||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
|  |  | ||||||
| GpsL1CaKfTracking::GpsL1CaKfTracking( | GpsL1CaKfTracking::GpsL1CaKfTracking( | ||||||
|         ConfigurationInterface* configuration, std::string role, |     ConfigurationInterface* configuration, std::string role, | ||||||
|         unsigned int in_streams, unsigned int out_streams) : |     unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) | ||||||
|                 role_(role), in_streams_(in_streams), out_streams_(out_streams) |  | ||||||
| { | { | ||||||
|     DLOG(INFO) << "role " << role; |     DLOG(INFO) << "role " << role; | ||||||
|     //################# CONFIGURATION PARAMETERS ######################## |     //################# CONFIGURATION PARAMETERS ######################## | ||||||
| @@ -66,11 +66,13 @@ GpsL1CaKfTracking::GpsL1CaKfTracking( | |||||||
|     fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); |     fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||||
|     f_if = configuration->property(role + ".if", 0); |     f_if = configuration->property(role + ".if", 0); | ||||||
|     dump = configuration->property(role + ".dump", false); |     dump = configuration->property(role + ".dump", false); | ||||||
|     pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); |     //pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); | ||||||
|  |     //if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz); | ||||||
|     dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); |     dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); | ||||||
|  |     if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast<float>(FLAGS_dll_bw_hz); | ||||||
|     early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); |     early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); | ||||||
|     std::string default_dump_filename = "./track_ch"; |     std::string default_dump_filename = "./track_ch"; | ||||||
|     dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); //unused! |     dump_filename = configuration->property(role + ".dump_filename", default_dump_filename);  //unused! | ||||||
|     vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); |     vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); | ||||||
|  |  | ||||||
|     //################# MAKE TRACKING GNURadio object ################### |     //################# MAKE TRACKING GNURadio object ################### | ||||||
| @@ -78,14 +80,13 @@ GpsL1CaKfTracking::GpsL1CaKfTracking( | |||||||
|         { |         { | ||||||
|             item_size_ = sizeof(gr_complex); |             item_size_ = sizeof(gr_complex); | ||||||
|             tracking_ = gps_l1_ca_kf_make_tracking_cc( |             tracking_ = gps_l1_ca_kf_make_tracking_cc( | ||||||
|                     f_if, |                 f_if, | ||||||
|                     fs_in, |                 fs_in, | ||||||
|                     vector_length, |                 vector_length, | ||||||
|                     dump, |                 dump, | ||||||
|                     dump_filename, |                 dump_filename, | ||||||
|                     pll_bw_hz, |                 dll_bw_hz, | ||||||
|                     dll_bw_hz, |                 early_late_space_chips); | ||||||
|                     early_late_space_chips); |  | ||||||
|         } |         } | ||||||
|     else |     else | ||||||
|         { |         { | ||||||
| @@ -98,7 +99,8 @@ GpsL1CaKfTracking::GpsL1CaKfTracking( | |||||||
|  |  | ||||||
|  |  | ||||||
| GpsL1CaKfTracking::~GpsL1CaKfTracking() | GpsL1CaKfTracking::~GpsL1CaKfTracking() | ||||||
| {} | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void GpsL1CaKfTracking::start_tracking() | void GpsL1CaKfTracking::start_tracking() | ||||||
| @@ -125,14 +127,18 @@ void GpsL1CaKfTracking::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) | |||||||
|  |  | ||||||
| void GpsL1CaKfTracking::connect(gr::top_block_sptr top_block) | void GpsL1CaKfTracking::connect(gr::top_block_sptr top_block) | ||||||
| { | { | ||||||
|     if(top_block) { /* top_block is not null */}; |     if (top_block) | ||||||
|  |         { /* top_block is not null */ | ||||||
|  |         }; | ||||||
|     //nothing to connect, now the tracking uses gr_sync_decimator |     //nothing to connect, now the tracking uses gr_sync_decimator | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void GpsL1CaKfTracking::disconnect(gr::top_block_sptr top_block) | void GpsL1CaKfTracking::disconnect(gr::top_block_sptr top_block) | ||||||
| { | { | ||||||
|     if(top_block) { /* top_block is not null */}; |     if (top_block) | ||||||
|  |         { /* top_block is not null */ | ||||||
|  |         }; | ||||||
|     //nothing to disconnect, now the tracking uses gr_sync_decimator |     //nothing to disconnect, now the tracking uses gr_sync_decimator | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -147,4 +153,3 @@ gr::basic_block_sptr GpsL1CaKfTracking::get_right_block() | |||||||
| { | { | ||||||
|     return tracking_; |     return tracking_; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -35,71 +35,59 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "gps_l1_ca_kf_tracking_cc.h" | #include "gps_l1_ca_kf_tracking_cc.h" | ||||||
| #include <cmath> | #include "gps_sdr_signal_processing.h" | ||||||
| #include <iostream> | #include "tracking_discriminators.h" | ||||||
| #include <memory> | #include "lock_detectors.h" | ||||||
| #include <sstream> | #include "gnss_sdr_flags.h" | ||||||
|  | #include "GPS_L1_CA.h" | ||||||
|  | #include "control_message_factory.h" | ||||||
| #include <boost/lexical_cast.hpp> | #include <boost/lexical_cast.hpp> | ||||||
| #include <gnuradio/io_signature.h> | #include <gnuradio/io_signature.h> | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <volk_gnsssdr/volk_gnsssdr.h> | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
| #include "gps_sdr_signal_processing.h" | #include <matio.h> | ||||||
| #include "tracking_discriminators.h" | #include <cmath> | ||||||
| #include "lock_detectors.h" | #include <iostream> | ||||||
| #include "GPS_L1_CA.h" | #include <memory> | ||||||
| #include "control_message_factory.h" | #include <sstream> | ||||||
|  |  | ||||||
|  |  | ||||||
| /*! |  | ||||||
|  * \todo Include in definition header file |  | ||||||
|  */ |  | ||||||
| #define CN0_ESTIMATION_SAMPLES 20 |  | ||||||
| #define MINIMUM_VALID_CN0 25 |  | ||||||
| #define MAXIMUM_LOCK_FAIL_COUNTER 5000 |  | ||||||
| #define CARRIER_LOCK_THRESHOLD 0.85 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
|  |  | ||||||
| gps_l1_ca_kf_tracking_cc_sptr | gps_l1_ca_kf_tracking_cc_sptr | ||||||
| gps_l1_ca_kf_make_tracking_cc( | gps_l1_ca_kf_make_tracking_cc( | ||||||
|         long if_freq, |     long if_freq, | ||||||
|         long fs_in, |     long fs_in, | ||||||
|         unsigned int vector_length, |     unsigned int vector_length, | ||||||
|         bool dump, |     bool dump, | ||||||
|         std::string dump_filename, |     std::string dump_filename, | ||||||
|         float pll_bw_hz, |     float dll_bw_hz, | ||||||
|         float dll_bw_hz, |     float early_late_space_chips) | ||||||
|         float early_late_space_chips) |  | ||||||
| { | { | ||||||
|     return gps_l1_ca_kf_tracking_cc_sptr(new Gps_L1_Ca_Kf_Tracking_cc(if_freq, |     return gps_l1_ca_kf_tracking_cc_sptr(new Gps_L1_Ca_Kf_Tracking_cc(if_freq, | ||||||
|             fs_in, vector_length, dump, dump_filename, pll_bw_hz, dll_bw_hz, early_late_space_chips)); |         fs_in, vector_length, dump, dump_filename, dll_bw_hz, early_late_space_chips)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void Gps_L1_Ca_Kf_Tracking_cc::forecast(int noutput_items, | ||||||
| void Gps_L1_Ca_Kf_Tracking_cc::forecast (int noutput_items, |     gr_vector_int &ninput_items_required) | ||||||
|         gr_vector_int &ninput_items_required) |  | ||||||
| { | { | ||||||
|     if (noutput_items != 0) |     if (noutput_items != 0) | ||||||
|         { |         { | ||||||
|             ninput_items_required[0] = static_cast<int>(d_vector_length) * 2; //set the required available samples in each call |             ninput_items_required[0] = static_cast<int>(d_vector_length) * 2;  //set the required available samples in each call | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Gps_L1_Ca_Kf_Tracking_cc::Gps_L1_Ca_Kf_Tracking_cc( | Gps_L1_Ca_Kf_Tracking_cc::Gps_L1_Ca_Kf_Tracking_cc( | ||||||
|         long if_freq, |     long if_freq, | ||||||
|         long fs_in, |     long fs_in, | ||||||
|         unsigned int vector_length, |     unsigned int vector_length, | ||||||
|         bool dump, |     bool dump, | ||||||
|         std::string dump_filename, |     std::string dump_filename, | ||||||
|         float pll_bw_hz, |     float dll_bw_hz, | ||||||
|         float dll_bw_hz, |     float early_late_space_chips) : gr::block("Gps_L1_Ca_Kf_Tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)), | ||||||
|         float early_late_space_chips) : |                                         gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) | ||||||
|                 gr::block("Gps_L1_Ca_Kf_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 |     // Telemetry bit synchronization message port input | ||||||
|     this->message_port_register_in(pmt::mp("preamble_timestamp_s")); |     this->message_port_register_in(pmt::mp("preamble_timestamp_s")); | ||||||
| @@ -116,25 +104,24 @@ Gps_L1_Ca_Kf_Tracking_cc::Gps_L1_Ca_Kf_Tracking_cc( | |||||||
|  |  | ||||||
|     // Initialize tracking  ========================================== |     // Initialize tracking  ========================================== | ||||||
|     d_code_loop_filter.set_DLL_BW(dll_bw_hz); |     d_code_loop_filter.set_DLL_BW(dll_bw_hz); | ||||||
|     d_carrier_loop_filter.set_PLL_BW(pll_bw_hz); |  | ||||||
|  |  | ||||||
|     //--- DLL variables -------------------------------------------------------- |     //--- DLL variables -------------------------------------------------------- | ||||||
|     d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips) |     d_early_late_spc_chips = early_late_space_chips;  // Define early-late offset (in chips) | ||||||
|  |  | ||||||
|     // Initialization of local code replica |     // Initialization of local code replica | ||||||
|     // Get space for a vector with the C/A code replica sampled 1x/chip |     // Get space for a vector with the C/A code replica sampled 1x/chip | ||||||
|     d_ca_code = static_cast<float*>(volk_gnsssdr_malloc(static_cast<int>(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment())); |     d_ca_code = static_cast<float *>(volk_gnsssdr_malloc(static_cast<int>(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment())); | ||||||
|  |  | ||||||
|     // correlator outputs (scalar) |     // correlator outputs (scalar) | ||||||
|     d_n_correlator_taps = 3; // Early, Prompt, and Late |     d_n_correlator_taps = 3;  // Early, Prompt, and Late | ||||||
|     d_correlator_outs = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); |     d_correlator_outs = static_cast<gr_complex *>(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); | ||||||
|     for (int n = 0; n < d_n_correlator_taps; n++) |     for (int n = 0; n < d_n_correlator_taps; n++) | ||||||
|         { |         { | ||||||
|             d_correlator_outs[n] = gr_complex(0,0); |             d_correlator_outs[n] = gr_complex(0, 0); | ||||||
|         } |         } | ||||||
|     d_local_code_shift_chips = static_cast<float*>(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(float), volk_gnsssdr_get_alignment())); |     d_local_code_shift_chips = static_cast<float *>(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(float), volk_gnsssdr_get_alignment())); | ||||||
|     // Set TAPs delay values [chips] |     // Set TAPs delay values [chips] | ||||||
|     d_local_code_shift_chips[0] = - d_early_late_spc_chips; |     d_local_code_shift_chips[0] = -d_early_late_spc_chips; | ||||||
|     d_local_code_shift_chips[1] = 0.0; |     d_local_code_shift_chips[1] = 0.0; | ||||||
|     d_local_code_shift_chips[2] = d_early_late_spc_chips; |     d_local_code_shift_chips[2] = d_early_late_spc_chips; | ||||||
|  |  | ||||||
| @@ -158,11 +145,11 @@ Gps_L1_Ca_Kf_Tracking_cc::Gps_L1_Ca_Kf_Tracking_cc( | |||||||
|  |  | ||||||
|     // CN0 estimation and lock detector buffers |     // CN0 estimation and lock detector buffers | ||||||
|     d_cn0_estimation_counter = 0; |     d_cn0_estimation_counter = 0; | ||||||
|     d_Prompt_buffer = new gr_complex[CN0_ESTIMATION_SAMPLES]; |     d_Prompt_buffer = new gr_complex[FLAGS_cn0_samples]; | ||||||
|     d_carrier_lock_test = 1; |     d_carrier_lock_test = 1; | ||||||
|     d_CN0_SNV_dB_Hz = 0; |     d_CN0_SNV_dB_Hz = 0; | ||||||
|     d_carrier_lock_fail_counter = 0; |     d_carrier_lock_fail_counter = 0; | ||||||
|     d_carrier_lock_threshold = CARRIER_LOCK_THRESHOLD; |     d_carrier_lock_threshold = FLAGS_carrier_lock_th; | ||||||
|  |  | ||||||
|     systemName["G"] = std::string("GPS"); |     systemName["G"] = std::string("GPS"); | ||||||
|     systemName["S"] = std::string("SBAS"); |     systemName["S"] = std::string("SBAS"); | ||||||
| @@ -182,43 +169,42 @@ Gps_L1_Ca_Kf_Tracking_cc::Gps_L1_Ca_Kf_Tracking_cc( | |||||||
|  |  | ||||||
|     // Kalman filter initialization (receiver initialization) |     // Kalman filter initialization (receiver initialization) | ||||||
|  |  | ||||||
|     double CN_dB_Hz=40; |     double CN_dB_Hz = 40; | ||||||
|     double CN_lin=pow(10,CN_dB_Hz/10.0); |     double CN_lin = pow(10, CN_dB_Hz / 10.0); | ||||||
|  |  | ||||||
|     double sigma2_phase_detector_cycles2; |     double sigma2_phase_detector_cycles2; | ||||||
|     sigma2_phase_detector_cycles2=(1.0/(2.0*CN_lin*GPS_L1_CA_CODE_PERIOD))*(1.0+1.0/(2.0*CN_lin*GPS_L1_CA_CODE_PERIOD)); |     sigma2_phase_detector_cycles2 = (1.0 / (2.0 * CN_lin * GPS_L1_CA_CODE_PERIOD)) * (1.0 + 1.0 / (2.0 * CN_lin * GPS_L1_CA_CODE_PERIOD)); | ||||||
|  |  | ||||||
|     //covariances (static) |     //covariances (static) | ||||||
|     double sigma2_carrier_phase=GPS_TWO_PI/4.0; |     double sigma2_carrier_phase = GPS_TWO_PI / 4; | ||||||
|     double sigma2_doppler=250; |     double sigma2_doppler = 250; | ||||||
|  |  | ||||||
|     kf_P_x_ini=arma::zeros(2,2); |     kf_P_x_ini = arma::zeros(2, 2); | ||||||
|     kf_P_x_ini(0,0)=sigma2_carrier_phase; |     kf_P_x_ini(0, 0) = sigma2_carrier_phase; | ||||||
|     kf_P_x_ini(1,1)=sigma2_doppler; |     kf_P_x_ini(1, 1) = sigma2_doppler; | ||||||
|  |  | ||||||
|     kf_R=arma::zeros(1,1); |     kf_R = arma::zeros(1, 1); | ||||||
|     kf_R(0,0)=sigma2_phase_detector_cycles2; |     kf_R(0, 0) = sigma2_phase_detector_cycles2; | ||||||
|  |  | ||||||
|     //arma::colvec G={pow(GPS_L1_CA_CODE_PERIOD,3)/6.0, pow(GPS_L1_CA_CODE_PERIOD,2)/2.0,GPS_L1_CA_CODE_PERIOD}; |     //arma::colvec G={pow(GPS_L1_CA_CODE_PERIOD,3)/6.0, pow(GPS_L1_CA_CODE_PERIOD,2)/2.0,GPS_L1_CA_CODE_PERIOD}; | ||||||
|     kf_Q=arma::zeros(2,2); |     kf_Q = arma::zeros(2, 2); | ||||||
|     kf_Q(0,0)=1e-14; |     kf_Q(0, 0) = 1e-12; | ||||||
|     kf_Q(1,1)=1e-2; |     kf_Q(1, 1) = 1e-2; | ||||||
|  |  | ||||||
| //    kf_Q=arma::diagmat(pow(GPS_L1_CA_CODE_PERIOD,6)*kf_Q); |     //    kf_Q=arma::diagmat(pow(GPS_L1_CA_CODE_PERIOD,6)*kf_Q); | ||||||
|     //std::cout<<"kf_Q="<<kf_Q<<std::endl; |     //std::cout<<"kf_Q="<<kf_Q<<std::endl; | ||||||
|  |  | ||||||
|     kf_F=arma::zeros(2,2); |     kf_F = arma::zeros(2, 2); | ||||||
|     kf_F(0,0)=1.0; |     kf_F(0, 0) = 1.0; | ||||||
|     kf_F(0,1)=GPS_TWO_PI*GPS_L1_CA_CODE_PERIOD; |     kf_F(0, 1) = GPS_TWO_PI * GPS_L1_CA_CODE_PERIOD; | ||||||
|     kf_F(1,0)=0.0; |     kf_F(1, 0) = 0.0; | ||||||
|     kf_F(1,1)=1.0; |     kf_F(1, 1) = 1.0; | ||||||
|  |  | ||||||
|     kf_H=arma::zeros(1,2); |     kf_H = arma::zeros(1, 2); | ||||||
|     kf_H(0,0)=1.0; |     kf_H(0, 0) = 1.0; | ||||||
|  |  | ||||||
|     kf_x=arma::zeros(2,1); |  | ||||||
|     kf_y=arma::zeros(1,1); |  | ||||||
|  |  | ||||||
|  |     kf_x = arma::zeros(2, 1); | ||||||
|  |     kf_y = arma::zeros(1, 1); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -233,7 +219,7 @@ void Gps_L1_Ca_Kf_Tracking_cc::start_tracking() | |||||||
|  |  | ||||||
|     long int acq_trk_diff_samples; |     long int acq_trk_diff_samples; | ||||||
|     double acq_trk_diff_seconds; |     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; |     acq_trk_diff_samples = static_cast<long int>(d_sample_counter) - static_cast<long int>(d_acq_sample_stamp);  //-d_vector_length; | ||||||
|     DLOG(INFO) << "Number of samples between Acquisition and Tracking = " << acq_trk_diff_samples; |     DLOG(INFO) << "Number of samples between Acquisition and Tracking = " << acq_trk_diff_samples; | ||||||
|     acq_trk_diff_seconds = static_cast<float>(acq_trk_diff_samples) / static_cast<float>(d_fs_in); |     acq_trk_diff_seconds = static_cast<float>(acq_trk_diff_samples) / static_cast<float>(d_fs_in); | ||||||
|     // Doppler effect |     // Doppler effect | ||||||
| @@ -245,7 +231,7 @@ void Gps_L1_Ca_Kf_Tracking_cc::start_tracking() | |||||||
|     double T_prn_mod_samples; |     double T_prn_mod_samples; | ||||||
|     d_code_freq_chips = radial_velocity * GPS_L1_CA_CODE_RATE_HZ; |     d_code_freq_chips = radial_velocity * GPS_L1_CA_CODE_RATE_HZ; | ||||||
|     d_code_phase_step_chips = static_cast<double>(d_code_freq_chips) / static_cast<double>(d_fs_in); |     d_code_phase_step_chips = static_cast<double>(d_code_freq_chips) / static_cast<double>(d_fs_in); | ||||||
|     T_chip_mod_seconds = 1/d_code_freq_chips; |     T_chip_mod_seconds = 1 / d_code_freq_chips; | ||||||
|     T_prn_mod_seconds = T_chip_mod_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; |     T_prn_mod_seconds = T_chip_mod_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; | ||||||
|     T_prn_mod_samples = T_prn_mod_seconds * static_cast<double>(d_fs_in); |     T_prn_mod_samples = T_prn_mod_seconds * static_cast<double>(d_fs_in); | ||||||
|  |  | ||||||
| @@ -268,9 +254,8 @@ void Gps_L1_Ca_Kf_Tracking_cc::start_tracking() | |||||||
|     d_carrier_doppler_hz = d_acq_carrier_doppler_hz; |     d_carrier_doppler_hz = d_acq_carrier_doppler_hz; | ||||||
|     d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in); |     d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in); | ||||||
|  |  | ||||||
|     // DLL/PLL filter initialization |     // DLL filter initialization | ||||||
|     d_carrier_loop_filter.initialize(); // initialize the carrier filter |     d_code_loop_filter.initialize();  // initialize the code filter | ||||||
|     d_code_loop_filter.initialize();    // initialize the code filter |  | ||||||
|  |  | ||||||
|     // generate local reference ALWAYS starting at chip 1 (1 sample per chip) |     // generate local reference ALWAYS starting at chip 1 (1 sample per chip) | ||||||
|     gps_l1_ca_code_gen_float(d_ca_code, d_acquisition_gnss_synchro->PRN, 0); |     gps_l1_ca_code_gen_float(d_ca_code, d_acquisition_gnss_synchro->PRN, 0); | ||||||
| @@ -278,7 +263,7 @@ void Gps_L1_Ca_Kf_Tracking_cc::start_tracking() | |||||||
|     multicorrelator_cpu.set_local_code_and_taps(static_cast<int>(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); |     multicorrelator_cpu.set_local_code_and_taps(static_cast<int>(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); | ||||||
|     for (int n = 0; n < d_n_correlator_taps; n++) |     for (int n = 0; n < d_n_correlator_taps; n++) | ||||||
|         { |         { | ||||||
|             d_correlator_outs[n] = gr_complex(0,0); |             d_correlator_outs[n] = gr_complex(0, 0); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     d_carrier_lock_fail_counter = 0; |     d_carrier_lock_fail_counter = 0; | ||||||
| @@ -290,7 +275,7 @@ void Gps_L1_Ca_Kf_Tracking_cc::start_tracking() | |||||||
|     d_code_phase_samples = d_acq_code_phase_samples; |     d_code_phase_samples = d_acq_code_phase_samples; | ||||||
|  |  | ||||||
|     std::string sys_ = &d_acquisition_gnss_synchro->System; |     std::string sys_ = &d_acquisition_gnss_synchro->System; | ||||||
|     sys = sys_.substr(0,1); |     sys = sys_.substr(0, 1); | ||||||
|  |  | ||||||
|     // DEBUG OUTPUT |     // DEBUG OUTPUT | ||||||
|     std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl; |     std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl; | ||||||
| @@ -301,9 +286,8 @@ void Gps_L1_Ca_Kf_Tracking_cc::start_tracking() | |||||||
|     d_enable_tracking = true; |     d_enable_tracking = true; | ||||||
|  |  | ||||||
|     LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz |     LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz | ||||||
|             << " Code Phase correction [samples]=" << delay_correction_samples |               << " Code Phase correction [samples]=" << delay_correction_samples | ||||||
|             << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; |               << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -312,32 +296,43 @@ Gps_L1_Ca_Kf_Tracking_cc::~Gps_L1_Ca_Kf_Tracking_cc() | |||||||
|     if (d_dump_file.is_open()) |     if (d_dump_file.is_open()) | ||||||
|         { |         { | ||||||
|             try |             try | ||||||
|             { |                 { | ||||||
|                     d_dump_file.close(); |                     d_dump_file.close(); | ||||||
|             } |                 } | ||||||
|             catch(const std::exception & ex) |             catch (const std::exception &ex) | ||||||
|             { |                 { | ||||||
|                     LOG(WARNING) << "Exception in destructor " << ex.what(); |                     LOG(WARNING) << "Exception in destructor " << ex.what(); | ||||||
|             } |                 } | ||||||
|  |         } | ||||||
|  |     if (d_dump) | ||||||
|  |         { | ||||||
|  |             if (d_channel == 0) | ||||||
|  |                 { | ||||||
|  |                     std::cout << "Writing .mat files ..."; | ||||||
|  |                 } | ||||||
|  |             Gps_L1_Ca_Kf_Tracking_cc::save_matfile(); | ||||||
|  |             if (d_channel == 0) | ||||||
|  |                 { | ||||||
|  |                     std::cout << " done." << std::endl; | ||||||
|  |                 } | ||||||
|         } |         } | ||||||
|     try |     try | ||||||
|     { |         { | ||||||
|             volk_gnsssdr_free(d_local_code_shift_chips); |             volk_gnsssdr_free(d_local_code_shift_chips); | ||||||
|             volk_gnsssdr_free(d_correlator_outs); |             volk_gnsssdr_free(d_correlator_outs); | ||||||
|             volk_gnsssdr_free(d_ca_code); |             volk_gnsssdr_free(d_ca_code); | ||||||
|             delete[] d_Prompt_buffer; |             delete[] d_Prompt_buffer; | ||||||
|             multicorrelator_cpu.free(); |             multicorrelator_cpu.free(); | ||||||
|     } |         } | ||||||
|     catch(const std::exception & ex) |     catch (const std::exception &ex) | ||||||
|     { |         { | ||||||
|             LOG(WARNING) << "Exception in destructor " << ex.what(); |             LOG(WARNING) << "Exception in destructor " << ex.what(); | ||||||
|     } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int Gps_L1_Ca_Kf_Tracking_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), | ||||||
| int Gps_L1_Ca_Kf_Tracking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), |     gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) | ||||||
|         gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) |  | ||||||
| { | { | ||||||
|     // process vars |     // process vars | ||||||
|     double carr_phase_error_rad = 0.0; |     double carr_phase_error_rad = 0.0; | ||||||
| @@ -346,7 +341,7 @@ int Gps_L1_Ca_Kf_Tracking_cc::general_work (int noutput_items __attribute__((unu | |||||||
|     double code_error_filt_chips = 0.0; |     double code_error_filt_chips = 0.0; | ||||||
|  |  | ||||||
|     // Block input data and block output stream pointers |     // Block input data and block output stream pointers | ||||||
|     const gr_complex* in = reinterpret_cast<const gr_complex *>(input_items[0]); |     const gr_complex *in = reinterpret_cast<const gr_complex *>(input_items[0]); | ||||||
|     Gnss_Synchro **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); |     Gnss_Synchro **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); | ||||||
|  |  | ||||||
|     // GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder |     // GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder | ||||||
| @@ -366,7 +361,7 @@ int Gps_L1_Ca_Kf_Tracking_cc::general_work (int noutput_items __attribute__((unu | |||||||
|                     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)); |                     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); |                     samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); | ||||||
|                     current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; |                     current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; | ||||||
|                     d_sample_counter = d_sample_counter + samples_offset; // count for the processed samples |                     d_sample_counter = d_sample_counter + samples_offset;  // count for the processed samples | ||||||
|                     d_pull_in = false; |                     d_pull_in = false; | ||||||
|                     // take into account the carrier cycles accumulated in the pull in signal alignment |                     // take into account the carrier cycles accumulated in the pull in signal alignment | ||||||
|                     d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * samples_offset; |                     d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * samples_offset; | ||||||
| @@ -376,12 +371,12 @@ int Gps_L1_Ca_Kf_Tracking_cc::general_work (int noutput_items __attribute__((unu | |||||||
|                     current_synchro_data.correlation_length_ms = 1; |                     current_synchro_data.correlation_length_ms = 1; | ||||||
|                     *out[0] = current_synchro_data; |                     *out[0] = current_synchro_data; | ||||||
|                     //Kalman filter initialization reset |                     //Kalman filter initialization reset | ||||||
|                     kf_P_x=kf_P_x_ini; |                     kf_P_x = kf_P_x_ini; | ||||||
|                     //Update Kalman states based on acquisition information |                     //Update Kalman states based on acquisition information | ||||||
|                     kf_x(0)=0.0; |                     kf_x(0) = d_carrier_phase_step_rad * samples_offset; | ||||||
|                     kf_x(1)=current_synchro_data.Carrier_Doppler_hz; |                     kf_x(1) = current_synchro_data.Carrier_Doppler_hz; | ||||||
|  |  | ||||||
|                     consume_each(samples_offset); // shift input to perform alignment with local replica |                     consume_each(samples_offset);  // shift input to perform alignment with local replica | ||||||
|                     return 1; |                     return 1; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| @@ -389,94 +384,86 @@ int Gps_L1_Ca_Kf_Tracking_cc::general_work (int noutput_items __attribute__((unu | |||||||
|             // perform carrier wipe-off and compute Early, Prompt and Late correlation |             // perform carrier wipe-off and compute Early, Prompt and Late correlation | ||||||
|             multicorrelator_cpu.set_input_output_vectors(d_correlator_outs, in); |             multicorrelator_cpu.set_input_output_vectors(d_correlator_outs, in); | ||||||
|             multicorrelator_cpu.Carrier_wipeoff_multicorrelator_resampler(d_rem_carr_phase_rad, |             multicorrelator_cpu.Carrier_wipeoff_multicorrelator_resampler(d_rem_carr_phase_rad, | ||||||
|                     d_carrier_phase_step_rad, |                 d_carrier_phase_step_rad, | ||||||
|                     d_rem_code_phase_chips, |                 d_rem_code_phase_chips, | ||||||
|                     d_code_phase_step_chips, |                 d_code_phase_step_chips, | ||||||
|                     d_current_prn_length_samples); |                 d_current_prn_length_samples); | ||||||
|  |  | ||||||
|             // remnant carrier phase to prevent overflow in the code NCO |  | ||||||
|             //d_rem_carr_phase_rad = d_rem_carr_phase_rad + d_carrier_phase_step_rad * d_current_prn_length_samples; |  | ||||||
|             //d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, GPS_TWO_PI); |  | ||||||
|  |  | ||||||
|             // ################## Kalman Carrier Tracking ###################################### |             // ################## Kalman Carrier Tracking ###################################### | ||||||
|  |  | ||||||
|             //Kalman state prediction (time update) |             //Kalman state prediction (time update) | ||||||
| 			kf_x_pre=kf_F*kf_x; //state prediction |             kf_x_pre = kf_F * kf_x;                        //state prediction | ||||||
| 			kf_P_x_pre=kf_F*kf_P_x*kf_F.t()+kf_Q; //state error covariance prediction |             kf_P_x_pre = kf_F * kf_P_x * kf_F.t() + kf_Q;  //state error covariance prediction | ||||||
|  |  | ||||||
|             // Update discriminator [rads/Ti] |             // Update discriminator [rads/Ti] | ||||||
|             carr_phase_error_rad = pll_cloop_two_quadrant_atan(d_correlator_outs[1]); // prompt output |             carr_phase_error_rad = pll_cloop_two_quadrant_atan(d_correlator_outs[1]);  // prompt output | ||||||
|  |  | ||||||
| 			//Kalman estimation (measuremant update) |             //Kalman estimation (measuremant update) | ||||||
| 			//kf_y_pre=kf_H*kf_x_pre; //measurement prediction |             double sigma2_phase_detector_cycles2; | ||||||
|  |             double CN_lin = pow(10, d_CN0_SNV_dB_Hz / 10.0); | ||||||
|  |             sigma2_phase_detector_cycles2 = (1.0 / (2.0 * CN_lin * GPS_L1_CA_CODE_PERIOD)) * (1.0 + 1.0 / (2.0 * CN_lin * GPS_L1_CA_CODE_PERIOD)); | ||||||
|  |             kf_R(0, 0) = sigma2_phase_detector_cycles2; | ||||||
|  |  | ||||||
| 			kf_P_y=kf_H*kf_P_x_pre*kf_H.t()+kf_R; //innovation covariance matrix |             kf_P_y = kf_H * kf_P_x_pre * kf_H.t() + kf_R;        // innovation covariance matrix | ||||||
| 			kf_K=(kf_P_x_pre*kf_H.t())*arma::inv(kf_P_y); //Kalman gain |             kf_K = (kf_P_x_pre * kf_H.t()) * arma::inv(kf_P_y);  // Kalman gain | ||||||
|  |  | ||||||
| 			kf_y(0)=carr_phase_error_rad; //measurement vector |             kf_y(0) = carr_phase_error_rad;  // measurement vector | ||||||
| 			//kf_x=kf_x_pre+kf_K*(kf_y-kf_y_pre); //updated state estimation |             kf_x = kf_x_pre + kf_K * kf_y;   // updated state estimation | ||||||
| 			kf_x=kf_x_pre+kf_K*kf_y; //updated state estimation |  | ||||||
|  |  | ||||||
| 			kf_x(0)=fmod(arma::as_scalar(kf_x(0)), GPS_TWO_PI); |             kf_P_x = (arma::eye(2, 2) - kf_K * kf_H) * kf_P_x_pre;  // update state estimation error covariance matrix | ||||||
| 			//kf_P_x=kf_P_x_pre-kf_K*kf_H*kf_P_x_pre; //update state estimation error covariance matrix |  | ||||||
| 			kf_P_x=(arma::eye(2,2)-kf_K*kf_H)*kf_P_x_pre; //update state estimation error covariance matrix |  | ||||||
|  |  | ||||||
| 			d_rem_carr_phase_rad=kf_x(0); //set a new carrier Phase estimation to the NCO |             d_rem_carr_phase_rad = kf_x(0);  // set a new carrier Phase estimation to the NCO | ||||||
| 			d_carrier_doppler_hz=kf_x(1); //set a new carrier Doppler estimation to the NCO |             d_carrier_doppler_hz = kf_x(1);  // set a new carrier Doppler estimation to the NCO | ||||||
|  |  | ||||||
| 			carr_phase_error_filt_rad=d_rem_carr_phase_rad; |             carr_phase_error_filt_rad = d_rem_carr_phase_rad; | ||||||
|  |  | ||||||
|             // ################## DLL ########################################################## |             // ################## DLL ########################################################## | ||||||
| 			// New code Doppler frequency estimation based on carrier frequency estimation |             // New code Doppler frequency estimation based on carrier frequency estimation | ||||||
|             d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ); |             d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ); | ||||||
|             // DLL discriminator |             // DLL discriminator | ||||||
|             code_error_chips = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); // [chips/Ti] //early and late |             code_error_chips = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]);  // [chips/Ti] early and late | ||||||
|             // Code discriminator filter |             // Code discriminator filter | ||||||
|             code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); // [chips/second] |             code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips);  // [chips/second] | ||||||
|             double T_chip_seconds = 1.0 / static_cast<double>(d_code_freq_chips); |             double T_chip_seconds = 1.0 / static_cast<double>(d_code_freq_chips); | ||||||
|             double T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; |             double T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; | ||||||
|             double code_error_filt_secs = (T_prn_seconds * code_error_filt_chips*T_chip_seconds); //[seconds] |             double code_error_filt_secs = (T_prn_seconds * code_error_filt_chips * T_chip_seconds);  // [seconds] | ||||||
|             //double code_error_filt_secs = (GPS_L1_CA_CODE_PERIOD * code_error_filt_chips) / GPS_L1_CA_CODE_RATE_HZ; // [seconds] |  | ||||||
|  |  | ||||||
|             // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT ####################### |             // ################## CARRIER AND CODE NCO BUFFER ALIGNMENT ####################### | ||||||
|             // keep alignment parameters for the next input buffer |             // keep alignment parameters for the next input buffer | ||||||
|             // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation |             // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation | ||||||
|             //double T_chip_seconds =  1.0 / static_cast<double>(d_code_freq_chips); |  | ||||||
|             //double T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; |  | ||||||
|             double T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in); |             double T_prn_samples = T_prn_seconds * static_cast<double>(d_fs_in); | ||||||
|             double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast<double>(d_fs_in); |             double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast<double>(d_fs_in); | ||||||
|             d_current_prn_length_samples = round(K_blk_samples); // round to a discrete number of samples |             d_current_prn_length_samples = round(K_blk_samples);  // round to a discrete number of samples | ||||||
|  |  | ||||||
|             //################### NCO COMMANDS ################################################# |             //################### NCO COMMANDS ################################################# | ||||||
|             // carrier phase step (NCO phase increment per sample) [rads/sample] |             // carrier phase step (NCO phase increment per sample) [rads/sample] | ||||||
|             d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in); |             d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in); | ||||||
|             // carrier phase accumulator |             // carrier phase accumulator | ||||||
|             d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * d_current_prn_length_samples; |             d_acc_carrier_phase_rad = -kf_x(0); | ||||||
|  |  | ||||||
|             //################### DLL COMMANDS ################################################# |             //################### DLL COMMANDS ################################################# | ||||||
|             // code phase step (Code resampler phase increment per sample) [chips/sample] |             // 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); |             d_code_phase_step_chips = d_code_freq_chips / static_cast<double>(d_fs_in); | ||||||
|             // remnant code phase [chips] |             // remnant code phase [chips] | ||||||
|             d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; // rounding error < 1 sample |             d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples;  // rounding error < 1 sample | ||||||
|             d_rem_code_phase_chips = d_code_freq_chips * (d_rem_code_phase_samples / static_cast<double>(d_fs_in)); |             d_rem_code_phase_chips = d_code_freq_chips * (d_rem_code_phase_samples / static_cast<double>(d_fs_in)); | ||||||
|  |  | ||||||
|             // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### |             // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### | ||||||
|             if (d_cn0_estimation_counter < CN0_ESTIMATION_SAMPLES) |             if (d_cn0_estimation_counter < FLAGS_cn0_samples) | ||||||
|                 { |                 { | ||||||
|                     // fill buffer with prompt correlator output values |                     // fill buffer with prompt correlator output values | ||||||
|                     d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1]; //prompt |                     d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1];  //prompt | ||||||
|                     d_cn0_estimation_counter++; |                     d_cn0_estimation_counter++; | ||||||
|                 } |                 } | ||||||
|             else |             else | ||||||
|                 { |                 { | ||||||
|                     d_cn0_estimation_counter = 0; |                     d_cn0_estimation_counter = 0; | ||||||
|                     // Code lock indicator |                     // 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); |                     d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, FLAGS_cn0_samples, d_fs_in, GPS_L1_CA_CODE_LENGTH_CHIPS); | ||||||
|                     //std::cout<<"Channel "<<d_channel<<" CN0: " <<d_CN0_SNV_dB_Hz<<"[dB_Hz]\n"; |  | ||||||
|                     // Carrier lock indicator |                     // Carrier lock indicator | ||||||
|                     d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, CN0_ESTIMATION_SAMPLES); |                     d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, FLAGS_cn0_samples); | ||||||
|                     // Loss of lock detection |                     // Loss of lock detection | ||||||
|                     if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < MINIMUM_VALID_CN0) |                     if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min) | ||||||
|                         { |                         { | ||||||
|                             d_carrier_lock_fail_counter++; |                             d_carrier_lock_fail_counter++; | ||||||
|                         } |                         } | ||||||
| @@ -484,13 +471,13 @@ int Gps_L1_Ca_Kf_Tracking_cc::general_work (int noutput_items __attribute__((unu | |||||||
|                         { |                         { | ||||||
|                             if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; |                             if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; | ||||||
|                         } |                         } | ||||||
|                     if (d_carrier_lock_fail_counter > MAXIMUM_LOCK_FAIL_COUNTER) |                     if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail) | ||||||
|                         { |                         { | ||||||
|                             std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; |                             std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; | ||||||
|                             LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; |                             LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; | ||||||
|                             this->message_port_pub(pmt::mp("events"), pmt::from_long(3)); // 3 -> loss of lock |                             this->message_port_pub(pmt::mp("events"), pmt::from_long(3));  // 3 -> loss of lock | ||||||
|                             d_carrier_lock_fail_counter = 0; |                             d_carrier_lock_fail_counter = 0; | ||||||
|                             d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine |                             d_enable_tracking = false;  // TODO: check if disabling tracking is consistent with the channel state machine | ||||||
|                         } |                         } | ||||||
|                 } |                 } | ||||||
|             // ########### Output the tracking data to navigation and PVT ########## |             // ########### Output the tracking data to navigation and PVT ########## | ||||||
| @@ -508,19 +495,19 @@ int Gps_L1_Ca_Kf_Tracking_cc::general_work (int noutput_items __attribute__((unu | |||||||
|         { |         { | ||||||
|             for (int n = 0; n < d_n_correlator_taps; n++) |             for (int n = 0; n < d_n_correlator_taps; n++) | ||||||
|                 { |                 { | ||||||
|                     d_correlator_outs[n] = gr_complex(0,0); |                     d_correlator_outs[n] = gr_complex(0, 0); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|             current_synchro_data.Tracking_sample_counter =d_sample_counter + d_current_prn_length_samples; |             current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; | ||||||
|             current_synchro_data.System = {'G'}; |             current_synchro_data.System = {'G'}; | ||||||
|             current_synchro_data.correlation_length_ms = 1; |             current_synchro_data.correlation_length_ms = 1; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     //assign the GNURadio block output data |     // assign the GNU Radio block output data | ||||||
|     current_synchro_data.fs = d_fs_in; |     current_synchro_data.fs = d_fs_in; | ||||||
|     *out[0] = current_synchro_data; |     *out[0] = current_synchro_data; | ||||||
|  |  | ||||||
|     if(d_dump) |     if (d_dump) | ||||||
|         { |         { | ||||||
|             // MULTIPLEXED FILE RECORDING - Record results to file |             // MULTIPLEXED FILE RECORDING - Record results to file | ||||||
|             float prompt_I; |             float prompt_I; | ||||||
| @@ -534,58 +521,264 @@ int Gps_L1_Ca_Kf_Tracking_cc::general_work (int noutput_items __attribute__((unu | |||||||
|             tmp_P = std::abs<float>(d_correlator_outs[1]); |             tmp_P = std::abs<float>(d_correlator_outs[1]); | ||||||
|             tmp_L = std::abs<float>(d_correlator_outs[2]); |             tmp_L = std::abs<float>(d_correlator_outs[2]); | ||||||
|             try |             try | ||||||
|             { |                 { | ||||||
|                     // EPR |                     // EPR | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&tmp_E), sizeof(float)); |                     d_dump_file.write(reinterpret_cast<char *>(&tmp_E), sizeof(float)); | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&tmp_P), sizeof(float)); |                     d_dump_file.write(reinterpret_cast<char *>(&tmp_P), sizeof(float)); | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&tmp_L), sizeof(float)); |                     d_dump_file.write(reinterpret_cast<char *>(&tmp_L), sizeof(float)); | ||||||
|                     // PROMPT I and Q (to analyze navigation symbols) |                     // PROMPT I and Q (to analyze navigation symbols) | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&prompt_I), sizeof(float)); |                     d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float)); | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&prompt_Q), sizeof(float)); |                     d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float)); | ||||||
|                     // PRN start sample stamp |                     // PRN start sample stamp | ||||||
|                     tmp_long = d_sample_counter + d_current_prn_length_samples; |                     tmp_long = d_sample_counter + d_current_prn_length_samples; | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&tmp_long), sizeof(unsigned long int)); |                     d_dump_file.write(reinterpret_cast<char *>(&tmp_long), sizeof(unsigned long int)); | ||||||
|                     // accumulated carrier phase |                     // accumulated carrier phase | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&d_acc_carrier_phase_rad), sizeof(double)); |                     d_dump_file.write(reinterpret_cast<char *>(&d_acc_carrier_phase_rad), sizeof(double)); | ||||||
|  |  | ||||||
|                     // carrier and code frequency |                     // carrier and code frequency | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&d_carrier_doppler_hz), sizeof(double)); |                     d_dump_file.write(reinterpret_cast<char *>(&d_carrier_doppler_hz), sizeof(double)); | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&d_code_freq_chips), sizeof(double)); |                     d_dump_file.write(reinterpret_cast<char *>(&d_code_freq_chips), sizeof(double)); | ||||||
|  |  | ||||||
|                     // PLL commands |                     // PLL commands | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&carr_phase_error_rad), sizeof(double)); |                     d_dump_file.write(reinterpret_cast<char *>(&carr_phase_error_rad), sizeof(double)); | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&carr_phase_error_filt_rad), sizeof(double)); |                     d_dump_file.write(reinterpret_cast<char *>(&carr_phase_error_filt_rad), sizeof(double)); | ||||||
|  |  | ||||||
|                     // DLL commands |                     // DLL commands | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&code_error_chips), sizeof(double)); |                     d_dump_file.write(reinterpret_cast<char *>(&code_error_chips), sizeof(double)); | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&code_error_filt_chips), sizeof(double)); |                     d_dump_file.write(reinterpret_cast<char *>(&code_error_filt_chips), sizeof(double)); | ||||||
|  |  | ||||||
|                     // CN0 and carrier lock test |                     // 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_CN0_SNV_dB_Hz), sizeof(double)); | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&d_carrier_lock_test), sizeof(double)); |                     d_dump_file.write(reinterpret_cast<char *>(&d_carrier_lock_test), sizeof(double)); | ||||||
|  |  | ||||||
|                     // AUX vars (for debug purposes) |                     // AUX vars (for debug purposes) | ||||||
|                     tmp_double = d_rem_code_phase_samples; |                     tmp_double = d_rem_code_phase_samples; | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&tmp_double), sizeof(double)); |                     d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double)); | ||||||
|                     tmp_double = static_cast<double>(d_sample_counter); |                     tmp_double = static_cast<double>(d_sample_counter); | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&tmp_double), sizeof(double)); |                     d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double)); | ||||||
|  |  | ||||||
|                     // PRN |                     // PRN | ||||||
|                     unsigned int prn_ = d_acquisition_gnss_synchro->PRN; |                     unsigned int prn_ = d_acquisition_gnss_synchro->PRN; | ||||||
|                     d_dump_file.write(reinterpret_cast<char*>(&prn_), sizeof(unsigned int)); |                     d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int)); | ||||||
|             } |                 } | ||||||
|             catch (const std::ifstream::failure &e) |             catch (const std::ifstream::failure &e) | ||||||
|             { |                 { | ||||||
|                     LOG(WARNING) << "Exception writing trk dump file " << e.what(); |                     LOG(WARNING) << "Exception writing trk dump file " << e.what(); | ||||||
|             } |                 } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     consume_each(d_current_prn_length_samples); // this is necessary in gr::block derivates |     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 |     d_sample_counter += d_current_prn_length_samples;  // count for the processed samples | ||||||
|     return 1; // output tracking result ALWAYS even in the case of d_enable_tracking==false |     return 1;                                          // output tracking result ALWAYS even in the case of d_enable_tracking==false | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int Gps_L1_Ca_Kf_Tracking_cc::save_matfile() | ||||||
|  | { | ||||||
|  |     // READ DUMP FILE | ||||||
|  |     std::ifstream::pos_type size; | ||||||
|  |     int number_of_double_vars = 11; | ||||||
|  |     int number_of_float_vars = 5; | ||||||
|  |     int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + | ||||||
|  |                            sizeof(float) * number_of_float_vars + sizeof(unsigned int); | ||||||
|  |     std::ifstream dump_file; | ||||||
|  |     dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); | ||||||
|  |     try | ||||||
|  |         { | ||||||
|  |             dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); | ||||||
|  |         } | ||||||
|  |     catch (const std::ifstream::failure &e) | ||||||
|  |         { | ||||||
|  |             std::cerr << "Problem opening dump file:" << e.what() << std::endl; | ||||||
|  |             return 1; | ||||||
|  |         } | ||||||
|  |     // count number of epochs and rewind | ||||||
|  |     long int num_epoch = 0; | ||||||
|  |     if (dump_file.is_open()) | ||||||
|  |         { | ||||||
|  |             size = dump_file.tellg(); | ||||||
|  |             num_epoch = static_cast<long int>(size) / static_cast<long int>(epoch_size_bytes); | ||||||
|  |             dump_file.seekg(0, std::ios::beg); | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             return 1; | ||||||
|  |         } | ||||||
|  |     float *abs_E = new float[num_epoch]; | ||||||
|  |     float *abs_P = new float[num_epoch]; | ||||||
|  |     float *abs_L = new float[num_epoch]; | ||||||
|  |     float *Prompt_I = new float[num_epoch]; | ||||||
|  |     float *Prompt_Q = new float[num_epoch]; | ||||||
|  |     unsigned long int *PRN_start_sample_count = new unsigned long int[num_epoch]; | ||||||
|  |     double *acc_carrier_phase_rad = new double[num_epoch]; | ||||||
|  |     double *carrier_doppler_hz = new double[num_epoch]; | ||||||
|  |     double *code_freq_chips = new double[num_epoch]; | ||||||
|  |     double *carr_error_hz = new double[num_epoch]; | ||||||
|  |     double *carr_error_filt_hz = new double[num_epoch]; | ||||||
|  |     double *code_error_chips = new double[num_epoch]; | ||||||
|  |     double *code_error_filt_chips = new double[num_epoch]; | ||||||
|  |     double *CN0_SNV_dB_Hz = new double[num_epoch]; | ||||||
|  |     double *carrier_lock_test = new double[num_epoch]; | ||||||
|  |     double *aux1 = new double[num_epoch]; | ||||||
|  |     double *aux2 = new double[num_epoch]; | ||||||
|  |     unsigned int *PRN = new unsigned int[num_epoch]; | ||||||
|  |  | ||||||
|  |     try | ||||||
|  |         { | ||||||
|  |             if (dump_file.is_open()) | ||||||
|  |                 { | ||||||
|  |                     for (long int i = 0; i < num_epoch; i++) | ||||||
|  |                         { | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&abs_E[i]), sizeof(float)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&abs_P[i]), sizeof(float)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&abs_L[i]), sizeof(float)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&Prompt_I[i]), sizeof(float)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&Prompt_Q[i]), sizeof(float)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&PRN_start_sample_count[i]), sizeof(unsigned long int)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&acc_carrier_phase_rad[i]), sizeof(double)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&carrier_doppler_hz[i]), sizeof(double)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&code_freq_chips[i]), sizeof(double)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&carr_error_hz[i]), sizeof(double)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&carr_error_filt_hz[i]), sizeof(double)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&code_error_chips[i]), sizeof(double)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&code_error_filt_chips[i]), sizeof(double)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&CN0_SNV_dB_Hz[i]), sizeof(double)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&carrier_lock_test[i]), sizeof(double)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&aux1[i]), sizeof(double)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&aux2[i]), sizeof(double)); | ||||||
|  |                             dump_file.read(reinterpret_cast<char *>(&PRN[i]), sizeof(unsigned int)); | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |             dump_file.close(); | ||||||
|  |         } | ||||||
|  |     catch (const std::ifstream::failure &e) | ||||||
|  |         { | ||||||
|  |             std::cerr << "Problem reading dump file:" << e.what() << std::endl; | ||||||
|  |             delete[] abs_E; | ||||||
|  |             delete[] abs_P; | ||||||
|  |             delete[] abs_L; | ||||||
|  |             delete[] Prompt_I; | ||||||
|  |             delete[] Prompt_Q; | ||||||
|  |             delete[] PRN_start_sample_count; | ||||||
|  |             delete[] acc_carrier_phase_rad; | ||||||
|  |             delete[] carrier_doppler_hz; | ||||||
|  |             delete[] code_freq_chips; | ||||||
|  |             delete[] carr_error_hz; | ||||||
|  |             delete[] carr_error_filt_hz; | ||||||
|  |             delete[] code_error_chips; | ||||||
|  |             delete[] code_error_filt_chips; | ||||||
|  |             delete[] CN0_SNV_dB_Hz; | ||||||
|  |             delete[] carrier_lock_test; | ||||||
|  |             delete[] aux1; | ||||||
|  |             delete[] aux2; | ||||||
|  |             delete[] PRN; | ||||||
|  |             return 1; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     // WRITE MAT FILE | ||||||
|  |     mat_t *matfp; | ||||||
|  |     matvar_t *matvar; | ||||||
|  |     std::string filename = d_dump_filename; | ||||||
|  |     filename.erase(filename.length() - 4, 4); | ||||||
|  |     filename.append(".mat"); | ||||||
|  |     matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); | ||||||
|  |     if (reinterpret_cast<long *>(matfp) != NULL) | ||||||
|  |         { | ||||||
|  |             size_t dims[2] = {1, static_cast<size_t>(num_epoch)}; | ||||||
|  |             matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, acc_carrier_phase_rad, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_doppler_hz, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("code_freq_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_freq_chips, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("carr_error_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_hz, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carr_error_filt_hz, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("code_error_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_chips, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, code_error_filt_chips, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, CN0_SNV_dB_Hz, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("carrier_lock_test", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, carrier_lock_test, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("aux1", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux1, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |  | ||||||
|  |             matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); | ||||||
|  |             Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB);  // or MAT_COMPRESSION_NONE | ||||||
|  |             Mat_VarFree(matvar); | ||||||
|  |         } | ||||||
|  |     Mat_Close(matfp); | ||||||
|  |     delete[] abs_E; | ||||||
|  |     delete[] abs_P; | ||||||
|  |     delete[] abs_L; | ||||||
|  |     delete[] Prompt_I; | ||||||
|  |     delete[] Prompt_Q; | ||||||
|  |     delete[] PRN_start_sample_count; | ||||||
|  |     delete[] acc_carrier_phase_rad; | ||||||
|  |     delete[] carrier_doppler_hz; | ||||||
|  |     delete[] code_freq_chips; | ||||||
|  |     delete[] carr_error_hz; | ||||||
|  |     delete[] carr_error_filt_hz; | ||||||
|  |     delete[] code_error_chips; | ||||||
|  |     delete[] code_error_filt_chips; | ||||||
|  |     delete[] CN0_SNV_dB_Hz; | ||||||
|  |     delete[] carrier_lock_test; | ||||||
|  |     delete[] aux1; | ||||||
|  |     delete[] aux2; | ||||||
|  |     delete[] PRN; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void Gps_L1_Ca_Kf_Tracking_cc::set_channel(unsigned int channel) | void Gps_L1_Ca_Kf_Tracking_cc::set_channel(unsigned int channel) | ||||||
| { | { | ||||||
| @@ -597,23 +790,23 @@ void Gps_L1_Ca_Kf_Tracking_cc::set_channel(unsigned int channel) | |||||||
|             if (d_dump_file.is_open() == false) |             if (d_dump_file.is_open() == false) | ||||||
|                 { |                 { | ||||||
|                     try |                     try | ||||||
|                     { |                         { | ||||||
|                             d_dump_filename.append(boost::lexical_cast<std::string>(d_channel)); |                             d_dump_filename.append(boost::lexical_cast<std::string>(d_channel)); | ||||||
|                             d_dump_filename.append(".dat"); |                             d_dump_filename.append(".dat"); | ||||||
|                             d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit); |                             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); |                             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(); |                             LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); | ||||||
|                     } |                         } | ||||||
|                     catch (const std::ifstream::failure &e) |                     catch (const std::ifstream::failure &e) | ||||||
|                     { |                         { | ||||||
|                             LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); |                             LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); | ||||||
|                     } |                         } | ||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void Gps_L1_Ca_Kf_Tracking_cc::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) | void Gps_L1_Ca_Kf_Tracking_cc::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) | ||||||
| { | { | ||||||
|     d_acquisition_gnss_synchro = p_gnss_synchro; |     d_acquisition_gnss_synchro = p_gnss_synchro; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -51,24 +51,21 @@ | |||||||
| class Gps_L1_Ca_Kf_Tracking_cc; | class Gps_L1_Ca_Kf_Tracking_cc; | ||||||
|  |  | ||||||
| typedef boost::shared_ptr<Gps_L1_Ca_Kf_Tracking_cc> | typedef boost::shared_ptr<Gps_L1_Ca_Kf_Tracking_cc> | ||||||
|         gps_l1_ca_kf_tracking_cc_sptr; |     gps_l1_ca_kf_tracking_cc_sptr; | ||||||
|  |  | ||||||
| gps_l1_ca_kf_tracking_cc_sptr | gps_l1_ca_kf_tracking_cc_sptr | ||||||
| gps_l1_ca_kf_make_tracking_cc(long if_freq, | gps_l1_ca_kf_make_tracking_cc(long if_freq, | ||||||
|                                    long fs_in, unsigned |     long fs_in, unsigned int vector_length, | ||||||
|                                    int vector_length, |     bool dump, | ||||||
|                                    bool dump, |     std::string dump_filename, | ||||||
|                                    std::string dump_filename, |     float pll_bw_hz, | ||||||
|                                    float pll_bw_hz, |     float early_late_space_chips); | ||||||
|                                    float dll_bw_hz, |  | ||||||
|                                    float early_late_space_chips); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /*! | /*! | ||||||
|  * \brief This class implements a DLL + PLL tracking loop block |  * \brief This class implements a DLL + PLL tracking loop block | ||||||
|  */ |  */ | ||||||
| class Gps_L1_Ca_Kf_Tracking_cc: public gr::block | class Gps_L1_Ca_Kf_Tracking_cc : public gr::block | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     ~Gps_L1_Ca_Kf_Tracking_cc(); |     ~Gps_L1_Ca_Kf_Tracking_cc(); | ||||||
| @@ -77,30 +74,26 @@ public: | |||||||
|     void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); |     void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); | ||||||
|     void start_tracking(); |     void start_tracking(); | ||||||
|  |  | ||||||
|     int general_work (int noutput_items, gr_vector_int &ninput_items, |     int general_work(int noutput_items, gr_vector_int& ninput_items, | ||||||
|             gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); |         gr_vector_const_void_star& input_items, gr_vector_void_star& output_items); | ||||||
|  |  | ||||||
|     void forecast (int noutput_items, gr_vector_int &ninput_items_required); |     void forecast(int noutput_items, gr_vector_int& ninput_items_required); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     friend gps_l1_ca_kf_tracking_cc_sptr |     friend gps_l1_ca_kf_tracking_cc_sptr | ||||||
|     gps_l1_ca_kf_make_tracking_cc(long if_freq, |     gps_l1_ca_kf_make_tracking_cc(long if_freq, | ||||||
|             long fs_in, unsigned |         long fs_in, unsigned int vector_length, | ||||||
|             int vector_length, |         bool dump, | ||||||
|             bool dump, |         std::string dump_filename, | ||||||
|             std::string dump_filename, |         float dll_bw_hz, | ||||||
|             float pll_bw_hz, |         float early_late_space_chips); | ||||||
|             float dll_bw_hz, |  | ||||||
|             float early_late_space_chips); |  | ||||||
|  |  | ||||||
|     Gps_L1_Ca_Kf_Tracking_cc(long if_freq, |     Gps_L1_Ca_Kf_Tracking_cc(long if_freq, | ||||||
|             long fs_in, unsigned |         long fs_in, unsigned int vector_length, | ||||||
|             int vector_length, |         bool dump, | ||||||
|             bool dump, |         std::string dump_filename, | ||||||
|             std::string dump_filename, |         float dll_bw_hz, | ||||||
|             float pll_bw_hz, |         float early_late_space_chips); | ||||||
|             float dll_bw_hz, |  | ||||||
|             float early_late_space_chips); |  | ||||||
|  |  | ||||||
|     // tracking configuration vars |     // tracking configuration vars | ||||||
|     unsigned int d_vector_length; |     unsigned int d_vector_length; | ||||||
| @@ -120,24 +113,24 @@ private: | |||||||
|     double d_rem_carr_phase_rad; |     double d_rem_carr_phase_rad; | ||||||
|  |  | ||||||
|     // Kalman filter variables |     // Kalman filter variables | ||||||
|     arma::mat kf_P_x_ini; //initial state error covariance matrix |     arma::mat kf_P_x_ini;   //initial state error covariance matrix | ||||||
|     arma::mat kf_P_x; //state error covariance matrix |     arma::mat kf_P_x;       //state error covariance matrix | ||||||
|     arma::mat kf_P_x_pre; //Predicted state error covariance matrix |     arma::mat kf_P_x_pre;   //Predicted state error covariance matrix | ||||||
|     arma::mat kf_P_y; //innovation covariance matrix |     arma::mat kf_P_y;       //innovation covariance matrix | ||||||
|     arma::mat kf_F; //state transition matrix |     arma::mat kf_F;         //state transition matrix | ||||||
|     arma::mat kf_H; //system matrix |     arma::mat kf_H;         //system matrix | ||||||
|     arma::mat kf_R; //measurement error covariance matrix |     arma::mat kf_R;         //measurement error covariance matrix | ||||||
|     arma::mat kf_Q; //system error covariance matrix |     arma::mat kf_Q;         //system error covariance matrix | ||||||
|     arma::colvec kf_x; //state vector |     arma::colvec kf_x;      //state vector | ||||||
|     arma::colvec kf_x_pre; //predicted state vector |     arma::colvec kf_x_pre;  //predicted state vector | ||||||
|     arma::colvec kf_y; //measurement vector |     arma::colvec kf_y;      //measurement vector | ||||||
|     arma::colvec kf_y_pre; //measurement vector |     arma::colvec kf_y_pre;  //measurement vector | ||||||
|     arma::mat kf_K; //Kalman gain matrix |     arma::mat kf_K;         //Kalman gain matrix | ||||||
|  |  | ||||||
|  |  | ||||||
|     // PLL and DLL filter library |     // PLL and DLL filter library | ||||||
|     Tracking_2nd_DLL_filter d_code_loop_filter; |     Tracking_2nd_DLL_filter d_code_loop_filter; | ||||||
|     Tracking_2nd_PLL_filter d_carrier_loop_filter; |     //Tracking_2nd_PLL_filter d_carrier_loop_filter; | ||||||
|  |  | ||||||
|     // acquisition |     // acquisition | ||||||
|     double d_acq_code_phase_samples; |     double d_acq_code_phase_samples; | ||||||
| @@ -182,6 +175,8 @@ private: | |||||||
|  |  | ||||||
|     std::map<std::string, std::string> systemName; |     std::map<std::string, std::string> systemName; | ||||||
|     std::string sys; |     std::string sys; | ||||||
|  |  | ||||||
|  |     int save_matfile(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif //GNSS_SDR_GPS_L1_CA_KF_TRACKING_CC_H | #endif  //GNSS_SDR_GPS_L1_CA_KF_TRACKING_CC_H | ||||||
|   | |||||||
| @@ -147,6 +147,7 @@ DECLARE_string(log_dir); | |||||||
| #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc" | #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc" | ||||||
| #if MODERN_ARMADILLO | #if MODERN_ARMADILLO | ||||||
| #include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc" | #include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc" | ||||||
|  | #include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_kf_tracking_test.cc" | ||||||
| #include "unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc" | #include "unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc" | ||||||
| #include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc" | #include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc" | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -51,6 +51,7 @@ | |||||||
| #include "tracking_dump_reader.h" | #include "tracking_dump_reader.h" | ||||||
| #include "signal_generator_flags.h" | #include "signal_generator_flags.h" | ||||||
| #include "gnuplot_i.h" | #include "gnuplot_i.h" | ||||||
|  | #include "gnss_sdr_flags.h" | ||||||
| #include "test_flags.h" | #include "test_flags.h" | ||||||
|  |  | ||||||
| DEFINE_bool(plot_gps_l1_tracking_test, false, "Plots results of GpsL1CADllPllTrackingTest with gnuplot"); | DEFINE_bool(plot_gps_l1_tracking_test, false, "Plots results of GpsL1CADllPllTrackingTest with gnuplot"); | ||||||
| @@ -222,8 +223,22 @@ void GpsL1CADllPllTrackingTest::configure_receiver() | |||||||
|     // Set Tracking |     // Set Tracking | ||||||
|     config->set_property("Tracking_1C.implementation", implementation); |     config->set_property("Tracking_1C.implementation", implementation); | ||||||
|     config->set_property("Tracking_1C.item_type", "gr_complex"); |     config->set_property("Tracking_1C.item_type", "gr_complex"); | ||||||
|     config->set_property("Tracking_1C.pll_bw_hz", "20.0"); |     if (FLAGS_pll_bw_hz != 0.0) | ||||||
|     config->set_property("Tracking_1C.dll_bw_hz", "2.0"); |         { | ||||||
|  |             config->set_property("Tracking_1C.pll_bw_hz", std::to_string(FLAGS_pll_bw_hz)); | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             config->set_property("Tracking_1C.pll_bw_hz", "20.0"); | ||||||
|  |         } | ||||||
|  |     if (FLAGS_dll_bw_hz != 0.0) | ||||||
|  |         { | ||||||
|  |             config->set_property("Tracking_1C.dll_bw_hz", std::to_string(FLAGS_dll_bw_hz)); | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             config->set_property("Tracking_1C.dll_bw_hz", "2.0"); | ||||||
|  |         } | ||||||
|     config->set_property("Tracking_1C.early_late_space_chips", "0.5"); |     config->set_property("Tracking_1C.early_late_space_chips", "0.5"); | ||||||
|     config->set_property("Tracking_1C.extend_correlation_ms", "1"); |     config->set_property("Tracking_1C.extend_correlation_ms", "1"); | ||||||
|     config->set_property("Tracking_1C.dump", "true"); |     config->set_property("Tracking_1C.dump", "true"); | ||||||
| @@ -501,7 +516,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) | |||||||
|     check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles); |     check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles); | ||||||
|  |  | ||||||
|     std::chrono::duration<double> elapsed_seconds = end - start; |     std::chrono::duration<double> elapsed_seconds = end - start; | ||||||
|     std::cout << "Signal tracking completed in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; |     std::cout << "Signal tracking completed in " << elapsed_seconds.count() << " seconds." << std::endl; | ||||||
|  |  | ||||||
|     if (FLAGS_plot_gps_l1_tracking_test == true) |     if (FLAGS_plot_gps_l1_tracking_test == true) | ||||||
|         { |         { | ||||||
|   | |||||||
| @@ -0,0 +1,569 @@ | |||||||
|  | /*! | ||||||
|  |  * \file gps_l1_ca_kf_tracking_test.cc | ||||||
|  |  * \brief  This class implements a tracking test for GPS_L1_CA_KF_Tracking | ||||||
|  |  *  implementation based on some input parameters. | ||||||
|  |  * \author Carles Fernandez, 2018 | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2012-2017  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <chrono> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <vector> | ||||||
|  | #include <armadillo> | ||||||
|  | #include <boost/filesystem.hpp> | ||||||
|  | #include <gnuradio/top_block.h> | ||||||
|  | #include <gnuradio/blocks/file_source.h> | ||||||
|  | #include <gnuradio/analog/sig_source_waveform.h> | ||||||
|  | #include <gnuradio/analog/sig_source_c.h> | ||||||
|  | #include <gnuradio/blocks/interleaved_char_to_complex.h> | ||||||
|  | #include <gnuradio/blocks/null_sink.h> | ||||||
|  | #include <gnuradio/blocks/skiphead.h> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  | #include "GPS_L1_CA.h" | ||||||
|  | #include "gnss_block_factory.h" | ||||||
|  | #include "tracking_interface.h" | ||||||
|  | #include "in_memory_configuration.h" | ||||||
|  | #include "tracking_true_obs_reader.h" | ||||||
|  | #include "tracking_dump_reader.h" | ||||||
|  | #include "signal_generator_flags.h" | ||||||
|  | #include "gnuplot_i.h" | ||||||
|  | #include "test_flags.h" | ||||||
|  | #include "gnss_sdr_flags.h" | ||||||
|  |  | ||||||
|  | DEFINE_bool(plot_gps_l1_kf_tracking_test, false, "Plots results of GpsL1CAKfTrackingTest with gnuplot"); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // ######## GNURADIO BLOCK MESSAGE RECEVER ######### | ||||||
|  | class GpsL1CAKfTrackingTest_msg_rx; | ||||||
|  |  | ||||||
|  | typedef boost::shared_ptr<GpsL1CAKfTrackingTest_msg_rx> GpsL1CAKfTrackingTest_msg_rx_sptr; | ||||||
|  |  | ||||||
|  | GpsL1CAKfTrackingTest_msg_rx_sptr GpsL1CAKfTrackingTest_msg_rx_make(); | ||||||
|  |  | ||||||
|  | class GpsL1CAKfTrackingTest_msg_rx : public gr::block | ||||||
|  | { | ||||||
|  | private: | ||||||
|  |     friend GpsL1CAKfTrackingTest_msg_rx_sptr GpsL1CAKfTrackingTest_msg_rx_make(); | ||||||
|  |     void msg_handler_events(pmt::pmt_t msg); | ||||||
|  |     GpsL1CAKfTrackingTest_msg_rx(); | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     int rx_message; | ||||||
|  |     ~GpsL1CAKfTrackingTest_msg_rx();  //!< Default destructor | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | GpsL1CAKfTrackingTest_msg_rx_sptr GpsL1CAKfTrackingTest_msg_rx_make() | ||||||
|  | { | ||||||
|  |     return GpsL1CAKfTrackingTest_msg_rx_sptr(new GpsL1CAKfTrackingTest_msg_rx()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void GpsL1CAKfTrackingTest_msg_rx::msg_handler_events(pmt::pmt_t msg) | ||||||
|  | { | ||||||
|  |     try | ||||||
|  |         { | ||||||
|  |             long int message = pmt::to_long(msg); | ||||||
|  |             rx_message = message; | ||||||
|  |         } | ||||||
|  |     catch (boost::bad_any_cast& e) | ||||||
|  |         { | ||||||
|  |             LOG(WARNING) << "msg_handler_telemetry Bad any cast!"; | ||||||
|  |             rx_message = 0; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | GpsL1CAKfTrackingTest_msg_rx::GpsL1CAKfTrackingTest_msg_rx() : gr::block("GpsL1CAKfTrackingTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) | ||||||
|  | { | ||||||
|  |     this->message_port_register_in(pmt::mp("events")); | ||||||
|  |     this->set_msg_handler(pmt::mp("events"), boost::bind(&GpsL1CAKfTrackingTest_msg_rx::msg_handler_events, this, _1)); | ||||||
|  |     rx_message = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | GpsL1CAKfTrackingTest_msg_rx::~GpsL1CAKfTrackingTest_msg_rx() | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // ########################################################### | ||||||
|  |  | ||||||
|  | class GpsL1CAKfTrackingTest : public ::testing::Test | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     std::string generator_binary; | ||||||
|  |     std::string p1; | ||||||
|  |     std::string p2; | ||||||
|  |     std::string p3; | ||||||
|  |     std::string p4; | ||||||
|  |     std::string p5; | ||||||
|  |  | ||||||
|  |     std::string implementation = "GPS_L1_CA_KF_Tracking";  // "GPS_L1_CA_KF_Tracking"; | ||||||
|  |  | ||||||
|  |     const int baseband_sampling_freq = FLAGS_fs_gen_sps; | ||||||
|  |  | ||||||
|  |     std::string filename_rinex_obs = FLAGS_filename_rinex_obs; | ||||||
|  |     std::string filename_raw_data = FLAGS_filename_raw_data; | ||||||
|  |  | ||||||
|  |     int configure_generator(); | ||||||
|  |     int generate_signal(); | ||||||
|  |     void check_results_doppler(arma::vec& true_time_s, | ||||||
|  |         arma::vec& true_value, | ||||||
|  |         arma::vec& meas_time_s, | ||||||
|  |         arma::vec& meas_value); | ||||||
|  |     void check_results_acc_carrier_phase(arma::vec& true_time_s, | ||||||
|  |         arma::vec& true_value, | ||||||
|  |         arma::vec& meas_time_s, | ||||||
|  |         arma::vec& meas_value); | ||||||
|  |     void check_results_codephase(arma::vec& true_time_s, | ||||||
|  |         arma::vec& true_value, | ||||||
|  |         arma::vec& meas_time_s, | ||||||
|  |         arma::vec& meas_value); | ||||||
|  |  | ||||||
|  |     GpsL1CAKfTrackingTest() | ||||||
|  |     { | ||||||
|  |         factory = std::make_shared<GNSSBlockFactory>(); | ||||||
|  |         config = std::make_shared<InMemoryConfiguration>(); | ||||||
|  |         item_size = sizeof(gr_complex); | ||||||
|  |         gnss_synchro = Gnss_Synchro(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ~GpsL1CAKfTrackingTest() | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void configure_receiver(); | ||||||
|  |  | ||||||
|  |     gr::top_block_sptr top_block; | ||||||
|  |     std::shared_ptr<GNSSBlockFactory> factory; | ||||||
|  |     std::shared_ptr<InMemoryConfiguration> config; | ||||||
|  |     Gnss_Synchro gnss_synchro; | ||||||
|  |     size_t item_size; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int GpsL1CAKfTrackingTest::configure_generator() | ||||||
|  | { | ||||||
|  |     // Configure signal generator | ||||||
|  |     generator_binary = FLAGS_generator_binary; | ||||||
|  |  | ||||||
|  |     p1 = std::string("-rinex_nav_file=") + FLAGS_rinex_nav_file; | ||||||
|  |     if (FLAGS_dynamic_position.empty()) | ||||||
|  |         { | ||||||
|  |             p2 = std::string("-static_position=") + FLAGS_static_position + std::string(",") + std::to_string(FLAGS_duration * 10); | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             p2 = std::string("-obs_pos_file=") + std::string(FLAGS_dynamic_position); | ||||||
|  |         } | ||||||
|  |     p3 = std::string("-rinex_obs_file=") + FLAGS_filename_rinex_obs;               // RINEX 2.10 observation file output | ||||||
|  |     p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data;                  // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples | ||||||
|  |     p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq);  // Baseband sampling frequency [MSps] | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int GpsL1CAKfTrackingTest::generate_signal() | ||||||
|  | { | ||||||
|  |     int child_status; | ||||||
|  |  | ||||||
|  |     char* const parmList[] = {&generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0], NULL}; | ||||||
|  |  | ||||||
|  |     int pid; | ||||||
|  |     if ((pid = fork()) == -1) | ||||||
|  |         perror("fork err"); | ||||||
|  |     else if (pid == 0) | ||||||
|  |         { | ||||||
|  |             execv(&generator_binary[0], parmList); | ||||||
|  |             std::cout << "Return not expected. Must be an execv err." << std::endl; | ||||||
|  |             std::terminate(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     waitpid(pid, &child_status, 0); | ||||||
|  |  | ||||||
|  |     std::cout << "Signal and Observables RINEX and RAW files created." << std::endl; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void GpsL1CAKfTrackingTest::configure_receiver() | ||||||
|  | { | ||||||
|  |     gnss_synchro.Channel_ID = 0; | ||||||
|  |     gnss_synchro.System = 'G'; | ||||||
|  |     std::string signal = "1C"; | ||||||
|  |     signal.copy(gnss_synchro.Signal, 2, 0); | ||||||
|  |     gnss_synchro.PRN = FLAGS_test_satellite_PRN; | ||||||
|  |  | ||||||
|  |     config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); | ||||||
|  |     // Set Tracking | ||||||
|  |     config->set_property("Tracking_1C.implementation", implementation); | ||||||
|  |     config->set_property("Tracking_1C.item_type", "gr_complex"); | ||||||
|  |     if (FLAGS_dll_bw_hz != 0.0) | ||||||
|  |         { | ||||||
|  |             config->set_property("Tracking_1C.dll_bw_hz", std::to_string(FLAGS_dll_bw_hz)); | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             config->set_property("Tracking_1C.dll_bw_hz", "2.0"); | ||||||
|  |         } | ||||||
|  |     config->set_property("Tracking_1C.early_late_space_chips", "0.5"); | ||||||
|  |     config->set_property("Tracking_1C.extend_correlation_ms", "1"); | ||||||
|  |     config->set_property("Tracking_1C.dump", "true"); | ||||||
|  |     config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void GpsL1CAKfTrackingTest::check_results_doppler(arma::vec& true_time_s, | ||||||
|  |     arma::vec& true_value, | ||||||
|  |     arma::vec& meas_time_s, | ||||||
|  |     arma::vec& meas_value) | ||||||
|  | { | ||||||
|  |     // 1. True value interpolation to match the measurement times | ||||||
|  |     arma::vec true_value_interp; | ||||||
|  |     arma::uvec true_time_s_valid = find(true_time_s > 0); | ||||||
|  |     true_time_s = true_time_s(true_time_s_valid); | ||||||
|  |     true_value = true_value(true_time_s_valid); | ||||||
|  |     arma::uvec meas_time_s_valid = find(meas_time_s > 0); | ||||||
|  |     meas_time_s = meas_time_s(meas_time_s_valid); | ||||||
|  |     meas_value = meas_value(meas_time_s_valid); | ||||||
|  |  | ||||||
|  |     arma::interp1(true_time_s, true_value, meas_time_s, true_value_interp); | ||||||
|  |  | ||||||
|  |     // 2. RMSE | ||||||
|  |     arma::vec err; | ||||||
|  |  | ||||||
|  |     err = meas_value - true_value_interp; | ||||||
|  |     arma::vec err2 = arma::square(err); | ||||||
|  |     double rmse = sqrt(arma::mean(err2)); | ||||||
|  |  | ||||||
|  |     // 3. Mean err and variance | ||||||
|  |     double error_mean = arma::mean(err); | ||||||
|  |     double error_var = arma::var(err); | ||||||
|  |  | ||||||
|  |     // 4. Peaks | ||||||
|  |     double max_error = arma::max(err); | ||||||
|  |     double min_error = arma::min(err); | ||||||
|  |  | ||||||
|  |     // 5. report | ||||||
|  |     std::streamsize ss = std::cout.precision(); | ||||||
|  |     std::cout << std::setprecision(10) << "TRK Doppler RMSE=" << rmse | ||||||
|  |               << ", mean=" << error_mean | ||||||
|  |               << ", stdev=" << sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Hz]" << std::endl; | ||||||
|  |     std::cout.precision(ss); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void GpsL1CAKfTrackingTest::check_results_acc_carrier_phase(arma::vec& true_time_s, | ||||||
|  |     arma::vec& true_value, | ||||||
|  |     arma::vec& meas_time_s, | ||||||
|  |     arma::vec& meas_value) | ||||||
|  | { | ||||||
|  |     // 1. True value interpolation to match the measurement times | ||||||
|  |     arma::vec true_value_interp; | ||||||
|  |     arma::uvec true_time_s_valid = find(true_time_s > 0); | ||||||
|  |     true_time_s = true_time_s(true_time_s_valid); | ||||||
|  |     true_value = true_value(true_time_s_valid); | ||||||
|  |     arma::uvec meas_time_s_valid = find(meas_time_s > 0); | ||||||
|  |     meas_time_s = meas_time_s(meas_time_s_valid); | ||||||
|  |     meas_value = meas_value(meas_time_s_valid); | ||||||
|  |  | ||||||
|  |     arma::interp1(true_time_s, true_value, meas_time_s, true_value_interp); | ||||||
|  |  | ||||||
|  |     // 2. RMSE | ||||||
|  |     arma::vec err; | ||||||
|  |     err = meas_value - true_value_interp; | ||||||
|  |     arma::vec err2 = arma::square(err); | ||||||
|  |     double rmse = sqrt(arma::mean(err2)); | ||||||
|  |  | ||||||
|  |     // 3. Mean err and variance | ||||||
|  |     double error_mean = arma::mean(err); | ||||||
|  |     double error_var = arma::var(err); | ||||||
|  |  | ||||||
|  |     // 4. Peaks | ||||||
|  |     double max_error = arma::max(err); | ||||||
|  |     double min_error = arma::min(err); | ||||||
|  |  | ||||||
|  |     // 5. report | ||||||
|  |     std::streamsize ss = std::cout.precision(); | ||||||
|  |     std::cout << std::setprecision(10) << "TRK acc carrier phase RMSE=" << rmse | ||||||
|  |               << ", mean=" << error_mean | ||||||
|  |               << ", stdev=" << sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Hz]" << std::endl; | ||||||
|  |     std::cout.precision(ss); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void GpsL1CAKfTrackingTest::check_results_codephase(arma::vec& true_time_s, | ||||||
|  |     arma::vec& true_value, | ||||||
|  |     arma::vec& meas_time_s, | ||||||
|  |     arma::vec& meas_value) | ||||||
|  | { | ||||||
|  |     // 1. True value interpolation to match the measurement times | ||||||
|  |     arma::vec true_value_interp; | ||||||
|  |     arma::uvec true_time_s_valid = find(true_time_s > 0); | ||||||
|  |     true_time_s = true_time_s(true_time_s_valid); | ||||||
|  |     true_value = true_value(true_time_s_valid); | ||||||
|  |     arma::uvec meas_time_s_valid = find(meas_time_s > 0); | ||||||
|  |     meas_time_s = meas_time_s(meas_time_s_valid); | ||||||
|  |     meas_value = meas_value(meas_time_s_valid); | ||||||
|  |  | ||||||
|  |     arma::interp1(true_time_s, true_value, meas_time_s, true_value_interp); | ||||||
|  |  | ||||||
|  |     // 2. RMSE | ||||||
|  |     arma::vec err; | ||||||
|  |  | ||||||
|  |     err = meas_value - true_value_interp; | ||||||
|  |     arma::vec err2 = arma::square(err); | ||||||
|  |     double rmse = sqrt(arma::mean(err2)); | ||||||
|  |  | ||||||
|  |     // 3. Mean err and variance | ||||||
|  |     double error_mean = arma::mean(err); | ||||||
|  |     double error_var = arma::var(err); | ||||||
|  |  | ||||||
|  |     // 4. Peaks | ||||||
|  |     double max_error = arma::max(err); | ||||||
|  |     double min_error = arma::min(err); | ||||||
|  |  | ||||||
|  |     // 5. report | ||||||
|  |     std::streamsize ss = std::cout.precision(); | ||||||
|  |     std::cout << std::setprecision(10) << "TRK code phase RMSE=" << rmse | ||||||
|  |               << ", mean=" << error_mean | ||||||
|  |               << ", stdev=" << sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Chips]" << std::endl; | ||||||
|  |     std::cout.precision(ss); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TEST_F(GpsL1CAKfTrackingTest, ValidationOfResults) | ||||||
|  | { | ||||||
|  |     // Configure the signal generator | ||||||
|  |     configure_generator(); | ||||||
|  |  | ||||||
|  |     // Generate signal raw signal samples and observations RINEX file | ||||||
|  |     if (FLAGS_disable_generator == false) | ||||||
|  |         { | ||||||
|  |             generate_signal(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     std::chrono::time_point<std::chrono::system_clock> start, end; | ||||||
|  |  | ||||||
|  |     configure_receiver(); | ||||||
|  |  | ||||||
|  |     // open true observables log file written by the simulator | ||||||
|  |     tracking_true_obs_reader true_obs_data; | ||||||
|  |     int test_satellite_PRN = FLAGS_test_satellite_PRN; | ||||||
|  |     std::cout << "Testing satellite PRN=" << test_satellite_PRN << std::endl; | ||||||
|  |     std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); | ||||||
|  |     true_obs_file.append(std::to_string(test_satellite_PRN)); | ||||||
|  |     true_obs_file.append(".dat"); | ||||||
|  |     ASSERT_EQ(true_obs_data.open_obs_file(true_obs_file), true) << "Failure opening true observables file"; | ||||||
|  |  | ||||||
|  |     top_block = gr::make_top_block("Tracking test"); | ||||||
|  |  | ||||||
|  |     std::shared_ptr<GNSSBlockInterface> trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1); | ||||||
|  |     std::shared_ptr<TrackingInterface> tracking = std::dynamic_pointer_cast<TrackingInterface>(trk_);  //std::make_shared<GpsL1CaDllPllCAidTracking>(config.get(), "Tracking_1C", 1, 1); | ||||||
|  |  | ||||||
|  |     boost::shared_ptr<GpsL1CAKfTrackingTest_msg_rx> msg_rx = GpsL1CAKfTrackingTest_msg_rx_make(); | ||||||
|  |  | ||||||
|  |     // load acquisition data based on the first epoch of the true observations | ||||||
|  |     ASSERT_EQ(true_obs_data.read_binary_obs(), true) | ||||||
|  |         << "Failure reading true tracking dump file." << std::endl | ||||||
|  |         << "Maybe sat PRN #" + std::to_string(FLAGS_test_satellite_PRN) + | ||||||
|  |                " is not available?"; | ||||||
|  |  | ||||||
|  |     // restart the epoch counter | ||||||
|  |     true_obs_data.restart(); | ||||||
|  |  | ||||||
|  |     std::cout << "Initial Doppler [Hz]=" << true_obs_data.doppler_l1_hz << " Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << std::endl; | ||||||
|  |     gnss_synchro.Acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD; | ||||||
|  |     gnss_synchro.Acq_doppler_hz = true_obs_data.doppler_l1_hz; | ||||||
|  |     gnss_synchro.Acq_samplestamp_samples = 0; | ||||||
|  |  | ||||||
|  |     ASSERT_NO_THROW({ | ||||||
|  |         tracking->set_channel(gnss_synchro.Channel_ID); | ||||||
|  |     }) << "Failure setting channel."; | ||||||
|  |  | ||||||
|  |     ASSERT_NO_THROW({ | ||||||
|  |         tracking->set_gnss_synchro(&gnss_synchro); | ||||||
|  |     }) << "Failure setting gnss_synchro."; | ||||||
|  |  | ||||||
|  |     ASSERT_NO_THROW({ | ||||||
|  |         tracking->connect(top_block); | ||||||
|  |     }) << "Failure connecting tracking to the top_block."; | ||||||
|  |  | ||||||
|  |     ASSERT_NO_THROW({ | ||||||
|  |         std::string file = "./" + filename_raw_data; | ||||||
|  |         const char* file_name = file.c_str(); | ||||||
|  |         gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); | ||||||
|  |         gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); | ||||||
|  |         gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); | ||||||
|  |         top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); | ||||||
|  |         top_block->connect(gr_interleaved_char_to_complex, 0, tracking->get_left_block(), 0); | ||||||
|  |         top_block->connect(tracking->get_right_block(), 0, sink, 0); | ||||||
|  |         top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); | ||||||
|  |     }) << "Failure connecting the blocks of tracking test."; | ||||||
|  |  | ||||||
|  |     tracking->start_tracking(); | ||||||
|  |  | ||||||
|  |     EXPECT_NO_THROW({ | ||||||
|  |         start = std::chrono::system_clock::now(); | ||||||
|  |         top_block->run();  // Start threads and wait | ||||||
|  |         end = std::chrono::system_clock::now(); | ||||||
|  |     }) << "Failure running the top_block."; | ||||||
|  |  | ||||||
|  |     // check results | ||||||
|  |     // load the true values | ||||||
|  |     long int nepoch = true_obs_data.num_epochs(); | ||||||
|  |     std::cout << "True observation epochs=" << nepoch << std::endl; | ||||||
|  |  | ||||||
|  |     arma::vec true_timestamp_s = arma::zeros(nepoch, 1); | ||||||
|  |     arma::vec true_acc_carrier_phase_cycles = arma::zeros(nepoch, 1); | ||||||
|  |     arma::vec true_Doppler_Hz = arma::zeros(nepoch, 1); | ||||||
|  |     arma::vec true_prn_delay_chips = arma::zeros(nepoch, 1); | ||||||
|  |     arma::vec true_tow_s = arma::zeros(nepoch, 1); | ||||||
|  |  | ||||||
|  |     long int epoch_counter = 0; | ||||||
|  |     while (true_obs_data.read_binary_obs()) | ||||||
|  |         { | ||||||
|  |             true_timestamp_s(epoch_counter) = true_obs_data.signal_timestamp_s; | ||||||
|  |             true_acc_carrier_phase_cycles(epoch_counter) = true_obs_data.acc_carrier_phase_cycles; | ||||||
|  |             true_Doppler_Hz(epoch_counter) = true_obs_data.doppler_l1_hz; | ||||||
|  |             true_prn_delay_chips(epoch_counter) = true_obs_data.prn_delay_chips; | ||||||
|  |             true_tow_s(epoch_counter) = true_obs_data.tow; | ||||||
|  |             epoch_counter++; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     //load the measured values | ||||||
|  |     tracking_dump_reader trk_dump; | ||||||
|  |  | ||||||
|  |     ASSERT_EQ(trk_dump.open_obs_file(std::string("./tracking_ch_0.dat")), true) | ||||||
|  |         << "Failure opening tracking dump file"; | ||||||
|  |  | ||||||
|  |     nepoch = trk_dump.num_epochs(); | ||||||
|  |     std::cout << "Measured observation epochs=" << nepoch << std::endl; | ||||||
|  |  | ||||||
|  |     arma::vec trk_timestamp_s = arma::zeros(nepoch, 1); | ||||||
|  |     arma::vec trk_acc_carrier_phase_cycles = arma::zeros(nepoch, 1); | ||||||
|  |     arma::vec trk_Doppler_Hz = arma::zeros(nepoch, 1); | ||||||
|  |     arma::vec trk_prn_delay_chips = arma::zeros(nepoch, 1); | ||||||
|  |  | ||||||
|  |     std::vector<double> prompt; | ||||||
|  |     std::vector<double> early; | ||||||
|  |     std::vector<double> late; | ||||||
|  |     std::vector<double> promptI; | ||||||
|  |     std::vector<double> promptQ; | ||||||
|  |  | ||||||
|  |     epoch_counter = 0; | ||||||
|  |     while (trk_dump.read_binary_obs()) | ||||||
|  |         { | ||||||
|  |             trk_timestamp_s(epoch_counter) = static_cast<double>(trk_dump.PRN_start_sample_count) / static_cast<double>(baseband_sampling_freq); | ||||||
|  |             trk_acc_carrier_phase_cycles(epoch_counter) = trk_dump.acc_carrier_phase_rad / GPS_TWO_PI; | ||||||
|  |             trk_Doppler_Hz(epoch_counter) = trk_dump.carrier_doppler_hz; | ||||||
|  |  | ||||||
|  |             double delay_chips = GPS_L1_CA_CODE_LENGTH_CHIPS - GPS_L1_CA_CODE_LENGTH_CHIPS * (fmod((static_cast<double>(trk_dump.PRN_start_sample_count) + trk_dump.aux1) / static_cast<double>(baseband_sampling_freq), 1.0e-3) / 1.0e-3); | ||||||
|  |  | ||||||
|  |             trk_prn_delay_chips(epoch_counter) = delay_chips; | ||||||
|  |             epoch_counter++; | ||||||
|  |             prompt.push_back(trk_dump.abs_P); | ||||||
|  |             early.push_back(trk_dump.abs_E); | ||||||
|  |             late.push_back(trk_dump.abs_L); | ||||||
|  |             promptI.push_back(trk_dump.prompt_I); | ||||||
|  |             promptQ.push_back(trk_dump.prompt_Q); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     // Align initial measurements and cut the tracking pull-in transitory | ||||||
|  |     double pull_in_offset_s = 1.0; | ||||||
|  |     arma::uvec initial_meas_point = arma::find(trk_timestamp_s >= (true_timestamp_s(0) + pull_in_offset_s), 1, "first"); | ||||||
|  |  | ||||||
|  |     trk_timestamp_s = trk_timestamp_s.subvec(initial_meas_point(0), trk_timestamp_s.size() - 1); | ||||||
|  |     trk_acc_carrier_phase_cycles = trk_acc_carrier_phase_cycles.subvec(initial_meas_point(0), trk_acc_carrier_phase_cycles.size() - 1); | ||||||
|  |     trk_Doppler_Hz = trk_Doppler_Hz.subvec(initial_meas_point(0), trk_Doppler_Hz.size() - 1); | ||||||
|  |     trk_prn_delay_chips = trk_prn_delay_chips.subvec(initial_meas_point(0), trk_prn_delay_chips.size() - 1); | ||||||
|  |  | ||||||
|  |     check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz); | ||||||
|  |     check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips); | ||||||
|  |     check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles); | ||||||
|  |  | ||||||
|  |     std::chrono::duration<double> elapsed_seconds = end - start; | ||||||
|  |     std::cout << "Signal tracking completed in " << elapsed_seconds.count() << " seconds." << std::endl; | ||||||
|  |  | ||||||
|  |     if (FLAGS_plot_gps_l1_kf_tracking_test == true) | ||||||
|  |         { | ||||||
|  |             const std::string gnuplot_executable(FLAGS_gnuplot_executable); | ||||||
|  |             if (gnuplot_executable.empty()) | ||||||
|  |                 { | ||||||
|  |                     std::cout << "WARNING: Although the flag plot_gps_l1_tracking_test has been set to TRUE," << std::endl; | ||||||
|  |                     std::cout << "gnuplot has not been found in your system." << std::endl; | ||||||
|  |                     std::cout << "Test results will not be plotted." << std::endl; | ||||||
|  |                 } | ||||||
|  |             else | ||||||
|  |                 { | ||||||
|  |                     try | ||||||
|  |                         { | ||||||
|  |                             boost::filesystem::path p(gnuplot_executable); | ||||||
|  |                             boost::filesystem::path dir = p.parent_path(); | ||||||
|  |                             std::string gnuplot_path = dir.native(); | ||||||
|  |                             Gnuplot::set_GNUPlotPath(gnuplot_path); | ||||||
|  |  | ||||||
|  |                             std::vector<double> timevec; | ||||||
|  |                             double t = 0.0; | ||||||
|  |                             for (auto it = prompt.begin(); it != prompt.end(); it++) | ||||||
|  |                                 { | ||||||
|  |                                     timevec.push_back(t); | ||||||
|  |                                     t = t + GPS_L1_CA_CODE_PERIOD; | ||||||
|  |                                 } | ||||||
|  |                             Gnuplot g1("linespoints"); | ||||||
|  |                             g1.set_title("GPS L1 C/A signal tracking correlators' output (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); | ||||||
|  |                             g1.set_grid(); | ||||||
|  |                             g1.set_xlabel("Time [s]"); | ||||||
|  |                             g1.set_ylabel("Correlators' output"); | ||||||
|  |                             g1.cmd("set key box opaque"); | ||||||
|  |                             unsigned int decimate = static_cast<unsigned int>(FLAGS_plot_decimate); | ||||||
|  |                             g1.plot_xy(timevec, prompt, "Prompt", decimate); | ||||||
|  |                             g1.plot_xy(timevec, early, "Early", decimate); | ||||||
|  |                             g1.plot_xy(timevec, late, "Late", decimate); | ||||||
|  |                             g1.savetops("Correlators_outputs"); | ||||||
|  |                             g1.savetopdf("Correlators_outputs", 18); | ||||||
|  |                             g1.showonscreen();  // window output | ||||||
|  |  | ||||||
|  |                             Gnuplot g2("points"); | ||||||
|  |                             g2.set_title("Constellation diagram (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); | ||||||
|  |                             g2.set_grid(); | ||||||
|  |                             g2.set_xlabel("Inphase"); | ||||||
|  |                             g2.set_ylabel("Quadrature"); | ||||||
|  |                             g2.cmd("set size ratio -1"); | ||||||
|  |                             g2.plot_xy(promptI, promptQ); | ||||||
|  |                             g2.savetops("Constellation"); | ||||||
|  |                             g2.savetopdf("Constellation", 18); | ||||||
|  |                             g2.showonscreen();  // window output | ||||||
|  |                         } | ||||||
|  |                     catch (const GnuplotException& ge) | ||||||
|  |                         { | ||||||
|  |                             std::cout << ge.what() << std::endl; | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 Carles Fernandez
					Carles Fernandez