From 67fe04f881c1d423e1d571288041ef68fa0a43a5 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 19 Jun 2018 09:15:46 +0200 Subject: [PATCH 01/40] Start work on acq performance tests --- .../common-files/signal_generator_flags.h | 2 + src/tests/test_main.cc | 1 + .../gps_l1_acq_performance_test.cc | 537 ++++++++++++++++++ .../gps_l1_ca_dll_pll_tracking_test.cc | 5 +- 4 files changed, 542 insertions(+), 3 deletions(-) create mode 100644 src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc diff --git a/src/tests/common-files/signal_generator_flags.h b/src/tests/common-files/signal_generator_flags.h index cfc93b8d0..e65e98846 100644 --- a/src/tests/common-files/signal_generator_flags.h +++ b/src/tests/common-files/signal_generator_flags.h @@ -32,6 +32,7 @@ #define GNSS_SDR_SIGNAL_GENERATOR_FLAGS_H_ #include +#include DEFINE_bool(disable_generator, false, "Disable the signal generator (a external signal file must be available for the test)"); DEFINE_string(generator_binary, std::string(SW_GENERATOR_BIN), "Path of software-defined signal generator binary"); @@ -44,5 +45,6 @@ DEFINE_string(filename_raw_data, "signal_out.bin", "Filename of output raw data DEFINE_int32(fs_gen_sps, 2600000, "Sampling frequency [sps]"); DEFINE_int32(test_satellite_PRN, 1, "PRN of the satellite under test (must be visible during the observation time)"); DEFINE_int32(test_satellite_PRN2, 2, "PRN of the satellite under test (must be visible during the observation time)"); +DEFINE_double(CN0_dBHz, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 [dB-Hz]"); #endif diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index b139e993e..39fe900b8 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -145,6 +145,7 @@ DECLARE_string(log_dir); #if EXTRA_TESTS #include "unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc" +#include "unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_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/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc" diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc new file mode 100644 index 000000000..08287722c --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -0,0 +1,537 @@ +/*! + * \file gps_l1_acq_performance_test.cc + * \brief This class implements an acquisition performance test + * \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.cat + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "test_flags.h" +#include "signal_generator_flags.h" +#include +#include +#include + +DEFINE_string(config_file_ptest, std::string(""), "File containing the configuration parameters for the position test."); + +// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +//class AcqPerfTest_msg_rx; +// +//typedef boost::shared_ptr AcqPerfTest_msg_rx_sptr; +// +//AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(); +// +//class AcqPerfTest_msg_rx : public gr::block +//{ +//private: +// friend AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(); +// void msg_handler_events(pmt::pmt_t msg); +// AcqPerfTest_msg_rx(); +// +//public: +// int rx_message; +// ~AcqPerfTest_msg_rx(); //!< Default destructor +//}; +// +// +//AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make() +//{ +// return AcqPerfTest_msg_rx_sptr(new AcqPerfTest_msg_rx()); +//} +// +// +//void AcqPerfTest_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; +// } +//} +// +// +//AcqPerfTest_msg_rx::AcqPerfTest_msg_rx() : gr::block("AcqPerfTest_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(&AcqPerfTest_msg_rx::msg_handler_events, this, _1)); +// rx_message = 0; +//} +// +// +//AcqPerfTest_msg_rx::~AcqPerfTest_msg_rx() +//{ +//} +// +//// ----------------------------------------- + + +class AcquisitionPerformanceTest : public ::testing::Test +{ +protected: + AcquisitionPerformanceTest() + { + config = std::make_shared(); + item_size = sizeof(gr_complex); + gnss_synchro = Gnss_Synchro(); + doppler_max = 5000; + doppler_step = 100; + } + + ~AcquisitionPerformanceTest() + { + } + + std::vector cn0_ = {41.0, 42.0, 43.0}; + int N_iterations = 2; + void init(); + //void plot_grid(); + + int configure_generator(double cn0); + int generate_signal(); + int configure_receiver(double cn0, unsigned int iter); + int run_receiver(); + void check_results(); + gr::top_block_sptr top_block; + Gnss_Synchro gnss_synchro; + size_t item_size; + unsigned int doppler_max; + unsigned int doppler_step; + std::string implementation = "GPS_L1_CA_PCPS_Acquisition"; + std::shared_ptr config; + std::shared_ptr config_f; + +private: + std::string generator_binary; + std::string p1; + std::string p2; + std::string p3; + std::string p4; + std::string p5; + std::string p6; + + const double baseband_sampling_freq = static_cast(FLAGS_fs_gen_sps); + + std::string filename_rinex_obs = FLAGS_filename_rinex_obs; + std::string filename_raw_data = FLAGS_filename_raw_data; + + /*void print_results(const std::vector& east, + const std::vector& north, + const std::vector& up);*/ + + double compute_stdev_precision(const std::vector& vec); + double compute_stdev_accuracy(const std::vector& vec, double ref); + + + //std::string generated_kml_file; +}; + + +void AcquisitionPerformanceTest::init() +{ + gnss_synchro.Channel_ID = 0; + gnss_synchro.System = 'G'; + std::string signal = "1C"; + signal.copy(gnss_synchro.Signal, 2, 0); + gnss_synchro.PRN = 1; +} + + +int AcquisitionPerformanceTest::configure_generator(double cn0) +{ + // Configure signal generator + generator_binary = FLAGS_generator_binary; + int duration_s = 2; + + 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(std::min(duration_s * 10, 3000)); + } + 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] + p6 = std::string("-CN0_dBHz=") + std::to_string(cn0); + return 0; +} + + +int AcquisitionPerformanceTest::generate_signal() +{ + pid_t wait_result; + int child_status; + std::cout << "Generating signal for " << p6 << "..." << std::endl; + char* const parmList[] = {&generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0], &p6[0], NULL}; + + int pid; + if ((pid = fork()) == -1) + perror("fork error"); + else if (pid == 0) + { + execv(&generator_binary[0], parmList); + std::cout << "Return not expected. Must be an execv error." << std::endl; + std::terminate(); + } + + wait_result = waitpid(pid, &child_status, 0); + if (wait_result == -1) perror("waitpid error"); + return 0; +} + + +int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter) +{ + if (FLAGS_config_file_ptest.empty()) + { + config = std::make_shared(); + const int sampling_rate_internal = baseband_sampling_freq; + + const int number_of_taps = 11; + const int number_of_bands = 2; + const float band1_begin = 0.0; + const float band1_end = 0.48; + const float band2_begin = 0.52; + const float band2_end = 1.0; + const float ampl1_begin = 1.0; + const float ampl1_end = 1.0; + const float ampl2_begin = 0.0; + const float ampl2_end = 0.0; + const float band1_error = 1.0; + const float band2_error = 1.0; + const int grid_density = 16; + + const float zero = 0.0; + const int number_of_channels = 1; + const int in_acquisition = 1; + + const float threshold = 0.01; + const float doppler_max = 8000.0; + const float doppler_step = 500.0; + const int max_dwells = 1; + const int tong_init_val = 2; + const int tong_max_val = 10; + const int tong_max_dwells = 30; + const int coherent_integration_time_ms = 1; + + const float pll_bw_hz = 30.0; + const float dll_bw_hz = 4.0; + const float early_late_space_chips = 0.5; + const float pll_bw_narrow_hz = 20.0; + const float dll_bw_narrow_hz = 2.0; + const int extend_correlation_ms = 1; + + const int display_rate_ms = 500; + const int output_rate_ms = 100; + + config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(sampling_rate_internal)); + + // Set the assistance system parameters + config->set_property("GNSS-SDR.SUPL_read_gps_assistance_xml", "false"); + config->set_property("GNSS-SDR.SUPL_gps_enabled", "false"); + config->set_property("GNSS-SDR.SUPL_gps_ephemeris_server", "supl.google.com"); + config->set_property("GNSS-SDR.SUPL_gps_ephemeris_port", std::to_string(7275)); + config->set_property("GNSS-SDR.SUPL_gps_acquisition_server", "supl.google.com"); + config->set_property("GNSS-SDR.SUPL_gps_acquisition_port", std::to_string(7275)); + config->set_property("GNSS-SDR.SUPL_MCC", std::to_string(244)); + config->set_property("GNSS-SDR.SUPL_MNS", std::to_string(5)); + config->set_property("GNSS-SDR.SUPL_LAC", "0x59e2"); + config->set_property("GNSS-SDR.SUPL_CI", "0x31b0"); + + // Set the Signal Source + config->set_property("SignalSource.implementation", "File_Signal_Source"); + config->set_property("SignalSource.filename", "./" + filename_raw_data); + config->set_property("SignalSource.sampling_frequency", std::to_string(sampling_rate_internal)); + config->set_property("SignalSource.item_type", "ibyte"); + config->set_property("SignalSource.samples", std::to_string(zero)); + + // Set the Signal Conditioner + config->set_property("SignalConditioner.implementation", "Signal_Conditioner"); + config->set_property("DataTypeAdapter.implementation", "Ibyte_To_Complex"); + config->set_property("InputFilter.implementation", "Fir_Filter"); + config->set_property("InputFilter.dump", "false"); + config->set_property("InputFilter.input_item_type", "gr_complex"); + config->set_property("InputFilter.output_item_type", "gr_complex"); + config->set_property("InputFilter.taps_item_type", "float"); + config->set_property("InputFilter.number_of_taps", std::to_string(number_of_taps)); + config->set_property("InputFilter.number_of_bands", std::to_string(number_of_bands)); + config->set_property("InputFilter.band1_begin", std::to_string(band1_begin)); + config->set_property("InputFilter.band1_end", std::to_string(band1_end)); + config->set_property("InputFilter.band2_begin", std::to_string(band2_begin)); + config->set_property("InputFilter.band2_end", std::to_string(band2_end)); + config->set_property("InputFilter.ampl1_begin", std::to_string(ampl1_begin)); + config->set_property("InputFilter.ampl1_end", std::to_string(ampl1_end)); + config->set_property("InputFilter.ampl2_begin", std::to_string(ampl2_begin)); + config->set_property("InputFilter.ampl2_end", std::to_string(ampl2_end)); + config->set_property("InputFilter.band1_error", std::to_string(band1_error)); + config->set_property("InputFilter.band2_error", std::to_string(band2_error)); + config->set_property("InputFilter.filter_type", "bandpass"); + config->set_property("InputFilter.grid_density", std::to_string(grid_density)); + config->set_property("InputFilter.sampling_frequency", std::to_string(sampling_rate_internal)); + config->set_property("InputFilter.IF", std::to_string(zero)); + config->set_property("Resampler.implementation", "Pass_Through"); + config->set_property("Resampler.dump", "false"); + config->set_property("Resampler.item_type", "gr_complex"); + config->set_property("Resampler.sample_freq_in", std::to_string(sampling_rate_internal)); + config->set_property("Resampler.sample_freq_out", std::to_string(sampling_rate_internal)); + + // Set the number of Channels + config->set_property("Channels_1C.count", std::to_string(number_of_channels)); + config->set_property("Channels.in_acquisition", std::to_string(in_acquisition)); + config->set_property("Channel.signal", "1C"); + + // Set Acquisition + config->set_property("Acquisition_1C.implementation", implementation); + config->set_property("Acquisition_1C.item_type", "gr_complex"); + config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max)); + config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); + + config->set_property("Acquisition_1C.threshold", "0.00001"); + //config->set_property("Acquisition_1C.pfa", "0.0"); + config->set_property("Acquisition_1C.use_CFAR_algorithm", "false"); + + config->set_property("Acquisition_1C.coherent_integration_time_ms", "1"); + config->set_property("Acquisition_1C.use_bit_transition_flag", "false"); + + config->set_property("Acquisition_1C.max_dwells", std::to_string(1)); + + config->set_property("Acquisition_1C.repeat_satellite", "false"); + + config->set_property("Acquisition_1C.blocking", "true"); + config->set_property("Acquisition_1C.make_two_steps", "false"); + config->set_property("Acquisition_1C.second_nbins", std::to_string(4)); + config->set_property("Acquisition_1C.second_doppler_step", std::to_string(125)); + //if (FLAGS_plot_acq_grid == true) + // { + config->set_property("Acquisition_1C.dump", "true"); + // } + //else + // { + // config->set_property("Acquisition_1C.dump", "false"); + // } + std::string dump_file = std::string("./acquisition_") + std::to_string(cn0) + "_" + std::to_string(iter); + config->set_property("Acquisition_1C.dump_filename", dump_file); + + // Set Tracking + config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_Tracking"); + //config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_C_Aid_Tracking"); + config->set_property("Tracking_1C.item_type", "gr_complex"); + config->set_property("Tracking_1C.dump", "false"); + config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); + config->set_property("Tracking_1C.pll_bw_hz", std::to_string(pll_bw_hz)); + config->set_property("Tracking_1C.dll_bw_hz", std::to_string(dll_bw_hz)); + config->set_property("Tracking_1C.early_late_space_chips", std::to_string(early_late_space_chips)); + + config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(pll_bw_narrow_hz)); + config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(dll_bw_narrow_hz)); + config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(extend_correlation_ms)); + + // Set Telemetry + config->set_property("TelemetryDecoder_1C.implementation", "GPS_L1_CA_Telemetry_Decoder"); + config->set_property("TelemetryDecoder_1C.dump", "false"); + + // Set Observables + config->set_property("Observables.implementation", "Hybrid_Observables"); + config->set_property("Observables.dump", "false"); + config->set_property("Observables.dump_filename", "./observables.dat"); + + // Set PVT + config->set_property("PVT.implementation", "RTKLIB_PVT"); + config->set_property("PVT.positioning_mode", "PPP_Static"); + config->set_property("PVT.output_rate_ms", std::to_string(output_rate_ms)); + config->set_property("PVT.display_rate_ms", std::to_string(display_rate_ms)); + config->set_property("PVT.dump_filename", "./PVT"); + config->set_property("PVT.nmea_dump_filename", "./gnss_sdr_pvt.nmea"); + config->set_property("PVT.flag_nmea_tty_port", "false"); + config->set_property("PVT.nmea_dump_devname", "/dev/pts/4"); + config->set_property("PVT.flag_rtcm_server", "false"); + config->set_property("PVT.flag_rtcm_tty_port", "false"); + config->set_property("PVT.rtcm_dump_devname", "/dev/pts/1"); + config->set_property("PVT.dump", "false"); + config->set_property("PVT.rinex_version", std::to_string(2)); + config->set_property("PVT.iono_model", "OFF"); + config->set_property("PVT.trop_model", "OFF"); + config->set_property("PVT.AR_GPS", "PPP-AR"); + + config_f = 0; + } + else + { + config_f = std::make_shared(FLAGS_config_file_ptest); + config = 0; + } + return 0; +} + + +int AcquisitionPerformanceTest::run_receiver() +{ + std::shared_ptr control_thread; + if (FLAGS_config_file_ptest.empty()) + { + control_thread = std::make_shared(config); + } + else + { + control_thread = std::make_shared(config_f); + } + + // start receiver + try + { + control_thread->run(); + } + catch (const boost::exception& e) + { + std::cout << "Boost exception: " << boost::diagnostic_information(e); + } + catch (const std::exception& ex) + { + std::cout << "STD exception: " << ex.what(); + } + return 0; +} + + +TEST_F(AcquisitionPerformanceTest, PdvsCn0) +{ + for (std::vector::const_iterator it = cn0_.cbegin(); it != cn0_.cend(); ++it) + { + // Set parameter to sweep + + // Do N_iterations of the experiment + for (unsigned iter = 0; iter < N_iterations; iter++) + { + // Configure the signal generator + configure_generator(*it); + + // Generate signal raw signal samples and observations RINEX file + generate_signal(); + + // Configure the receiver + configure_receiver(*it, iter); + + // Run it + run_receiver(); + + // Read and store reference data and results + } + } + + // Compute results +} + +//TEST_F(AcquisitionPerformanceTest, ValidationOfResults) +//{ +// std::chrono::time_point start, end; +// std::chrono::duration elapsed_seconds(0.0); +// top_block = gr::make_top_block("Acquisition test"); +// +// double expected_delay_samples = 524; +// double expected_doppler_hz = 1680; +// +// init(); +// +// if (FLAGS_plot_acq_grid == true) +// { +// std::string data_str = "./tmp-acq-gps1"; +// if (boost::filesystem::exists(data_str)) +// { +// boost::filesystem::remove_all(data_str); +// } +// boost::filesystem::create_directory(data_str); +// } +// +// std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 0); +// boost::shared_ptr msg_rx = AcqPerfTest_msg_rx_make(); +// +// ASSERT_NO_THROW({ +// acquisition->set_channel(1); +// }) << "Failure setting channel."; +// +// ASSERT_NO_THROW({ +// acquisition->set_gnss_synchro(&gnss_synchro); +// }) << "Failure setting gnss_synchro."; +// +// ASSERT_NO_THROW({ +// acquisition->set_threshold(0.001); +// }) << "Failure setting threshold."; +// +// ASSERT_NO_THROW({ +// acquisition->set_doppler_max(doppler_max); +// }) << "Failure setting doppler_max."; +// +// ASSERT_NO_THROW({ +// acquisition->set_doppler_step(doppler_step); +// }) << "Failure setting doppler_step."; +// +// ASSERT_NO_THROW({ +// acquisition->connect(top_block); +// }) << "Failure connecting acquisition to the top_block."; +// +// ASSERT_NO_THROW({ +// std::string path = std::string(TEST_PATH); +// std::string file = path + "signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat"; +// const char* file_name = file.c_str(); +// gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(gr_complex), file_name, false); +// top_block->connect(file_source, 0, acquisition->get_left_block(), 0); +// top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); +// }) << "Failure connecting the blocks of acquisition test."; +// +// acquisition->set_local_code(); +// acquisition->set_state(1); // Ensure that acquisition starts at the first sample +// acquisition->init(); +// +// EXPECT_NO_THROW({ +// start = std::chrono::system_clock::now(); +// top_block->run(); // Start threads and wait +// end = std::chrono::system_clock::now(); +// elapsed_seconds = end - start; +// }) << "Failure running the top_block."; +// +// unsigned long int nsamples = gnss_synchro.Acq_samplestamp_samples; +// std::cout << "Acquired " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; +// ASSERT_EQ(1, msg_rx->rx_message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS."; +// +// double delay_error_samples = std::abs(expected_delay_samples - gnss_synchro.Acq_delay_samples); +// float delay_error_chips = static_cast(delay_error_samples * 1023 / 4000); +// double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro.Acq_doppler_hz); +// +// EXPECT_LE(doppler_error_hz, 666) << "Doppler error exceeds the expected value: 666 Hz = 2/(3*integration period)"; +// EXPECT_LT(delay_error_chips, 0.5) << "Delay error exceeds the expected value: 0.5 chips"; +// +// /*if (FLAGS_plot_acq_grid == true) +// { +// plot_grid(); +// }*/ +//} diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index b8363c383..30a48cb71 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -54,7 +54,6 @@ #include "test_flags.h" DEFINE_bool(plot_gps_l1_tracking_test, false, "Plots results of GpsL1CADllPllTrackingTest with gnuplot"); -DEFINE_double(CN0_dBHz, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 [dB-Hz]"); DEFINE_int32(extend_correlation_symbols, 1, "Set the tracking coherent correlation to N symbols (up to 20 for GPS L1 C/A)"); // ######## GNURADIO BLOCK MESSAGE RECEVER ######### @@ -184,7 +183,7 @@ int GpsL1CADllPllTrackingTest::configure_generator() 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] - p6 = std::string("-CN0_dBHz=") + std::to_string(FLAGS_CN0_dBHz); // Signal generator CN0 + p6 = std::string("-CN0_dBHz=") + std::to_string(FLAGS_CN0_dBHz); // Signal generator CN0 return 0; } @@ -193,7 +192,7 @@ int GpsL1CADllPllTrackingTest::generate_signal() { int child_status; - char* const parmList[] = {&generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0],&p6[0], NULL}; + char* const parmList[] = {&generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0], &p6[0], NULL}; int pid; if ((pid = fork()) == -1) From 799fe4583077643ad73d1597032f4b62fe5a6d28 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Tue, 19 Jun 2018 11:36:15 +0200 Subject: [PATCH 02/40] Migrating DLL/PLL configuration from struct to class and adding tracking quality indicators plot sample MATLAB script --- .../galileo_e1_dll_pll_veml_tracking.cc | 3 +- .../adapters/galileo_e5a_dll_pll_tracking.cc | 4 +- .../adapters/gps_l1_ca_dll_pll_tracking.cc | 8 +-- .../adapters/gps_l2_m_dll_pll_tracking.cc | 4 +- .../adapters/gps_l5_dll_pll_tracking.cc | 4 +- .../gnuradio_blocks/dll_pll_veml_tracking.cc | 4 +- .../gnuradio_blocks/dll_pll_veml_tracking.h | 37 +++------- src/algorithms/tracking/libs/CMakeLists.txt | 1 + src/algorithms/tracking/libs/dll_pll_conf.cc | 29 ++++++++ src/algorithms/tracking/libs/dll_pll_conf.h | 68 +++++++++++++++++++ .../matlab/plot_tracking_quality_indicators.m | 18 +++++ 11 files changed, 138 insertions(+), 42 deletions(-) create mode 100644 src/algorithms/tracking/libs/dll_pll_conf.cc create mode 100644 src/algorithms/tracking/libs/dll_pll_conf.h create mode 100644 src/utils/matlab/plot_tracking_quality_indicators.m diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc index 61eddf20a..e4ee5a8fd 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc @@ -34,6 +34,7 @@ * ------------------------------------------------------------------------- */ +#include "dll_pll_conf.h" #include "galileo_e1_dll_pll_veml_tracking.h" #include "configuration_interface.h" #include "Galileo_E1.h" @@ -48,7 +49,7 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - dllpllconf_t trk_param; + Dll_Pll_Conf trk_param; DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## std::string default_item_type = "gr_complex"; diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc index 8fd0cd955..a3c21b6bb 100644 --- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc @@ -35,7 +35,7 @@ * * ------------------------------------------------------------------------- */ - +#include "dll_pll_conf.h" #include "galileo_e5a_dll_pll_tracking.h" #include "configuration_interface.h" #include "Galileo_E5a.h" @@ -49,7 +49,7 @@ GalileoE5aDllPllTracking::GalileoE5aDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - dllpllconf_t trk_param; + Dll_Pll_Conf trk_param; DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## std::string default_item_type = "gr_complex"; diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc index 6d6ded849..3fcd02fa0 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc @@ -35,7 +35,7 @@ * ------------------------------------------------------------------------- */ - +#include "dll_pll_conf.h" #include "gps_l1_ca_dll_pll_tracking.h" #include "configuration_interface.h" #include "GPS_L1_CA.h" @@ -49,7 +49,7 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - dllpllconf_t trk_param; + Dll_Pll_Conf trk_param; DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## std::string default_item_type = "gr_complex"; @@ -108,13 +108,13 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( int cn0_samples = configuration->property(role + ".cn0_samples", 20); if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples; trk_param.cn0_samples = cn0_samples; - int cn0_min = configuration->property(role + ".cn0_min", 25); + int cn0_min = configuration->property(role + ".cn0_min", 30); if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min; trk_param.cn0_min = cn0_min; int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; trk_param.max_lock_fail = max_lock_fail; - double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); + double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.80); if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th; trk_param.carrier_lock_th = carrier_lock_th; diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc index 13374590c..81accbc09 100644 --- a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc @@ -34,7 +34,7 @@ * ------------------------------------------------------------------------- */ - +#include "dll_pll_conf.h" #include "gps_l2_m_dll_pll_tracking.h" #include "configuration_interface.h" #include "GPS_L2C.h" @@ -49,7 +49,7 @@ GpsL2MDllPllTracking::GpsL2MDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - dllpllconf_t trk_param; + Dll_Pll_Conf trk_param; DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## std::string default_item_type = "gr_complex"; diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc index 554b1ca41..c039e1434 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc @@ -34,7 +34,7 @@ * ------------------------------------------------------------------------- */ - +#include "dll_pll_conf.h" #include "gps_l5_dll_pll_tracking.h" #include "configuration_interface.h" #include "GPS_L5.h" @@ -49,7 +49,7 @@ GpsL5DllPllTracking::GpsL5DllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - dllpllconf_t trk_param; + Dll_Pll_Conf trk_param; DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## std::string default_item_type = "gr_complex"; diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index 738e3dd90..130409307 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -60,7 +60,7 @@ using google::LogMessage; -dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(dllpllconf_t conf_) +dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(Dll_Pll_Conf conf_) { return dll_pll_veml_tracking_sptr(new dll_pll_veml_tracking(conf_)); } @@ -76,7 +76,7 @@ void dll_pll_veml_tracking::forecast(int noutput_items, } -dll_pll_veml_tracking::dll_pll_veml_tracking(dllpllconf_t conf_) : gr::block("dll_pll_veml_tracking", gr::io_signature::make(1, 1, sizeof(gr_complex)), +dll_pll_veml_tracking::dll_pll_veml_tracking(Dll_Pll_Conf conf_) : gr::block("dll_pll_veml_tracking", gr::io_signature::make(1, 1, sizeof(gr_complex)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { trk_parameters = conf_; diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h index 9444c6ccb..67a65b15b 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h @@ -31,6 +31,7 @@ #ifndef GNSS_SDR_DLL_PLL_VEML_TRACKING_H #define GNSS_SDR_DLL_PLL_VEML_TRACKING_H +#include "dll_pll_conf.h" #include "gnss_synchro.h" #include "tracking_2nd_DLL_filter.h" #include "tracking_2nd_PLL_filter.h" @@ -39,37 +40,14 @@ #include #include #include - -typedef struct -{ - /* DLL/PLL tracking configuration */ - double fs_in; - unsigned int vector_length; - bool dump; - std::string dump_filename; - float pll_bw_hz; - float dll_bw_hz; - float pll_bw_narrow_hz; - float dll_bw_narrow_hz; - float early_late_space_chips; - float very_early_late_space_chips; - float early_late_space_narrow_chips; - float very_early_late_space_narrow_chips; - int extend_correlation_symbols; - int cn0_samples; - int cn0_min; - int max_lock_fail; - double carrier_lock_th; - bool track_pilot; - char system; - char signal[3]; -} dllpllconf_t; +#include +#include class dll_pll_veml_tracking; typedef boost::shared_ptr dll_pll_veml_tracking_sptr; -dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(dllpllconf_t conf_); +dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(Dll_Pll_Conf conf_); /*! * \brief This class implements a code DLL + carrier PLL tracking block. @@ -89,9 +67,9 @@ public: void forecast(int noutput_items, gr_vector_int &ninput_items_required); private: - friend dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(dllpllconf_t conf_); + friend dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(Dll_Pll_Conf conf_); - dll_pll_veml_tracking(dllpllconf_t conf_); + dll_pll_veml_tracking(Dll_Pll_Conf conf_); bool cn0_and_tracking_lock_status(double coh_integration_time_s); bool acquire_secondary(); @@ -104,7 +82,7 @@ private: int save_matfile(); // tracking configuration vars - dllpllconf_t trk_parameters; + Dll_Pll_Conf trk_parameters; bool d_veml; bool d_cloop; unsigned int d_channel; @@ -201,6 +179,7 @@ private: // CN0 estimation and lock detector int d_cn0_estimation_counter; int d_carrier_lock_fail_counter; + std::deque d_carrier_lock_detector_queue; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; double d_carrier_lock_threshold; diff --git a/src/algorithms/tracking/libs/CMakeLists.txt b/src/algorithms/tracking/libs/CMakeLists.txt index 9c5051ea2..fdb35a4e9 100644 --- a/src/algorithms/tracking/libs/CMakeLists.txt +++ b/src/algorithms/tracking/libs/CMakeLists.txt @@ -43,6 +43,7 @@ set(TRACKING_LIB_SOURCES tracking_discriminators.cc tracking_FLL_PLL_filter.cc tracking_loop_filter.cc + dll_pll_conf.cc ) if(ENABLE_FPGA) diff --git a/src/algorithms/tracking/libs/dll_pll_conf.cc b/src/algorithms/tracking/libs/dll_pll_conf.cc new file mode 100644 index 000000000..c244b4420 --- /dev/null +++ b/src/algorithms/tracking/libs/dll_pll_conf.cc @@ -0,0 +1,29 @@ +#include "dll_pll_conf.h" +#include + +Dll_Pll_Conf::Dll_Pll_Conf() +{ + /* DLL/PLL tracking configuration */ + fs_in = 0.0; + vector_length = 0; + dump = false; + dump_filename = "./dll_pll_dump.dat"; + pll_bw_hz = 40.0; + dll_bw_hz = 2.0; + pll_bw_narrow_hz = 5.0; + dll_bw_narrow_hz = 0.75; + early_late_space_chips = 0.5; + very_early_late_space_chips = 0.5; + early_late_space_narrow_chips = 0.1; + very_early_late_space_narrow_chips = 0.1; + extend_correlation_symbols = 5; + cn0_samples = 20; + carrier_lock_det_mav_samples = 20; + cn0_min = 25; + max_lock_fail = 50; + carrier_lock_th = 0.85; + track_pilot = false; + system = 'G'; + char sig_[3] = "1C"; + std::memcpy(signal, sig_, 3); +} diff --git a/src/algorithms/tracking/libs/dll_pll_conf.h b/src/algorithms/tracking/libs/dll_pll_conf.h new file mode 100644 index 000000000..2cee8c405 --- /dev/null +++ b/src/algorithms/tracking/libs/dll_pll_conf.h @@ -0,0 +1,68 @@ +/*! + * \file dll_pll_conf.h + * \brief Class that contains all the configuration parameters for generic tracking block based on a DLL and a PLL. + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * Class that contains all the configuration parameters for generic tracking block based on a DLL and a PLL. + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_DLL_PLL_CONF_H_ +#define GNSS_SDR_DLL_PLL_CONF_H_ + +#include + +class Dll_Pll_Conf +{ +private: +public: + /* DLL/PLL tracking configuration */ + double fs_in; + unsigned int vector_length; + bool dump; + std::string dump_filename; + float pll_bw_hz; + float dll_bw_hz; + float pll_bw_narrow_hz; + float dll_bw_narrow_hz; + float early_late_space_chips; + float very_early_late_space_chips; + float early_late_space_narrow_chips; + float very_early_late_space_narrow_chips; + int extend_correlation_symbols; + int cn0_samples; + int carrier_lock_det_mav_samples; + int cn0_min; + int max_lock_fail; + double carrier_lock_th; + bool track_pilot; + char system; + char signal[3]; + + Dll_Pll_Conf(); +}; + +#endif diff --git a/src/utils/matlab/plot_tracking_quality_indicators.m b/src/utils/matlab/plot_tracking_quality_indicators.m new file mode 100644 index 000000000..a1c263aa3 --- /dev/null +++ b/src/utils/matlab/plot_tracking_quality_indicators.m @@ -0,0 +1,18 @@ +%plot tracking quality indicators +figure; +hold on; +title('Carrier lock test output for all the channels'); +for n=1:1:length(GNSS_tracking) + plot(GNSS_tracking(n).carrier_lock_test) + plotnames{n}=['SV ' num2str(round(mean(GNSS_tracking(n).PRN)))]; +end +legend(plotnames); + +figure; +hold on; +title('Carrier CN0 output for all the channels'); +for n=1:1:length(GNSS_tracking) + plot(GNSS_tracking(n).CN0_SNV_dB_Hz) + plotnames{n}=['SV ' num2str(round(mean(GNSS_tracking(n).PRN)))]; +end +legend(plotnames); \ No newline at end of file From 69b05ff96d96e4ba1f6bad63df08ca38f7a65353 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 19 Jun 2018 12:55:14 +0200 Subject: [PATCH 03/40] Initialize configuration object --- .../tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc | 2 +- .../tracking/adapters/galileo_e5a_dll_pll_tracking.cc | 2 +- src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc | 2 +- src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc | 2 +- src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc index e4ee5a8fd..48e821674 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc @@ -49,7 +49,7 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - Dll_Pll_Conf trk_param; + Dll_Pll_Conf trk_param = Dll_Pll_Conf(); DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## std::string default_item_type = "gr_complex"; diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc index a3c21b6bb..fe6f4a7d6 100644 --- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc @@ -49,7 +49,7 @@ GalileoE5aDllPllTracking::GalileoE5aDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - Dll_Pll_Conf trk_param; + Dll_Pll_Conf trk_param = Dll_Pll_Conf(); DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## std::string default_item_type = "gr_complex"; diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc index 3fcd02fa0..ffa6e1000 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc @@ -49,7 +49,7 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - Dll_Pll_Conf trk_param; + Dll_Pll_Conf trk_param = Dll_Pll_Conf(); DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## std::string default_item_type = "gr_complex"; diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc index 81accbc09..499427dfa 100644 --- a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc @@ -49,7 +49,7 @@ GpsL2MDllPllTracking::GpsL2MDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - Dll_Pll_Conf trk_param; + Dll_Pll_Conf trk_param = Dll_Pll_Conf(); DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## std::string default_item_type = "gr_complex"; diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc index c039e1434..8fbd56531 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc @@ -49,7 +49,7 @@ GpsL5DllPllTracking::GpsL5DllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - Dll_Pll_Conf trk_param; + Dll_Pll_Conf trk_param = Dll_Pll_Conf(); DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## std::string default_item_type = "gr_complex"; From 2c0f5a6062ca996ea758ef5fb6f0afe0106b7475 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 19 Jun 2018 12:56:53 +0200 Subject: [PATCH 04/40] Take the configuration object by reference --- .../tracking/gnuradio_blocks/dll_pll_veml_tracking.cc | 6 +++--- .../tracking/gnuradio_blocks/dll_pll_veml_tracking.h | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index 130409307..bd822c74c 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -60,7 +60,7 @@ using google::LogMessage; -dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(Dll_Pll_Conf conf_) +dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(const Dll_Pll_Conf &conf_) { return dll_pll_veml_tracking_sptr(new dll_pll_veml_tracking(conf_)); } @@ -76,8 +76,8 @@ void dll_pll_veml_tracking::forecast(int noutput_items, } -dll_pll_veml_tracking::dll_pll_veml_tracking(Dll_Pll_Conf conf_) : gr::block("dll_pll_veml_tracking", gr::io_signature::make(1, 1, sizeof(gr_complex)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) +dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::block("dll_pll_veml_tracking", gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { trk_parameters = conf_; // Telemetry bit synchronization message port input diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h index 67a65b15b..0437e8a35 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h @@ -41,13 +41,12 @@ #include #include #include -#include class dll_pll_veml_tracking; typedef boost::shared_ptr dll_pll_veml_tracking_sptr; -dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(Dll_Pll_Conf conf_); +dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(const Dll_Pll_Conf &conf_); /*! * \brief This class implements a code DLL + carrier PLL tracking block. @@ -67,9 +66,9 @@ public: void forecast(int noutput_items, gr_vector_int &ninput_items_required); private: - friend dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(Dll_Pll_Conf conf_); + friend dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(const Dll_Pll_Conf &conf_); - dll_pll_veml_tracking(Dll_Pll_Conf conf_); + dll_pll_veml_tracking(const Dll_Pll_Conf &conf_); bool cn0_and_tracking_lock_status(double coh_integration_time_s); bool acquire_secondary(); From acd662b88fbe8caddbb0d88925cfaadda46acf3b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 19 Jun 2018 12:57:43 +0200 Subject: [PATCH 05/40] Add file header --- src/algorithms/tracking/libs/dll_pll_conf.cc | 32 ++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/algorithms/tracking/libs/dll_pll_conf.cc b/src/algorithms/tracking/libs/dll_pll_conf.cc index c244b4420..89c6a1256 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf.cc +++ b/src/algorithms/tracking/libs/dll_pll_conf.cc @@ -1,3 +1,35 @@ +/*! + * \file dll_pll_conf.cc + * \brief Class that contains all the configuration parameters for generic + * tracking block based on a DLL and a PLL. + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + + #include "dll_pll_conf.h" #include From 423176de7b75f36ab76a322a1ae9c37cdb15f5d0 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 19 Jun 2018 12:59:54 +0200 Subject: [PATCH 06/40] Replace acq configuration struct by a class --- src/algorithms/acquisition/CMakeLists.txt | 5 +- .../acquisition/adapters/CMakeLists.txt | 2 +- .../galileo_e1_pcps_ambiguous_acquisition.cc | 3 +- .../adapters/galileo_e5a_pcps_acquisition.cc | 3 +- .../glonass_l1_ca_pcps_acquisition.cc | 3 +- .../glonass_l2_ca_pcps_acquisition.cc | 3 +- .../adapters/gps_l1_ca_pcps_acquisition.cc | 3 +- .../adapters/gps_l2_m_pcps_acquisition.cc | 3 +- .../adapters/gps_l5i_pcps_acquisition.cc | 3 +- .../gnuradio_blocks/CMakeLists.txt | 6 +- .../gnuradio_blocks/pcps_acquisition.cc | 8 +-- .../gnuradio_blocks/pcps_acquisition.h | 28 ++------- .../acquisition/libs/CMakeLists.txt | 20 +++--- src/algorithms/acquisition/libs/acq_conf.cc | 52 ++++++++++++++++ src/algorithms/acquisition/libs/acq_conf.h | 61 +++++++++++++++++++ 15 files changed, 152 insertions(+), 51 deletions(-) create mode 100644 src/algorithms/acquisition/libs/acq_conf.cc create mode 100644 src/algorithms/acquisition/libs/acq_conf.h diff --git a/src/algorithms/acquisition/CMakeLists.txt b/src/algorithms/acquisition/CMakeLists.txt index 0dc31ec9b..96259341c 100644 --- a/src/algorithms/acquisition/CMakeLists.txt +++ b/src/algorithms/acquisition/CMakeLists.txt @@ -18,7 +18,4 @@ add_subdirectory(adapters) add_subdirectory(gnuradio_blocks) -if(ENABLE_FPGA) - add_subdirectory(libs) -endif(ENABLE_FPGA) - +add_subdirectory(libs) diff --git a/src/algorithms/acquisition/adapters/CMakeLists.txt b/src/algorithms/acquisition/adapters/CMakeLists.txt index 831601796..82b4b33c1 100644 --- a/src/algorithms/acquisition/adapters/CMakeLists.txt +++ b/src/algorithms/acquisition/adapters/CMakeLists.txt @@ -65,4 +65,4 @@ file(GLOB ACQ_ADAPTER_HEADERS "*.h") list(SORT ACQ_ADAPTER_HEADERS) add_library(acq_adapters ${ACQ_ADAPTER_SOURCES} ${ACQ_ADAPTER_HEADERS}) source_group(Headers FILES ${ACQ_ADAPTER_HEADERS}) -target_link_libraries(acq_adapters gnss_sp_libs gnss_sdr_flags acq_gr_blocks ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES}) +target_link_libraries(acq_adapters acquisition_lib gnss_sp_libs gnss_sdr_flags acq_gr_blocks ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES}) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc index 755d8e48e..a9f96da43 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc @@ -34,6 +34,7 @@ #include "galileo_e1_signal_processing.h" #include "Galileo_E1.h" #include "gnss_sdr_flags.h" +#include "acq_conf.h" #include #include #include @@ -45,7 +46,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - pcpsconf_t acq_parameters; + Acq_Conf acq_parameters; configuration_ = configuration; std::string default_item_type = "gr_complex"; std::string default_dump_filename = "./data/acquisition.dat"; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc index 82bbb896e..16142eab9 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc @@ -33,6 +33,7 @@ #include "galileo_e5_signal_processing.h" #include "Galileo_E5a.h" #include "gnss_sdr_flags.h" +#include "acq_conf.h" #include #include #include @@ -44,7 +45,7 @@ using google::LogMessage; GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - pcpsconf_t acq_parameters; + Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; std::string default_dump_filename = "../data/acquisition.dat"; diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc index 90370eef4..c49f1f0c4 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc @@ -35,6 +35,7 @@ #include "configuration_interface.h" #include "glonass_l1_signal_processing.h" #include "gnss_sdr_flags.h" +#include "acq_conf.h" #include "GLONASS_L1_L2_CA.h" #include #include @@ -46,7 +47,7 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - pcpsconf_t acq_parameters; + Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; std::string default_dump_filename = "./data/acquisition.dat"; diff --git a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc index de9a28bb5..ec17ad911 100644 --- a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc @@ -35,6 +35,7 @@ #include "glonass_l2_signal_processing.h" #include "GLONASS_L1_L2_CA.h" #include "gnss_sdr_flags.h" +#include "acq_conf.h" #include #include @@ -45,7 +46,7 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - pcpsconf_t acq_parameters; + Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; std::string default_dump_filename = "./data/acquisition.dat"; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc index d319cc46f..45a8d743c 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc @@ -38,6 +38,7 @@ #include "gps_sdr_signal_processing.h" #include "GPS_L1_CA.h" #include "gnss_sdr_flags.h" +#include "acq_conf.h" #include #include @@ -48,7 +49,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - pcpsconf_t acq_parameters; + Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; std::string default_dump_filename = "./data/acquisition.dat"; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc index a1c97a9a2..bb185c92c 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc @@ -36,6 +36,7 @@ #include "gps_l2c_signal.h" #include "GPS_L2C.h" #include "gnss_sdr_flags.h" +#include "acq_conf.h" #include #include @@ -46,7 +47,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - pcpsconf_t acq_parameters; + Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; std::string default_dump_filename = "./data/acquisition.dat"; diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc index d41824d94..4595bd2e2 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc @@ -36,6 +36,7 @@ #include "gps_l5_signal.h" #include "GPS_L5.h" #include "gnss_sdr_flags.h" +#include "acq_conf.h" #include #include @@ -46,7 +47,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - pcpsconf_t acq_parameters; + Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; std::string default_dump_filename = "./data/acquisition.dat"; diff --git a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt index fbc33410e..50fc61ae9 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt @@ -26,12 +26,12 @@ set(ACQ_GR_BLOCKS_SOURCES pcps_quicksync_acquisition_cc.cc galileo_pcps_8ms_acquisition_cc.cc galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc -) +) if(ENABLE_FPGA) set(ACQ_GR_BLOCKS_SOURCES ${ACQ_GR_BLOCKS_SOURCES} pcps_acquisition_fpga.cc) endif(ENABLE_FPGA) - + if(OPENCL_FOUND) set(ACQ_GR_BLOCKS_SOURCES ${ACQ_GR_BLOCKS_SOURCES} pcps_opencl_acquisition_cc.cc) endif(OPENCL_FOUND) @@ -64,7 +64,7 @@ endif(OPENCL_FOUND) file(GLOB ACQ_GR_BLOCKS_HEADERS "*.h") list(SORT ACQ_GR_BLOCKS_HEADERS) add_library(acq_gr_blocks ${ACQ_GR_BLOCKS_SOURCES} ${ACQ_GR_BLOCKS_HEADERS}) -source_group(Headers FILES ${ACQ_GR_BLOCKS_HEADERS}) +source_group(Headers FILES ${ACQ_GR_BLOCKS_HEADERS}) if(ENABLE_FPGA) target_link_libraries(acq_gr_blocks acquisition_lib gnss_sp_libs gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_FFT_LIBRARIES} ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${OPT_LIBRARIES} ${OPT_ACQUISITION_LIBRARIES}) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 4ac53ab41..1176105d3 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -45,15 +45,15 @@ using google::LogMessage; -pcps_acquisition_sptr pcps_make_acquisition(pcpsconf_t conf_) +pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_) { return pcps_acquisition_sptr(new pcps_acquisition(conf_)); } -pcps_acquisition::pcps_acquisition(pcpsconf_t conf_) : gr::block("pcps_acquisition", - gr::io_signature::make(1, 1, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1)), - gr::io_signature::make(0, 0, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1))) +pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acquisition", + gr::io_signature::make(1, 1, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1)), + gr::io_signature::make(0, 0, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1))) { this->message_port_register_out(pmt::mp("events")); diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index 4c4dab929..615957921 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -53,38 +53,20 @@ #define GNSS_SDR_PCPS_ACQUISITION_H_ #include "gnss_synchro.h" +#include "acq_conf.h" #include #include #include #include #include -typedef struct -{ - /* pcps acquisition configuration */ - unsigned int sampled_ms; - unsigned int max_dwells; - unsigned int doppler_max; - unsigned int num_doppler_bins_step2; - float doppler_step2; - long fs_in; - int samples_per_ms; - int samples_per_code; - bool bit_transition_flag; - bool use_CFAR_algorithm_flag; - bool dump; - bool blocking; - bool make_2_steps; - std::string dump_filename; - size_t it_size; -} pcpsconf_t; class pcps_acquisition; typedef boost::shared_ptr pcps_acquisition_sptr; pcps_acquisition_sptr -pcps_make_acquisition(pcpsconf_t conf_); +pcps_make_acquisition(const Acq_Conf& conf_); /*! * \brief This class implements a Parallel Code Phase Search Acquisition. @@ -96,9 +78,9 @@ class pcps_acquisition : public gr::block { private: friend pcps_acquisition_sptr - pcps_make_acquisition(pcpsconf_t conf_); + pcps_make_acquisition(const Acq_Conf& conf_); - pcps_acquisition(pcpsconf_t conf_); + pcps_acquisition(const Acq_Conf& conf_); void update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq); void update_grid_doppler_wipeoffs(); @@ -111,7 +93,7 @@ private: void send_positive_acquisition(); - pcpsconf_t acq_parameters; + Acq_Conf acq_parameters; bool d_active; bool d_worker_active; bool d_cshort; diff --git a/src/algorithms/acquisition/libs/CMakeLists.txt b/src/algorithms/acquisition/libs/CMakeLists.txt index 332d83723..05a116e0f 100644 --- a/src/algorithms/acquisition/libs/CMakeLists.txt +++ b/src/algorithms/acquisition/libs/CMakeLists.txt @@ -16,12 +16,9 @@ # along with GNSS-SDR. If not, see . # - -set(ACQUISITION_LIB_SOURCES - fpga_acquisition.cc -) - -include_directories( +if(ENABLE_FPGA) + set(ACQUISITION_LIB_SOURCES fpga_acquisition.cc ) + include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src/core/system_parameters ${CMAKE_SOURCE_DIR}/src/core/interfaces @@ -31,10 +28,16 @@ include_directories( ${GLOG_INCLUDE_DIRS} ${GFlags_INCLUDE_DIRS} ${VOLK_GNSSSDR_INCLUDE_DIRS} -) + ) -file(GLOB ACQUISITION_LIB_HEADERS "*.h") + file(GLOB ACQUISITION_LIB_HEADERS "*.h") +endif(ENABLE_FPGA) + +set(ACQUISITION_LIB_HEADERS ${ACQUISITION_LIB_HEADERS} acq_conf.h) list(SORT ACQUISITION_LIB_HEADERS) + +set(ACQUISITION_LIB_SOURCES ${ACQUISITION_LIB_SOURCES} acq_conf.cc) + add_library(acquisition_lib ${ACQUISITION_LIB_SOURCES} ${ACQUISITION_LIB_HEADERS}) source_group(Headers FILES ${ACQUISITION_LIB_HEADERS}) target_link_libraries(acquisition_lib ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES}) @@ -43,4 +46,3 @@ if(VOLK_GNSSSDR_FOUND) else(VOLK_GNSSSDR_FOUND) add_dependencies(acquisition_lib glog-${glog_RELEASE} volk_gnsssdr_module) endif() - diff --git a/src/algorithms/acquisition/libs/acq_conf.cc b/src/algorithms/acquisition/libs/acq_conf.cc new file mode 100644 index 000000000..c1b288ef4 --- /dev/null +++ b/src/algorithms/acquisition/libs/acq_conf.cc @@ -0,0 +1,52 @@ +/*! + * \file acq_conf.cc + * \brief Class that contains all the configuration parameters for generic + * acquisition block based on the PCPS algoritm. + * \author Carles Fernandez, 2018. cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include "acq_conf.h" + +Acq_Conf::Acq_Conf() +{ + /* PCPS acquisition configuration */ + sampled_ms = 0; + max_dwells = 0; + unsigned int doppler_max = 0; + unsigned int num_doppler_bins_step2 = 0; + float doppler_step2 = 0.0; + long fs_in = 0; + int samples_per_ms = 0; + int samples_per_code = 0; + bool bit_transition_flag = false; + bool use_CFAR_algorithm_flag = false; + bool dump = false; + bool blocking = false; + bool make_2_steps = false; + std::string dump_filename = ""; + it_size = sizeof(char); +} diff --git a/src/algorithms/acquisition/libs/acq_conf.h b/src/algorithms/acquisition/libs/acq_conf.h new file mode 100644 index 000000000..422e889bc --- /dev/null +++ b/src/algorithms/acquisition/libs/acq_conf.h @@ -0,0 +1,61 @@ +/*! + * \file acq_conf.cc + * \brief Class that contains all the configuration parameters for generic + * acquisition block based on the PCPS algoritm. + * \author Carles Fernandez, 2018. cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_ACQ_CONF_H_ +#define GNSS_SDR_ACQ_CONF_H_ + +#include +#include + +class Acq_Conf +{ +public: + /* PCPS Acquisition configuration */ + unsigned int sampled_ms; + unsigned int max_dwells; + unsigned int doppler_max; + unsigned int num_doppler_bins_step2; + float doppler_step2; + long fs_in; + int samples_per_ms; + int samples_per_code; + bool bit_transition_flag; + bool use_CFAR_algorithm_flag; + bool dump; + bool blocking; + bool make_2_steps; + std::string dump_filename; + size_t it_size; + + Acq_Conf(); +}; + +#endif From df667b843271edf157105f504d359d6577d0802b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 19 Jun 2018 14:56:11 +0200 Subject: [PATCH 07/40] Fix constructor --- src/algorithms/acquisition/libs/acq_conf.cc | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/algorithms/acquisition/libs/acq_conf.cc b/src/algorithms/acquisition/libs/acq_conf.cc index c1b288ef4..f403992e4 100644 --- a/src/algorithms/acquisition/libs/acq_conf.cc +++ b/src/algorithms/acquisition/libs/acq_conf.cc @@ -36,17 +36,17 @@ Acq_Conf::Acq_Conf() /* PCPS acquisition configuration */ sampled_ms = 0; max_dwells = 0; - unsigned int doppler_max = 0; - unsigned int num_doppler_bins_step2 = 0; - float doppler_step2 = 0.0; - long fs_in = 0; - int samples_per_ms = 0; - int samples_per_code = 0; - bool bit_transition_flag = false; - bool use_CFAR_algorithm_flag = false; - bool dump = false; - bool blocking = false; - bool make_2_steps = false; - std::string dump_filename = ""; + doppler_max = 0; + num_doppler_bins_step2 = 0; + doppler_step2 = 0.0; + fs_in = 0; + samples_per_ms = 0; + samples_per_code = 0; + bit_transition_flag = false; + use_CFAR_algorithm_flag = false; + dump = false; + blocking = false; + make_2_steps = false; + dump_filename = ""; it_size = sizeof(char); } From bfef0122313a7caa49fb925122164469722bb391 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Tue, 19 Jun 2018 17:51:22 +0200 Subject: [PATCH 08/40] Adding CN0 sweep option to the GPS L1 CA DLL/PLL unit test and adding extra results plots --- .../libs/observables_dump_reader.cc | 7 + .../libs/observables_dump_reader.h | 1 + .../libs/tracking_true_obs_reader.cc | 12 +- .../libs/tracking_true_obs_reader.h | 1 + .../gps_l1_ca_dll_pll_tracking_test.cc | 537 ++++++++++++------ 5 files changed, 376 insertions(+), 182 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc index 72a40389d..a913eeee0 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc @@ -112,6 +112,13 @@ bool observables_dump_reader::open_obs_file(std::string out_file) } } +void observables_dump_reader::close_obs_file() +{ + if (d_dump_file.is_open() == false) + { + d_dump_file.close(); + } +} observables_dump_reader::observables_dump_reader(int n_channels_) { diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.h index 41c7a60f2..c87062eaf 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.h +++ b/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.h @@ -44,6 +44,7 @@ public: bool restart(); long int num_epochs(); bool open_obs_file(std::string out_file); + void close_obs_file(); //dump variables diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc index 8b1f91c65..b27c44688 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc @@ -89,15 +89,16 @@ bool tracking_true_obs_reader::open_obs_file(std::string out_file) { try { + d_dump_file.clear(); d_dump_filename = out_file; d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); d_dump_file.open(d_dump_filename.c_str(), std::ios::in | std::ios::binary); - std::cout << "Observables dump enabled, Log file: " << d_dump_filename.c_str() << std::endl; + std::cout << "Tracking Log file: " << d_dump_filename.c_str() << " open ok " << std::endl; return true; } catch (const std::ifstream::failure &e) { - std::cout << "Problem opening Observables dump Log file: " << d_dump_filename.c_str() << std::endl; + std::cout << "Problem opening Tracking dump Log file: " << d_dump_filename.c_str() << " Error: " << e.what() << std::endl; return false; } } @@ -107,6 +108,13 @@ bool tracking_true_obs_reader::open_obs_file(std::string out_file) } } +void tracking_true_obs_reader::close_obs_file() +{ + if (d_dump_file.is_open() == true) + { + d_dump_file.close(); + } +} tracking_true_obs_reader::~tracking_true_obs_reader() { diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.h index 9c4a5db7c..84bd2d7b0 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.h +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.h @@ -43,6 +43,7 @@ public: bool restart(); long int num_epochs(); bool open_obs_file(std::string out_file); + void close_obs_file(); bool d_dump; double signal_timestamp_s; diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index b8363c383..d28289e83 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -53,10 +53,23 @@ #include "gnuplot_i.h" #include "test_flags.h" -DEFINE_bool(plot_gps_l1_tracking_test, false, "Plots results of GpsL1CADllPllTrackingTest with gnuplot"); -DEFINE_double(CN0_dBHz, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 [dB-Hz]"); + +// Input signal configuration +DEFINE_bool(enable_external_signal_file, false, "Use an external signal file capture instead of the software-defined signal generator"); +DEFINE_string(signal_file, std::string("gps_l1_capture.dat"), "Path of the external signal capture file"); +DEFINE_double(CN0_dBHz_start, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]"); +DEFINE_double(CN0_dBHz_stop, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 stop sweep value [dB-Hz]"); +DEFINE_double(CN0_dB_step, 3.0, "Noise generator CN0 sweep step value [dB]"); + + +//Emulated acquisition configuration + +//Tracking configuration DEFINE_int32(extend_correlation_symbols, 1, "Set the tracking coherent correlation to N symbols (up to 20 for GPS L1 C/A)"); +//Test output configuration +DEFINE_bool(plot_gps_l1_tracking_test, false, "Plots results of GpsL1CADllPllTrackingTest with gnuplot"); + // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class GpsL1CADllPllTrackingTest_msg_rx; @@ -130,17 +143,17 @@ public: std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; - int configure_generator(); + int configure_generator(double CN0_dBHz, int file_idx); int generate_signal(); - void check_results_doppler(arma::vec& true_time_s, + std::vector 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, + std::vector 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, + std::vector check_results_codephase(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, arma::vec& meas_value); @@ -167,7 +180,7 @@ public: }; -int GpsL1CADllPllTrackingTest::configure_generator() +int GpsL1CADllPllTrackingTest::configure_generator(double CN0_dBHz, int file_idx) { // Configure signal generator generator_binary = FLAGS_generator_binary; @@ -181,10 +194,10 @@ int GpsL1CADllPllTrackingTest::configure_generator() { 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] - p6 = std::string("-CN0_dBHz=") + std::to_string(FLAGS_CN0_dBHz); // Signal generator CN0 + 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 + std::to_string(file_idx); // 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] + p6 = std::string("-CN0_dBHz=") + std::to_string(CN0_dBHz); // Signal generator CN0 return 0; } @@ -193,7 +206,7 @@ int GpsL1CADllPllTrackingTest::generate_signal() { int child_status; - char* const parmList[] = {&generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0],&p6[0], NULL}; + char* const parmList[] = {&generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0], &p6[0], NULL}; int pid; if ((pid = fork()) == -1) @@ -236,7 +249,7 @@ void GpsL1CADllPllTrackingTest::configure_receiver() } -void GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec& true_time_s, +std::vector GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, arma::vec& meas_value) @@ -256,6 +269,10 @@ void GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec& true_time_s, arma::vec err; err = meas_value - true_value_interp; + + //conversion between arma::vec and std:vector + std::vector err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows); + arma::vec err2 = arma::square(err); double rmse = sqrt(arma::mean(err2)); @@ -273,10 +290,11 @@ void GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec& true_time_s, << ", mean=" << error_mean << ", stdev=" << sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Hz]" << std::endl; std::cout.precision(ss); + return err_std_vector; } -void GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(arma::vec& true_time_s, +std::vector GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, arma::vec& meas_value) @@ -296,6 +314,9 @@ void GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(arma::vec& true_ arma::vec err; err = meas_value - true_value_interp; arma::vec err2 = arma::square(err); + //conversion between arma::vec and std:vector + std::vector err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows); + double rmse = sqrt(arma::mean(err2)); // 3. Mean err and variance @@ -312,10 +333,11 @@ void GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(arma::vec& true_ << ", mean=" << error_mean << ", stdev=" << sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Hz]" << std::endl; std::cout.precision(ss); + return err_std_vector; } -void GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec& true_time_s, +std::vector GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, arma::vec& meas_value) @@ -335,6 +357,9 @@ void GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec& true_time_s, arma::vec err; err = meas_value - true_value_interp; + //conversion between arma::vec and std:vector + std::vector err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows); + arma::vec err2 = arma::square(err); double rmse = sqrt(arma::mean(err2)); @@ -352,164 +377,259 @@ void GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec& true_time_s, << ", mean=" << error_mean << ", stdev=" << sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Chips]" << std::endl; std::cout.precision(ss); + return err_std_vector; } TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) { - // Configure the signal generator - configure_generator(); + //************************************************* + //***** STEP 2: Prepare the parameters sweep ****** + //************************************************* - // Generate signal raw signal samples and observations RINEX file - if (FLAGS_disable_generator == false) + std::vector generator_CN0_values; + + std::vector> prompt_sweep; + std::vector> early_sweep; + std::vector> late_sweep; + std::vector> promptI_sweep; + std::vector> promptQ_sweep; + std::vector> CN0_dBHz_sweep; + + //error vectors + std::vector> doppler_error_sweep; + std::vector> code_phase_error_sweep; + std::vector> acc_carrier_phase_error_sweep; + std::vector> trk_timestamp_s_sweep; + + if (FLAGS_CN0_dBHz_start == FLAGS_CN0_dBHz_stop) { - generate_signal(); + generator_CN0_values.push_back(FLAGS_CN0_dBHz_start); + } + else + { + for (double cn0 = FLAGS_CN0_dBHz_start; cn0 > FLAGS_CN0_dBHz_stop; cn0 = cn0 - FLAGS_CN0_dB_step) + { + generator_CN0_values.push_back(cn0); + } } - std::chrono::time_point start, end; - - configure_receiver(); - - // open true observables log file written by the simulator + int test_satellite_PRN = 0; + double acq_delay_samples = 0.0; + double acq_doppler_hz = 0.0; 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 trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1); - std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); //std::make_shared(config.get(), "Tracking_1C", 1, 1); - - boost::shared_ptr msg_rx = GpsL1CADllPllTrackingTest_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) * static_cast(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()) + //********************************************* + //***** STEP 3: Generate the input signal ***** + //********************************************* + // use generator or use an external capture file + if (FLAGS_enable_external_signal_file) { - 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++; + //todo: create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters + } + else + { + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + // Configure the signal generator + configure_generator(generator_CN0_values.at(current_cn0_idx), current_cn0_idx); + // Generate signal raw signal samples and observations RINEX file + if (FLAGS_disable_generator == false) + { + generate_signal(); + } + // open true observables log file written by the simulator + } } - //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"; + //CN0 LOOP - 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 prompt; - std::vector early; - std::vector late; - std::vector promptI; - std::vector promptQ; - std::vector CN0_dBHz; - - epoch_counter = 0; - while (trk_dump.read_binary_obs()) + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) { - trk_timestamp_s(epoch_counter) = static_cast(trk_dump.PRN_start_sample_count) / static_cast(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; + //****************************************************************************************** + //***** Obtain the initial signal sinchronization parameters (emulating an acquisition) **** + //****************************************************************************************** + if (!FLAGS_enable_external_signal_file) + { + test_satellite_PRN = FLAGS_test_satellite_PRN; + 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"); + true_obs_data.close_obs_file(); + ASSERT_EQ(true_obs_data.open_obs_file(true_obs_file), true) << "Failure opening true observables file"; + // 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?"; + std::cout << "Testing satellite PRN=" << test_satellite_PRN << std::endl; + std::cout << "Initial Doppler [Hz]=" << true_obs_data.doppler_l1_hz << " Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << std::endl; + acq_doppler_hz = true_obs_data.doppler_l1_hz; + acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * static_cast(baseband_sampling_freq) * GPS_L1_CA_CODE_PERIOD; + // restart the epoch counter + true_obs_data.restart(); + } - double delay_chips = GPS_L1_CA_CODE_LENGTH_CHIPS - GPS_L1_CA_CODE_LENGTH_CHIPS * (fmod((static_cast(trk_dump.PRN_start_sample_count) + trk_dump.aux1) / static_cast(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); - CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz); - } + //***** STEP 4: Configure the signal tracking parameters ***** + //************************************************************ + std::chrono::time_point start, end; + configure_receiver(); - // 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"); + top_block = gr::make_top_block("Tracking test"); - 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); + std::shared_ptr trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1); + std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); - 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); + boost::shared_ptr msg_rx = GpsL1CADllPllTrackingTest_msg_rx_make(); - std::chrono::duration elapsed_seconds = end - start; - std::cout << "Signal tracking completed in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; + gnss_synchro.Acq_delay_samples = acq_delay_samples; + gnss_synchro.Acq_doppler_hz = acq_doppler_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 + std::to_string(current_cn0_idx); + 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."; + + + //******************************************************************** + //***** STEP 5: Perform the signal tracking and read the results ***** + //******************************************************************** + 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."; + + std::chrono::duration elapsed_seconds = end - start; + std::cout << "Signal tracking completed in " << elapsed_seconds.count() << " seconds" << std::endl; + + //check results + //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"; + + long int n_measured_epochs = trk_dump.num_epochs(); + std::cout << "Measured observation epochs=" << n_measured_epochs << std::endl; + + arma::vec trk_timestamp_s = arma::zeros(n_measured_epochs, 1); + arma::vec trk_acc_carrier_phase_cycles = arma::zeros(n_measured_epochs, 1); + arma::vec trk_Doppler_Hz = arma::zeros(n_measured_epochs, 1); + arma::vec trk_prn_delay_chips = arma::zeros(n_measured_epochs, 1); + + long int epoch_counter = 0; + + std::vector prompt; + std::vector early; + std::vector late; + std::vector promptI; + std::vector promptQ; + std::vector CN0_dBHz; + while (trk_dump.read_binary_obs()) + { + trk_timestamp_s(epoch_counter) = static_cast(trk_dump.PRN_start_sample_count) / static_cast(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(trk_dump.PRN_start_sample_count) + trk_dump.aux1) / static_cast(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); + CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz); + } + + prompt_sweep.push_back(prompt); + early_sweep.push_back(early); + late_sweep.push_back(late); + promptI_sweep.push_back(promptI); + promptQ_sweep.push_back(promptQ); + CN0_dBHz_sweep.push_back(CN0_dBHz); + + //*********************************************************** + //***** STEP 6: Compare with true values (if available) ***** + //*********************************************************** + if (!FLAGS_enable_external_signal_file) + { + // load the true values + long int n_true_epochs = true_obs_data.num_epochs(); + std::cout << "True observation epochs=" << n_true_epochs << std::endl; + + arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); + arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); + arma::vec true_Doppler_Hz = arma::zeros(n_true_epochs, 1); + arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); + arma::vec true_tow_s = arma::zeros(n_true_epochs, 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++; + } + // 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); + + std::vector doppler_error_hz; + std::vector code_phase_error_chips; + std::vector acc_carrier_phase_hz; + doppler_error_hz = check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz); + code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips); + acc_carrier_phase_hz = check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles); + //save tracking measurement timestamps to std::vector + std::vector vector_trk_timestamp_s(trk_timestamp_s.colptr(0), trk_timestamp_s.colptr(0) + trk_timestamp_s.n_rows); + trk_timestamp_s_sweep.push_back(vector_trk_timestamp_s); + + doppler_error_sweep.push_back(doppler_error_hz); + code_phase_error_sweep.push_back(code_phase_error_chips); + acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz); + } + + } //CN0 LOOP + + //******************************** + //***** STEP 7: Plot results ***** + //******************************** if (FLAGS_plot_gps_l1_tracking_test == true) { const std::string gnuplot_executable(FLAGS_gnuplot_executable); @@ -527,49 +647,106 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) boost::filesystem::path dir = p.parent_path(); std::string gnuplot_path = dir.native(); Gnuplot::set_GNUPlotPath(gnuplot_path); - std::vector 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(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 - + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + timevec.clear(); + //todo: timevector MUST BE READED from the trk output file + double t = 0.0; + for (auto it = prompt_sweep.at(current_cn0_idx).begin(); it != prompt_sweep.at(current_cn0_idx).end(); it++) + { + timevec.push_back(t); + t = t + GPS_L1_CA_CODE_PERIOD; + } + Gnuplot g1("linespoints"); + g1.set_title("[" + std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz ] 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"); + g1.plot_xy(timevec, prompt_sweep.at(current_cn0_idx), "Prompt", decimate); + g1.plot_xy(timevec, early_sweep.at(current_cn0_idx), "Early", decimate); + g1.plot_xy(timevec, late_sweep.at(current_cn0_idx), "Late", decimate); + g1.savetops("Correlators_outputs"); + g1.savetopdf("Correlators_outputs", 18); + g1.showonscreen(); // window output + Gnuplot g2("points"); + g2.set_title("[" + std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz ] 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_sweep.at(current_cn0_idx), promptQ_sweep.at(current_cn0_idx)); + g2.savetops("Constellation"); + g2.savetopdf("Constellation", 18); + g2.showonscreen(); // window output + } Gnuplot g3("linespoints"); g3.set_title("GPS L1 C/A tracking CN0 output (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g3.set_grid(); g3.set_xlabel("Time [s]"); g3.set_ylabel("Reported CN0 [dB-Hz]"); g3.cmd("set key box opaque"); - g3.plot_xy(timevec, CN0_dBHz, "Prompt", decimate); + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g3.plot_xy(timevec, CN0_dBHz_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + g3.set_legend(); g3.savetops("CN0_output"); g3.savetopdf("CN0_output", 18); g3.showonscreen(); // window output + + Gnuplot g4("points"); + g4.set_title("Doppler error (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g4.set_grid(); + g4.set_xlabel("Time [s]"); + g4.set_ylabel("Dopper error [Hz]"); + g4.cmd("set key box opaque"); + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g4.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), doppler_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + g4.set_legend(); + g4.savetops("Doppler_error_output"); + g4.savetopdf("Doppler_error_output", 18); + g4.showonscreen(); // window output + + Gnuplot g5("points"); + g5.set_title("Code delay error (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g5.set_grid(); + g5.set_xlabel("Time [s]"); + g5.set_ylabel("Code delay error [Chips]"); + g5.cmd("set key box opaque"); + + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g5.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + g5.set_legend(); + g5.savetops("Code_error_output"); + g5.savetopdf("Code_error_output", 18); + g5.showonscreen(); // window output + + Gnuplot g6("points"); + g6.set_title("Accumulated carrier phase error (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g6.set_grid(); + g6.set_xlabel("Time [s]"); + g6.set_ylabel("Accumulated carrier phase error [Cycles]"); + g6.cmd("set key box opaque"); + + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g6.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), acc_carrier_phase_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + g6.set_legend(); + g6.savetops("Carrier_phase_error_output"); + g6.savetopdf("Carrier_phase_error_output", 18); + g6.showonscreen(); // window output } catch (const GnuplotException& ge) { From 306f8103d2915d605b67f25a017cef181f2d7fca Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Wed, 20 Jun 2018 12:04:03 +0200 Subject: [PATCH 09/40] Fix GNUPLOT interface to support multiplots and improving tracking unit test plots --- src/tests/common-files/gnuplot_i.h | 60 ++-- .../gps_l1_ca_dll_pll_tracking_test.cc | 262 ++++++++++++------ 2 files changed, 206 insertions(+), 116 deletions(-) diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index 2df3a9c92..448cdf4b9 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -302,9 +302,9 @@ public: /// /// \return <-- reference to the gnuplot object // ----------------------------------------------- - inline Gnuplot &set_multiplot() + inline Gnuplot &set_multiplot(int rows, int cols) { - cmd("set multiplot"); + cmd("set multiplot layout " + std::to_string(rows) + "," + std::to_string(cols)); //+ " rowfirst"); return *this; }; @@ -1906,11 +1906,11 @@ void Gnuplot::init() std::string tmp = Gnuplot::m_sGNUPlotPath + "/" + Gnuplot::m_sGNUPlotFileName; - // FILE *popen(const char *command, const char *mode); - // The popen() function shall execute the command specified by the string - // command, create a pipe between the calling program and the executed - // command, and return a pointer to a stream that can be used to either read - // from or write to the pipe. +// FILE *popen(const char *command, const char *mode); +// The popen() function shall execute the command specified by the string +// command, create a pipe between the calling program and the executed +// command, and return a pointer to a stream that can be used to either read +// from or write to the pipe. #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) gnucmd = _popen(tmp.c_str(), "w"); #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) @@ -1974,7 +1974,7 @@ bool Gnuplot::get_program_path() std::list ls; - //split path (one long string) into list ls of strings +//split path (one long string) into list ls of strings #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) stringtok(ls, path_str, ";"); #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) @@ -2018,16 +2018,16 @@ bool Gnuplot::file_exists(const std::string &filename, int mode) return false; } - // int _access(const char *path, int mode); - // returns 0 if the file has the given mode, - // it returns -1 if the named file does not exist or is not accessible in - // the given mode - // mode = 0 (F_OK) (default): checks file for existence only - // mode = 1 (X_OK): execution permission - // mode = 2 (W_OK): write permission - // mode = 4 (R_OK): read permission - // mode = 6 : read and write permission - // mode = 7 : read, write and execution permission +// int _access(const char *path, int mode); +// returns 0 if the file has the given mode, +// it returns -1 if the named file does not exist or is not accessible in +// the given mode +// mode = 0 (F_OK) (default): checks file for existence only +// mode = 1 (X_OK): execution permission +// mode = 2 (W_OK): write permission +// mode = 4 (R_OK): read permission +// mode = 6 : read and write permission +// mode = 7 : read, write and execution permission #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) if (_access(filename.c_str(), mode) == 0) #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) @@ -2089,19 +2089,19 @@ std::string Gnuplot::create_tmpfile(std::ofstream &tmp) throw GnuplotException(except.str()); } - // int mkstemp(char *name); - // shall replace the contents of the string pointed to by "name" by a unique - // filename, and return a file descriptor for the file open for reading and - // writing. Otherwise, -1 shall be returned if no suitable file could be - // created. The string in template should look like a filename with six - // trailing 'X' s; mkstemp() replaces each 'X' with a character from the - // portable filename character set. The characters are chosen such that the - // resulting name does not duplicate the name of an existing file at the - // time of a call to mkstemp() +// int mkstemp(char *name); +// shall replace the contents of the string pointed to by "name" by a unique +// filename, and return a file descriptor for the file open for reading and +// writing. Otherwise, -1 shall be returned if no suitable file could be +// created. The string in template should look like a filename with six +// trailing 'X' s; mkstemp() replaces each 'X' with a character from the +// portable filename character set. The characters are chosen such that the +// resulting name does not duplicate the name of an existing file at the +// time of a call to mkstemp() - // - // open temporary files for output - // +// +// open temporary files for output +// #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) if (_mktemp(name) == NULL) diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index d28289e83..e60ccf76d 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -148,15 +148,21 @@ public: std::vector check_results_doppler(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, - arma::vec& meas_value); + arma::vec& meas_value, + double& mean_error, + double& std_dev_error); std::vector check_results_acc_carrier_phase(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, - arma::vec& meas_value); + arma::vec& meas_value, + double& mean_error, + double& std_dev_error); std::vector check_results_codephase(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, - arma::vec& meas_value); + arma::vec& meas_value, + double& mean_error, + double& std_dev_error); GpsL1CADllPllTrackingTest() { @@ -252,7 +258,9 @@ void GpsL1CADllPllTrackingTest::configure_receiver() std::vector GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, - arma::vec& meas_value) + arma::vec& meas_value, + double& mean_error, + double& std_dev_error) { // 1. True value interpolation to match the measurement times arma::vec true_value_interp; @@ -280,6 +288,9 @@ std::vector GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec& double error_mean = arma::mean(err); double error_var = arma::var(err); + mean_error = error_mean; + std_dev_error = sqrt(error_var); + // 4. Peaks double max_error = arma::max(err); double min_error = arma::min(err); @@ -297,7 +308,9 @@ std::vector GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec& std::vector GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, - arma::vec& meas_value) + arma::vec& meas_value, + double& mean_error, + double& std_dev_error) { // 1. True value interpolation to match the measurement times arma::vec true_value_interp; @@ -323,6 +336,8 @@ std::vector GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(a double error_mean = arma::mean(err); double error_var = arma::var(err); + mean_error = error_mean; + std_dev_error = sqrt(error_var); // 4. Peaks double max_error = arma::max(err); double min_error = arma::min(err); @@ -340,7 +355,9 @@ std::vector GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(a std::vector GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, - arma::vec& meas_value) + arma::vec& meas_value, + double& mean_error, + double& std_dev_error) { // 1. True value interpolation to match the measurement times arma::vec true_value_interp; @@ -367,6 +384,9 @@ std::vector GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec double error_mean = arma::mean(err); double error_var = arma::var(err); + mean_error = error_mean; + std_dev_error = sqrt(error_var); + // 4. Peaks double max_error = arma::max(err); double min_error = arma::min(err); @@ -395,12 +415,22 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std::vector> promptI_sweep; std::vector> promptQ_sweep; std::vector> CN0_dBHz_sweep; + std::vector> trk_timestamp_s_sweep; //error vectors std::vector> doppler_error_sweep; + std::vector mean_doppler_error_sweep; + std::vector std_dev_doppler_error_sweep; + std::vector> code_phase_error_sweep; + std::vector mean_code_phase_error_sweep; + std::vector std_dev_code_phase_error_sweep; + std::vector> acc_carrier_phase_error_sweep; - std::vector> trk_timestamp_s_sweep; + std::vector mean_carrier_phase_error_sweep; + std::vector std_dev_carrier_phase_error_sweep; + + std::vector> trk_valid_timestamp_s_sweep; if (FLAGS_CN0_dBHz_start == FLAGS_CN0_dBHz_stop) { @@ -544,6 +574,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) long int epoch_counter = 0; + std::vector timestamp_s; std::vector prompt; std::vector early; std::vector late; @@ -558,17 +589,18 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) double delay_chips = GPS_L1_CA_CODE_LENGTH_CHIPS - GPS_L1_CA_CODE_LENGTH_CHIPS * (fmod((static_cast(trk_dump.PRN_start_sample_count) + trk_dump.aux1) / static_cast(baseband_sampling_freq), 1.0e-3) / 1.0e-3); trk_prn_delay_chips(epoch_counter) = delay_chips; - epoch_counter++; - + timestamp_s.push_back(trk_timestamp_s(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); CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz); - } + epoch_counter++; + } + trk_timestamp_s_sweep.push_back(timestamp_s); prompt_sweep.push_back(prompt); early_sweep.push_back(early); late_sweep.push_back(late); @@ -613,12 +645,25 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std::vector doppler_error_hz; std::vector code_phase_error_chips; std::vector acc_carrier_phase_hz; - doppler_error_hz = check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz); - code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips); - acc_carrier_phase_hz = check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles); + + double mean_error; + double std_dev_error; + + doppler_error_hz = check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz, mean_error, std_dev_error); + mean_doppler_error_sweep.push_back(mean_error); + std_dev_doppler_error_sweep.push_back(std_dev_error); + + code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips, mean_error, std_dev_error); + mean_code_phase_error_sweep.push_back(mean_error); + std_dev_code_phase_error_sweep.push_back(std_dev_error); + + acc_carrier_phase_hz = check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles, mean_error, std_dev_error); + mean_carrier_phase_error_sweep.push_back(mean_error); + std_dev_carrier_phase_error_sweep.push_back(std_dev_error); + //save tracking measurement timestamps to std::vector std::vector vector_trk_timestamp_s(trk_timestamp_s.colptr(0), trk_timestamp_s.colptr(0) + trk_timestamp_s.n_rows); - trk_timestamp_s_sweep.push_back(vector_trk_timestamp_s); + trk_valid_timestamp_s_sweep.push_back(vector_trk_timestamp_s); doppler_error_sweep.push_back(doppler_error_hz); code_phase_error_sweep.push_back(code_phase_error_chips); @@ -647,50 +692,53 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) boost::filesystem::path dir = p.parent_path(); std::string gnuplot_path = dir.native(); Gnuplot::set_GNUPlotPath(gnuplot_path); - std::vector timevec; unsigned int decimate = static_cast(FLAGS_plot_decimate); + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) { - timevec.clear(); - //todo: timevector MUST BE READED from the trk output file - double t = 0.0; - for (auto it = prompt_sweep.at(current_cn0_idx).begin(); it != prompt_sweep.at(current_cn0_idx).end(); it++) - { - timevec.push_back(t); - t = t + GPS_L1_CA_CODE_PERIOD; - } Gnuplot g1("linespoints"); - g1.set_title("[" + std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz ] GPS L1 C/A signal tracking correlators' output (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g1.showonscreen(); // window output + g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz GPS L1 C/A (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"); - g1.plot_xy(timevec, prompt_sweep.at(current_cn0_idx), "Prompt", decimate); - g1.plot_xy(timevec, early_sweep.at(current_cn0_idx), "Early", decimate); - g1.plot_xy(timevec, late_sweep.at(current_cn0_idx), "Late", decimate); - g1.savetops("Correlators_outputs"); - g1.savetopdf("Correlators_outputs", 18); - g1.showonscreen(); // window output - Gnuplot g2("points"); - g2.set_title("[" + std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz ] Constellation diagram (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + //g1.cmd("set key box opaque"); + g1.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), prompt_sweep.at(current_cn0_idx), "Prompt", decimate); + g1.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), early_sweep.at(current_cn0_idx), "Early", decimate); + g1.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), late_sweep.at(current_cn0_idx), "Late", decimate); + g1.set_legend(); + g1.savetops("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx))); + g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18); + } + + + Gnuplot g2("points"); + g2.showonscreen(); // window output + g2.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), + ceil(static_cast(generator_CN0_values.size()) / 2)); + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g2.reset_plot(); + g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation (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.cmd("set size ratio -1"); g2.plot_xy(promptI_sweep.at(current_cn0_idx), promptQ_sweep.at(current_cn0_idx)); - g2.savetops("Constellation"); - g2.savetopdf("Constellation", 18); - g2.showonscreen(); // window output } + g2.unset_multiplot(); + g2.savetops("Constellation"); + g2.savetopdf("Constellation", 18); + Gnuplot g3("linespoints"); - g3.set_title("GPS L1 C/A tracking CN0 output (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g3.set_title("GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g3.set_grid(); g3.set_xlabel("Time [s]"); g3.set_ylabel("Reported CN0 [dB-Hz]"); g3.cmd("set key box opaque"); for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) { - g3.plot_xy(timevec, CN0_dBHz_sweep.at(current_cn0_idx), + g3.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), CN0_dBHz_sweep.at(current_cn0_idx), std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); } g3.set_legend(); @@ -698,55 +746,97 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g3.savetopdf("CN0_output", 18); g3.showonscreen(); // window output - Gnuplot g4("points"); - g4.set_title("Doppler error (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g4.set_grid(); - g4.set_xlabel("Time [s]"); - g4.set_ylabel("Dopper error [Hz]"); - g4.cmd("set key box opaque"); - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + //PLOT ERROR FIGURES (only if it is used the signal generator) + if (!FLAGS_enable_external_signal_file) { - g4.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), doppler_error_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + Gnuplot g4("points"); + g4.showonscreen(); // window output + g4.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), + ceil(static_cast(generator_CN0_values.size()) / 2)); + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g4.reset_plot(); + g4.set_title(std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]" + " Doppler error (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g4.set_grid(); + //g4.cmd("set key box opaque"); + g4.set_xlabel("Time [s]"); + g4.set_ylabel("Dopper error [Hz]"); + g4.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), doppler_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + //g4.set_legend(); + } + g4.unset_multiplot(); + g4.savetops("Doppler_error_output"); + g4.savetopdf("Doppler_error_output", 18); + + Gnuplot g5("points"); + g5.set_title("Code delay error (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g5.set_grid(); + g5.set_xlabel("Time [s]"); + g5.set_ylabel("Code delay error [Chips]"); + g5.cmd("set key box opaque"); + + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g5.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + g5.set_legend(); + g5.savetops("Code_error_output"); + g5.savetopdf("Code_error_output", 18); + g5.showonscreen(); // window output + + Gnuplot g6("points"); + g6.set_title("Accumulated carrier phase error (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g6.set_grid(); + g6.set_xlabel("Time [s]"); + g6.set_ylabel("Accumulated carrier phase error [Cycles]"); + g6.cmd("set key box opaque"); + + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g6.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), acc_carrier_phase_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + g6.set_legend(); + g6.savetops("Carrier_phase_error_output"); + g6.savetopdf("Carrier_phase_error_output", 18); + g6.showonscreen(); // window output + + if (generator_CN0_values.size() > 1) + { + //plot metrics + Gnuplot g7("linespoints"); + g7.set_title("Doppler error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g7.set_grid(); + g7.set_xlabel("CN0 [dB-Hz]"); + g7.set_ylabel("Doppler error [Hz]"); + g7.cmd("set key box opaque"); + g7.plot_xy_err(generator_CN0_values, mean_doppler_error_sweep, std_dev_doppler_error_sweep, "Doppler error"); + g7.savetops("Doppler_error_metrics"); + g7.savetopdf("Doppler_error_metrics", 18); + + Gnuplot g8("linespoints"); + g8.set_title("Accumulated carrier phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g8.set_grid(); + g8.set_xlabel("CN0 [dB-Hz]"); + g8.set_ylabel("Accumulated Carrier Phase error [Hz]"); + g8.cmd("set key box opaque"); + g8.plot_xy_err(generator_CN0_values, mean_carrier_phase_error_sweep, std_dev_carrier_phase_error_sweep, "Carrier Phase error"); + g8.savetops("Carrier_error_metrics"); + g8.savetopdf("Carrier_error_metrics", 18); + + Gnuplot g9("linespoints"); + g9.set_title("Code Phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g9.set_grid(); + g9.set_xlabel("CN0 [dB-Hz]"); + g9.set_ylabel("Code Phase error [Hz]"); + g9.cmd("set key box opaque"); + g9.plot_xy_err(generator_CN0_values, mean_code_phase_error_sweep, std_dev_code_phase_error_sweep, "Code Phase error"); + g9.savetops("Code_error_metrics"); + g9.savetopdf("Code_error_metrics", 18); + } } - g4.set_legend(); - g4.savetops("Doppler_error_output"); - g4.savetopdf("Doppler_error_output", 18); - g4.showonscreen(); // window output - - Gnuplot g5("points"); - g5.set_title("Code delay error (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g5.set_grid(); - g5.set_xlabel("Time [s]"); - g5.set_ylabel("Code delay error [Chips]"); - g5.cmd("set key box opaque"); - - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) - { - g5.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); - } - g5.set_legend(); - g5.savetops("Code_error_output"); - g5.savetopdf("Code_error_output", 18); - g5.showonscreen(); // window output - - Gnuplot g6("points"); - g6.set_title("Accumulated carrier phase error (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g6.set_grid(); - g6.set_xlabel("Time [s]"); - g6.set_ylabel("Accumulated carrier phase error [Cycles]"); - g6.cmd("set key box opaque"); - - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) - { - g6.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), acc_carrier_phase_error_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); - } - g6.set_legend(); - g6.savetops("Carrier_phase_error_output"); - g6.savetopdf("Carrier_phase_error_output", 18); - g6.showonscreen(); // window output } catch (const GnuplotException& ge) { From 6bb284b9bb25745a1d746022d88c8a2e68ae70af Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Wed, 20 Jun 2018 18:42:06 +0200 Subject: [PATCH 10/40] Improving gnuplot and adding DLL/PLL bandwidth sweep options to DLL/PLL unit test --- src/tests/common-files/gnuplot_i.h | 2 +- .../gps_l1_ca_dll_pll_tracking_test.cc | 833 +++++++++++------- 2 files changed, 495 insertions(+), 340 deletions(-) diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index 448cdf4b9..67e6fb1f8 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -69,7 +69,7 @@ #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) //all UNIX-like OSs (Linux, *BSD, MacOSX, Solaris, ...) #include // for access(), mkstemp() -#define GP_MAX_TMP_FILES 64 +#define GP_MAX_TMP_FILES 1024 #else #error unsupported or unknown operating system #endif diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index e60ccf76d..1b3598489 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -61,6 +61,15 @@ DEFINE_double(CN0_dBHz_start, std::numeric_limits::infinity(), "Enable n DEFINE_double(CN0_dBHz_stop, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 stop sweep value [dB-Hz]"); DEFINE_double(CN0_dB_step, 3.0, "Noise generator CN0 sweep step value [dB]"); +DEFINE_double(PLL_bw_hz_start, 40.0, "PLL Wide configuration start sweep value [Hz]"); +DEFINE_double(PLL_bw_hz_stop, 40.0, "PLL Wide configuration stop sweep value [Hz]"); +DEFINE_double(PLL_bw_hz_step, 5.0, "PLL Wide configuration sweep step value [Hz]"); + +DEFINE_double(DLL_bw_hz_start, 1.5, "DLL Wide configuration start sweep value [Hz]"); +DEFINE_double(DLL_bw_hz_stop, 1.5, "DLL Wide configuration stop sweep value [Hz]"); +DEFINE_double(DLL_bw_hz_step, 0.25, "DLL Wide configuration sweep step value [Hz]"); + +DEFINE_bool(plot_extra, false, "Enable or disable plots of the correlators output and constellation diagrams"); //Emulated acquisition configuration @@ -176,7 +185,11 @@ public: { } - void configure_receiver(); + void configure_receiver(double PLL_wide_bw_hz, + double DLL_wide_bw_hz, + double PLL_narrow_bw_hz, + double DLL_narrow_bw_hz, + int extend_correlation_symbols); gr::top_block_sptr top_block; std::shared_ptr factory; @@ -231,7 +244,12 @@ int GpsL1CADllPllTrackingTest::generate_signal() } -void GpsL1CADllPllTrackingTest::configure_receiver() +void GpsL1CADllPllTrackingTest::configure_receiver( + double PLL_wide_bw_hz, + double DLL_wide_bw_hz, + double PLL_narrow_bw_hz, + double DLL_narrow_bw_hz, + int extend_correlation_symbols) { gnss_synchro.Channel_ID = 0; gnss_synchro.System = 'G'; @@ -239,19 +257,31 @@ void GpsL1CADllPllTrackingTest::configure_receiver() signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = FLAGS_test_satellite_PRN; + config = std::make_shared(); 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"); - config->set_property("Tracking_1C.pll_bw_hz", "20.0"); - config->set_property("Tracking_1C.dll_bw_hz", "1.5"); + config->set_property("Tracking_1C.pll_bw_hz", std::to_string(PLL_wide_bw_hz)); + config->set_property("Tracking_1C.dll_bw_hz", std::to_string(DLL_wide_bw_hz)); config->set_property("Tracking_1C.early_late_space_chips", "0.5"); - config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(FLAGS_extend_correlation_symbols)); - config->set_property("Tracking_1C.pll_bw_narrow_hz", "2.0"); - config->set_property("Tracking_1C.dll_bw_narrow_hz", "1.0"); + config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(extend_correlation_symbols)); + config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz)); + config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz)); config->set_property("Tracking_1C.early_late_space_narrow_chips", "0.5"); config->set_property("Tracking_1C.dump", "true"); config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); + + std::cout << "*****************************************\n"; + std::cout << "*** Tracking configuration parameters ***\n"; + std::cout << "*****************************************\n"; + std::cout << "pll_bw_hz: " << config->property("Tracking_1C.pll_bw_hz", 0.0) << " Hz\n"; + std::cout << "dll_bw_hz: " << config->property("Tracking_1C.dll_bw_hz", 0.0) << " Hz\n"; + std::cout << "pll_bw_narrow_hz: " << config->property("Tracking_1C.pll_bw_narrow_hz", 0.0) << " Hz\n"; + std::cout << "dll_bw_narrow_hz: " << config->property("Tracking_1C.dll_bw_narrow_hz", 0.0) << " Hz\n"; + std::cout << "extend_correlation_symbols: " << config->property("Tracking_1C.extend_correlation_symbols", 0) << " Symbols\n"; + std::cout << "*****************************************\n"; + std::cout << "*****************************************\n"; } @@ -409,26 +439,16 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std::vector generator_CN0_values; - std::vector> prompt_sweep; - std::vector> early_sweep; - std::vector> late_sweep; - std::vector> promptI_sweep; - std::vector> promptQ_sweep; - std::vector> CN0_dBHz_sweep; - std::vector> trk_timestamp_s_sweep; - //error vectors - std::vector> doppler_error_sweep; - std::vector mean_doppler_error_sweep; - std::vector std_dev_doppler_error_sweep; + //data containers for config param sweep + std::vector> mean_doppler_error_sweep; //swep config param and cn0 sweep + std::vector> std_dev_doppler_error_sweep; //swep config param and cn0 sweep - std::vector> code_phase_error_sweep; - std::vector mean_code_phase_error_sweep; - std::vector std_dev_code_phase_error_sweep; + std::vector> mean_code_phase_error_sweep; //swep config param and cn0 sweep + std::vector> std_dev_code_phase_error_sweep; //swep config param and cn0 sweep - std::vector> acc_carrier_phase_error_sweep; - std::vector mean_carrier_phase_error_sweep; - std::vector std_dev_carrier_phase_error_sweep; + std::vector> mean_carrier_phase_error_sweep; //swep config param and cn0 sweep + std::vector> std_dev_carrier_phase_error_sweep; //swep config param and cn0 sweep std::vector> trk_valid_timestamp_s_sweep; @@ -474,207 +494,430 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) } - //CN0 LOOP + // CONFIG PARAM SWEEP LOOP + std::vector PLL_wide_bw_values; + std::vector DLL_wide_bw_values; - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + + if (FLAGS_PLL_bw_hz_start == FLAGS_PLL_bw_hz_stop) { - //****************************************************************************************** - //***** Obtain the initial signal sinchronization parameters (emulating an acquisition) **** - //****************************************************************************************** - if (!FLAGS_enable_external_signal_file) + if (FLAGS_DLL_bw_hz_start == FLAGS_DLL_bw_hz_stop) { - test_satellite_PRN = FLAGS_test_satellite_PRN; - 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"); - true_obs_data.close_obs_file(); - ASSERT_EQ(true_obs_data.open_obs_file(true_obs_file), true) << "Failure opening true observables file"; - // 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?"; - std::cout << "Testing satellite PRN=" << test_satellite_PRN << std::endl; - std::cout << "Initial Doppler [Hz]=" << true_obs_data.doppler_l1_hz << " Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << std::endl; - acq_doppler_hz = true_obs_data.doppler_l1_hz; - acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * static_cast(baseband_sampling_freq) * GPS_L1_CA_CODE_PERIOD; - // restart the epoch counter - true_obs_data.restart(); + //NO PLL/DLL BW sweep + PLL_wide_bw_values.push_back(FLAGS_PLL_bw_hz_start); + DLL_wide_bw_values.push_back(FLAGS_DLL_bw_hz_start); } - - - //***** STEP 4: Configure the signal tracking parameters ***** - //************************************************************ - std::chrono::time_point start, end; - configure_receiver(); - - top_block = gr::make_top_block("Tracking test"); - - std::shared_ptr trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1); - std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); - - boost::shared_ptr msg_rx = GpsL1CADllPllTrackingTest_msg_rx_make(); - - gnss_synchro.Acq_delay_samples = acq_delay_samples; - gnss_synchro.Acq_doppler_hz = acq_doppler_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 + std::to_string(current_cn0_idx); - 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."; - - - //******************************************************************** - //***** STEP 5: Perform the signal tracking and read the results ***** - //******************************************************************** - 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."; - - std::chrono::duration elapsed_seconds = end - start; - std::cout << "Signal tracking completed in " << elapsed_seconds.count() << " seconds" << std::endl; - - //check results - //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"; - - long int n_measured_epochs = trk_dump.num_epochs(); - std::cout << "Measured observation epochs=" << n_measured_epochs << std::endl; - - arma::vec trk_timestamp_s = arma::zeros(n_measured_epochs, 1); - arma::vec trk_acc_carrier_phase_cycles = arma::zeros(n_measured_epochs, 1); - arma::vec trk_Doppler_Hz = arma::zeros(n_measured_epochs, 1); - arma::vec trk_prn_delay_chips = arma::zeros(n_measured_epochs, 1); - - long int epoch_counter = 0; - - std::vector timestamp_s; - std::vector prompt; - std::vector early; - std::vector late; - std::vector promptI; - std::vector promptQ; - std::vector CN0_dBHz; - while (trk_dump.read_binary_obs()) + else { - trk_timestamp_s(epoch_counter) = static_cast(trk_dump.PRN_start_sample_count) / static_cast(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(trk_dump.PRN_start_sample_count) + trk_dump.aux1) / static_cast(baseband_sampling_freq), 1.0e-3) / 1.0e-3); - - trk_prn_delay_chips(epoch_counter) = delay_chips; - - timestamp_s.push_back(trk_timestamp_s(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); - CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz); - - epoch_counter++; + //DLL BW Sweep + for (double dll_bw = FLAGS_DLL_bw_hz_start; dll_bw > FLAGS_DLL_bw_hz_stop; dll_bw = dll_bw - FLAGS_DLL_bw_hz_step) + { + PLL_wide_bw_values.push_back(FLAGS_PLL_bw_hz_start); + DLL_wide_bw_values.push_back(dll_bw); + } } - trk_timestamp_s_sweep.push_back(timestamp_s); - prompt_sweep.push_back(prompt); - early_sweep.push_back(early); - late_sweep.push_back(late); - promptI_sweep.push_back(promptI); - promptQ_sweep.push_back(promptQ); - CN0_dBHz_sweep.push_back(CN0_dBHz); - - //*********************************************************** - //***** STEP 6: Compare with true values (if available) ***** - //*********************************************************** - if (!FLAGS_enable_external_signal_file) + } + else + { + //PLL BW Sweep + for (double pll_bw = FLAGS_PLL_bw_hz_start; pll_bw > FLAGS_PLL_bw_hz_stop; pll_bw = pll_bw - FLAGS_PLL_bw_hz_step) { - // load the true values - long int n_true_epochs = true_obs_data.num_epochs(); - std::cout << "True observation epochs=" << n_true_epochs << std::endl; + PLL_wide_bw_values.push_back(pll_bw); + DLL_wide_bw_values.push_back(FLAGS_DLL_bw_hz_start); + } + } - arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); - arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); - arma::vec true_Doppler_Hz = arma::zeros(n_true_epochs, 1); - arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); - arma::vec true_tow_s = arma::zeros(n_true_epochs, 1); + for (int config_idx = 0; config_idx < PLL_wide_bw_values.size(); config_idx++) + { + //CN0 LOOP + // data containers for CN0 sweep + std::vector> prompt_sweep; + std::vector> early_sweep; + std::vector> late_sweep; + std::vector> promptI_sweep; + std::vector> promptQ_sweep; + std::vector> CN0_dBHz_sweep; + std::vector> trk_timestamp_s_sweep; + + std::vector> doppler_error_sweep; + std::vector> code_phase_error_sweep; + std::vector> acc_carrier_phase_error_sweep; + + std::vector mean_doppler_error; + std::vector std_dev_doppler_error; + std::vector mean_code_phase_error; + std::vector std_dev_code_phase_error; + std::vector mean_carrier_phase_error; + std::vector std_dev_carrier_phase_error; + + configure_receiver(PLL_wide_bw_values.at(config_idx), + DLL_wide_bw_values.at(config_idx), + 2.0, + 1.0, + FLAGS_extend_correlation_symbols); + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + //****************************************************************************************** + //***** Obtain the initial signal sinchronization parameters (emulating an acquisition) **** + //****************************************************************************************** + if (!FLAGS_enable_external_signal_file) + { + test_satellite_PRN = FLAGS_test_satellite_PRN; + 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"); + true_obs_data.close_obs_file(); + ASSERT_EQ(true_obs_data.open_obs_file(true_obs_file), true) << "Failure opening true observables file"; + // 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?"; + std::cout << "Testing satellite PRN=" << test_satellite_PRN << std::endl; + std::cout << "Initial Doppler [Hz]=" << true_obs_data.doppler_l1_hz << " Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << std::endl; + acq_doppler_hz = true_obs_data.doppler_l1_hz; + acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * static_cast(baseband_sampling_freq) * GPS_L1_CA_CODE_PERIOD; + // restart the epoch counter + true_obs_data.restart(); + } + + + //***** STEP 4: Configure the signal tracking parameters ***** + //************************************************************ + std::chrono::time_point start, end; + + top_block = gr::make_top_block("Tracking test"); + + std::shared_ptr trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1); + std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); + + boost::shared_ptr msg_rx = GpsL1CADllPllTrackingTest_msg_rx_make(); + + gnss_synchro.Acq_delay_samples = acq_delay_samples; + gnss_synchro.Acq_doppler_hz = acq_doppler_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 + std::to_string(current_cn0_idx); + 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."; + + + //******************************************************************** + //***** STEP 5: Perform the signal tracking and read the results ***** + //******************************************************************** + 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."; + + std::chrono::duration elapsed_seconds = end - start; + std::cout << "Signal tracking completed in " << elapsed_seconds.count() << " seconds" << std::endl; + + //check results + //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"; + + long int n_measured_epochs = trk_dump.num_epochs(); + std::cout << "Measured observation epochs=" << n_measured_epochs << std::endl; + + arma::vec trk_timestamp_s = arma::zeros(n_measured_epochs, 1); + arma::vec trk_acc_carrier_phase_cycles = arma::zeros(n_measured_epochs, 1); + arma::vec trk_Doppler_Hz = arma::zeros(n_measured_epochs, 1); + arma::vec trk_prn_delay_chips = arma::zeros(n_measured_epochs, 1); long int epoch_counter = 0; - while (true_obs_data.read_binary_obs()) + + std::vector timestamp_s; + std::vector prompt; + std::vector early; + std::vector late; + std::vector promptI; + std::vector promptQ; + std::vector CN0_dBHz; + while (trk_dump.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; + trk_timestamp_s(epoch_counter) = static_cast(trk_dump.PRN_start_sample_count) / static_cast(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(trk_dump.PRN_start_sample_count) + trk_dump.aux1) / static_cast(baseband_sampling_freq), 1.0e-3) / 1.0e-3); + + trk_prn_delay_chips(epoch_counter) = delay_chips; + + timestamp_s.push_back(trk_timestamp_s(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); + CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz); + epoch_counter++; } - // 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_sweep.push_back(timestamp_s); + prompt_sweep.push_back(prompt); + early_sweep.push_back(early); + late_sweep.push_back(late); + promptI_sweep.push_back(promptI); + promptQ_sweep.push_back(promptQ); + CN0_dBHz_sweep.push_back(CN0_dBHz); - 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); + //*********************************************************** + //***** STEP 6: Compare with true values (if available) ***** + //*********************************************************** + if (!FLAGS_enable_external_signal_file) + { + std::vector doppler_error_hz; + std::vector code_phase_error_chips; + std::vector acc_carrier_phase_hz; + try + { + // load the true values + long int n_true_epochs = true_obs_data.num_epochs(); + std::cout << "True observation epochs=" << n_true_epochs << std::endl; - std::vector doppler_error_hz; - std::vector code_phase_error_chips; - std::vector acc_carrier_phase_hz; + arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); + arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); + arma::vec true_Doppler_Hz = arma::zeros(n_true_epochs, 1); + arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); + arma::vec true_tow_s = arma::zeros(n_true_epochs, 1); - double mean_error; - double std_dev_error; + 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++; + } + // Align initial measurements and cut the tracking pull-in transitory + double pull_in_offset_s = 1.0; - doppler_error_hz = check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz, mean_error, std_dev_error); - mean_doppler_error_sweep.push_back(mean_error); - std_dev_doppler_error_sweep.push_back(std_dev_error); + arma::uvec initial_meas_point = arma::find(trk_timestamp_s >= (true_timestamp_s(0) + pull_in_offset_s), 1, "first"); - code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips, mean_error, std_dev_error); - mean_code_phase_error_sweep.push_back(mean_error); - std_dev_code_phase_error_sweep.push_back(std_dev_error); + 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); - acc_carrier_phase_hz = check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles, mean_error, std_dev_error); - mean_carrier_phase_error_sweep.push_back(mean_error); - std_dev_carrier_phase_error_sweep.push_back(std_dev_error); - //save tracking measurement timestamps to std::vector - std::vector vector_trk_timestamp_s(trk_timestamp_s.colptr(0), trk_timestamp_s.colptr(0) + trk_timestamp_s.n_rows); - trk_valid_timestamp_s_sweep.push_back(vector_trk_timestamp_s); + double mean_error; + double std_dev_error; - doppler_error_sweep.push_back(doppler_error_hz); - code_phase_error_sweep.push_back(code_phase_error_chips); - acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz); + doppler_error_hz = check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz, mean_error, std_dev_error); + mean_doppler_error.push_back(mean_error); + std_dev_doppler_error.push_back(std_dev_error); + + code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips, mean_error, std_dev_error); + mean_code_phase_error.push_back(mean_error); + std_dev_code_phase_error.push_back(std_dev_error); + + acc_carrier_phase_hz = check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles, mean_error, std_dev_error); + mean_carrier_phase_error.push_back(mean_error); + std_dev_carrier_phase_error.push_back(std_dev_error); + + //save tracking measurement timestamps to std::vector + std::vector vector_trk_timestamp_s(trk_timestamp_s.colptr(0), trk_timestamp_s.colptr(0) + trk_timestamp_s.n_rows); + trk_valid_timestamp_s_sweep.push_back(vector_trk_timestamp_s); + + doppler_error_sweep.push_back(doppler_error_hz); + code_phase_error_sweep.push_back(code_phase_error_chips); + acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz); + } + catch (const std::exception& ex) + { + std::cout << "Tracking output could not be used, possible loss of lock " << ex.what() << std::endl; + + std::vector vector_trk_timestamp_s; + trk_valid_timestamp_s_sweep.push_back(vector_trk_timestamp_s); + doppler_error_sweep.push_back(doppler_error_hz); + code_phase_error_sweep.push_back(code_phase_error_chips); + acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz); + } + } + + } //CN0 LOOP + + if (!FLAGS_enable_external_signal_file) + { + mean_doppler_error_sweep.push_back(mean_doppler_error); + std_dev_doppler_error_sweep.push_back(std_dev_doppler_error); + mean_code_phase_error_sweep.push_back(mean_code_phase_error); + std_dev_code_phase_error_sweep.push_back(std_dev_code_phase_error); + mean_carrier_phase_error_sweep.push_back(mean_carrier_phase_error); + std_dev_carrier_phase_error_sweep.push_back(std_dev_carrier_phase_error); } - } //CN0 LOOP + std::cout << "A\n\n\n"; + //******************************** + //***** STEP 7: Plot results ***** + //******************************** + if (FLAGS_plot_gps_l1_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); + unsigned int decimate = static_cast(FLAGS_plot_decimate); + + if (FLAGS_plot_extra) + { + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + Gnuplot g1("linespoints"); + g1.showonscreen(); // window output + g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz" + "GPS L1 C/A (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"); + g1.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), prompt_sweep.at(current_cn0_idx), "Prompt", decimate); + g1.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), early_sweep.at(current_cn0_idx), "Early", decimate); + g1.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), late_sweep.at(current_cn0_idx), "Late", decimate); + g1.set_legend(); + g1.savetops("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx))); + g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18); + } + Gnuplot g2("points"); + g2.showonscreen(); // window output + g2.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), + ceil(static_cast(generator_CN0_values.size()) / 2)); + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g2.reset_plot(); + g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz" + "GPS L1 C/A (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_sweep.at(current_cn0_idx), promptQ_sweep.at(current_cn0_idx)); + } + g2.unset_multiplot(); + g2.savetops("Constellation"); + g2.savetopdf("Constellation", 18); + + Gnuplot g3("linespoints"); + g3.set_title("GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g3.set_grid(); + g3.set_xlabel("Time [s]"); + g3.set_ylabel("Reported CN0 [dB-Hz]"); + g3.cmd("set key box opaque"); + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g3.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), CN0_dBHz_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + g3.set_legend(); + g3.savetops("CN0_output"); + g3.savetopdf("CN0_output", 18); + g3.showonscreen(); // window output + } + + std::cout << "B\n\n\n"; + //PLOT ERROR FIGURES (only if it is used the signal generator) + if (!FLAGS_enable_external_signal_file) + { + Gnuplot g4("points"); + g4.showonscreen(); // window output + g4.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), + ceil(static_cast(generator_CN0_values.size()) / 2)); + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g4.reset_plot(); + g4.set_title(std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz] Doppler error " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g4.set_grid(); + //g4.cmd("set key box opaque"); + g4.set_xlabel("Time [s]"); + g4.set_ylabel("Dopper error [Hz]"); + g4.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), doppler_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + //g4.set_legend(); + } + g4.unset_multiplot(); + g4.savetops("Doppler_error_output"); + g4.savetopdf("Doppler_error_output", 18); + + Gnuplot g5("points"); + g5.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g5.set_grid(); + g5.set_xlabel("Time [s]"); + g5.set_ylabel("Code delay error [Chips]"); + g5.cmd("set key box opaque"); + + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g5.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + g5.set_legend(); + g5.savetops("Code_error_output"); + g5.savetopdf("Code_error_output", 18); + g5.showonscreen(); // window output + + Gnuplot g6("points"); + g6.set_title("Accumulated carrier phase error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g6.set_grid(); + g6.set_xlabel("Time [s]"); + g6.set_ylabel("Accumulated carrier phase error [Cycles]"); + g6.cmd("set key box opaque"); + + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g6.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), acc_carrier_phase_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + g6.set_legend(); + g6.savetops("Carrier_phase_error_output"); + g6.savetopdf("Carrier_phase_error_output", 18); + g6.showonscreen(); // window output + } + } + catch (const GnuplotException& ge) + { + std::cout << ge.what() << std::endl; + } + } + } + } + - //******************************** - //***** STEP 7: Plot results ***** - //******************************** if (FLAGS_plot_gps_l1_tracking_test == true) { const std::string gnuplot_executable(FLAGS_gnuplot_executable); @@ -688,154 +931,66 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) { 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); - unsigned int decimate = static_cast(FLAGS_plot_decimate); - - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + if (generator_CN0_values.size() > 1) { - Gnuplot g1("linespoints"); - g1.showonscreen(); // window output - g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz GPS L1 C/A (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"); - g1.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), prompt_sweep.at(current_cn0_idx), "Prompt", decimate); - g1.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), early_sweep.at(current_cn0_idx), "Early", decimate); - g1.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), late_sweep.at(current_cn0_idx), "Late", decimate); - g1.set_legend(); - g1.savetops("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx))); - g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18); - } + //plot metrics - - Gnuplot g2("points"); - g2.showonscreen(); // window output - g2.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), - ceil(static_cast(generator_CN0_values.size()) / 2)); - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) - { - g2.reset_plot(); - g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation (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_sweep.at(current_cn0_idx), promptQ_sweep.at(current_cn0_idx)); - } - g2.unset_multiplot(); - g2.savetops("Constellation"); - g2.savetopdf("Constellation", 18); - - Gnuplot g3("linespoints"); - g3.set_title("GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g3.set_grid(); - g3.set_xlabel("Time [s]"); - g3.set_ylabel("Reported CN0 [dB-Hz]"); - g3.cmd("set key box opaque"); - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) - { - g3.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), CN0_dBHz_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); - } - g3.set_legend(); - g3.savetops("CN0_output"); - g3.savetopdf("CN0_output", 18); - g3.showonscreen(); // window output - - //PLOT ERROR FIGURES (only if it is used the signal generator) - if (!FLAGS_enable_external_signal_file) - { - Gnuplot g4("points"); - g4.showonscreen(); // window output - g4.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), - ceil(static_cast(generator_CN0_values.size()) / 2)); - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + Gnuplot g7("linespoints"); + g7.set_title("Doppler error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g7.set_grid(); + g7.set_xlabel("CN0 [dB-Hz]"); + g7.set_ylabel("Doppler error [Hz]"); + g7.set_pointsize(2); + g7.cmd("set termoption lw 2"); + g7.cmd("set key box opaque"); + for (int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++) { - g4.reset_plot(); - g4.set_title(std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]" + " Doppler error (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g4.set_grid(); - //g4.cmd("set key box opaque"); - g4.set_xlabel("Time [s]"); - g4.set_ylabel("Dopper error [Hz]"); - g4.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), doppler_error_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); - //g4.set_legend(); + g7.plot_xy_err(generator_CN0_values, + mean_doppler_error_sweep.at(config_sweep_idx), + std_dev_doppler_error_sweep.at(config_sweep_idx), + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + + +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); } - g4.unset_multiplot(); - g4.savetops("Doppler_error_output"); - g4.savetopdf("Doppler_error_output", 18); + g7.savetops("Doppler_error_metrics"); + g7.savetopdf("Doppler_error_metrics", 18); - Gnuplot g5("points"); - g5.set_title("Code delay error (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g5.set_grid(); - g5.set_xlabel("Time [s]"); - g5.set_ylabel("Code delay error [Chips]"); - g5.cmd("set key box opaque"); - - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + Gnuplot g8("linespoints"); + g8.set_title("Accumulated carrier phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g8.set_grid(); + g8.set_xlabel("CN0 [dB-Hz]"); + g8.set_ylabel("Accumulated Carrier Phase error [Cycles]"); + g8.cmd("set key box opaque"); + g8.cmd("set termoption lw 2"); + g8.set_pointsize(2); + for (int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++) { - g5.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + g8.plot_xy_err(generator_CN0_values, + mean_carrier_phase_error_sweep.at(config_sweep_idx), + std_dev_carrier_phase_error_sweep.at(config_sweep_idx), + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + + +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); } - g5.set_legend(); - g5.savetops("Code_error_output"); - g5.savetopdf("Code_error_output", 18); - g5.showonscreen(); // window output + g8.savetops("Carrier_error_metrics"); + g8.savetopdf("Carrier_error_metrics", 18); - Gnuplot g6("points"); - g6.set_title("Accumulated carrier phase error (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g6.set_grid(); - g6.set_xlabel("Time [s]"); - g6.set_ylabel("Accumulated carrier phase error [Cycles]"); - g6.cmd("set key box opaque"); - - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + Gnuplot g9("linespoints"); + g9.set_title("Code Phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g9.set_grid(); + g9.set_xlabel("CN0 [dB-Hz]"); + g9.set_ylabel("Code Phase error [Chips]"); + g9.cmd("set key box opaque"); + g9.cmd("set termoption lw 2"); + g9.set_pointsize(2); + for (int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++) { - g6.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), acc_carrier_phase_error_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); - } - g6.set_legend(); - g6.savetops("Carrier_phase_error_output"); - g6.savetopdf("Carrier_phase_error_output", 18); - g6.showonscreen(); // window output - - if (generator_CN0_values.size() > 1) - { - //plot metrics - Gnuplot g7("linespoints"); - g7.set_title("Doppler error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g7.set_grid(); - g7.set_xlabel("CN0 [dB-Hz]"); - g7.set_ylabel("Doppler error [Hz]"); - g7.cmd("set key box opaque"); - g7.plot_xy_err(generator_CN0_values, mean_doppler_error_sweep, std_dev_doppler_error_sweep, "Doppler error"); - g7.savetops("Doppler_error_metrics"); - g7.savetopdf("Doppler_error_metrics", 18); - - Gnuplot g8("linespoints"); - g8.set_title("Accumulated carrier phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g8.set_grid(); - g8.set_xlabel("CN0 [dB-Hz]"); - g8.set_ylabel("Accumulated Carrier Phase error [Hz]"); - g8.cmd("set key box opaque"); - g8.plot_xy_err(generator_CN0_values, mean_carrier_phase_error_sweep, std_dev_carrier_phase_error_sweep, "Carrier Phase error"); - g8.savetops("Carrier_error_metrics"); - g8.savetopdf("Carrier_error_metrics", 18); - - Gnuplot g9("linespoints"); - g9.set_title("Code Phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g9.set_grid(); - g9.set_xlabel("CN0 [dB-Hz]"); - g9.set_ylabel("Code Phase error [Hz]"); - g9.cmd("set key box opaque"); - g9.plot_xy_err(generator_CN0_values, mean_code_phase_error_sweep, std_dev_code_phase_error_sweep, "Code Phase error"); - g9.savetops("Code_error_metrics"); - g9.savetopdf("Code_error_metrics", 18); + g9.plot_xy_err(generator_CN0_values, + mean_code_phase_error_sweep.at(config_sweep_idx), + std_dev_code_phase_error_sweep.at(config_sweep_idx), + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + + +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); } + g9.savetops("Code_error_metrics"); + g9.savetopdf("Code_error_metrics", 18); } } catch (const GnuplotException& ge) From 175f1355d599484435994a1848bd6df6428ae7a0 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 20 Jun 2018 20:09:58 +0200 Subject: [PATCH 11/40] Add work on acq performance test --- .../gps_l1_acq_performance_test.cc | 166 ++++++++++++------ 1 file changed, 112 insertions(+), 54 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index 08287722c..c0d2e8133 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -38,59 +38,60 @@ DEFINE_string(config_file_ptest, std::string(""), "File containing the configuration parameters for the position test."); // ######## GNURADIO BLOCK MESSAGE RECEVER ######### -//class AcqPerfTest_msg_rx; +class AcqPerfTest_msg_rx; // -//typedef boost::shared_ptr AcqPerfTest_msg_rx_sptr; +typedef boost::shared_ptr AcqPerfTest_msg_rx_sptr; // -//AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(); +AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(); // -//class AcqPerfTest_msg_rx : public gr::block -//{ -//private: -// friend AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(); -// void msg_handler_events(pmt::pmt_t msg); -// AcqPerfTest_msg_rx(); -// -//public: -// int rx_message; -// ~AcqPerfTest_msg_rx(); //!< Default destructor -//}; -// -// -//AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make() -//{ -// return AcqPerfTest_msg_rx_sptr(new AcqPerfTest_msg_rx()); -//} -// -// -//void AcqPerfTest_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; -// } -//} -// -// -//AcqPerfTest_msg_rx::AcqPerfTest_msg_rx() : gr::block("AcqPerfTest_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(&AcqPerfTest_msg_rx::msg_handler_events, this, _1)); -// rx_message = 0; -//} -// -// -//AcqPerfTest_msg_rx::~AcqPerfTest_msg_rx() -//{ -//} -// -//// ----------------------------------------- +class AcqPerfTest_msg_rx : public gr::block +{ +private: + friend AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(); + void msg_handler_events(pmt::pmt_t msg); + AcqPerfTest_msg_rx(); + +public: + int rx_message; + ~AcqPerfTest_msg_rx(); //!< Default destructor +}; + + +AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make() +{ + return AcqPerfTest_msg_rx_sptr(new AcqPerfTest_msg_rx()); +} + + +void AcqPerfTest_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; + } + std::cout << "Received message:" << rx_message << std::endl; +} + + +AcqPerfTest_msg_rx::AcqPerfTest_msg_rx() : gr::block("AcqPerfTest_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(&AcqPerfTest_msg_rx::msg_handler_events, this, _1)); + rx_message = 0; +} + + +AcqPerfTest_msg_rx::~AcqPerfTest_msg_rx() +{ +} + +// ----------------------------------------- class AcquisitionPerformanceTest : public ::testing::Test @@ -109,8 +110,8 @@ protected: { } - std::vector cn0_ = {41.0, 42.0, 43.0}; - int N_iterations = 2; + std::vector cn0_ = {38.0, 40.0, 43.0}; + int N_iterations = 1; void init(); //void plot_grid(); @@ -118,6 +119,7 @@ protected: int generate_signal(); int configure_receiver(double cn0, unsigned int iter); int run_receiver(); + int run_receiver2(); void check_results(); gr::top_block_sptr top_block; Gnss_Synchro gnss_synchro; @@ -125,6 +127,7 @@ protected: unsigned int doppler_max; unsigned int doppler_step; std::string implementation = "GPS_L1_CA_PCPS_Acquisition"; + boost::shared_ptr acquisition; std::shared_ptr config; std::shared_ptr config_f; @@ -325,7 +328,7 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter config->set_property("Acquisition_1C.max_dwells", std::to_string(1)); - config->set_property("Acquisition_1C.repeat_satellite", "false"); + config->set_property("Acquisition_1C.repeat_satellite", "true"); config->set_property("Acquisition_1C.blocking", "true"); config->set_property("Acquisition_1C.make_two_steps", "false"); @@ -355,6 +358,9 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(pll_bw_narrow_hz)); config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(dll_bw_narrow_hz)); config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(extend_correlation_ms)); + config->set_property("Tracking_1C.cn0_min", std::to_string(50)); + config->set_property("Tracking_1C.max_lock_fail", std::to_string(1)); + config->set_property("Tracking_1C.cn0_samples", std::to_string(1)); // Set Telemetry config->set_property("TelemetryDecoder_1C.implementation", "GPS_L1_CA_Telemetry_Decoder"); @@ -395,6 +401,58 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter int AcquisitionPerformanceTest::run_receiver() +{ + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); + std::string file = "./" + filename_raw_data; //+ std::to_string(current_cn0_idx); + 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); + + for (unsigned k = 0; k < 2; k++) + { + gr::top_block_sptr top_block_ = gr::make_top_block("Acquisition test"); + boost::shared_ptr msg_rx = AcqPerfTest_msg_rx_make(); + + gnss_synchro = Gnss_Synchro(); + init(); + auto acquisition_ = boost::make_shared(config.get(), "Acquisition_1C", 1, 0); + + //acquisition->connect(top_block); + acquisition_->set_gnss_synchro(&gnss_synchro); + + acquisition_->connect(top_block_); + acquisition_->set_local_code(); + acquisition_->set_state(1); // Ensure that acquisition starts at the first sample + acquisition_->init(); + //file_source->seek(static_cast(100 * k), SEEK_SET); + + if (not file_source->seek(static_cast(100 * k), SEEK_SET)) + { + std::cout << "Error skipping " << k << std::endl; + } + gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); + top_block_->connect(file_source, 0, gr_interleaved_char_to_complex, 0); + top_block_->connect(gr_interleaved_char_to_complex, 0, acquisition_->get_left_block(), 0); + top_block_->msg_connect(acquisition_->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + + + start = std::chrono::system_clock::now(); + top_block_->run(); // Start threads and wait + end = std::chrono::system_clock::now(); + //file_source->close(); + elapsed_seconds = end - start; + std::cout << "Acq_delay_samples: " << gnss_synchro.Acq_delay_samples << std::endl; + std::cout << "Acq_doppler_hz: " << gnss_synchro.Acq_doppler_hz << std::endl; + std::cout << "Acq_samplestamp_samples: " << gnss_synchro.Acq_samplestamp_samples << std::endl + << std::endl; + } + + //std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; + + return 0; +} + +int AcquisitionPerformanceTest::run_receiver2() { std::shared_ptr control_thread; if (FLAGS_config_file_ptest.empty()) @@ -442,7 +500,7 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) configure_receiver(*it, iter); // Run it - run_receiver(); + run_receiver2(); // Read and store reference data and results } From f133392a8ceb750f00daa87a8a67b357139fe715 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 20 Jun 2018 20:16:19 +0200 Subject: [PATCH 12/40] Fix bug in matio usage --- .../acquisition/gnuradio_blocks/pcps_acquisition.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 1176105d3..7058e6bdb 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -462,11 +462,11 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) dims[0] = static_cast(1); dims[1] = static_cast(1); - matvar = Mat_VarCreate("doppler_max", MAT_C_SINGLE, MAT_T_UINT32, 1, dims, &acq_parameters.doppler_max, 0); + matvar = Mat_VarCreate("doppler_max", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &acq_parameters.doppler_max, 0); Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarFree(matvar); - matvar = Mat_VarCreate("doppler_step", MAT_C_SINGLE, MAT_T_UINT32, 1, dims, &d_doppler_step, 0); + matvar = Mat_VarCreate("doppler_step", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_doppler_step, 0); Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarFree(matvar); From 2a9a8f5b29fba1cc986f31cb66afb3995a784e00 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 20 Jun 2018 20:44:13 +0200 Subject: [PATCH 13/40] Stire results also when using the refinement stage --- .../gnuradio_blocks/pcps_acquisition.cc | 88 +++++++++++-------- .../gnuradio_blocks/pcps_acquisition.h | 2 + 2 files changed, 52 insertions(+), 38 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 1176105d3..8e93024a8 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -335,6 +335,50 @@ void pcps_acquisition::send_negative_acquisition() } +void pcps_acquisition::dump_results(unsigned int doppler_index, int effective_fft_size) +{ + memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size); + if (doppler_index == (d_num_doppler_bins - 1)) + { + std::string filename = acq_parameters.dump_filename; + filename.append("_"); + filename.append(1, d_gnss_synchro->System); + filename.append("_"); + filename.append(1, d_gnss_synchro->Signal[0]); + filename.append(1, d_gnss_synchro->Signal[1]); + filename.append("_sat_"); + filename.append(std::to_string(d_gnss_synchro->PRN)); + filename.append(".mat"); + + mat_t* matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if (matfp == NULL) + { + std::cout << "Unable to create or open Acquisition dump file" << std::endl; + acq_parameters.dump = false; + } + else + { + size_t dims[2] = {static_cast(effective_fft_size), static_cast(d_num_doppler_bins)}; + matvar_t* matvar = Mat_VarCreate("grid", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, grid_.memptr(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + dims[0] = static_cast(1); + dims[1] = static_cast(1); + matvar = Mat_VarCreate("doppler_max", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &acq_parameters.doppler_max, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("doppler_step", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_doppler_step, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + Mat_Close(matfp); + } + } +} + + void pcps_acquisition::acquisition_core(unsigned long int samp_count) { gr::thread::scoped_lock lk(d_setlock); @@ -435,44 +479,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) // Record results to file if required if (acq_parameters.dump) { - memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size); - if (doppler_index == (d_num_doppler_bins - 1)) - { - std::string filename = acq_parameters.dump_filename; - filename.append("_"); - filename.append(1, d_gnss_synchro->System); - filename.append("_"); - filename.append(1, d_gnss_synchro->Signal[0]); - filename.append(1, d_gnss_synchro->Signal[1]); - filename.append("_sat_"); - filename.append(std::to_string(d_gnss_synchro->PRN)); - filename.append(".mat"); - mat_t* matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (matfp == NULL) - { - std::cout << "Unable to create or open Acquisition dump file" << std::endl; - acq_parameters.dump = false; - } - else - { - size_t dims[2] = {static_cast(effective_fft_size), static_cast(d_num_doppler_bins)}; - matvar_t* matvar = Mat_VarCreate("grid", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, grid_.memptr(), 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); - - dims[0] = static_cast(1); - dims[1] = static_cast(1); - matvar = Mat_VarCreate("doppler_max", MAT_C_SINGLE, MAT_T_UINT32, 1, dims, &acq_parameters.doppler_max, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); - - matvar = Mat_VarCreate("doppler_step", MAT_C_SINGLE, MAT_T_UINT32, 1, dims, &d_doppler_step, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); - - Mat_Close(matfp); - } - } + pcps_acquisition::dump_results(doppler_index, effective_fft_size); } } } @@ -538,6 +545,11 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) d_test_statistics = d_mag / d_input_power; } } + // Record results to file if required + if (acq_parameters.dump) + { + pcps_acquisition::dump_results(doppler_index, effective_fft_size); + } } } lk.lock(); diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index 615957921..429353bd9 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -93,6 +93,8 @@ private: void send_positive_acquisition(); + void dump_results(unsigned int doppler_index, int effective_fft_size); + Acq_Conf acq_parameters; bool d_active; bool d_worker_active; From c0337528f57d98ea09d98396e1089565b7eb2d04 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 20 Jun 2018 20:48:43 +0200 Subject: [PATCH 14/40] Store results also when using the refinement stage --- .../gnuradio_blocks/pcps_acquisition.cc | 88 +++++++++++-------- .../gnuradio_blocks/pcps_acquisition.h | 2 + 2 files changed, 52 insertions(+), 38 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 7058e6bdb..8e93024a8 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -335,6 +335,50 @@ void pcps_acquisition::send_negative_acquisition() } +void pcps_acquisition::dump_results(unsigned int doppler_index, int effective_fft_size) +{ + memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size); + if (doppler_index == (d_num_doppler_bins - 1)) + { + std::string filename = acq_parameters.dump_filename; + filename.append("_"); + filename.append(1, d_gnss_synchro->System); + filename.append("_"); + filename.append(1, d_gnss_synchro->Signal[0]); + filename.append(1, d_gnss_synchro->Signal[1]); + filename.append("_sat_"); + filename.append(std::to_string(d_gnss_synchro->PRN)); + filename.append(".mat"); + + mat_t* matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if (matfp == NULL) + { + std::cout << "Unable to create or open Acquisition dump file" << std::endl; + acq_parameters.dump = false; + } + else + { + size_t dims[2] = {static_cast(effective_fft_size), static_cast(d_num_doppler_bins)}; + matvar_t* matvar = Mat_VarCreate("grid", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, grid_.memptr(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + dims[0] = static_cast(1); + dims[1] = static_cast(1); + matvar = Mat_VarCreate("doppler_max", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &acq_parameters.doppler_max, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("doppler_step", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_doppler_step, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + Mat_Close(matfp); + } + } +} + + void pcps_acquisition::acquisition_core(unsigned long int samp_count) { gr::thread::scoped_lock lk(d_setlock); @@ -435,44 +479,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) // Record results to file if required if (acq_parameters.dump) { - memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size); - if (doppler_index == (d_num_doppler_bins - 1)) - { - std::string filename = acq_parameters.dump_filename; - filename.append("_"); - filename.append(1, d_gnss_synchro->System); - filename.append("_"); - filename.append(1, d_gnss_synchro->Signal[0]); - filename.append(1, d_gnss_synchro->Signal[1]); - filename.append("_sat_"); - filename.append(std::to_string(d_gnss_synchro->PRN)); - filename.append(".mat"); - mat_t* matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (matfp == NULL) - { - std::cout << "Unable to create or open Acquisition dump file" << std::endl; - acq_parameters.dump = false; - } - else - { - size_t dims[2] = {static_cast(effective_fft_size), static_cast(d_num_doppler_bins)}; - matvar_t* matvar = Mat_VarCreate("grid", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, grid_.memptr(), 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); - - dims[0] = static_cast(1); - dims[1] = static_cast(1); - matvar = Mat_VarCreate("doppler_max", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &acq_parameters.doppler_max, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); - - matvar = Mat_VarCreate("doppler_step", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_doppler_step, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); - - Mat_Close(matfp); - } - } + pcps_acquisition::dump_results(doppler_index, effective_fft_size); } } } @@ -538,6 +545,11 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) d_test_statistics = d_mag / d_input_power; } } + // Record results to file if required + if (acq_parameters.dump) + { + pcps_acquisition::dump_results(doppler_index, effective_fft_size); + } } } lk.lock(); diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index 615957921..429353bd9 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -93,6 +93,8 @@ private: void send_positive_acquisition(); + void dump_results(unsigned int doppler_index, int effective_fft_size); + Acq_Conf acq_parameters; bool d_active; bool d_worker_active; From 47c9ad0160ab7c549d48b3dcc06699e267617f66 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 21 Jun 2018 08:05:33 +0200 Subject: [PATCH 15/40] Save results for all executions, not just the last one --- .../gnuradio_blocks/pcps_acquisition.cc | 83 ++++++++++--------- .../gnuradio_blocks/pcps_acquisition.h | 3 +- .../libs/acquisition_dump_reader.cc | 11 ++- .../libs/acquisition_dump_reader.h | 8 +- src/utils/matlab/plot_acq_grid.m | 4 +- 5 files changed, 66 insertions(+), 43 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 8e93024a8..7f81d68e3 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -121,6 +121,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu } grid_ = arma::fmat(); d_step_two = false; + d_dump_number = 0; } @@ -335,46 +336,47 @@ void pcps_acquisition::send_negative_acquisition() } -void pcps_acquisition::dump_results(unsigned int doppler_index, int effective_fft_size) +void pcps_acquisition::dump_results(int effective_fft_size) { - memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size); - if (doppler_index == (d_num_doppler_bins - 1)) + d_dump_number++; + std::string filename = acq_parameters.dump_filename; + filename.append("_"); + filename.append(1, d_gnss_synchro->System); + filename.append("_"); + filename.append(1, d_gnss_synchro->Signal[0]); + filename.append(1, d_gnss_synchro->Signal[1]); + filename.append("_ch_"); + filename.append(std::to_string(d_channel)); + filename.append("_"); + filename.append(std::to_string(d_dump_number)); + filename.append("_sat_"); + filename.append(std::to_string(d_gnss_synchro->PRN)); + filename.append(".mat"); + + mat_t* matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if (matfp == NULL) { - std::string filename = acq_parameters.dump_filename; - filename.append("_"); - filename.append(1, d_gnss_synchro->System); - filename.append("_"); - filename.append(1, d_gnss_synchro->Signal[0]); - filename.append(1, d_gnss_synchro->Signal[1]); - filename.append("_sat_"); - filename.append(std::to_string(d_gnss_synchro->PRN)); - filename.append(".mat"); + std::cout << "Unable to create or open Acquisition dump file" << std::endl; + acq_parameters.dump = false; + } + else + { + size_t dims[2] = {static_cast(effective_fft_size), static_cast(d_num_doppler_bins)}; + matvar_t* matvar = Mat_VarCreate("grid", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, grid_.memptr(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - mat_t* matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (matfp == NULL) - { - std::cout << "Unable to create or open Acquisition dump file" << std::endl; - acq_parameters.dump = false; - } - else - { - size_t dims[2] = {static_cast(effective_fft_size), static_cast(d_num_doppler_bins)}; - matvar_t* matvar = Mat_VarCreate("grid", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, grid_.memptr(), 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + dims[0] = static_cast(1); + dims[1] = static_cast(1); + matvar = Mat_VarCreate("doppler_max", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &acq_parameters.doppler_max, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - dims[0] = static_cast(1); - dims[1] = static_cast(1); - matvar = Mat_VarCreate("doppler_max", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &acq_parameters.doppler_max, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); + matvar = Mat_VarCreate("doppler_step", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_doppler_step, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); - matvar = Mat_VarCreate("doppler_step", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_doppler_step, 0); - Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE - Mat_VarFree(matvar); - - Mat_Close(matfp); - } + Mat_Close(matfp); } } @@ -386,7 +388,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) // initialize acquisition algorithm uint32_t indext = 0; float magt = 0.0; - const gr_complex* in = d_data_buffer; //Get the input samples pointer + const gr_complex* in = d_data_buffer; // Get the input samples pointer int effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size); if (d_cshort) { @@ -479,7 +481,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) // Record results to file if required if (acq_parameters.dump) { - pcps_acquisition::dump_results(doppler_index, effective_fft_size); + memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size); } } } @@ -548,10 +550,15 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) // Record results to file if required if (acq_parameters.dump) { - pcps_acquisition::dump_results(doppler_index, effective_fft_size); + memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size); } } } + // Record results to file if required + if (acq_parameters.dump) + { + pcps_acquisition::dump_results(effective_fft_size); + } lk.lock(); if (!acq_parameters.bit_transition_flag) { diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index 429353bd9..f0fd69e7f 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -93,7 +93,7 @@ private: void send_positive_acquisition(); - void dump_results(unsigned int doppler_index, int effective_fft_size); + void dump_results(int effective_fft_size); Acq_Conf acq_parameters; bool d_active; @@ -123,6 +123,7 @@ private: gr::fft::fft_complex* d_ifft; Gnss_Synchro* d_gnss_synchro; arma::fmat grid_; + long int d_dump_number; public: ~pcps_acquisition(); diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc index 32b6de6e2..5fcd1308b 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc @@ -73,6 +73,7 @@ bool acquisition_dump_reader::read_binary_acq() Mat_Close(matfile); return false; } + std::vector >::iterator it1; std::vector::iterator it2; float* aux = static_cast(var_->data); @@ -93,7 +94,13 @@ bool acquisition_dump_reader::read_binary_acq() } -acquisition_dump_reader::acquisition_dump_reader(const std::string& basename, unsigned int sat, unsigned int doppler_max, unsigned int doppler_step, unsigned int samples_per_code) +acquisition_dump_reader::acquisition_dump_reader(const std::string& basename, + unsigned int sat, + unsigned int doppler_max, + unsigned int doppler_step, + unsigned int samples_per_code, + int channel, + int execution) { d_basename = basename; d_sat = sat; @@ -103,7 +110,7 @@ acquisition_dump_reader::acquisition_dump_reader(const std::string& basename, un d_num_doppler_bins = static_cast(ceil(static_cast(static_cast(d_doppler_max) - static_cast(-d_doppler_max)) / static_cast(d_doppler_step))); std::vector > mag_aux(d_num_doppler_bins, std::vector(d_samples_per_code)); mag = mag_aux; - d_dump_filename = d_basename + "_sat_" + std::to_string(d_sat) + ".mat"; + d_dump_filename = d_basename + "_ch_" + std::to_string(channel) + "_" + std::to_string(execution) + "_sat_" + std::to_string(d_sat) + ".mat"; for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) { doppler.push_back(-static_cast(d_doppler_max) + d_doppler_step * doppler_index); diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h index 7dd8ee44b..089d36821 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h @@ -38,7 +38,13 @@ class acquisition_dump_reader { public: - acquisition_dump_reader(const std::string& basename, unsigned int sat, unsigned int doppler_max, unsigned int doppler_step, unsigned int samples_per_code); + acquisition_dump_reader(const std::string& basename, + unsigned int sat, + unsigned int doppler_max, + unsigned int doppler_step, + unsigned int samples_per_code, + int channel = 0, + int execution = 1); ~acquisition_dump_reader(); bool read_binary_acq(); diff --git a/src/utils/matlab/plot_acq_grid.m b/src/utils/matlab/plot_acq_grid.m index c18e44556..182c09b02 100644 --- a/src/utils/matlab/plot_acq_grid.m +++ b/src/utils/matlab/plot_acq_grid.m @@ -33,6 +33,8 @@ file = 'acq'; sat = 7; +channel = 0; +execution = 1; % Signal: % 1 GPS L1 % 2 GPS L2M @@ -77,7 +79,7 @@ switch(signal_type) system = 'R'; signal = '1G'; end -filename = [path file '_' system '_' signal '_sat_' num2str(sat) '.mat']; +filename = [path file '_' system '_' signal '_ch_' num2str(channel) '_' num2str(execution) '_sat_' num2str(sat) '.mat']; load(filename); [n_fft n_dop_bins] = size(grid); [d_max f_max] = find(grid == max(max(grid))); From 68fd25a20f78821a75585342f5b0483353f28f18 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 21 Jun 2018 09:53:47 +0200 Subject: [PATCH 16/40] Merging --- .../gps_l1_acq_performance_test.cc | 166 ++-- .../gps_l1_ca_dll_pll_tracking_test.cc | 838 ++++++++++++------ 2 files changed, 659 insertions(+), 345 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index 08287722c..c0d2e8133 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -38,59 +38,60 @@ DEFINE_string(config_file_ptest, std::string(""), "File containing the configuration parameters for the position test."); // ######## GNURADIO BLOCK MESSAGE RECEVER ######### -//class AcqPerfTest_msg_rx; +class AcqPerfTest_msg_rx; // -//typedef boost::shared_ptr AcqPerfTest_msg_rx_sptr; +typedef boost::shared_ptr AcqPerfTest_msg_rx_sptr; // -//AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(); +AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(); // -//class AcqPerfTest_msg_rx : public gr::block -//{ -//private: -// friend AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(); -// void msg_handler_events(pmt::pmt_t msg); -// AcqPerfTest_msg_rx(); -// -//public: -// int rx_message; -// ~AcqPerfTest_msg_rx(); //!< Default destructor -//}; -// -// -//AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make() -//{ -// return AcqPerfTest_msg_rx_sptr(new AcqPerfTest_msg_rx()); -//} -// -// -//void AcqPerfTest_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; -// } -//} -// -// -//AcqPerfTest_msg_rx::AcqPerfTest_msg_rx() : gr::block("AcqPerfTest_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(&AcqPerfTest_msg_rx::msg_handler_events, this, _1)); -// rx_message = 0; -//} -// -// -//AcqPerfTest_msg_rx::~AcqPerfTest_msg_rx() -//{ -//} -// -//// ----------------------------------------- +class AcqPerfTest_msg_rx : public gr::block +{ +private: + friend AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(); + void msg_handler_events(pmt::pmt_t msg); + AcqPerfTest_msg_rx(); + +public: + int rx_message; + ~AcqPerfTest_msg_rx(); //!< Default destructor +}; + + +AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make() +{ + return AcqPerfTest_msg_rx_sptr(new AcqPerfTest_msg_rx()); +} + + +void AcqPerfTest_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; + } + std::cout << "Received message:" << rx_message << std::endl; +} + + +AcqPerfTest_msg_rx::AcqPerfTest_msg_rx() : gr::block("AcqPerfTest_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(&AcqPerfTest_msg_rx::msg_handler_events, this, _1)); + rx_message = 0; +} + + +AcqPerfTest_msg_rx::~AcqPerfTest_msg_rx() +{ +} + +// ----------------------------------------- class AcquisitionPerformanceTest : public ::testing::Test @@ -109,8 +110,8 @@ protected: { } - std::vector cn0_ = {41.0, 42.0, 43.0}; - int N_iterations = 2; + std::vector cn0_ = {38.0, 40.0, 43.0}; + int N_iterations = 1; void init(); //void plot_grid(); @@ -118,6 +119,7 @@ protected: int generate_signal(); int configure_receiver(double cn0, unsigned int iter); int run_receiver(); + int run_receiver2(); void check_results(); gr::top_block_sptr top_block; Gnss_Synchro gnss_synchro; @@ -125,6 +127,7 @@ protected: unsigned int doppler_max; unsigned int doppler_step; std::string implementation = "GPS_L1_CA_PCPS_Acquisition"; + boost::shared_ptr acquisition; std::shared_ptr config; std::shared_ptr config_f; @@ -325,7 +328,7 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter config->set_property("Acquisition_1C.max_dwells", std::to_string(1)); - config->set_property("Acquisition_1C.repeat_satellite", "false"); + config->set_property("Acquisition_1C.repeat_satellite", "true"); config->set_property("Acquisition_1C.blocking", "true"); config->set_property("Acquisition_1C.make_two_steps", "false"); @@ -355,6 +358,9 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(pll_bw_narrow_hz)); config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(dll_bw_narrow_hz)); config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(extend_correlation_ms)); + config->set_property("Tracking_1C.cn0_min", std::to_string(50)); + config->set_property("Tracking_1C.max_lock_fail", std::to_string(1)); + config->set_property("Tracking_1C.cn0_samples", std::to_string(1)); // Set Telemetry config->set_property("TelemetryDecoder_1C.implementation", "GPS_L1_CA_Telemetry_Decoder"); @@ -395,6 +401,58 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter int AcquisitionPerformanceTest::run_receiver() +{ + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); + std::string file = "./" + filename_raw_data; //+ std::to_string(current_cn0_idx); + 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); + + for (unsigned k = 0; k < 2; k++) + { + gr::top_block_sptr top_block_ = gr::make_top_block("Acquisition test"); + boost::shared_ptr msg_rx = AcqPerfTest_msg_rx_make(); + + gnss_synchro = Gnss_Synchro(); + init(); + auto acquisition_ = boost::make_shared(config.get(), "Acquisition_1C", 1, 0); + + //acquisition->connect(top_block); + acquisition_->set_gnss_synchro(&gnss_synchro); + + acquisition_->connect(top_block_); + acquisition_->set_local_code(); + acquisition_->set_state(1); // Ensure that acquisition starts at the first sample + acquisition_->init(); + //file_source->seek(static_cast(100 * k), SEEK_SET); + + if (not file_source->seek(static_cast(100 * k), SEEK_SET)) + { + std::cout << "Error skipping " << k << std::endl; + } + gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); + top_block_->connect(file_source, 0, gr_interleaved_char_to_complex, 0); + top_block_->connect(gr_interleaved_char_to_complex, 0, acquisition_->get_left_block(), 0); + top_block_->msg_connect(acquisition_->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + + + start = std::chrono::system_clock::now(); + top_block_->run(); // Start threads and wait + end = std::chrono::system_clock::now(); + //file_source->close(); + elapsed_seconds = end - start; + std::cout << "Acq_delay_samples: " << gnss_synchro.Acq_delay_samples << std::endl; + std::cout << "Acq_doppler_hz: " << gnss_synchro.Acq_doppler_hz << std::endl; + std::cout << "Acq_samplestamp_samples: " << gnss_synchro.Acq_samplestamp_samples << std::endl + << std::endl; + } + + //std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; + + return 0; +} + +int AcquisitionPerformanceTest::run_receiver2() { std::shared_ptr control_thread; if (FLAGS_config_file_ptest.empty()) @@ -442,7 +500,7 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) configure_receiver(*it, iter); // Run it - run_receiver(); + run_receiver2(); // Read and store reference data and results } diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index d429460b5..1b3598489 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -53,7 +53,27 @@ #include "gnuplot_i.h" #include "test_flags.h" -DEFINE_bool(plot_gps_l1_tracking_test, false, "Plots results of GpsL1CADllPllTrackingTest with gnuplot"); + +// Input signal configuration +DEFINE_bool(enable_external_signal_file, false, "Use an external signal file capture instead of the software-defined signal generator"); +DEFINE_string(signal_file, std::string("gps_l1_capture.dat"), "Path of the external signal capture file"); +DEFINE_double(CN0_dBHz_start, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]"); +DEFINE_double(CN0_dBHz_stop, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 stop sweep value [dB-Hz]"); +DEFINE_double(CN0_dB_step, 3.0, "Noise generator CN0 sweep step value [dB]"); + +DEFINE_double(PLL_bw_hz_start, 40.0, "PLL Wide configuration start sweep value [Hz]"); +DEFINE_double(PLL_bw_hz_stop, 40.0, "PLL Wide configuration stop sweep value [Hz]"); +DEFINE_double(PLL_bw_hz_step, 5.0, "PLL Wide configuration sweep step value [Hz]"); + +DEFINE_double(DLL_bw_hz_start, 1.5, "DLL Wide configuration start sweep value [Hz]"); +DEFINE_double(DLL_bw_hz_stop, 1.5, "DLL Wide configuration stop sweep value [Hz]"); +DEFINE_double(DLL_bw_hz_step, 0.25, "DLL Wide configuration sweep step value [Hz]"); + +DEFINE_bool(plot_extra, false, "Enable or disable plots of the correlators output and constellation diagrams"); + +//Emulated acquisition configuration + +//Tracking configuration DEFINE_int32(extend_correlation_symbols, 1, "Set the tracking coherent correlation to N symbols (up to 20 for GPS L1 C/A)"); //Test output configuration @@ -137,15 +157,21 @@ public: std::vector check_results_doppler(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, - arma::vec& meas_value); + arma::vec& meas_value, + double& mean_error, + double& std_dev_error); std::vector check_results_acc_carrier_phase(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, - arma::vec& meas_value); + arma::vec& meas_value, + double& mean_error, + double& std_dev_error); std::vector check_results_codephase(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, - arma::vec& meas_value); + arma::vec& meas_value, + double& mean_error, + double& std_dev_error); GpsL1CADllPllTrackingTest() { @@ -159,7 +185,11 @@ public: { } - void configure_receiver(); + void configure_receiver(double PLL_wide_bw_hz, + double DLL_wide_bw_hz, + double PLL_narrow_bw_hz, + double DLL_narrow_bw_hz, + int extend_correlation_symbols); gr::top_block_sptr top_block; std::shared_ptr factory; @@ -214,7 +244,12 @@ int GpsL1CADllPllTrackingTest::generate_signal() } -void GpsL1CADllPllTrackingTest::configure_receiver() +void GpsL1CADllPllTrackingTest::configure_receiver( + double PLL_wide_bw_hz, + double DLL_wide_bw_hz, + double PLL_narrow_bw_hz, + double DLL_narrow_bw_hz, + int extend_correlation_symbols) { gnss_synchro.Channel_ID = 0; gnss_synchro.System = 'G'; @@ -222,26 +257,40 @@ void GpsL1CADllPllTrackingTest::configure_receiver() signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = FLAGS_test_satellite_PRN; + config = std::make_shared(); 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"); - config->set_property("Tracking_1C.pll_bw_hz", "20.0"); - config->set_property("Tracking_1C.dll_bw_hz", "1.5"); + config->set_property("Tracking_1C.pll_bw_hz", std::to_string(PLL_wide_bw_hz)); + config->set_property("Tracking_1C.dll_bw_hz", std::to_string(DLL_wide_bw_hz)); config->set_property("Tracking_1C.early_late_space_chips", "0.5"); - config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(FLAGS_extend_correlation_symbols)); - config->set_property("Tracking_1C.pll_bw_narrow_hz", "2.0"); - config->set_property("Tracking_1C.dll_bw_narrow_hz", "1.0"); + config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(extend_correlation_symbols)); + config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz)); + config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz)); config->set_property("Tracking_1C.early_late_space_narrow_chips", "0.5"); config->set_property("Tracking_1C.dump", "true"); config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); + + std::cout << "*****************************************\n"; + std::cout << "*** Tracking configuration parameters ***\n"; + std::cout << "*****************************************\n"; + std::cout << "pll_bw_hz: " << config->property("Tracking_1C.pll_bw_hz", 0.0) << " Hz\n"; + std::cout << "dll_bw_hz: " << config->property("Tracking_1C.dll_bw_hz", 0.0) << " Hz\n"; + std::cout << "pll_bw_narrow_hz: " << config->property("Tracking_1C.pll_bw_narrow_hz", 0.0) << " Hz\n"; + std::cout << "dll_bw_narrow_hz: " << config->property("Tracking_1C.dll_bw_narrow_hz", 0.0) << " Hz\n"; + std::cout << "extend_correlation_symbols: " << config->property("Tracking_1C.extend_correlation_symbols", 0) << " Symbols\n"; + std::cout << "*****************************************\n"; + std::cout << "*****************************************\n"; } std::vector GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, - arma::vec& meas_value) + arma::vec& meas_value, + double& mean_error, + double& std_dev_error) { // 1. True value interpolation to match the measurement times arma::vec true_value_interp; @@ -269,6 +318,9 @@ std::vector GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec& double error_mean = arma::mean(err); double error_var = arma::var(err); + mean_error = error_mean; + std_dev_error = sqrt(error_var); + // 4. Peaks double max_error = arma::max(err); double min_error = arma::min(err); @@ -286,7 +338,9 @@ std::vector GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec& std::vector GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, - arma::vec& meas_value) + arma::vec& meas_value, + double& mean_error, + double& std_dev_error) { // 1. True value interpolation to match the measurement times arma::vec true_value_interp; @@ -312,6 +366,8 @@ std::vector GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(a double error_mean = arma::mean(err); double error_var = arma::var(err); + mean_error = error_mean; + std_dev_error = sqrt(error_var); // 4. Peaks double max_error = arma::max(err); double min_error = arma::min(err); @@ -329,7 +385,9 @@ std::vector GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(a std::vector GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, - arma::vec& meas_value) + arma::vec& meas_value, + double& mean_error, + double& std_dev_error) { // 1. True value interpolation to match the measurement times arma::vec true_value_interp; @@ -356,6 +414,9 @@ std::vector GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec double error_mean = arma::mean(err); double error_var = arma::var(err); + mean_error = error_mean; + std_dev_error = sqrt(error_var); + // 4. Peaks double max_error = arma::max(err); double min_error = arma::min(err); @@ -378,18 +439,18 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std::vector generator_CN0_values; - std::vector> prompt_sweep; - std::vector> early_sweep; - std::vector> late_sweep; - std::vector> promptI_sweep; - std::vector> promptQ_sweep; - std::vector> CN0_dBHz_sweep; - //error vectors - std::vector> doppler_error_sweep; - std::vector> code_phase_error_sweep; - std::vector> acc_carrier_phase_error_sweep; - std::vector> trk_timestamp_s_sweep; + //data containers for config param sweep + std::vector> mean_doppler_error_sweep; //swep config param and cn0 sweep + std::vector> std_dev_doppler_error_sweep; //swep config param and cn0 sweep + + std::vector> mean_code_phase_error_sweep; //swep config param and cn0 sweep + std::vector> std_dev_code_phase_error_sweep; //swep config param and cn0 sweep + + std::vector> mean_carrier_phase_error_sweep; //swep config param and cn0 sweep + std::vector> std_dev_carrier_phase_error_sweep; //swep config param and cn0 sweep + + std::vector> trk_valid_timestamp_s_sweep; if (FLAGS_CN0_dBHz_start == FLAGS_CN0_dBHz_stop) { @@ -433,192 +494,430 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) } - //CN0 LOOP + // CONFIG PARAM SWEEP LOOP + std::vector PLL_wide_bw_values; + std::vector DLL_wide_bw_values; - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + + if (FLAGS_PLL_bw_hz_start == FLAGS_PLL_bw_hz_stop) { - //****************************************************************************************** - //***** Obtain the initial signal sinchronization parameters (emulating an acquisition) **** - //****************************************************************************************** - if (!FLAGS_enable_external_signal_file) + if (FLAGS_DLL_bw_hz_start == FLAGS_DLL_bw_hz_stop) { - test_satellite_PRN = FLAGS_test_satellite_PRN; - 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"); - true_obs_data.close_obs_file(); - ASSERT_EQ(true_obs_data.open_obs_file(true_obs_file), true) << "Failure opening true observables file"; - // 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?"; - std::cout << "Testing satellite PRN=" << test_satellite_PRN << std::endl; - std::cout << "Initial Doppler [Hz]=" << true_obs_data.doppler_l1_hz << " Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << std::endl; - acq_doppler_hz = true_obs_data.doppler_l1_hz; - acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * static_cast(baseband_sampling_freq) * GPS_L1_CA_CODE_PERIOD; - // restart the epoch counter - true_obs_data.restart(); + //NO PLL/DLL BW sweep + PLL_wide_bw_values.push_back(FLAGS_PLL_bw_hz_start); + DLL_wide_bw_values.push_back(FLAGS_DLL_bw_hz_start); } - - - //***** STEP 4: Configure the signal tracking parameters ***** - //************************************************************ - std::chrono::time_point start, end; - configure_receiver(); - - top_block = gr::make_top_block("Tracking test"); - - std::shared_ptr trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1); - std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); - - boost::shared_ptr msg_rx = GpsL1CADllPllTrackingTest_msg_rx_make(); - - gnss_synchro.Acq_delay_samples = acq_delay_samples; - gnss_synchro.Acq_doppler_hz = acq_doppler_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 + std::to_string(current_cn0_idx); - 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."; - - - //******************************************************************** - //***** STEP 5: Perform the signal tracking and read the results ***** - //******************************************************************** - 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."; - - std::chrono::duration elapsed_seconds = end - start; - std::cout << "Signal tracking completed in " << elapsed_seconds.count() << " seconds" << std::endl; - - //check results - //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"; - - long int n_measured_epochs = trk_dump.num_epochs(); - std::cout << "Measured observation epochs=" << n_measured_epochs << std::endl; - - arma::vec trk_timestamp_s = arma::zeros(n_measured_epochs, 1); - arma::vec trk_acc_carrier_phase_cycles = arma::zeros(n_measured_epochs, 1); - arma::vec trk_Doppler_Hz = arma::zeros(n_measured_epochs, 1); - arma::vec trk_prn_delay_chips = arma::zeros(n_measured_epochs, 1); - - long int epoch_counter = 0; - - std::vector prompt; - std::vector early; - std::vector late; - std::vector promptI; - std::vector promptQ; - std::vector CN0_dBHz; - while (trk_dump.read_binary_obs()) + else { - trk_timestamp_s(epoch_counter) = static_cast(trk_dump.PRN_start_sample_count) / static_cast(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(trk_dump.PRN_start_sample_count) + trk_dump.aux1) / static_cast(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); - CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz); + //DLL BW Sweep + for (double dll_bw = FLAGS_DLL_bw_hz_start; dll_bw > FLAGS_DLL_bw_hz_stop; dll_bw = dll_bw - FLAGS_DLL_bw_hz_step) + { + PLL_wide_bw_values.push_back(FLAGS_PLL_bw_hz_start); + DLL_wide_bw_values.push_back(dll_bw); + } } - - prompt_sweep.push_back(prompt); - early_sweep.push_back(early); - late_sweep.push_back(late); - promptI_sweep.push_back(promptI); - promptQ_sweep.push_back(promptQ); - CN0_dBHz_sweep.push_back(CN0_dBHz); - - //*********************************************************** - //***** STEP 6: Compare with true values (if available) ***** - //*********************************************************** - if (!FLAGS_enable_external_signal_file) + } + else + { + //PLL BW Sweep + for (double pll_bw = FLAGS_PLL_bw_hz_start; pll_bw > FLAGS_PLL_bw_hz_stop; pll_bw = pll_bw - FLAGS_PLL_bw_hz_step) { - // load the true values - long int n_true_epochs = true_obs_data.num_epochs(); - std::cout << "True observation epochs=" << n_true_epochs << std::endl; + PLL_wide_bw_values.push_back(pll_bw); + DLL_wide_bw_values.push_back(FLAGS_DLL_bw_hz_start); + } + } - arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); - arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); - arma::vec true_Doppler_Hz = arma::zeros(n_true_epochs, 1); - arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); - arma::vec true_tow_s = arma::zeros(n_true_epochs, 1); + for (int config_idx = 0; config_idx < PLL_wide_bw_values.size(); config_idx++) + { + //CN0 LOOP + // data containers for CN0 sweep + std::vector> prompt_sweep; + std::vector> early_sweep; + std::vector> late_sweep; + std::vector> promptI_sweep; + std::vector> promptQ_sweep; + std::vector> CN0_dBHz_sweep; + std::vector> trk_timestamp_s_sweep; + + std::vector> doppler_error_sweep; + std::vector> code_phase_error_sweep; + std::vector> acc_carrier_phase_error_sweep; + + std::vector mean_doppler_error; + std::vector std_dev_doppler_error; + std::vector mean_code_phase_error; + std::vector std_dev_code_phase_error; + std::vector mean_carrier_phase_error; + std::vector std_dev_carrier_phase_error; + + configure_receiver(PLL_wide_bw_values.at(config_idx), + DLL_wide_bw_values.at(config_idx), + 2.0, + 1.0, + FLAGS_extend_correlation_symbols); + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + //****************************************************************************************** + //***** Obtain the initial signal sinchronization parameters (emulating an acquisition) **** + //****************************************************************************************** + if (!FLAGS_enable_external_signal_file) + { + test_satellite_PRN = FLAGS_test_satellite_PRN; + 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"); + true_obs_data.close_obs_file(); + ASSERT_EQ(true_obs_data.open_obs_file(true_obs_file), true) << "Failure opening true observables file"; + // 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?"; + std::cout << "Testing satellite PRN=" << test_satellite_PRN << std::endl; + std::cout << "Initial Doppler [Hz]=" << true_obs_data.doppler_l1_hz << " Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << std::endl; + acq_doppler_hz = true_obs_data.doppler_l1_hz; + acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * static_cast(baseband_sampling_freq) * GPS_L1_CA_CODE_PERIOD; + // restart the epoch counter + true_obs_data.restart(); + } + + + //***** STEP 4: Configure the signal tracking parameters ***** + //************************************************************ + std::chrono::time_point start, end; + + top_block = gr::make_top_block("Tracking test"); + + std::shared_ptr trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1); + std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); + + boost::shared_ptr msg_rx = GpsL1CADllPllTrackingTest_msg_rx_make(); + + gnss_synchro.Acq_delay_samples = acq_delay_samples; + gnss_synchro.Acq_doppler_hz = acq_doppler_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 + std::to_string(current_cn0_idx); + 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."; + + + //******************************************************************** + //***** STEP 5: Perform the signal tracking and read the results ***** + //******************************************************************** + 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."; + + std::chrono::duration elapsed_seconds = end - start; + std::cout << "Signal tracking completed in " << elapsed_seconds.count() << " seconds" << std::endl; + + //check results + //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"; + + long int n_measured_epochs = trk_dump.num_epochs(); + std::cout << "Measured observation epochs=" << n_measured_epochs << std::endl; + + arma::vec trk_timestamp_s = arma::zeros(n_measured_epochs, 1); + arma::vec trk_acc_carrier_phase_cycles = arma::zeros(n_measured_epochs, 1); + arma::vec trk_Doppler_Hz = arma::zeros(n_measured_epochs, 1); + arma::vec trk_prn_delay_chips = arma::zeros(n_measured_epochs, 1); long int epoch_counter = 0; - while (true_obs_data.read_binary_obs()) + + std::vector timestamp_s; + std::vector prompt; + std::vector early; + std::vector late; + std::vector promptI; + std::vector promptQ; + std::vector CN0_dBHz; + while (trk_dump.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; + trk_timestamp_s(epoch_counter) = static_cast(trk_dump.PRN_start_sample_count) / static_cast(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(trk_dump.PRN_start_sample_count) + trk_dump.aux1) / static_cast(baseband_sampling_freq), 1.0e-3) / 1.0e-3); + + trk_prn_delay_chips(epoch_counter) = delay_chips; + + timestamp_s.push_back(trk_timestamp_s(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); + CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz); + epoch_counter++; } - // 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_sweep.push_back(timestamp_s); + prompt_sweep.push_back(prompt); + early_sweep.push_back(early); + late_sweep.push_back(late); + promptI_sweep.push_back(promptI); + promptQ_sweep.push_back(promptQ); + CN0_dBHz_sweep.push_back(CN0_dBHz); - 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); + //*********************************************************** + //***** STEP 6: Compare with true values (if available) ***** + //*********************************************************** + if (!FLAGS_enable_external_signal_file) + { + std::vector doppler_error_hz; + std::vector code_phase_error_chips; + std::vector acc_carrier_phase_hz; + try + { + // load the true values + long int n_true_epochs = true_obs_data.num_epochs(); + std::cout << "True observation epochs=" << n_true_epochs << std::endl; - std::vector doppler_error_hz; - std::vector code_phase_error_chips; - std::vector acc_carrier_phase_hz; - doppler_error_hz = check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz); - code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips); - acc_carrier_phase_hz = check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles); - //save tracking measurement timestamps to std::vector - std::vector vector_trk_timestamp_s(trk_timestamp_s.colptr(0), trk_timestamp_s.colptr(0) + trk_timestamp_s.n_rows); - trk_timestamp_s_sweep.push_back(vector_trk_timestamp_s); + arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); + arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); + arma::vec true_Doppler_Hz = arma::zeros(n_true_epochs, 1); + arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); + arma::vec true_tow_s = arma::zeros(n_true_epochs, 1); - doppler_error_sweep.push_back(doppler_error_hz); - code_phase_error_sweep.push_back(code_phase_error_chips); - acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz); + 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++; + } + // 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); + + + double mean_error; + double std_dev_error; + + doppler_error_hz = check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz, mean_error, std_dev_error); + mean_doppler_error.push_back(mean_error); + std_dev_doppler_error.push_back(std_dev_error); + + code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips, mean_error, std_dev_error); + mean_code_phase_error.push_back(mean_error); + std_dev_code_phase_error.push_back(std_dev_error); + + acc_carrier_phase_hz = check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles, mean_error, std_dev_error); + mean_carrier_phase_error.push_back(mean_error); + std_dev_carrier_phase_error.push_back(std_dev_error); + + //save tracking measurement timestamps to std::vector + std::vector vector_trk_timestamp_s(trk_timestamp_s.colptr(0), trk_timestamp_s.colptr(0) + trk_timestamp_s.n_rows); + trk_valid_timestamp_s_sweep.push_back(vector_trk_timestamp_s); + + doppler_error_sweep.push_back(doppler_error_hz); + code_phase_error_sweep.push_back(code_phase_error_chips); + acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz); + } + catch (const std::exception& ex) + { + std::cout << "Tracking output could not be used, possible loss of lock " << ex.what() << std::endl; + + std::vector vector_trk_timestamp_s; + trk_valid_timestamp_s_sweep.push_back(vector_trk_timestamp_s); + doppler_error_sweep.push_back(doppler_error_hz); + code_phase_error_sweep.push_back(code_phase_error_chips); + acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz); + } + } + + } //CN0 LOOP + + if (!FLAGS_enable_external_signal_file) + { + mean_doppler_error_sweep.push_back(mean_doppler_error); + std_dev_doppler_error_sweep.push_back(std_dev_doppler_error); + mean_code_phase_error_sweep.push_back(mean_code_phase_error); + std_dev_code_phase_error_sweep.push_back(std_dev_code_phase_error); + mean_carrier_phase_error_sweep.push_back(mean_carrier_phase_error); + std_dev_carrier_phase_error_sweep.push_back(std_dev_carrier_phase_error); } - } //CN0 LOOP + std::cout << "A\n\n\n"; + //******************************** + //***** STEP 7: Plot results ***** + //******************************** + if (FLAGS_plot_gps_l1_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); + unsigned int decimate = static_cast(FLAGS_plot_decimate); + + if (FLAGS_plot_extra) + { + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + Gnuplot g1("linespoints"); + g1.showonscreen(); // window output + g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz" + "GPS L1 C/A (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"); + g1.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), prompt_sweep.at(current_cn0_idx), "Prompt", decimate); + g1.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), early_sweep.at(current_cn0_idx), "Early", decimate); + g1.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), late_sweep.at(current_cn0_idx), "Late", decimate); + g1.set_legend(); + g1.savetops("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx))); + g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18); + } + Gnuplot g2("points"); + g2.showonscreen(); // window output + g2.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), + ceil(static_cast(generator_CN0_values.size()) / 2)); + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g2.reset_plot(); + g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz" + "GPS L1 C/A (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_sweep.at(current_cn0_idx), promptQ_sweep.at(current_cn0_idx)); + } + g2.unset_multiplot(); + g2.savetops("Constellation"); + g2.savetopdf("Constellation", 18); + + Gnuplot g3("linespoints"); + g3.set_title("GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g3.set_grid(); + g3.set_xlabel("Time [s]"); + g3.set_ylabel("Reported CN0 [dB-Hz]"); + g3.cmd("set key box opaque"); + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g3.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), CN0_dBHz_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + g3.set_legend(); + g3.savetops("CN0_output"); + g3.savetopdf("CN0_output", 18); + g3.showonscreen(); // window output + } + + std::cout << "B\n\n\n"; + //PLOT ERROR FIGURES (only if it is used the signal generator) + if (!FLAGS_enable_external_signal_file) + { + Gnuplot g4("points"); + g4.showonscreen(); // window output + g4.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), + ceil(static_cast(generator_CN0_values.size()) / 2)); + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g4.reset_plot(); + g4.set_title(std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz] Doppler error " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g4.set_grid(); + //g4.cmd("set key box opaque"); + g4.set_xlabel("Time [s]"); + g4.set_ylabel("Dopper error [Hz]"); + g4.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), doppler_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + //g4.set_legend(); + } + g4.unset_multiplot(); + g4.savetops("Doppler_error_output"); + g4.savetopdf("Doppler_error_output", 18); + + Gnuplot g5("points"); + g5.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g5.set_grid(); + g5.set_xlabel("Time [s]"); + g5.set_ylabel("Code delay error [Chips]"); + g5.cmd("set key box opaque"); + + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g5.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + g5.set_legend(); + g5.savetops("Code_error_output"); + g5.savetopdf("Code_error_output", 18); + g5.showonscreen(); // window output + + Gnuplot g6("points"); + g6.set_title("Accumulated carrier phase error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g6.set_grid(); + g6.set_xlabel("Time [s]"); + g6.set_ylabel("Accumulated carrier phase error [Cycles]"); + g6.cmd("set key box opaque"); + + for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + g6.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), acc_carrier_phase_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + g6.set_legend(); + g6.savetops("Carrier_phase_error_output"); + g6.savetopdf("Carrier_phase_error_output", 18); + g6.showonscreen(); // window output + } + } + catch (const GnuplotException& ge) + { + std::cout << ge.what() << std::endl; + } + } + } + } + - //******************************** - //***** STEP 7: Plot results ***** - //******************************** if (FLAGS_plot_gps_l1_tracking_test == true) { const std::string gnuplot_executable(FLAGS_gnuplot_executable); @@ -632,110 +931,67 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) { 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 timevec; - unsigned int decimate = static_cast(FLAGS_plot_decimate); - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + if (generator_CN0_values.size() > 1) { - timevec.clear(); - //todo: timevector MUST BE READED from the trk output file - double t = 0.0; - for (auto it = prompt_sweep.at(current_cn0_idx).begin(); it != prompt_sweep.at(current_cn0_idx).end(); it++) + //plot metrics + + Gnuplot g7("linespoints"); + g7.set_title("Doppler error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g7.set_grid(); + g7.set_xlabel("CN0 [dB-Hz]"); + g7.set_ylabel("Doppler error [Hz]"); + g7.set_pointsize(2); + g7.cmd("set termoption lw 2"); + g7.cmd("set key box opaque"); + for (int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++) { - timevec.push_back(t); - t = t + GPS_L1_CA_CODE_PERIOD; + g7.plot_xy_err(generator_CN0_values, + mean_doppler_error_sweep.at(config_sweep_idx), + std_dev_doppler_error_sweep.at(config_sweep_idx), + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + + +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); } - Gnuplot g1("linespoints"); - g1.set_title("[" + std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz ] 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"); - g1.plot_xy(timevec, prompt_sweep.at(current_cn0_idx), "Prompt", decimate); - g1.plot_xy(timevec, early_sweep.at(current_cn0_idx), "Early", decimate); - g1.plot_xy(timevec, late_sweep.at(current_cn0_idx), "Late", decimate); - g1.savetops("Correlators_outputs"); - g1.savetopdf("Correlators_outputs", 18); - g1.showonscreen(); // window output - Gnuplot g2("points"); - g2.set_title("[" + std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz ] 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_sweep.at(current_cn0_idx), promptQ_sweep.at(current_cn0_idx)); - g2.savetops("Constellation"); - g2.savetopdf("Constellation", 18); - g2.showonscreen(); // window output - } - Gnuplot g3("linespoints"); - g3.set_title("GPS L1 C/A tracking CN0 output (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g3.set_grid(); - g3.set_xlabel("Time [s]"); - g3.set_ylabel("Reported CN0 [dB-Hz]"); - g3.cmd("set key box opaque"); - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) - { - g3.plot_xy(timevec, CN0_dBHz_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); - } - g3.set_legend(); - g3.savetops("CN0_output"); - g3.savetopdf("CN0_output", 18); - g3.showonscreen(); // window output + g7.savetops("Doppler_error_metrics"); + g7.savetopdf("Doppler_error_metrics", 18); - Gnuplot g4("points"); - g4.set_title("Doppler error (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g4.set_grid(); - g4.set_xlabel("Time [s]"); - g4.set_ylabel("Dopper error [Hz]"); - g4.cmd("set key box opaque"); - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) - { - g4.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), doppler_error_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + Gnuplot g8("linespoints"); + g8.set_title("Accumulated carrier phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g8.set_grid(); + g8.set_xlabel("CN0 [dB-Hz]"); + g8.set_ylabel("Accumulated Carrier Phase error [Cycles]"); + g8.cmd("set key box opaque"); + g8.cmd("set termoption lw 2"); + g8.set_pointsize(2); + for (int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++) + { + g8.plot_xy_err(generator_CN0_values, + mean_carrier_phase_error_sweep.at(config_sweep_idx), + std_dev_carrier_phase_error_sweep.at(config_sweep_idx), + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + + +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); + } + g8.savetops("Carrier_error_metrics"); + g8.savetopdf("Carrier_error_metrics", 18); + + Gnuplot g9("linespoints"); + g9.set_title("Code Phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g9.set_grid(); + g9.set_xlabel("CN0 [dB-Hz]"); + g9.set_ylabel("Code Phase error [Chips]"); + g9.cmd("set key box opaque"); + g9.cmd("set termoption lw 2"); + g9.set_pointsize(2); + for (int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++) + { + g9.plot_xy_err(generator_CN0_values, + mean_code_phase_error_sweep.at(config_sweep_idx), + std_dev_code_phase_error_sweep.at(config_sweep_idx), + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + + +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); + } + g9.savetops("Code_error_metrics"); + g9.savetopdf("Code_error_metrics", 18); } - g4.set_legend(); - g4.savetops("Doppler_error_output"); - g4.savetopdf("Doppler_error_output", 18); - g4.showonscreen(); // window output - - Gnuplot g5("points"); - g5.set_title("Code delay error (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g5.set_grid(); - g5.set_xlabel("Time [s]"); - g5.set_ylabel("Code delay error [Chips]"); - g5.cmd("set key box opaque"); - - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) - { - g5.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); - } - g5.set_legend(); - g5.savetops("Code_error_output"); - g5.savetopdf("Code_error_output", 18); - g5.showonscreen(); // window output - - Gnuplot g6("points"); - g6.set_title("Accumulated carrier phase error (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g6.set_grid(); - g6.set_xlabel("Time [s]"); - g6.set_ylabel("Accumulated carrier phase error [Cycles]"); - g6.cmd("set key box opaque"); - - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) - { - g6.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), acc_carrier_phase_error_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); - } - g6.set_legend(); - g6.savetops("Carrier_phase_error_output"); - g6.savetopdf("Carrier_phase_error_output", 18); - g6.showonscreen(); // window output } catch (const GnuplotException& ge) { From eadabaf900a006d8d4fd2ce070e9bd768ae1eca6 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 21 Jun 2018 12:21:35 +0200 Subject: [PATCH 17/40] Add more info in acquisition dumps --- .../gnuradio_blocks/pcps_acquisition.cc | 45 ++++++++++++++++--- .../gnuradio_blocks/pcps_acquisition.h | 1 + .../gps_l1_ca_pcps_acquisition_test.cc | 2 +- .../libs/acquisition_dump_reader.cc | 14 +++++- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 7f81d68e3..f16855790 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -60,6 +60,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu acq_parameters = conf_; d_sample_counter = 0; // SAMPLE COUNTER d_active = false; + d_positive_acq = 0; d_state = 0; d_old_freq = 0; d_well_count = 0; @@ -376,6 +377,36 @@ void pcps_acquisition::dump_results(int effective_fft_size) Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarFree(matvar); + matvar = Mat_VarCreate("d_positive_acq", MAT_C_INT32, MAT_T_INT32, 1, dims, &d_positive_acq, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + float aux = static_cast(d_gnss_synchro->Acq_doppler_hz); + matvar = Mat_VarCreate("acq_doppler_hz", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &aux, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + aux = static_cast(d_gnss_synchro->Acq_delay_samples); + matvar = Mat_VarCreate("acq_delay_samples", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &aux, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("test_statistic", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &d_test_statistics, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("threshold", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &d_threshold, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("input_power", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &d_input_power, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("sample_counter", MAT_C_UINT64, MAT_T_UINT64, 1, dims, &d_sample_counter, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + Mat_Close(matfp); } } @@ -554,11 +585,6 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) } } } - // Record results to file if required - if (acq_parameters.dump) - { - pcps_acquisition::dump_results(effective_fft_size); - } lk.lock(); if (!acq_parameters.bit_transition_flag) { @@ -572,6 +598,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) send_positive_acquisition(); d_step_two = false; d_state = 0; // Positive acquisition + d_positive_acq = 1; } else { @@ -583,6 +610,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) { send_positive_acquisition(); d_state = 0; // Positive acquisition + d_positive_acq = 1; } } else if (d_well_count == acq_parameters.max_dwells) @@ -605,6 +633,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) send_positive_acquisition(); d_step_two = false; d_state = 0; // Positive acquisition + d_positive_acq = 1; } else { @@ -616,6 +645,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) { send_positive_acquisition(); d_state = 0; // Positive acquisition + d_positive_acq = 1; } } else @@ -626,6 +656,11 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) } } d_worker_active = false; + // Record results to file if required + if (acq_parameters.dump) + { + pcps_acquisition::dump_results(effective_fft_size); + } } diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index f0fd69e7f..d34888fd8 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -100,6 +100,7 @@ private: bool d_worker_active; bool d_cshort; bool d_step_two; + int d_positive_acq; float d_threshold; float d_mag; float d_input_power; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc index 05b374e06..d2c5a96c9 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc @@ -175,7 +175,7 @@ void GpsL1CaPcpsAcquisitionTest::plot_grid() unsigned int sat = static_cast(gnss_synchro.PRN); unsigned int samples_per_code = static_cast(round(4000000 / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); // !! - acquisition_dump_reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code); + acquisition_dump_reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code, 1); if (!acq_dump.read_binary_acq()) std::cout << "Error reading files" << std::endl; diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc index 5fcd1308b..6302f2e63 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc @@ -73,17 +73,27 @@ bool acquisition_dump_reader::read_binary_acq() Mat_Close(matfile); return false; } + matvar_t* var2_ = Mat_VarRead(matfile, "doppler_max"); + d_doppler_max = *static_cast(var2_->data); + Mat_VarFree(var2_); + + var2_ = Mat_VarRead(matfile, "doppler_step"); + d_doppler_step = *static_cast(var2_->data); + Mat_VarFree(var2_); + + var2_ = Mat_VarRead(matfile, "input_power"); + float normalization_factor = *static_cast(var2_->data); + Mat_VarFree(var2_); std::vector >::iterator it1; std::vector::iterator it2; float* aux = static_cast(var_->data); int k = 0; - float normalization_factor = std::pow(d_samples_per_code, 2); for (it1 = mag.begin(); it1 != mag.end(); it1++) { for (it2 = it1->begin(); it2 != it1->end(); it2++) { - *it2 = static_cast(std::sqrt(aux[k])) / normalization_factor; + *it2 = static_cast(aux[k]) / normalization_factor; k++; } } From 020603c3b82f10125ad9d4898a9d6ef951466665 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 21 Jun 2018 12:21:35 +0200 Subject: [PATCH 18/40] Add more info in acquisition dumps --- .../gnuradio_blocks/pcps_acquisition.cc | 45 ++++++++++++++++--- .../gnuradio_blocks/pcps_acquisition.h | 1 + .../gps_l1_ca_pcps_acquisition_test.cc | 2 +- .../libs/acquisition_dump_reader.cc | 14 +++++- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 7f81d68e3..f16855790 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -60,6 +60,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu acq_parameters = conf_; d_sample_counter = 0; // SAMPLE COUNTER d_active = false; + d_positive_acq = 0; d_state = 0; d_old_freq = 0; d_well_count = 0; @@ -376,6 +377,36 @@ void pcps_acquisition::dump_results(int effective_fft_size) Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarFree(matvar); + matvar = Mat_VarCreate("d_positive_acq", MAT_C_INT32, MAT_T_INT32, 1, dims, &d_positive_acq, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + float aux = static_cast(d_gnss_synchro->Acq_doppler_hz); + matvar = Mat_VarCreate("acq_doppler_hz", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &aux, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + aux = static_cast(d_gnss_synchro->Acq_delay_samples); + matvar = Mat_VarCreate("acq_delay_samples", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &aux, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("test_statistic", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &d_test_statistics, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("threshold", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &d_threshold, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("input_power", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &d_input_power, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("sample_counter", MAT_C_UINT64, MAT_T_UINT64, 1, dims, &d_sample_counter, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + Mat_Close(matfp); } } @@ -554,11 +585,6 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) } } } - // Record results to file if required - if (acq_parameters.dump) - { - pcps_acquisition::dump_results(effective_fft_size); - } lk.lock(); if (!acq_parameters.bit_transition_flag) { @@ -572,6 +598,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) send_positive_acquisition(); d_step_two = false; d_state = 0; // Positive acquisition + d_positive_acq = 1; } else { @@ -583,6 +610,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) { send_positive_acquisition(); d_state = 0; // Positive acquisition + d_positive_acq = 1; } } else if (d_well_count == acq_parameters.max_dwells) @@ -605,6 +633,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) send_positive_acquisition(); d_step_two = false; d_state = 0; // Positive acquisition + d_positive_acq = 1; } else { @@ -616,6 +645,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) { send_positive_acquisition(); d_state = 0; // Positive acquisition + d_positive_acq = 1; } } else @@ -626,6 +656,11 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) } } d_worker_active = false; + // Record results to file if required + if (acq_parameters.dump) + { + pcps_acquisition::dump_results(effective_fft_size); + } } diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index f0fd69e7f..d34888fd8 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -100,6 +100,7 @@ private: bool d_worker_active; bool d_cshort; bool d_step_two; + int d_positive_acq; float d_threshold; float d_mag; float d_input_power; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc index 05b374e06..d2c5a96c9 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc @@ -175,7 +175,7 @@ void GpsL1CaPcpsAcquisitionTest::plot_grid() unsigned int sat = static_cast(gnss_synchro.PRN); unsigned int samples_per_code = static_cast(round(4000000 / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); // !! - acquisition_dump_reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code); + acquisition_dump_reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code, 1); if (!acq_dump.read_binary_acq()) std::cout << "Error reading files" << std::endl; diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc index 5fcd1308b..6302f2e63 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc @@ -73,17 +73,27 @@ bool acquisition_dump_reader::read_binary_acq() Mat_Close(matfile); return false; } + matvar_t* var2_ = Mat_VarRead(matfile, "doppler_max"); + d_doppler_max = *static_cast(var2_->data); + Mat_VarFree(var2_); + + var2_ = Mat_VarRead(matfile, "doppler_step"); + d_doppler_step = *static_cast(var2_->data); + Mat_VarFree(var2_); + + var2_ = Mat_VarRead(matfile, "input_power"); + float normalization_factor = *static_cast(var2_->data); + Mat_VarFree(var2_); std::vector >::iterator it1; std::vector::iterator it2; float* aux = static_cast(var_->data); int k = 0; - float normalization_factor = std::pow(d_samples_per_code, 2); for (it1 = mag.begin(); it1 != mag.end(); it1++) { for (it2 = it1->begin(); it2 != it1->end(); it2++) { - *it2 = static_cast(std::sqrt(aux[k])) / normalization_factor; + *it2 = static_cast(aux[k]) / normalization_factor; k++; } } From 5c283c06435ea9d5d84659699bd4ae5ce4d5a2ab Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 21 Jun 2018 12:54:36 +0200 Subject: [PATCH 19/40] Read results from acquisition dumps --- .../libs/acquisition_dump_reader.cc | 35 +++++++++++++++++-- .../libs/acquisition_dump_reader.h | 7 ++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc index 6302f2e63..063d02837 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc @@ -82,7 +82,31 @@ bool acquisition_dump_reader::read_binary_acq() Mat_VarFree(var2_); var2_ = Mat_VarRead(matfile, "input_power"); - float normalization_factor = *static_cast(var2_->data); + input_power = *static_cast(var2_->data); + Mat_VarFree(var2_); + + var2_ = Mat_VarRead(matfile, "acq_doppler_hz"); + acq_doppler_hz = *static_cast(var2_->data); + Mat_VarFree(var2_); + + var2_ = Mat_VarRead(matfile, "acq_delay_samples"); + acq_delay_samples = *static_cast(var2_->data); + Mat_VarFree(var2_); + + var2_ = Mat_VarRead(matfile, "test_statistic"); + test_statistic = *static_cast(var2_->data); + Mat_VarFree(var2_); + + var2_ = Mat_VarRead(matfile, "threshold"); + threshold = *static_cast(var2_->data); + Mat_VarFree(var2_); + + var2_ = Mat_VarRead(matfile, "sample_counter"); + sample_counter = *static_cast(var2_->data); + Mat_VarFree(var2_); + + var2_ = Mat_VarRead(matfile, "d_positive_acq"); + positive_acq = *static_cast(var2_->data); Mat_VarFree(var2_); std::vector >::iterator it1; @@ -93,7 +117,7 @@ bool acquisition_dump_reader::read_binary_acq() { for (it2 = it1->begin(); it2 != it1->end(); it2++) { - *it2 = static_cast(aux[k]) / normalization_factor; + *it2 = static_cast(aux[k]) / input_power; k++; } } @@ -117,6 +141,13 @@ acquisition_dump_reader::acquisition_dump_reader(const std::string& basename, d_doppler_max = doppler_max; d_doppler_step = doppler_step; d_samples_per_code = samples_per_code; + acq_doppler_hz = 0.0; + acq_delay_samples = 0.0; + test_statistic = 0.0; + input_power = 0.0; + threshold = 0.0; + positive_acq = 0; + sample_counter = 0; d_num_doppler_bins = static_cast(ceil(static_cast(static_cast(d_doppler_max) - static_cast(-d_doppler_max)) / static_cast(d_doppler_step))); std::vector > mag_aux(d_num_doppler_bins, std::vector(d_samples_per_code)); mag = mag_aux; diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h index 089d36821..3f6b40365 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h @@ -51,6 +51,13 @@ public: std::vector doppler; std::vector samples; std::vector > mag; + float acq_doppler_hz; + float acq_delay_samples; + float test_statistic; + float input_power; + float threshold; + int positive_acq; + long unsigned int sample_counter; private: std::string d_basename; From 73a944aaf4735c0cb7141a66cf038a252fb61f1c Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 21 Jun 2018 19:26:46 +0200 Subject: [PATCH 20/40] Read results --- .../gps_l1_acq_performance_test.cc | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index c0d2e8133..a013f3b73 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -483,6 +483,7 @@ int AcquisitionPerformanceTest::run_receiver2() TEST_F(AcquisitionPerformanceTest, PdvsCn0) { + init(); for (std::vector::const_iterator it = cn0_.cbegin(); it != cn0_.cend(); ++it) { // Set parameter to sweep @@ -503,6 +504,37 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) run_receiver2(); // Read and store reference data and results + std::string basename = std::string("./acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + gnss_synchro.System + "_1C"; + std::cout << basename << std::endl; + //count executions + FILE* fp; + std::string argum2 = std::string("/bin/ls ") + basename + "* | wc -l"; + char buffer[1024]; + fp = popen(&argum2[0], "r"); + int num_executions = 1; + if (fp == NULL) + { + std::cout << "Failed to run command: " << argum2 << std::endl; + //return -1; + } + while (fgets(buffer, sizeof(buffer), fp) != NULL) + { + std::string aux = std::string(buffer); + EXPECT_EQ(aux.empty(), false); + num_executions = std::stoi(aux); + } + pclose(fp); + + for (int ch = 0; ch < config->property("Channels_1C.count", 0); ch++) + { + for (int execution = 1; execution <= num_executions; execution++) + { + acquisition_dump_reader acq_dump(basename, 1, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * 0.001, ch, execution); + acq_dump.read_binary_acq(); + std::cout << "Doppler: " << acq_dump.acq_doppler_hz << std::endl; + std::cout << "Execution: " << execution << std::endl; + } + } } } From 4e6bd76f279c0260046367bf62f5a4068a7b043b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 22 Jun 2018 12:24:39 +0200 Subject: [PATCH 21/40] Add work on performance test --- .../gps_l1_acq_performance_test.cc | 128 ++++++++++++++++-- 1 file changed, 114 insertions(+), 14 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index a013f3b73..5beafd726 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -31,6 +31,8 @@ #include "test_flags.h" #include "signal_generator_flags.h" +#include "tracking_true_obs_reader.h" +#include "true_observables_reader.h" #include #include #include @@ -130,6 +132,7 @@ protected: boost::shared_ptr acquisition; std::shared_ptr config; std::shared_ptr config_f; + const double baseband_sampling_freq = static_cast(FLAGS_fs_gen_sps); private: std::string generator_binary; @@ -140,7 +143,6 @@ private: std::string p5; std::string p6; - const double baseband_sampling_freq = static_cast(FLAGS_fs_gen_sps); std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; @@ -281,7 +283,8 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter // Set the Signal Conditioner config->set_property("SignalConditioner.implementation", "Signal_Conditioner"); config->set_property("DataTypeAdapter.implementation", "Ibyte_To_Complex"); - config->set_property("InputFilter.implementation", "Fir_Filter"); + //config->set_property("InputFilter.implementation", "Fir_Filter"); + config->set_property("InputFilter.implementation", "Pass_Through"); config->set_property("InputFilter.dump", "false"); config->set_property("InputFilter.input_item_type", "gr_complex"); config->set_property("InputFilter.output_item_type", "gr_complex"); @@ -312,6 +315,7 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter config->set_property("Channels_1C.count", std::to_string(number_of_channels)); config->set_property("Channels.in_acquisition", std::to_string(in_acquisition)); config->set_property("Channel.signal", "1C"); + config->set_property("Channel0.satellite", "1"); // Set Acquisition config->set_property("Acquisition_1C.implementation", implementation); @@ -319,7 +323,7 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max)); config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); - config->set_property("Acquisition_1C.threshold", "0.00001"); + config->set_property("Acquisition_1C.threshold", "15.0"); //config->set_property("Acquisition_1C.pfa", "0.0"); config->set_property("Acquisition_1C.use_CFAR_algorithm", "false"); @@ -443,8 +447,7 @@ int AcquisitionPerformanceTest::run_receiver() elapsed_seconds = end - start; std::cout << "Acq_delay_samples: " << gnss_synchro.Acq_delay_samples << std::endl; std::cout << "Acq_doppler_hz: " << gnss_synchro.Acq_doppler_hz << std::endl; - std::cout << "Acq_samplestamp_samples: " << gnss_synchro.Acq_samplestamp_samples << std::endl - << std::endl; + std::cout << "Acq_samplestamp_samples: " << gnss_synchro.Acq_samplestamp_samples << std::endl; } //std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; @@ -484,6 +487,8 @@ int AcquisitionPerformanceTest::run_receiver2() TEST_F(AcquisitionPerformanceTest, PdvsCn0) { init(); + tracking_true_obs_reader true_trk_data; + //true_observables_reader true_obs_data; for (std::vector::const_iterator it = cn0_.cbegin(); it != cn0_.cend(); ++it) { // Set parameter to sweep @@ -491,6 +496,8 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) // Do N_iterations of the experiment for (unsigned iter = 0; iter < N_iterations; iter++) { + std::string basename = std::string("./acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + gnss_synchro.System + "_1C"; + // Configure the signal generator configure_generator(*it); @@ -500,18 +507,23 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) // Configure the receiver configure_receiver(*it, iter); + // remove old files + FILE* fp2; + std::string remove_old_files = std::string("/bin/rm ") + basename + "*.mat"; + fp2 = popen(&remove_old_files[0], "r"); + pclose(fp2); + // Run it run_receiver2(); // Read and store reference data and results - std::string basename = std::string("./acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + gnss_synchro.System + "_1C"; std::cout << basename << std::endl; - //count executions + // count executions FILE* fp; std::string argum2 = std::string("/bin/ls ") + basename + "* | wc -l"; char buffer[1024]; fp = popen(&argum2[0], "r"); - int num_executions = 1; + int num_executions = 0; if (fp == NULL) { std::cout << "Failed to run command: " << argum2 << std::endl; @@ -527,20 +539,108 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) for (int ch = 0; ch < config->property("Channels_1C.count", 0); ch++) { + arma::vec meas_timestamp_s = arma::zeros(num_executions, 1); + arma::vec meas_doppler = arma::zeros(num_executions, 1); + arma::vec positive_acq = arma::zeros(num_executions, 1); + arma::vec meas_acq_delay_chips = arma::zeros(num_executions, 1); + std::cout << "Num executions: " + << num_executions << std::endl; for (int execution = 1; execution <= num_executions; execution++) { - acquisition_dump_reader acq_dump(basename, 1, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * 0.001, ch, execution); + acquisition_dump_reader acq_dump(basename, 1, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * GPS_L1_CA_CODE_PERIOD, ch, execution); acq_dump.read_binary_acq(); - std::cout << "Doppler: " << acq_dump.acq_doppler_hz << std::endl; - std::cout << "Execution: " << execution << std::endl; + //std::cout << "Doppler: " << acq_dump.acq_doppler_hz << std::endl; + //std::cout << "Execution: " << execution << std::endl; + //std::cout << "Sample counter [s]: " << acq_dump.sample_counter / baseband_sampling_freq << std::endl; + if (acq_dump.positive_acq) + { + //std::cout << "Meas acq_delay_samples: " << acq_dump.acq_delay_samples << " chips: " << acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS) << std::endl; + meas_timestamp_s(execution - 1) = acq_dump.sample_counter / baseband_sampling_freq; + meas_doppler(execution - 1) = acq_dump.acq_doppler_hz; + meas_acq_delay_chips(execution - 1) = acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS); + positive_acq(execution - 1) = acq_dump.positive_acq; + } + else + { + //std::cout << "Failed acquisition." << std::endl; + meas_timestamp_s(execution - 1) = arma::datum::inf; + meas_doppler(execution - 1) = arma::datum::inf; + meas_acq_delay_chips(execution - 1) = arma::datum::inf; + positive_acq(execution - 1) = acq_dump.positive_acq; + } } + + std::string true_trk_file = std::string("./gps_l1_ca_obs_prn"); + true_trk_file.append(std::to_string(1)); + true_trk_file.append(".dat"); + true_trk_data.close_obs_file(); + true_trk_data.open_obs_file(true_trk_file); + + + // load the true values + long int n_true_epochs = true_trk_data.num_epochs(); + + arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); + arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); + arma::vec true_Doppler_Hz = arma::zeros(n_true_epochs, 1); + arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); + arma::vec true_tow_s = arma::zeros(n_true_epochs, 1); + + long int epoch_counter = 0; + while (true_trk_data.read_binary_obs()) + { + true_timestamp_s(epoch_counter) = true_trk_data.signal_timestamp_s; + true_acc_carrier_phase_cycles(epoch_counter) = true_trk_data.acc_carrier_phase_cycles; + true_Doppler_Hz(epoch_counter) = true_trk_data.doppler_l1_hz; + true_prn_delay_chips(epoch_counter) = GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips; + true_tow_s(epoch_counter) = true_trk_data.tow; + epoch_counter++; + //std::cout << "True PRN_Delay chips = " << GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips << " at " << true_trk_data.signal_timestamp_s << std::endl; + } + + arma::vec true_interpolated_doppler = arma::zeros(num_executions, 1); + arma::vec true_interpolated_prn_delay_chips = arma::zeros(num_executions, 1); + interp1(true_timestamp_s, true_Doppler_Hz, meas_timestamp_s, true_interpolated_doppler); + interp1(true_timestamp_s, true_prn_delay_chips, meas_timestamp_s, true_interpolated_prn_delay_chips); + + arma::vec doppler_estimation_error = true_interpolated_doppler - meas_doppler; + std::cout << "Doppler estimation error [Hz]: "; + for (int i = 0; i < num_executions - 1; i++) + { + std::cout << doppler_estimation_error(i) << " "; + } + std::cout << std::endl; + arma::vec delay_estimation_error = true_interpolated_prn_delay_chips - meas_acq_delay_chips; + std::cout << "Delay estimation error [chips]: "; + for (int i = 0; i < num_executions - 1; i++) + { + std::cout << delay_estimation_error(i) << " "; + } + std::cout << std::endl; + + double detected = arma::accu(positive_acq); + std::cout << "Probability of detection for channel=" << ch << ", CN0=" << *it << " dBHz" + << ": " << (num_executions > 0 ? (detected / num_executions) : 0.0) << std::endl; + + arma::vec correct_acq = arma::zeros(num_executions, 1); + double correctly_detected = 0.0; + for (int i = 0; i < num_executions - 1; i++) + + { + if (abs(delay_estimation_error(i)) < 0.5) + { + correctly_detected = correctly_detected + 1.0; + } + } + std::cout << "Probability of correct detection for channel=" << ch << ", CN0=" << *it << " dBHz" + << ": " << (num_executions > 0 ? (correctly_detected / num_executions) : 0.0) << std::endl; + true_trk_data.restart(); } } + + // Compute results } - - // Compute results } - //TEST_F(AcquisitionPerformanceTest, ValidationOfResults) //{ // std::chrono::time_point start, end; From cef26aa89beeed2772e1606f2337ced47d3187ef Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 22 Jun 2018 12:30:30 +0200 Subject: [PATCH 22/40] Fix annotation of acq result in dump file --- .../acquisition/gnuradio_blocks/pcps_acquisition.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index f16855790..cf38db852 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -314,7 +314,7 @@ void pcps_acquisition::send_positive_acquisition() << ", doppler " << d_gnss_synchro->Acq_doppler_hz << ", magnitude " << d_mag << ", input signal power " << d_input_power; - + d_positive_acq = 1; this->message_port_pub(pmt::mp("events"), pmt::from_long(1)); } @@ -332,7 +332,7 @@ void pcps_acquisition::send_negative_acquisition() << ", doppler " << d_gnss_synchro->Acq_doppler_hz << ", magnitude " << d_mag << ", input signal power " << d_input_power; - + d_positive_acq = 0; this->message_port_pub(pmt::mp("events"), pmt::from_long(2)); } @@ -598,7 +598,6 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) send_positive_acquisition(); d_step_two = false; d_state = 0; // Positive acquisition - d_positive_acq = 1; } else { @@ -610,7 +609,6 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) { send_positive_acquisition(); d_state = 0; // Positive acquisition - d_positive_acq = 1; } } else if (d_well_count == acq_parameters.max_dwells) @@ -633,7 +631,6 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) send_positive_acquisition(); d_step_two = false; d_state = 0; // Positive acquisition - d_positive_acq = 1; } else { @@ -645,7 +642,6 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) { send_positive_acquisition(); d_state = 0; // Positive acquisition - d_positive_acq = 1; } } else From 89185fbb58f4696bf3e5546d2cc5682dae074ed2 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Fri, 22 Jun 2018 16:10:22 +0200 Subject: [PATCH 23/40] Adding more features to DLL/PLL unit test --- .../libs/observables_dump_reader.cc | 1 - .../libs/tracking_dump_reader.cc | 1 - .../libs/tracking_true_obs_reader.cc | 1 - .../gps_l1_ca_dll_pll_tracking_test.cc | 445 ++++++++++-------- 4 files changed, 239 insertions(+), 209 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc index a913eeee0..eb0cb8fac 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc @@ -97,7 +97,6 @@ bool observables_dump_reader::open_obs_file(std::string out_file) d_dump_filename = out_file; d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); d_dump_file.open(d_dump_filename.c_str(), std::ios::in | std::ios::binary); - std::cout << "Observables sum file opened, Log file: " << d_dump_filename.c_str() << std::endl; return true; } catch (const std::ifstream::failure &e) diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc index 502c99ea5..ff82a6a01 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc @@ -109,7 +109,6 @@ bool tracking_dump_reader::open_obs_file(std::string out_file) d_dump_filename = out_file; d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); d_dump_file.open(d_dump_filename.c_str(), std::ios::in | std::ios::binary); - std::cout << "Tracking dump enabled, Log file: " << d_dump_filename.c_str() << std::endl; return true; } catch (const std::ifstream::failure &e) diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc index b27c44688..b2e00a1e8 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc @@ -93,7 +93,6 @@ bool tracking_true_obs_reader::open_obs_file(std::string out_file) d_dump_filename = out_file; d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); d_dump_file.open(d_dump_filename.c_str(), std::ios::in | std::ios::binary); - std::cout << "Tracking Log file: " << d_dump_filename.c_str() << " open ok " << std::endl; return true; } catch (const std::ifstream::failure &e) diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index 1b3598489..9a521eba0 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -69,7 +69,10 @@ DEFINE_double(DLL_bw_hz_start, 1.5, "DLL Wide configuration start sweep value [H DEFINE_double(DLL_bw_hz_stop, 1.5, "DLL Wide configuration stop sweep value [Hz]"); DEFINE_double(DLL_bw_hz_step, 0.25, "DLL Wide configuration sweep step value [Hz]"); -DEFINE_bool(plot_extra, false, "Enable or disable plots of the correlators output and constellation diagrams"); +DEFINE_double(PLL_narrow_bw_hz, 5.0, "PLL Narrow configuration value [Hz]"); +DEFINE_double(DLL_narrow_bw_hz, 0.75, "DLL Narrow configuration value [Hz]"); + +DEFINE_int32(plot_detail_level, 0, "Specify the desired plot detail (0,1,2): 0 - Minimum plots (default) 2 - Plot all tracking parameters"); //Emulated acquisition configuration @@ -110,7 +113,8 @@ void GpsL1CADllPllTrackingTest_msg_rx::msg_handler_events(pmt::pmt_t msg) try { long int message = pmt::to_long(msg); - rx_message = message; + rx_message = message; //3 -> loss of lock + //std::cout << "Received trk message: " << rx_message << std::endl; } catch (boost::bad_any_cast& e) { @@ -451,18 +455,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std::vector> std_dev_carrier_phase_error_sweep; //swep config param and cn0 sweep std::vector> trk_valid_timestamp_s_sweep; - - if (FLAGS_CN0_dBHz_start == FLAGS_CN0_dBHz_stop) - { - generator_CN0_values.push_back(FLAGS_CN0_dBHz_start); - } - else - { - for (double cn0 = FLAGS_CN0_dBHz_start; cn0 > FLAGS_CN0_dBHz_stop; cn0 = cn0 - FLAGS_CN0_dB_step) - { - generator_CN0_values.push_back(cn0); - } - } + std::vector> generator_CN0_values_sweep_copy; int test_satellite_PRN = 0; double acq_delay_samples = 0.0; @@ -470,35 +463,15 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) tracking_true_obs_reader true_obs_data; - //********************************************* - //***** STEP 3: Generate the input signal ***** - //********************************************* - // use generator or use an external capture file - if (FLAGS_enable_external_signal_file) - { - //todo: create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters - } - else - { - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) - { - // Configure the signal generator - configure_generator(generator_CN0_values.at(current_cn0_idx), current_cn0_idx); - // Generate signal raw signal samples and observations RINEX file - if (FLAGS_disable_generator == false) - { - generate_signal(); - } - // open true observables log file written by the simulator - } - } - - // CONFIG PARAM SWEEP LOOP std::vector PLL_wide_bw_values; std::vector DLL_wide_bw_values; + //*********************************************************** + //***** STEP 2: Tracking configuration parameters sweep ***** + //*********************************************************** + if (FLAGS_PLL_bw_hz_start == FLAGS_PLL_bw_hz_stop) { if (FLAGS_DLL_bw_hz_start == FLAGS_DLL_bw_hz_stop) @@ -510,7 +483,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) else { //DLL BW Sweep - for (double dll_bw = FLAGS_DLL_bw_hz_start; dll_bw > FLAGS_DLL_bw_hz_stop; dll_bw = dll_bw - FLAGS_DLL_bw_hz_step) + for (double dll_bw = FLAGS_DLL_bw_hz_start; dll_bw >= FLAGS_DLL_bw_hz_stop; dll_bw = dll_bw - FLAGS_DLL_bw_hz_step) { PLL_wide_bw_values.push_back(FLAGS_PLL_bw_hz_start); DLL_wide_bw_values.push_back(dll_bw); @@ -520,14 +493,55 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) else { //PLL BW Sweep - for (double pll_bw = FLAGS_PLL_bw_hz_start; pll_bw > FLAGS_PLL_bw_hz_stop; pll_bw = pll_bw - FLAGS_PLL_bw_hz_step) + for (double pll_bw = FLAGS_PLL_bw_hz_start; pll_bw >= FLAGS_PLL_bw_hz_stop; pll_bw = pll_bw - FLAGS_PLL_bw_hz_step) { PLL_wide_bw_values.push_back(pll_bw); DLL_wide_bw_values.push_back(FLAGS_DLL_bw_hz_start); } } - for (int config_idx = 0; config_idx < PLL_wide_bw_values.size(); config_idx++) + //********************************************* + //***** STEP 3: Generate the input signal ***** + //********************************************* + + + std::vector cno_vector; + if (FLAGS_CN0_dBHz_start == FLAGS_CN0_dBHz_stop) + { + generator_CN0_values.push_back(FLAGS_CN0_dBHz_start); + } + else + { + for (double cn0 = FLAGS_CN0_dBHz_start; cn0 > FLAGS_CN0_dBHz_stop; cn0 = cn0 - FLAGS_CN0_dB_step) + { + generator_CN0_values.push_back(cn0); + } + } + + // use generator or use an external capture file + if (FLAGS_enable_external_signal_file) + { + //todo: create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters + } + else + { + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + // Configure the signal generator + configure_generator(generator_CN0_values.at(current_cn0_idx), current_cn0_idx); + // Generate signal raw signal samples and observations RINEX file + if (FLAGS_disable_generator == false) + { + generate_signal(); + } + // open true observables log file written by the simulator + } + } + + //************************************************************ + //***** STEP 4: Configure the signal tracking parameters ***** + //************************************************************ + for (unsigned int config_idx = 0; config_idx < PLL_wide_bw_values.size(); config_idx++) { //CN0 LOOP // data containers for CN0 sweep @@ -549,13 +563,14 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std::vector std_dev_code_phase_error; std::vector mean_carrier_phase_error; std::vector std_dev_carrier_phase_error; + std::vector valid_CN0_values; configure_receiver(PLL_wide_bw_values.at(config_idx), DLL_wide_bw_values.at(config_idx), - 2.0, - 1.0, + FLAGS_PLL_narrow_bw_hz, + FLAGS_DLL_narrow_bw_hz, FLAGS_extend_correlation_symbols); - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) { //****************************************************************************************** //***** Obtain the initial signal sinchronization parameters (emulating an acquisition) **** @@ -582,8 +597,6 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) } - //***** STEP 4: Configure the signal tracking parameters ***** - //************************************************************ std::chrono::time_point start, end; top_block = gr::make_top_block("Tracking test"); @@ -625,6 +638,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) //******************************************************************** //***** STEP 5: Perform the signal tracking and read the results ***** //******************************************************************** + std::cout << "------------ START TRACKING -------------" << std::endl; tracking->start_tracking(); EXPECT_NO_THROW({ @@ -636,6 +650,8 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std::chrono::duration elapsed_seconds = end - start; std::cout << "Signal tracking completed in " << elapsed_seconds.count() << " seconds" << std::endl; + int tracking_last_msg = msg_rx->rx_message; //save last aasynchronous tracking message in order to detect a loss of lock + //check results //load the measured values tracking_dump_reader trk_dump; @@ -643,7 +659,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) << "Failure opening tracking dump file"; long int n_measured_epochs = trk_dump.num_epochs(); - std::cout << "Measured observation epochs=" << n_measured_epochs << std::endl; + //std::cout << "Measured observation epochs=" << n_measured_epochs << std::endl; arma::vec trk_timestamp_s = arma::zeros(n_measured_epochs, 1); arma::vec trk_acc_carrier_phase_cycles = arma::zeros(n_measured_epochs, 1); @@ -694,11 +710,12 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std::vector doppler_error_hz; std::vector code_phase_error_chips; std::vector acc_carrier_phase_hz; + try { // load the true values long int n_true_epochs = true_obs_data.num_epochs(); - std::cout << "True observation epochs=" << n_true_epochs << std::endl; + //std::cout << "True observation epochs=" << n_true_epochs << std::endl; arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); @@ -720,45 +737,47 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) 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); + if (initial_meas_point.size() > 0 and tracking_last_msg != 3) + { + 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); - double mean_error; - double std_dev_error; + double mean_error; + double std_dev_error; - doppler_error_hz = check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz, mean_error, std_dev_error); - mean_doppler_error.push_back(mean_error); - std_dev_doppler_error.push_back(std_dev_error); + valid_CN0_values.push_back(generator_CN0_values.at(current_cn0_idx)); //save the current cn0 value (valid tracking) - code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips, mean_error, std_dev_error); - mean_code_phase_error.push_back(mean_error); - std_dev_code_phase_error.push_back(std_dev_error); + doppler_error_hz = check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz, mean_error, std_dev_error); + mean_doppler_error.push_back(mean_error); + std_dev_doppler_error.push_back(std_dev_error); - acc_carrier_phase_hz = check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles, mean_error, std_dev_error); - mean_carrier_phase_error.push_back(mean_error); - std_dev_carrier_phase_error.push_back(std_dev_error); + code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips, mean_error, std_dev_error); + mean_code_phase_error.push_back(mean_error); + std_dev_code_phase_error.push_back(std_dev_error); - //save tracking measurement timestamps to std::vector - std::vector vector_trk_timestamp_s(trk_timestamp_s.colptr(0), trk_timestamp_s.colptr(0) + trk_timestamp_s.n_rows); - trk_valid_timestamp_s_sweep.push_back(vector_trk_timestamp_s); + acc_carrier_phase_hz = check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles, mean_error, std_dev_error); + mean_carrier_phase_error.push_back(mean_error); + std_dev_carrier_phase_error.push_back(std_dev_error); - doppler_error_sweep.push_back(doppler_error_hz); - code_phase_error_sweep.push_back(code_phase_error_chips); - acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz); + //save tracking measurement timestamps to std::vector + std::vector vector_trk_timestamp_s(trk_timestamp_s.colptr(0), trk_timestamp_s.colptr(0) + trk_timestamp_s.n_rows); + trk_valid_timestamp_s_sweep.push_back(vector_trk_timestamp_s); + + doppler_error_sweep.push_back(doppler_error_hz); + code_phase_error_sweep.push_back(code_phase_error_chips); + acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz); + } + else + { + std::cout << "Tracking output could not be used, possible loss of lock " << std::endl; + } } catch (const std::exception& ex) { std::cout << "Tracking output could not be used, possible loss of lock " << ex.what() << std::endl; - - std::vector vector_trk_timestamp_s; - trk_valid_timestamp_s_sweep.push_back(vector_trk_timestamp_s); - doppler_error_sweep.push_back(doppler_error_hz); - code_phase_error_sweep.push_back(code_phase_error_chips); - acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz); } } @@ -772,9 +791,10 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std_dev_code_phase_error_sweep.push_back(std_dev_code_phase_error); mean_carrier_phase_error_sweep.push_back(mean_carrier_phase_error); std_dev_carrier_phase_error_sweep.push_back(std_dev_carrier_phase_error); + //make a copy of the CN0 vector for each configuration parameter in order to filter the loss of lock events + generator_CN0_values_sweep_copy.push_back(valid_CN0_values); } - std::cout << "A\n\n\n"; //******************************** //***** STEP 7: Plot results ***** //******************************** @@ -797,9 +817,9 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) Gnuplot::set_GNUPlotPath(gnuplot_path); unsigned int decimate = static_cast(FLAGS_plot_decimate); - if (FLAGS_plot_extra) + if (FLAGS_plot_detail_level >= 2) { - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) { Gnuplot g1("linespoints"); g1.showonscreen(); // window output @@ -819,7 +839,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g2.showonscreen(); // window output g2.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), ceil(static_cast(generator_CN0_values.size()) / 2)); - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) { g2.reset_plot(); g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz" + "GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); @@ -839,7 +859,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g3.set_xlabel("Time [s]"); g3.set_ylabel("Reported CN0 [dB-Hz]"); g3.cmd("set key box opaque"); - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) { g3.plot_xy(trk_timestamp_s_sweep.at(current_cn0_idx), CN0_dBHz_sweep.at(current_cn0_idx), std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); @@ -850,63 +870,85 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g3.showonscreen(); // window output } - std::cout << "B\n\n\n"; //PLOT ERROR FIGURES (only if it is used the signal generator) if (!FLAGS_enable_external_signal_file) { - Gnuplot g4("points"); - g4.showonscreen(); // window output - g4.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), - ceil(static_cast(generator_CN0_values.size()) / 2)); - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + if (FLAGS_plot_detail_level >= 1) { - g4.reset_plot(); - g4.set_title(std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz] Doppler error " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g4.set_grid(); - //g4.cmd("set key box opaque"); - g4.set_xlabel("Time [s]"); - g4.set_ylabel("Dopper error [Hz]"); - g4.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), doppler_error_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); - //g4.set_legend(); + Gnuplot g5("points"); + g5.showonscreen(); // window output + g5.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g5.set_grid(); + g5.set_xlabel("Time [s]"); + g5.set_ylabel("Code delay error [Chips]"); + + + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values_sweep_copy.at(config_idx).size(); current_cn0_idx++) + { + try + { + g5.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + catch (const GnuplotException& ge) + { + } + } + g5.set_legend(); + g5.set_legend(); + g5.savetops("Code_error_output"); + g5.savetopdf("Code_error_output", 18); + + + Gnuplot g6("points"); + g6.showonscreen(); // window output + g6.set_title("Accumulated carrier phase error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g6.set_grid(); + g6.set_xlabel("Time [s]"); + g6.set_ylabel("Accumulated carrier phase error [Cycles]"); + + + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values_sweep_copy.at(config_idx).size(); current_cn0_idx++) + { + try + { + g6.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), acc_carrier_phase_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + catch (const GnuplotException& ge) + { + } + } + g6.set_legend(); + g6.set_legend(); + g6.savetops("Carrier_phase_error_output"); + g6.savetopdf("Carrier_phase_error_output", 18); + + Gnuplot g4("points"); + g4.showonscreen(); // window output + g4.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), + ceil(static_cast(generator_CN0_values.size()) / 2)); + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values_sweep_copy.at(config_idx).size(); current_cn0_idx++) + { + g4.reset_plot(); + g4.set_title(std::to_string(static_cast(round(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)))) + "[dB-Hz], PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g4.set_grid(); + //g4.cmd("set key box opaque"); + g4.set_xlabel("Time [s]"); + g4.set_ylabel("Dopper error [Hz]"); + try + { + g4.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), doppler_error_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + catch (const GnuplotException& ge) + { + } + } + g4.unset_multiplot(); + g4.savetops("Doppler_error_output"); + g4.savetopdf("Doppler_error_output", 18); } - g4.unset_multiplot(); - g4.savetops("Doppler_error_output"); - g4.savetopdf("Doppler_error_output", 18); - - Gnuplot g5("points"); - g5.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g5.set_grid(); - g5.set_xlabel("Time [s]"); - g5.set_ylabel("Code delay error [Chips]"); - g5.cmd("set key box opaque"); - - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) - { - g5.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); - } - g5.set_legend(); - g5.savetops("Code_error_output"); - g5.savetopdf("Code_error_output", 18); - g5.showonscreen(); // window output - - Gnuplot g6("points"); - g6.set_title("Accumulated carrier phase error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g6.set_grid(); - g6.set_xlabel("Time [s]"); - g6.set_ylabel("Accumulated carrier phase error [Cycles]"); - g6.cmd("set key box opaque"); - - for (int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) - { - g6.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), acc_carrier_phase_error_sweep.at(current_cn0_idx), - std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); - } - g6.set_legend(); - g6.savetops("Carrier_phase_error_output"); - g6.savetopdf("Carrier_phase_error_output", 18); - g6.showonscreen(); // window output } } catch (const GnuplotException& ge) @@ -917,86 +959,77 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) } } - if (FLAGS_plot_gps_l1_tracking_test == true) { - const std::string gnuplot_executable(FLAGS_gnuplot_executable); - if (gnuplot_executable.empty()) + std::cout << "Ploting performance metrics..." << std::endl; + try { - 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 + if (generator_CN0_values.size() > 1) { - if (generator_CN0_values.size() > 1) + //plot metrics + + Gnuplot g7("linespoints"); + g7.showonscreen(); // window output + g7.set_title("Doppler error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g7.set_grid(); + g7.set_xlabel("CN0 [dB-Hz]"); + g7.set_ylabel("Doppler error [Hz]"); + g7.set_pointsize(2); + g7.cmd("set termoption lw 2"); + g7.cmd("set key box opaque"); + for (unsigned int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++) { - //plot metrics - - Gnuplot g7("linespoints"); - g7.set_title("Doppler error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g7.set_grid(); - g7.set_xlabel("CN0 [dB-Hz]"); - g7.set_ylabel("Doppler error [Hz]"); - g7.set_pointsize(2); - g7.cmd("set termoption lw 2"); - g7.cmd("set key box opaque"); - for (int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++) - { - g7.plot_xy_err(generator_CN0_values, - mean_doppler_error_sweep.at(config_sweep_idx), - std_dev_doppler_error_sweep.at(config_sweep_idx), - "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + - +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); - } - g7.savetops("Doppler_error_metrics"); - g7.savetopdf("Doppler_error_metrics", 18); - - Gnuplot g8("linespoints"); - g8.set_title("Accumulated carrier phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g8.set_grid(); - g8.set_xlabel("CN0 [dB-Hz]"); - g8.set_ylabel("Accumulated Carrier Phase error [Cycles]"); - g8.cmd("set key box opaque"); - g8.cmd("set termoption lw 2"); - g8.set_pointsize(2); - for (int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++) - { - g8.plot_xy_err(generator_CN0_values, - mean_carrier_phase_error_sweep.at(config_sweep_idx), - std_dev_carrier_phase_error_sweep.at(config_sweep_idx), - "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + - +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); - } - g8.savetops("Carrier_error_metrics"); - g8.savetopdf("Carrier_error_metrics", 18); - - Gnuplot g9("linespoints"); - g9.set_title("Code Phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - g9.set_grid(); - g9.set_xlabel("CN0 [dB-Hz]"); - g9.set_ylabel("Code Phase error [Chips]"); - g9.cmd("set key box opaque"); - g9.cmd("set termoption lw 2"); - g9.set_pointsize(2); - for (int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++) - { - g9.plot_xy_err(generator_CN0_values, - mean_code_phase_error_sweep.at(config_sweep_idx), - std_dev_code_phase_error_sweep.at(config_sweep_idx), - "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + - +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); - } - g9.savetops("Code_error_metrics"); - g9.savetopdf("Code_error_metrics", 18); + g7.plot_xy_err(generator_CN0_values_sweep_copy.at(config_sweep_idx), + mean_doppler_error_sweep.at(config_sweep_idx), + std_dev_doppler_error_sweep.at(config_sweep_idx), + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + + +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); } + g7.savetops("Doppler_error_metrics"); + g7.savetopdf("Doppler_error_metrics", 18); + + Gnuplot g8("linespoints"); + g8.set_title("Accumulated carrier phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g8.set_grid(); + g8.set_xlabel("CN0 [dB-Hz]"); + g8.set_ylabel("Accumulated Carrier Phase error [Cycles]"); + g8.cmd("set key box opaque"); + g8.cmd("set termoption lw 2"); + g8.set_pointsize(2); + for (unsigned int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++) + { + g8.plot_xy_err(generator_CN0_values_sweep_copy.at(config_sweep_idx), + mean_carrier_phase_error_sweep.at(config_sweep_idx), + std_dev_carrier_phase_error_sweep.at(config_sweep_idx), + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + + +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); + } + g8.savetops("Carrier_error_metrics"); + g8.savetopdf("Carrier_error_metrics", 18); + + Gnuplot g9("linespoints"); + g9.set_title("Code Phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g9.set_grid(); + g9.set_xlabel("CN0 [dB-Hz]"); + g9.set_ylabel("Code Phase error [Chips]"); + g9.cmd("set key box opaque"); + g9.cmd("set termoption lw 2"); + g9.set_pointsize(2); + for (unsigned int config_sweep_idx = 0; config_sweep_idx < mean_doppler_error_sweep.size(); config_sweep_idx++) + { + g9.plot_xy_err(generator_CN0_values_sweep_copy.at(config_sweep_idx), + mean_code_phase_error_sweep.at(config_sweep_idx), + std_dev_code_phase_error_sweep.at(config_sweep_idx), + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + + +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); + } + g9.savetops("Code_error_metrics"); + g9.savetopdf("Code_error_metrics", 18); } - catch (const GnuplotException& ge) - { - std::cout << ge.what() << std::endl; - } + } + catch (const GnuplotException& ge) + { + std::cout << ge.what() << std::endl; } } } From 54fd4c83f2a5c4045cd2c7bf59ca3a86055aa98a Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 24 Jun 2018 10:53:12 +0200 Subject: [PATCH 24/40] Add work in acquisition performance test --- .../gps_l1_acq_performance_test.cc | 369 ++++++++++++------ 1 file changed, 242 insertions(+), 127 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index 5beafd726..209779d57 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -38,20 +38,24 @@ #include DEFINE_string(config_file_ptest, std::string(""), "File containing the configuration parameters for the position test."); +DEFINE_double(acq_test_threshold, 0.001, "Acquisition threshold"); +DEFINE_int32(acq_test_coherent_time_ms, 10, "Acquisition coherent time, in ms"); +DEFINE_int32(acq_test_PRN, 1, "PRN number"); // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class AcqPerfTest_msg_rx; // typedef boost::shared_ptr AcqPerfTest_msg_rx_sptr; // -AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(); +AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(concurrent_queue& queue); // class AcqPerfTest_msg_rx : public gr::block { private: - friend AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(); + friend AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(concurrent_queue& queue); void msg_handler_events(pmt::pmt_t msg); - AcqPerfTest_msg_rx(); + AcqPerfTest_msg_rx(concurrent_queue& queue); + concurrent_queue& channel_internal_queue; public: int rx_message; @@ -59,9 +63,9 @@ public: }; -AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make() +AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(concurrent_queue& queue) { - return AcqPerfTest_msg_rx_sptr(new AcqPerfTest_msg_rx()); + return AcqPerfTest_msg_rx_sptr(new AcqPerfTest_msg_rx(queue)); } @@ -71,17 +75,18 @@ void AcqPerfTest_msg_rx::msg_handler_events(pmt::pmt_t msg) { long int message = pmt::to_long(msg); rx_message = message; + channel_internal_queue.push(rx_message); } catch (boost::bad_any_cast& e) { LOG(WARNING) << "msg_handler_telemetry Bad any cast!"; rx_message = 0; } - std::cout << "Received message:" << rx_message << std::endl; + //std::cout << "Received message:" << rx_message << std::endl; } -AcqPerfTest_msg_rx::AcqPerfTest_msg_rx() : gr::block("AcqPerfTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) +AcqPerfTest_msg_rx::AcqPerfTest_msg_rx(concurrent_queue& queue) : gr::block("AcqPerfTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)), channel_internal_queue(queue) { this->message_port_register_in(pmt::mp("events")); this->set_msg_handler(pmt::mp("events"), boost::bind(&AcqPerfTest_msg_rx::msg_handler_events, this, _1)); @@ -105,7 +110,10 @@ protected: item_size = sizeof(gr_complex); gnss_synchro = Gnss_Synchro(); doppler_max = 5000; - doppler_step = 100; + doppler_step = 125; + stop = false; + acquisition = 0; + init(); } ~AcquisitionPerformanceTest() @@ -120,19 +128,46 @@ protected: int configure_generator(double cn0); int generate_signal(); int configure_receiver(double cn0, unsigned int iter); + void start_queue(); + void wait_message(); + void process_message(); + void stop_queue(); int run_receiver(); int run_receiver2(); void check_results(); + + concurrent_queue channel_internal_queue; + + gr::msg_queue::sptr queue; gr::top_block_sptr top_block; + std::shared_ptr acquisition; + std::shared_ptr config; + std::shared_ptr config_f; Gnss_Synchro gnss_synchro; size_t item_size; unsigned int doppler_max; unsigned int doppler_step; + bool stop; + + int message; + boost::thread ch_thread; + std::string implementation = "GPS_L1_CA_PCPS_Acquisition"; - boost::shared_ptr acquisition; - std::shared_ptr config; - std::shared_ptr config_f; + const double baseband_sampling_freq = static_cast(FLAGS_fs_gen_sps); + const int coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + const int number_of_channels = 2; + const int in_acquisition = 1; + const float threshold = FLAGS_acq_test_threshold; + const int max_dwells = 1; + const int tong_init_val = 2; + const int tong_max_val = 10; + const int tong_max_dwells = 30; + + int generated_signal_duration_s = 2; + + unsigned int num_of_realizations = (generated_signal_duration_s * 1000) / FLAGS_acq_test_coherent_time_ms; + unsigned int realization_counter; private: std::string generator_binary; @@ -147,10 +182,6 @@ private: std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; - /*void print_results(const std::vector& east, - const std::vector& north, - const std::vector& up);*/ - double compute_stdev_precision(const std::vector& vec); double compute_stdev_accuracy(const std::vector& vec, double ref); @@ -166,6 +197,85 @@ void AcquisitionPerformanceTest::init() std::string signal = "1C"; signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = 1; + message = 0; + realization_counter = 0; +} + + +void AcquisitionPerformanceTest::start_queue() +{ + stop = false; + ch_thread = boost::thread(&AcquisitionPerformanceTest::wait_message, this); +} + + +void AcquisitionPerformanceTest::wait_message() +{ + //std::chrono::time_point start, end; + //std::chrono::duration elapsed_seconds(0); + + while (!stop) + { + acquisition->reset(); + acquisition->set_state(1); + + //start = std::chrono::system_clock::now(); + + channel_internal_queue.wait_and_pop(message); + + //end = std::chrono::system_clock::now(); + //elapsed_seconds = end - start; + + //mean_acq_time_us += elapsed_seconds.count() * 1e6; + + process_message(); + } +} + + +void AcquisitionPerformanceTest::process_message() +{ + if (message == 1) + { + //detection_counter++; + + // The term -5 is here to correct the additional delay introduced by the FIR filter + //double delay_error_chips = std::abs(static_cast(expected_delay_chips) - static_cast(gnss_synchro.Acq_delay_samples - 5) * 1023.0 / (static_cast(fs_in) * 1e-3)); + //double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro.Acq_doppler_hz); + + // mse_delay += std::pow(delay_error_chips, 2); + // mse_doppler += std::pow(doppler_error_hz, 2); + + // if ((delay_error_chips < max_delay_error_chips) && (doppler_error_hz < max_doppler_error_hz)) + // { + // correct_estimation_counter++; + // } + } + + realization_counter++; + + std::cout << "Progress: " << round(static_cast(realization_counter) / static_cast(num_of_realizations) * 100.0) << "% \r" << std::flush; + + if (realization_counter == num_of_realizations) + { + // mse_delay /= num_of_realizations; + // mse_doppler /= num_of_realizations; + + //Pd = static_cast(correct_estimation_counter) / static_cast(num_of_realizations); + //Pfa_a = static_cast(detection_counter) / static_cast(num_of_realizations); + //Pfa_p = static_cast(detection_counter - correct_estimation_counter) / static_cast(num_of_realizations); + + // mean_acq_time_us /= num_of_realizations; + + stop_queue(); + top_block->stop(); + } +} + + +void AcquisitionPerformanceTest::stop_queue() +{ + stop = true; } @@ -173,12 +283,11 @@ int AcquisitionPerformanceTest::configure_generator(double cn0) { // Configure signal generator generator_binary = FLAGS_generator_binary; - int duration_s = 2; 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(std::min(duration_s * 10, 3000)); + p2 = std::string("-static_position=") + FLAGS_static_position + std::string(",") + std::to_string(std::min(generated_signal_duration_s * 10, 3000)); } else { @@ -237,17 +346,7 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter const int grid_density = 16; const float zero = 0.0; - const int number_of_channels = 1; - const int in_acquisition = 1; - const float threshold = 0.01; - const float doppler_max = 8000.0; - const float doppler_step = 500.0; - const int max_dwells = 1; - const int tong_init_val = 2; - const int tong_max_val = 10; - const int tong_max_dwells = 30; - const int coherent_integration_time_ms = 1; const float pll_bw_hz = 30.0; const float dll_bw_hz = 4.0; @@ -315,7 +414,7 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter config->set_property("Channels_1C.count", std::to_string(number_of_channels)); config->set_property("Channels.in_acquisition", std::to_string(in_acquisition)); config->set_property("Channel.signal", "1C"); - config->set_property("Channel0.satellite", "1"); + //config->set_property("Channel0.satellite", std::to_string(FLAGS_acq_test_PRN)); // Set Acquisition config->set_property("Acquisition_1C.implementation", implementation); @@ -323,11 +422,11 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max)); config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); - config->set_property("Acquisition_1C.threshold", "15.0"); + config->set_property("Acquisition_1C.threshold", std::to_string(threshold)); //config->set_property("Acquisition_1C.pfa", "0.0"); - config->set_property("Acquisition_1C.use_CFAR_algorithm", "false"); + config->set_property("Acquisition_1C.use_CFAR_algorithm", "true"); - config->set_property("Acquisition_1C.coherent_integration_time_ms", "1"); + config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); config->set_property("Acquisition_1C.use_bit_transition_flag", "false"); config->set_property("Acquisition_1C.max_dwells", std::to_string(1)); @@ -408,47 +507,56 @@ int AcquisitionPerformanceTest::run_receiver() { std::chrono::time_point start, end; std::chrono::duration elapsed_seconds(0); - std::string file = "./" + filename_raw_data; //+ std::to_string(current_cn0_idx); + 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); + std::cout << "Source created" << std::endl; - for (unsigned k = 0; k < 2; k++) - { - gr::top_block_sptr top_block_ = gr::make_top_block("Acquisition test"); - boost::shared_ptr msg_rx = AcqPerfTest_msg_rx_make(); + gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); + std::cout << "Interleaver created" << std::endl; - gnss_synchro = Gnss_Synchro(); - init(); - auto acquisition_ = boost::make_shared(config.get(), "Acquisition_1C", 1, 0); + top_block = gr::make_top_block("Acquisition test"); + boost::shared_ptr msg_rx = AcqPerfTest_msg_rx_make(channel_internal_queue); - //acquisition->connect(top_block); - acquisition_->set_gnss_synchro(&gnss_synchro); + queue = gr::msg_queue::make(0); + gnss_synchro = Gnss_Synchro(); + init(); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 0); + int nsamples = floor(config->property("GNSS-SDR.internal_fs_sps", 2000000) * generated_signal_duration_s); + boost::shared_ptr valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); - acquisition_->connect(top_block_); - acquisition_->set_local_code(); - acquisition_->set_state(1); // Ensure that acquisition starts at the first sample - acquisition_->init(); - //file_source->seek(static_cast(100 * k), SEEK_SET); - - if (not file_source->seek(static_cast(100 * k), SEEK_SET)) - { - std::cout << "Error skipping " << k << std::endl; - } - gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); - top_block_->connect(file_source, 0, gr_interleaved_char_to_complex, 0); - top_block_->connect(gr_interleaved_char_to_complex, 0, acquisition_->get_left_block(), 0); - top_block_->msg_connect(acquisition_->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + acquisition->set_gnss_synchro(&gnss_synchro); + acquisition->set_channel(0); + acquisition->set_local_code(); + acquisition->set_doppler_max(config->property("Acquisition_1C.doppler_max", 10000)); + acquisition->set_doppler_step(config->property("Acquisition_1C.doppler_step", 500)); + acquisition->set_threshold(config->property("Acquisition_1C.threshold", 0.0)); + acquisition->set_state(1); // Ensure that acquisition starts at the first sample + acquisition->connect(top_block); + top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - start = std::chrono::system_clock::now(); - top_block_->run(); // Start threads and wait - end = std::chrono::system_clock::now(); - //file_source->close(); - elapsed_seconds = end - start; - std::cout << "Acq_delay_samples: " << gnss_synchro.Acq_delay_samples << std::endl; - std::cout << "Acq_doppler_hz: " << gnss_synchro.Acq_doppler_hz << std::endl; - std::cout << "Acq_samplestamp_samples: " << gnss_synchro.Acq_samplestamp_samples << std::endl; - } + acquisition->init(); + + top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); + top_block->connect(gr_interleaved_char_to_complex, 0, valve, 0); + top_block->connect(valve, 0, acquisition->get_left_block(), 0); + std::cout << "Num of realizations: " << num_of_realizations << std::endl; + start_queue(); + start = std::chrono::system_clock::now(); + top_block->run(); // Start threads and wait + end = std::chrono::system_clock::now(); + //file_source->close(); + elapsed_seconds = end - start; + std::cout << "Acq_delay_samples: " << gnss_synchro.Acq_delay_samples << std::endl; + std::cout << "Acq_doppler_hz: " << gnss_synchro.Acq_doppler_hz << std::endl; + std::cout << "Acq_samplestamp_samples: " << gnss_synchro.Acq_samplestamp_samples << std::endl; +#ifdef OLD_BOOST + ch_thread.timed_join(boost::posix_time::seconds(1)); +#endif +#ifndef OLD_BOOST + ch_thread.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(50)); +#endif //std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; @@ -488,7 +596,6 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) { init(); tracking_true_obs_reader true_trk_data; - //true_observables_reader true_obs_data; for (std::vector::const_iterator it = cn0_.cbegin(); it != cn0_.cend(); ++it) { // Set parameter to sweep @@ -508,13 +615,13 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) configure_receiver(*it, iter); // remove old files - FILE* fp2; - std::string remove_old_files = std::string("/bin/rm ") + basename + "*.mat"; - fp2 = popen(&remove_old_files[0], "r"); - pclose(fp2); + // FILE* fp2; + // std::string remove_old_files = std::string("/bin/rm ") + basename + "*.mat"; + // fp2 = popen(&remove_old_files[0], "r"); + // pclose(fp2); // Run it - run_receiver2(); + run_receiver(); // Read and store reference data and results std::cout << basename << std::endl; @@ -523,7 +630,7 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) std::string argum2 = std::string("/bin/ls ") + basename + "* | wc -l"; char buffer[1024]; fp = popen(&argum2[0], "r"); - int num_executions = 0; + int num_executions = 1; if (fp == NULL) { std::cout << "Failed to run command: " << argum2 << std::endl; @@ -536,68 +643,68 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) num_executions = std::stoi(aux); } pclose(fp); + int ch = 0; - for (int ch = 0; ch < config->property("Channels_1C.count", 0); ch++) + arma::vec meas_timestamp_s = arma::zeros(num_executions, 1); + arma::vec meas_doppler = arma::zeros(num_executions, 1); + arma::vec positive_acq = arma::zeros(num_executions, 1); + arma::vec meas_acq_delay_chips = arma::zeros(num_executions, 1); + + double coh_time_ms = config->property("Acquisition_1C.coherent_integration_time_ms", 1); + + std::cout << "Num executions: " << std::endl; + for (int execution = 1; execution <= num_executions; execution++) { - arma::vec meas_timestamp_s = arma::zeros(num_executions, 1); - arma::vec meas_doppler = arma::zeros(num_executions, 1); - arma::vec positive_acq = arma::zeros(num_executions, 1); - arma::vec meas_acq_delay_chips = arma::zeros(num_executions, 1); - std::cout << "Num executions: " - << num_executions << std::endl; - for (int execution = 1; execution <= num_executions; execution++) + acquisition_dump_reader acq_dump(basename, FLAGS_acq_test_PRN, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * GPS_L1_CA_CODE_PERIOD * static_cast(coh_time_ms), ch, execution); + if (!acq_dump.read_binary_acq()) + ; + if (acq_dump.positive_acq) { - acquisition_dump_reader acq_dump(basename, 1, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * GPS_L1_CA_CODE_PERIOD, ch, execution); - acq_dump.read_binary_acq(); - //std::cout << "Doppler: " << acq_dump.acq_doppler_hz << std::endl; - //std::cout << "Execution: " << execution << std::endl; - //std::cout << "Sample counter [s]: " << acq_dump.sample_counter / baseband_sampling_freq << std::endl; - if (acq_dump.positive_acq) - { - //std::cout << "Meas acq_delay_samples: " << acq_dump.acq_delay_samples << " chips: " << acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS) << std::endl; - meas_timestamp_s(execution - 1) = acq_dump.sample_counter / baseband_sampling_freq; - meas_doppler(execution - 1) = acq_dump.acq_doppler_hz; - meas_acq_delay_chips(execution - 1) = acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS); - positive_acq(execution - 1) = acq_dump.positive_acq; - } - else - { - //std::cout << "Failed acquisition." << std::endl; - meas_timestamp_s(execution - 1) = arma::datum::inf; - meas_doppler(execution - 1) = arma::datum::inf; - meas_acq_delay_chips(execution - 1) = arma::datum::inf; - positive_acq(execution - 1) = acq_dump.positive_acq; - } + //std::cout << "Meas acq_delay_samples: " << acq_dump.acq_delay_samples << " chips: " << acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS) << std::endl; + meas_timestamp_s(execution - 1) = acq_dump.sample_counter / baseband_sampling_freq; + meas_doppler(execution - 1) = acq_dump.acq_doppler_hz; + meas_acq_delay_chips(execution - 1) = acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS); + positive_acq(execution - 1) = acq_dump.positive_acq; } - - std::string true_trk_file = std::string("./gps_l1_ca_obs_prn"); - true_trk_file.append(std::to_string(1)); - true_trk_file.append(".dat"); - true_trk_data.close_obs_file(); - true_trk_data.open_obs_file(true_trk_file); - - - // load the true values - long int n_true_epochs = true_trk_data.num_epochs(); - - arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); - arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); - arma::vec true_Doppler_Hz = arma::zeros(n_true_epochs, 1); - arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); - arma::vec true_tow_s = arma::zeros(n_true_epochs, 1); - - long int epoch_counter = 0; - while (true_trk_data.read_binary_obs()) + else { - true_timestamp_s(epoch_counter) = true_trk_data.signal_timestamp_s; - true_acc_carrier_phase_cycles(epoch_counter) = true_trk_data.acc_carrier_phase_cycles; - true_Doppler_Hz(epoch_counter) = true_trk_data.doppler_l1_hz; - true_prn_delay_chips(epoch_counter) = GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips; - true_tow_s(epoch_counter) = true_trk_data.tow; - epoch_counter++; - //std::cout << "True PRN_Delay chips = " << GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips << " at " << true_trk_data.signal_timestamp_s << std::endl; + //std::cout << "Failed acquisition." << std::endl; + meas_timestamp_s(execution - 1) = arma::datum::inf; + meas_doppler(execution - 1) = arma::datum::inf; + meas_acq_delay_chips(execution - 1) = arma::datum::inf; + positive_acq(execution - 1) = acq_dump.positive_acq; } + } + std::string true_trk_file = std::string("./gps_l1_ca_obs_prn"); + true_trk_file.append(std::to_string(FLAGS_acq_test_PRN)); + true_trk_file.append(".dat"); + true_trk_data.close_obs_file(); + true_trk_data.open_obs_file(true_trk_file); + + + // load the true values + long int n_true_epochs = true_trk_data.num_epochs(); + + arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); + arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); + arma::vec true_Doppler_Hz = arma::zeros(n_true_epochs, 1); + arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); + arma::vec true_tow_s = arma::zeros(n_true_epochs, 1); + + long int epoch_counter = 0; + while (true_trk_data.read_binary_obs()) + { + true_timestamp_s(epoch_counter) = true_trk_data.signal_timestamp_s; + true_acc_carrier_phase_cycles(epoch_counter) = true_trk_data.acc_carrier_phase_cycles; + true_Doppler_Hz(epoch_counter) = true_trk_data.doppler_l1_hz; + true_prn_delay_chips(epoch_counter) = GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips; + true_tow_s(epoch_counter) = true_trk_data.tow; + epoch_counter++; + //std::cout << "True PRN_Delay chips = " << GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips << " at " << true_trk_data.signal_timestamp_s << std::endl; + } + if (epoch_counter > 2) + { arma::vec true_interpolated_doppler = arma::zeros(num_executions, 1); arma::vec true_interpolated_prn_delay_chips = arma::zeros(num_executions, 1); interp1(true_timestamp_s, true_Doppler_Hz, meas_timestamp_s, true_interpolated_doppler); @@ -634,8 +741,16 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) } std::cout << "Probability of correct detection for channel=" << ch << ", CN0=" << *it << " dBHz" << ": " << (num_executions > 0 ? (correctly_detected / num_executions) : 0.0) << std::endl; - true_trk_data.restart(); } + else + { + std::cout << "No reference data has been found. Maybe a non-present satellite?" << std::endl; + + double wrongly_detected = arma::accu(positive_acq); + std::cout << "Probability of false alarm for channel=" << ch << ", CN0=" << *it << " dBHz" + << ": " << (num_executions > 0 ? (wrongly_detected / num_executions) : 0.0) << std::endl; + } + true_trk_data.restart(); } // Compute results From 559a9a7c43b6ca1e152d889cf293bae848ce63ca Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 24 Jun 2018 11:05:58 +0200 Subject: [PATCH 25/40] Fix problem caused by hdf5 when saving concurrently Only one acquisition channel info is stored in dump file if dump is activated. New configuration parameter dump_channel, set to 0 by default. Name of Matlab variable changed from gird to acq_grid to not overlap Matlab command. --- .../galileo_e1_pcps_ambiguous_acquisition.cc | 1 + .../adapters/galileo_e5a_pcps_acquisition.cc | 1 + .../glonass_l1_ca_pcps_acquisition.cc | 1 + .../glonass_l2_ca_pcps_acquisition.cc | 1 + .../adapters/gps_l1_ca_pcps_acquisition.cc | 1 + .../adapters/gps_l2_m_pcps_acquisition.cc | 1 + .../adapters/gps_l5i_pcps_acquisition.cc | 1 + .../gnuradio_blocks/pcps_acquisition.cc | 13 +++-- .../gnuradio_blocks/pcps_acquisition.h | 1 + src/algorithms/acquisition/libs/acq_conf.cc | 1 + src/algorithms/acquisition/libs/acq_conf.h | 1 + .../gps_l1_ca_pcps_acquisition_test.cc | 1 + .../gps_l2_m_pcps_acquisition_test.cc | 7 +-- .../libs/acquisition_dump_reader.cc | 53 ++++++++++++++++++- .../libs/acquisition_dump_reader.h | 7 +++ src/utils/matlab/plot_acq_grid.m | 3 +- 16 files changed, 84 insertions(+), 10 deletions(-) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc index a9f96da43..3dedecfff 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc @@ -60,6 +60,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( acq_parameters.fs_in = fs_in_; dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; + acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); blocking_ = configuration_->property(role + ".blocking", true); acq_parameters.blocking = blocking_; doppler_max_ = configuration_->property(role + ".doppler_max", 5000); diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc index 16142eab9..203f8b58b 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc @@ -65,6 +65,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con } dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; + acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); doppler_max_ = configuration_->property(role + ".doppler_max", 5000); if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; acq_parameters.doppler_max = doppler_max_; diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc index c49f1f0c4..29fc072fb 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc @@ -61,6 +61,7 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( acq_parameters.fs_in = fs_in_; dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; + acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); blocking_ = configuration_->property(role + ".blocking", true); acq_parameters.blocking = blocking_; doppler_max_ = configuration_->property(role + ".doppler_max", 5000); diff --git a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc index ec17ad911..5222e0ad8 100644 --- a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc @@ -60,6 +60,7 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( acq_parameters.fs_in = fs_in_; dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; + acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); blocking_ = configuration_->property(role + ".blocking", true); acq_parameters.blocking = blocking_; doppler_max_ = configuration_->property(role + ".doppler_max", 5000); diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc index 45a8d743c..f3bc7dcb2 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc @@ -62,6 +62,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( acq_parameters.fs_in = fs_in_; dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; + acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); blocking_ = configuration_->property(role + ".blocking", true); acq_parameters.blocking = blocking_; doppler_max_ = configuration_->property(role + ".doppler_max", 5000); diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc index bb185c92c..2da535b82 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc @@ -62,6 +62,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( acq_parameters.fs_in = fs_in_; dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; + acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); blocking_ = configuration_->property(role + ".blocking", true); acq_parameters.blocking = blocking_; doppler_max_ = configuration->property(role + ".doppler_max", 5000); diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc index 4595bd2e2..94d9356ad 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc @@ -61,6 +61,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( acq_parameters.fs_in = fs_in_; dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; + acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); blocking_ = configuration_->property(role + ".blocking", true); acq_parameters.blocking = blocking_; doppler_max_ = configuration->property(role + ".doppler_max", 5000); diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index cf38db852..76adfc28c 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -123,6 +123,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu grid_ = arma::fmat(); d_step_two = false; d_dump_number = 0; + d_dump_channel = acq_parameters.dump_channel; } @@ -363,7 +364,7 @@ void pcps_acquisition::dump_results(int effective_fft_size) else { size_t dims[2] = {static_cast(effective_fft_size), static_cast(d_num_doppler_bins)}; - matvar_t* matvar = Mat_VarCreate("grid", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, grid_.memptr(), 0); + matvar_t* matvar = Mat_VarCreate("acq_grid", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, grid_.memptr(), 0); Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarFree(matvar); @@ -407,6 +408,10 @@ void pcps_acquisition::dump_results(int effective_fft_size) Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarFree(matvar); + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_gnss_synchro->PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + Mat_Close(matfp); } } @@ -510,7 +515,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) } } // Record results to file if required - if (acq_parameters.dump) + if (acq_parameters.dump and d_channel == d_dump_channel) { memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size); } @@ -579,7 +584,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) } } // Record results to file if required - if (acq_parameters.dump) + if (acq_parameters.dump and d_channel == d_dump_channel) { memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size); } @@ -653,7 +658,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) } d_worker_active = false; // Record results to file if required - if (acq_parameters.dump) + if (acq_parameters.dump and d_channel == d_dump_channel) { pcps_acquisition::dump_results(effective_fft_size); } diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index d34888fd8..91bfaf112 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -125,6 +125,7 @@ private: Gnss_Synchro* d_gnss_synchro; arma::fmat grid_; long int d_dump_number; + unsigned int d_dump_channel; public: ~pcps_acquisition(); diff --git a/src/algorithms/acquisition/libs/acq_conf.cc b/src/algorithms/acquisition/libs/acq_conf.cc index f403992e4..f44f7a15f 100644 --- a/src/algorithms/acquisition/libs/acq_conf.cc +++ b/src/algorithms/acquisition/libs/acq_conf.cc @@ -48,5 +48,6 @@ Acq_Conf::Acq_Conf() blocking = false; make_2_steps = false; dump_filename = ""; + dump_channel = 0; it_size = sizeof(char); } diff --git a/src/algorithms/acquisition/libs/acq_conf.h b/src/algorithms/acquisition/libs/acq_conf.h index 422e889bc..7abcb2e98 100644 --- a/src/algorithms/acquisition/libs/acq_conf.h +++ b/src/algorithms/acquisition/libs/acq_conf.h @@ -53,6 +53,7 @@ public: bool blocking; bool make_2_steps; std::string dump_filename; + unsigned int dump_channel; size_t it_size; Acq_Conf(); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc index d2c5a96c9..332dcc0e4 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc @@ -160,6 +160,7 @@ void GpsL1CaPcpsAcquisitionTest::init() config->set_property("Acquisition_1C.dump", "false"); } config->set_property("Acquisition_1C.dump_filename", "./tmp-acq-gps1/acquisition"); + config->set_property("Acquisition_1C.dump_channel", "1"); config->set_property("Acquisition_1C.threshold", "0.00001"); config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max)); config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc index 31e6e60ab..9d6caf0e6 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc @@ -163,7 +163,8 @@ void GpsL2MPcpsAcquisitionTest::init() { config->set_property("Acquisition_2S.dump", "false"); } - config->set_property("Acquisition_2S.dump_filename", "./tmp-acq-gps2/acquisition"); + config->set_property("Acquisition_2S.dump_filename", "./tmp-acq-gps2/acquisition_test"); + config->set_property("Acquisition_2S.dump_channel", "1"); config->set_property("Acquisition_2S.threshold", "0.001"); config->set_property("Acquisition_2S.doppler_max", std::to_string(doppler_max)); config->set_property("Acquisition_2S.doppler_step", std::to_string(doppler_step)); @@ -175,11 +176,11 @@ void GpsL2MPcpsAcquisitionTest::init() void GpsL2MPcpsAcquisitionTest::plot_grid() { //load the measured values - std::string basename = "./tmp-acq-gps2/acquisition_G_2S"; + std::string basename = "./tmp-acq-gps2/acquisition_test_G_2S"; unsigned int sat = static_cast(gnss_synchro.PRN); unsigned int samples_per_code = static_cast(floor(static_cast(sampling_frequency_hz) / (GPS_L2_M_CODE_RATE_HZ / static_cast(GPS_L2_M_CODE_LENGTH_CHIPS)))); - acquisition_dump_reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code); + acquisition_dump_reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code, 1); if (!acq_dump.read_binary_acq()) std::cout << "Error reading files" << std::endl; std::vector *doppler = &acq_dump.doppler; diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc index 063d02837..8cb81718b 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc @@ -43,7 +43,7 @@ bool acquisition_dump_reader::read_binary_acq() std::cout << "¡¡¡Unreachable Acquisition dump file!!!" << std::endl; return false; } - matvar_t* var_ = Mat_VarRead(matfile, "grid"); + matvar_t* var_ = Mat_VarRead(matfile, "acq_grid"); if (var_ == NULL) { std::cout << "¡¡¡Unreachable grid variable into Acquisition dump file!!!" << std::endl; @@ -109,15 +109,20 @@ bool acquisition_dump_reader::read_binary_acq() positive_acq = *static_cast(var2_->data); Mat_VarFree(var2_); + var2_ = Mat_VarRead(matfile, "PRN"); + PRN = *static_cast(var2_->data); + Mat_VarFree(var2_); + std::vector >::iterator it1; std::vector::iterator it2; float* aux = static_cast(var_->data); int k = 0; + float normalization_factor = std::pow(d_samples_per_code, 4) * input_power; for (it1 = mag.begin(); it1 != mag.end(); it1++) { for (it2 = it1->begin(); it2 != it1->end(); it2++) { - *it2 = static_cast(aux[k]) / input_power; + *it2 = static_cast(aux[k]) / normalization_factor; k++; } } @@ -128,6 +133,49 @@ bool acquisition_dump_reader::read_binary_acq() } +acquisition_dump_reader::acquisition_dump_reader(const std::string& basename, + int channel, + int execution) +{ + unsigned int sat_ = 0; + unsigned int doppler_max_ = 0; + unsigned int doppler_step_ = 0; + unsigned int samples_per_code_ = 0; + + mat_t* matfile = Mat_Open(d_dump_filename.c_str(), MAT_ACC_RDONLY); + if (matfile != NULL) + { + matvar_t* var_ = Mat_VarRead(matfile, "doppler_max"); + doppler_max_ = *static_cast(var_->data); + Mat_VarFree(var_); + + var_ = Mat_VarRead(matfile, "doppler_step"); + doppler_step_ = *static_cast(var_->data); + Mat_VarFree(var_); + + var_ = Mat_VarRead(matfile, "PRN"); + sat_ = *static_cast(var_->data); + Mat_VarFree(var_); + + var_ = Mat_VarRead(matfile, "grid"); + samples_per_code_ = var_->dims[0]; + Mat_VarFree(var_); + + Mat_Close(matfile); + } + else + { + std::cout << "¡¡¡Unreachable Acquisition dump file!!!" << std::endl; + } + acquisition_dump_reader(basename, + sat_, + doppler_max_, + doppler_step_, + samples_per_code_, + channel, + execution); +} + acquisition_dump_reader::acquisition_dump_reader(const std::string& basename, unsigned int sat, unsigned int doppler_max, @@ -148,6 +196,7 @@ acquisition_dump_reader::acquisition_dump_reader(const std::string& basename, threshold = 0.0; positive_acq = 0; sample_counter = 0; + PRN = 0; d_num_doppler_bins = static_cast(ceil(static_cast(static_cast(d_doppler_max) - static_cast(-d_doppler_max)) / static_cast(d_doppler_step))); std::vector > mag_aux(d_num_doppler_bins, std::vector(d_samples_per_code)); mag = mag_aux; diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h index 3f6b40365..3958b98b2 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h @@ -45,7 +45,13 @@ public: unsigned int samples_per_code, int channel = 0, int execution = 1); + + acquisition_dump_reader(const std::string& basename, + int channel = 0, + int execution = 1); + ~acquisition_dump_reader(); + bool read_binary_acq(); std::vector doppler; @@ -57,6 +63,7 @@ public: float input_power; float threshold; int positive_acq; + unsigned int PRN; long unsigned int sample_counter; private: diff --git a/src/utils/matlab/plot_acq_grid.m b/src/utils/matlab/plot_acq_grid.m index 182c09b02..86a710e76 100644 --- a/src/utils/matlab/plot_acq_grid.m +++ b/src/utils/matlab/plot_acq_grid.m @@ -107,7 +107,8 @@ xlabel('Doppler shift / Hz') ylabel('Test statistics') title(['Fixed code delay to ' num2str((d_max - 1) / n_fft * n_chips) ' chips']) subplot(2,1,2) -plot(delay, grid(:, f_max)) +normalization = (d_samples_per_code^4) * input_power; +plot(delay, acq_grid(:, f_max)./normalization) xlim([min(delay) max(delay)]) xlabel('Code delay / chips') ylabel('Test statistics') From d6cb8aa2c0ccb813cd845ce0e59d8c6f60ddd8b1 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Sun, 24 Jun 2018 22:31:44 +0200 Subject: [PATCH 26/40] Adding a tracking pull-in test for GPS L1 C/A tracking --- src/tests/common-files/tracking_tests_flags.h | 75 +++ src/tests/test_main.cc | 1 + ...gps_l1_ca_dll_pll_tracking_pull-in_test.cc | 573 ++++++++++++++++++ .../gps_l1_ca_dll_pll_tracking_test.cc | 31 +- 4 files changed, 651 insertions(+), 29 deletions(-) create mode 100644 src/tests/common-files/tracking_tests_flags.h create mode 100644 src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc diff --git a/src/tests/common-files/tracking_tests_flags.h b/src/tests/common-files/tracking_tests_flags.h new file mode 100644 index 000000000..bed99d3d7 --- /dev/null +++ b/src/tests/common-files/tracking_tests_flags.h @@ -0,0 +1,75 @@ +/*! + * \file tracking_tests_flags.h + * \brief Helper file for unit testing + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_TRACKING_TESTS_FLAGS_H_ +#define GNSS_SDR_TRACKING_TESTS_FLAGS_H_ + +#include +#include + +// Input signal configuration +DEFINE_bool(enable_external_signal_file, false, "Use an external signal file capture instead of the software-defined signal generator"); +DEFINE_string(signal_file, std::string("gps_l1_capture.dat"), "Path of the external signal capture file"); +DEFINE_double(CN0_dBHz_start, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]"); +DEFINE_double(CN0_dBHz_stop, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 stop sweep value [dB-Hz]"); +DEFINE_double(CN0_dB_step, 3.0, "Noise generator CN0 sweep step value [dB]"); + +DEFINE_double(PLL_bw_hz_start, 40.0, "PLL Wide configuration start sweep value [Hz]"); +DEFINE_double(PLL_bw_hz_stop, 40.0, "PLL Wide configuration stop sweep value [Hz]"); +DEFINE_double(PLL_bw_hz_step, 5.0, "PLL Wide configuration sweep step value [Hz]"); + +DEFINE_double(DLL_bw_hz_start, 1.5, "DLL Wide configuration start sweep value [Hz]"); +DEFINE_double(DLL_bw_hz_stop, 1.5, "DLL Wide configuration stop sweep value [Hz]"); +DEFINE_double(DLL_bw_hz_step, 0.25, "DLL Wide configuration sweep step value [Hz]"); + +DEFINE_double(PLL_narrow_bw_hz, 5.0, "PLL Narrow configuration value [Hz]"); +DEFINE_double(DLL_narrow_bw_hz, 0.75, "DLL Narrow configuration value [Hz]"); + +DEFINE_double(Acq_Doppler_error_hz_start, 500.0, "Acquisition Doppler error start sweep value [Hz]"); +DEFINE_double(Acq_Doppler_error_hz_stop, -500.0, "Acquisition Doppler error stop sweep value [Hz]"); +DEFINE_double(Acq_Doppler_error_hz_step, -50.0, "Acquisition Doppler error sweep step value [Hz]"); + +DEFINE_double(Acq_Delay_error_chips_start, 2.0, "Acquisition Code Delay error start sweep value [Hz]"); +DEFINE_double(Acq_Delay_error_chips_stop, -2.0, "Acquisition Code Delay error stop sweep value [Hz]"); +DEFINE_double(Acq_Delay_error_chips_step, -0.1, "Acquisition Code Delay error sweep step value [Hz]"); + + +DEFINE_int32(plot_detail_level, 0, "Specify the desired plot detail (0,1,2): 0 - Minimum plots (default) 2 - Plot all tracking parameters"); + +//Emulated acquisition configuration + +//Tracking configuration +DEFINE_int32(extend_correlation_symbols, 1, "Set the tracking coherent correlation to N symbols (up to 20 for GPS L1 C/A)"); + +//Test output configuration +DEFINE_bool(plot_gps_l1_tracking_test, false, "Plots results of GpsL1CADllPllTrackingTest with gnuplot"); + + +#endif diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index b139e993e..454a4a9a5 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -147,6 +147,7 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_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_dll_pll_tracking_pull-in_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" #endif diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc new file mode 100644 index 000000000..7a11f3178 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc @@ -0,0 +1,573 @@ +/*! + * \file gps_l1_ca_dll_pll_tracking_test.cc + * \brief This class implements a tracking Pull-In test for GPS_L1_CA_DLL_PLL_Tracking + * implementation based on some input parameters. + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2012-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 "tracking_tests_flags.h" + +// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +class GpsL1CADllPllTrackingPullInTest_msg_rx; + +typedef boost::shared_ptr GpsL1CADllPllTrackingPullInTest_msg_rx_sptr; + +GpsL1CADllPllTrackingPullInTest_msg_rx_sptr GpsL1CADllPllTrackingPullInTest_msg_rx_make(); + +class GpsL1CADllPllTrackingPullInTest_msg_rx : public gr::block +{ +private: + friend GpsL1CADllPllTrackingPullInTest_msg_rx_sptr GpsL1CADllPllTrackingPullInTest_msg_rx_make(); + void msg_handler_events(pmt::pmt_t msg); + GpsL1CADllPllTrackingPullInTest_msg_rx(); + +public: + int rx_message; + ~GpsL1CADllPllTrackingPullInTest_msg_rx(); //!< Default destructor +}; + + +GpsL1CADllPllTrackingPullInTest_msg_rx_sptr GpsL1CADllPllTrackingPullInTest_msg_rx_make() +{ + return GpsL1CADllPllTrackingPullInTest_msg_rx_sptr(new GpsL1CADllPllTrackingPullInTest_msg_rx()); +} + + +void GpsL1CADllPllTrackingPullInTest_msg_rx::msg_handler_events(pmt::pmt_t msg) +{ + try + { + long int message = pmt::to_long(msg); + rx_message = message; //3 -> loss of lock + //std::cout << "Received trk message: " << rx_message << std::endl; + } + catch (boost::bad_any_cast& e) + { + LOG(WARNING) << "msg_handler_telemetry Bad any cast!"; + rx_message = 0; + } +} + + +GpsL1CADllPllTrackingPullInTest_msg_rx::GpsL1CADllPllTrackingPullInTest_msg_rx() : gr::block("GpsL1CADllPllTrackingPullInTest_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(&GpsL1CADllPllTrackingPullInTest_msg_rx::msg_handler_events, this, _1)); + rx_message = 0; +} + + +GpsL1CADllPllTrackingPullInTest_msg_rx::~GpsL1CADllPllTrackingPullInTest_msg_rx() +{ +} + + +// ########################################################### + +class GpsL1CADllPllTrackingPullInTest : 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 p6; + std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking"; //"GPS_L1_CA_DLL_PLL_C_Aid_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(double CN0_dBHz, int file_idx); + int generate_signal(); + std::vector check_results_doppler(arma::vec& true_time_s, + arma::vec& true_value, + arma::vec& meas_time_s, + arma::vec& meas_value, + double& mean_error, + double& std_dev_error); + std::vector check_results_acc_carrier_phase(arma::vec& true_time_s, + arma::vec& true_value, + arma::vec& meas_time_s, + arma::vec& meas_value, + double& mean_error, + double& std_dev_error); + std::vector check_results_codephase(arma::vec& true_time_s, + arma::vec& true_value, + arma::vec& meas_time_s, + arma::vec& meas_value, + double& mean_error, + double& std_dev_error); + + GpsL1CADllPllTrackingPullInTest() + { + factory = std::make_shared(); + config = std::make_shared(); + item_size = sizeof(gr_complex); + gnss_synchro = Gnss_Synchro(); + } + + ~GpsL1CADllPllTrackingPullInTest() + { + } + + void configure_receiver(double PLL_wide_bw_hz, + double DLL_wide_bw_hz, + double PLL_narrow_bw_hz, + double DLL_narrow_bw_hz, + int extend_correlation_symbols); + + gr::top_block_sptr top_block; + std::shared_ptr factory; + std::shared_ptr config; + Gnss_Synchro gnss_synchro; + size_t item_size; +}; + + +int GpsL1CADllPllTrackingPullInTest::configure_generator(double CN0_dBHz, int file_idx) +{ + // 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 + std::to_string(file_idx); // 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] + p6 = std::string("-CN0_dBHz=") + std::to_string(CN0_dBHz); // Signal generator CN0 + return 0; +} + + +int GpsL1CADllPllTrackingPullInTest::generate_signal() +{ + int child_status; + + char* const parmList[] = {&generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0], &p6[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 GpsL1CADllPllTrackingPullInTest::configure_receiver( + double PLL_wide_bw_hz, + double DLL_wide_bw_hz, + double PLL_narrow_bw_hz, + double DLL_narrow_bw_hz, + int extend_correlation_symbols) +{ + 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 = std::make_shared(); + 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"); + config->set_property("Tracking_1C.pll_bw_hz", std::to_string(PLL_wide_bw_hz)); + config->set_property("Tracking_1C.dll_bw_hz", std::to_string(DLL_wide_bw_hz)); + config->set_property("Tracking_1C.early_late_space_chips", "0.5"); + config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(extend_correlation_symbols)); + config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz)); + config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz)); + config->set_property("Tracking_1C.early_late_space_narrow_chips", "0.5"); + config->set_property("Tracking_1C.dump", "true"); + config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); + + std::cout << "*****************************************\n"; + std::cout << "*** Tracking configuration parameters ***\n"; + std::cout << "*****************************************\n"; + std::cout << "pll_bw_hz: " << config->property("Tracking_1C.pll_bw_hz", 0.0) << " Hz\n"; + std::cout << "dll_bw_hz: " << config->property("Tracking_1C.dll_bw_hz", 0.0) << " Hz\n"; + std::cout << "pll_bw_narrow_hz: " << config->property("Tracking_1C.pll_bw_narrow_hz", 0.0) << " Hz\n"; + std::cout << "dll_bw_narrow_hz: " << config->property("Tracking_1C.dll_bw_narrow_hz", 0.0) << " Hz\n"; + std::cout << "extend_correlation_symbols: " << config->property("Tracking_1C.extend_correlation_symbols", 0) << " Symbols\n"; + std::cout << "*****************************************\n"; + std::cout << "*****************************************\n"; +} + + +TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) +{ + //************************************************* + //***** STEP 2: Prepare the parameters sweep ****** + //************************************************* + std::vector acq_doppler_error_hz_values; + std::vector> acq_delay_error_chips_values; //vector of vector + + for (double doppler_hz = FLAGS_Acq_Doppler_error_hz_start; doppler_hz >= FLAGS_Acq_Doppler_error_hz_stop; doppler_hz = doppler_hz + FLAGS_Acq_Doppler_error_hz_step) + { + acq_doppler_error_hz_values.push_back(doppler_hz); + std::vector tmp_vector; + //Code Delay Sweep + for (double code_delay_chips = FLAGS_Acq_Delay_error_chips_start; code_delay_chips >= FLAGS_Acq_Delay_error_chips_stop; code_delay_chips = code_delay_chips + FLAGS_Acq_Delay_error_chips_step) + { + tmp_vector.push_back(code_delay_chips); + } + acq_delay_error_chips_values.push_back(tmp_vector); + } + + + //********************************************* + //***** STEP 3: Generate the input signal ***** + //********************************************* + std::vector generator_CN0_values; + if (FLAGS_CN0_dBHz_start == FLAGS_CN0_dBHz_stop) + { + generator_CN0_values.push_back(FLAGS_CN0_dBHz_start); + } + else + { + for (double cn0 = FLAGS_CN0_dBHz_start; cn0 > FLAGS_CN0_dBHz_stop; cn0 = cn0 - FLAGS_CN0_dB_step) + { + generator_CN0_values.push_back(cn0); + } + } + + // use generator or use an external capture file + if (FLAGS_enable_external_signal_file) + { + //todo: create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters + } + else + { + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + // Configure the signal generator + configure_generator(generator_CN0_values.at(current_cn0_idx), current_cn0_idx); + // Generate signal raw signal samples and observations RINEX file + if (FLAGS_disable_generator == false) + { + generate_signal(); + } + } + } + + + configure_receiver(FLAGS_PLL_bw_hz_start, + FLAGS_DLL_bw_hz_start, + FLAGS_PLL_narrow_bw_hz, + FLAGS_DLL_narrow_bw_hz, + FLAGS_extend_correlation_symbols); + + //****************************************************************************************** + //***** Obtain the initial signal sinchronization parameters (emulating an acquisition) **** + //****************************************************************************************** + int test_satellite_PRN = 0; + tracking_true_obs_reader true_obs_data; + if (!FLAGS_enable_external_signal_file) + { + test_satellite_PRN = FLAGS_test_satellite_PRN; + 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"); + true_obs_data.close_obs_file(); + ASSERT_EQ(true_obs_data.open_obs_file(true_obs_file), true) << "Failure opening true observables file"; + // 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?"; + std::cout << "Testing satellite PRN=" << test_satellite_PRN << std::endl; + std::cout << "True Initial Doppler [Hz]=" << true_obs_data.doppler_l1_hz << " rue Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << std::endl; + } + else + { + //todo: Simulate a perfect acquisition for the external capture file + } + //CN0 LOOP + std::vector> pull_in_results_v_v; + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + std::vector pull_in_results_v; + for (unsigned int current_acq_doppler_error_idx = 0; current_acq_doppler_error_idx < acq_doppler_error_hz_values.size(); current_acq_doppler_error_idx++) + { + for (unsigned int current_acq_code_error_idx = 0; current_acq_code_error_idx < acq_delay_error_chips_values.at(current_acq_doppler_error_idx).size(); current_acq_code_error_idx++) + { + //simulate a Doppler error in acquisition + double acq_doppler_hz = true_obs_data.doppler_l1_hz + acq_doppler_error_hz_values.at(current_acq_doppler_error_idx); + //simulate Code Delay error in acquisition + double acq_delay_samples; + acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * static_cast(baseband_sampling_freq) * GPS_L1_CA_CODE_PERIOD; + acq_delay_samples += (acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx) / GPS_L1_CA_CODE_RATE_HZ) * static_cast(baseband_sampling_freq); + + //create flowgraph + top_block = gr::make_top_block("Tracking test"); + std::shared_ptr trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1); + std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); + + boost::shared_ptr msg_rx = GpsL1CADllPllTrackingPullInTest_msg_rx_make(); + + gnss_synchro.Acq_delay_samples = acq_delay_samples; + gnss_synchro.Acq_doppler_hz = acq_doppler_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 + std::to_string(current_cn0_idx); + 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."; + + + //******************************************************************** + //***** STEP 5: Perform the signal tracking and read the results ***** + //******************************************************************** + std::cout << "------------ START TRACKING -------------" << std::endl; + tracking->start_tracking(); + std::chrono::time_point start, end; + 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."; + + std::chrono::duration elapsed_seconds = end - start; + std::cout << "Signal tracking completed in " << elapsed_seconds.count() << " seconds" << std::endl; + + + pull_in_results_v.push_back(msg_rx->rx_message != 3); //save last asynchronous tracking message in order to detect a loss of lock + + //******************************** + //***** STEP 7: Plot results ***** + //******************************** + if (FLAGS_plot_gps_l1_tracking_test == true) + { + //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"; + + long int n_measured_epochs = trk_dump.num_epochs(); + //todo: use vectors instead + arma::vec trk_timestamp_s = arma::zeros(n_measured_epochs, 1); + arma::vec trk_acc_carrier_phase_cycles = arma::zeros(n_measured_epochs, 1); + arma::vec trk_Doppler_Hz = arma::zeros(n_measured_epochs, 1); + arma::vec trk_prn_delay_chips = arma::zeros(n_measured_epochs, 1); + std::vector timestamp_s; + std::vector prompt; + std::vector early; + std::vector late; + std::vector promptI; + std::vector promptQ; + std::vector CN0_dBHz; + long int epoch_counter = 0; + while (trk_dump.read_binary_obs()) + { + trk_timestamp_s(epoch_counter) = static_cast(trk_dump.PRN_start_sample_count) / static_cast(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(trk_dump.PRN_start_sample_count) + trk_dump.aux1) / static_cast(baseband_sampling_freq), 1.0e-3) / 1.0e-3); + + trk_prn_delay_chips(epoch_counter) = delay_chips; + + timestamp_s.push_back(trk_timestamp_s(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); + CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz); + + epoch_counter++; + } + + + 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); + unsigned int decimate = static_cast(FLAGS_plot_decimate); + + if (FLAGS_plot_detail_level >= 2) + { + Gnuplot g1("linespoints"); + g1.showonscreen(); // window output + g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " Hz" + "GPS L1 C/A (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"); + g1.plot_xy(trk_timestamp_s, prompt, "Prompt", decimate); + g1.plot_xy(trk_timestamp_s, early, "Early", decimate); + g1.plot_xy(trk_timestamp_s, late, "Late", decimate); + g1.set_legend(); + //g1.savetops("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx))); + //g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18); + + Gnuplot g2("points"); + g2.showonscreen(); // window output + g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " Hz" + "GPS L1 C/A (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); + + Gnuplot g3("linespoints"); + g3.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g3.set_grid(); + g3.set_xlabel("Time [s]"); + g3.set_ylabel("Reported CN0 [dB-Hz]"); + g3.cmd("set key box opaque"); + + g3.plot_xy(trk_timestamp_s, CN0_dBHz, + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + + g3.set_legend(); + //g3.savetops("CN0_output"); + //g3.savetopdf("CN0_output", 18); + g3.showonscreen(); // window output + } + } + catch (const GnuplotException& ge) + { + std::cout << ge.what() << std::endl; + } + } + } //end plot + + } //end acquisition Delay errors loop + } //end acquisition Doppler errors loop + pull_in_results_v_v.push_back(pull_in_results_v); + + + } //end CN0 LOOP + //build the mesh grid + std::vector doppler_error_mesh; + std::vector code_delay_error_mesh; + for (unsigned int current_acq_doppler_error_idx = 0; current_acq_doppler_error_idx < acq_doppler_error_hz_values.size(); current_acq_doppler_error_idx++) + { + for (unsigned int current_acq_code_error_idx = 0; current_acq_code_error_idx < acq_delay_error_chips_values.at(current_acq_doppler_error_idx).size(); current_acq_code_error_idx++) + { + doppler_error_mesh.push_back(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)); + code_delay_error_mesh.push_back(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)); + } + } + + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + std::vector pull_in_result_mesh; + pull_in_result_mesh = pull_in_results_v_v.at(current_cn0_idx); + //plot grid + Gnuplot g4("points palette pointsize 2 pointtype 7"); + g4.cmd("set palette defined ( 0 \"black\", 1 \"green\" )"); + g4.cmd("set key off"); + g4.cmd("set view map"); + std::string title("Tracking Pull-in result grid at CN0:" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + " dB-Hz, PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " Hz."); + g4.set_title(title); + g4.set_grid(); + g4.set_xlabel("Acquisition Doppler error [Hz]"); + g4.set_ylabel("Acquisition Code Delay error [Chips]"); + + g4.plot_xyz(doppler_error_mesh, + code_delay_error_mesh, + pull_in_result_mesh); + g4.set_legend(); + g4.savetops("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx))))); + g4.savetopdf("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))), 12); + g4.showonscreen(); // window output + } +} diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index 9a521eba0..0fac7c6d3 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -1,6 +1,6 @@ /*! * \file gps_l1_ca_dll_pll_tracking_test.cc - * \brief This class implements a tracking test for Galileo_E5a_DLL_PLL_Tracking + * \brief This class implements a tracking test for GPS_L1_CA_DLL_PLL_Tracking * implementation based on some input parameters. * \author Javier Arribas, 2017. jarribas(at)cttc.es * @@ -52,36 +52,9 @@ #include "signal_generator_flags.h" #include "gnuplot_i.h" #include "test_flags.h" +#include "tracking_tests_flags.h" -// Input signal configuration -DEFINE_bool(enable_external_signal_file, false, "Use an external signal file capture instead of the software-defined signal generator"); -DEFINE_string(signal_file, std::string("gps_l1_capture.dat"), "Path of the external signal capture file"); -DEFINE_double(CN0_dBHz_start, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]"); -DEFINE_double(CN0_dBHz_stop, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 stop sweep value [dB-Hz]"); -DEFINE_double(CN0_dB_step, 3.0, "Noise generator CN0 sweep step value [dB]"); - -DEFINE_double(PLL_bw_hz_start, 40.0, "PLL Wide configuration start sweep value [Hz]"); -DEFINE_double(PLL_bw_hz_stop, 40.0, "PLL Wide configuration stop sweep value [Hz]"); -DEFINE_double(PLL_bw_hz_step, 5.0, "PLL Wide configuration sweep step value [Hz]"); - -DEFINE_double(DLL_bw_hz_start, 1.5, "DLL Wide configuration start sweep value [Hz]"); -DEFINE_double(DLL_bw_hz_stop, 1.5, "DLL Wide configuration stop sweep value [Hz]"); -DEFINE_double(DLL_bw_hz_step, 0.25, "DLL Wide configuration sweep step value [Hz]"); - -DEFINE_double(PLL_narrow_bw_hz, 5.0, "PLL Narrow configuration value [Hz]"); -DEFINE_double(DLL_narrow_bw_hz, 0.75, "DLL Narrow configuration value [Hz]"); - -DEFINE_int32(plot_detail_level, 0, "Specify the desired plot detail (0,1,2): 0 - Minimum plots (default) 2 - Plot all tracking parameters"); - -//Emulated acquisition configuration - -//Tracking configuration -DEFINE_int32(extend_correlation_symbols, 1, "Set the tracking coherent correlation to N symbols (up to 20 for GPS L1 C/A)"); - -//Test output configuration -DEFINE_bool(plot_gps_l1_tracking_test, false, "Plots results of GpsL1CADllPllTrackingTest with gnuplot"); - // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class GpsL1CADllPllTrackingTest_msg_rx; From e7bc582e5f39e03f7d59efaf034da10b8f4c1a10 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 25 Jun 2018 00:56:11 +0200 Subject: [PATCH 27/40] Add work on acqusition performance test --- .../gps_l1_acq_performance_test.cc | 478 ++++++++---------- 1 file changed, 201 insertions(+), 277 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index 209779d57..529514c88 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -33,22 +33,27 @@ #include "signal_generator_flags.h" #include "tracking_true_obs_reader.h" #include "true_observables_reader.h" +#include "display.h" #include #include #include DEFINE_string(config_file_ptest, std::string(""), "File containing the configuration parameters for the position test."); DEFINE_double(acq_test_threshold, 0.001, "Acquisition threshold"); +DEFINE_double(acq_test_pfa, -1.0, "Set threshold via probability of false alarm"); DEFINE_int32(acq_test_coherent_time_ms, 10, "Acquisition coherent time, in ms"); DEFINE_int32(acq_test_PRN, 1, "PRN number"); +DEFINE_int32(acq_test_fake_PRN, 33, "Fake PRN number"); +DEFINE_int32(acq_test_signal_duration_s, 2, "Generated signal duration"); +DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag"); // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class AcqPerfTest_msg_rx; -// + typedef boost::shared_ptr AcqPerfTest_msg_rx_sptr; -// + AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(concurrent_queue& queue); -// + class AcqPerfTest_msg_rx : public gr::block { private: @@ -59,7 +64,7 @@ private: public: int rx_message; - ~AcqPerfTest_msg_rx(); //!< Default destructor + ~AcqPerfTest_msg_rx(); }; @@ -82,7 +87,6 @@ void AcqPerfTest_msg_rx::msg_handler_events(pmt::pmt_t msg) LOG(WARNING) << "msg_handler_telemetry Bad any cast!"; rx_message = 0; } - //std::cout << "Received message:" << rx_message << std::endl; } @@ -134,6 +138,7 @@ protected: void stop_queue(); int run_receiver(); int run_receiver2(); + int count_executions(const std::string& basename, unsigned int sat); void check_results(); concurrent_queue channel_internal_queue; @@ -160,15 +165,15 @@ protected: const int in_acquisition = 1; const float threshold = FLAGS_acq_test_threshold; const int max_dwells = 1; - const int tong_init_val = 2; - const int tong_max_val = 10; - const int tong_max_dwells = 30; + const int dump_channel = 0; - int generated_signal_duration_s = 2; + int generated_signal_duration_s = FLAGS_acq_test_signal_duration_s; unsigned int num_of_realizations = (generated_signal_duration_s * 1000) / FLAGS_acq_test_coherent_time_ms; unsigned int realization_counter; + unsigned int observed_satellite = FLAGS_acq_test_PRN; + private: std::string generator_binary; std::string p1; @@ -196,7 +201,7 @@ void AcquisitionPerformanceTest::init() gnss_synchro.System = 'G'; std::string signal = "1C"; signal.copy(gnss_synchro.Signal, 2, 0); - gnss_synchro.PRN = 1; + gnss_synchro.PRN = observed_satellite; message = 0; realization_counter = 0; } @@ -211,23 +216,13 @@ void AcquisitionPerformanceTest::start_queue() void AcquisitionPerformanceTest::wait_message() { - //std::chrono::time_point start, end; - //std::chrono::duration elapsed_seconds(0); - while (!stop) { acquisition->reset(); acquisition->set_state(1); - //start = std::chrono::system_clock::now(); - channel_internal_queue.wait_and_pop(message); - //end = std::chrono::system_clock::now(); - //elapsed_seconds = end - start; - - //mean_acq_time_us += elapsed_seconds.count() * 1e6; - process_message(); } } @@ -235,38 +230,12 @@ void AcquisitionPerformanceTest::wait_message() void AcquisitionPerformanceTest::process_message() { - if (message == 1) - { - //detection_counter++; - - // The term -5 is here to correct the additional delay introduced by the FIR filter - //double delay_error_chips = std::abs(static_cast(expected_delay_chips) - static_cast(gnss_synchro.Acq_delay_samples - 5) * 1023.0 / (static_cast(fs_in) * 1e-3)); - //double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro.Acq_doppler_hz); - - // mse_delay += std::pow(delay_error_chips, 2); - // mse_doppler += std::pow(doppler_error_hz, 2); - - // if ((delay_error_chips < max_delay_error_chips) && (doppler_error_hz < max_doppler_error_hz)) - // { - // correct_estimation_counter++; - // } - } - realization_counter++; - - std::cout << "Progress: " << round(static_cast(realization_counter) / static_cast(num_of_realizations) * 100.0) << "% \r" << std::flush; + acquisition->reset(); + acquisition->set_state(1); if (realization_counter == num_of_realizations) { - // mse_delay /= num_of_realizations; - // mse_doppler /= num_of_realizations; - - //Pd = static_cast(correct_estimation_counter) / static_cast(num_of_realizations); - //Pfa_a = static_cast(detection_counter) / static_cast(num_of_realizations); - //Pfa_p = static_cast(detection_counter - correct_estimation_counter) / static_cast(num_of_realizations); - - // mean_acq_time_us /= num_of_realizations; - stop_queue(); top_block->stop(); } @@ -414,7 +383,7 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter config->set_property("Channels_1C.count", std::to_string(number_of_channels)); config->set_property("Channels.in_acquisition", std::to_string(in_acquisition)); config->set_property("Channel.signal", "1C"); - //config->set_property("Channel0.satellite", std::to_string(FLAGS_acq_test_PRN)); + //config->set_property("Channel1.satellite", std::to_string(FLAGS_acq_test_PRN)); // Set Acquisition config->set_property("Acquisition_1C.implementation", implementation); @@ -423,11 +392,19 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); config->set_property("Acquisition_1C.threshold", std::to_string(threshold)); - //config->set_property("Acquisition_1C.pfa", "0.0"); + if (FLAGS_acq_test_pfa > 0.0) config->set_property("Acquisition_1C.pfa", std::to_string(FLAGS_acq_test_pfa)); + config->set_property("Acquisition_1C.use_CFAR_algorithm", "true"); config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); - config->set_property("Acquisition_1C.use_bit_transition_flag", "false"); + if (FLAGS_acq_test_bit_transition_flag) + { + config->set_property("Acquisition_1C.bit_transition_flag", "true"); + } + else + { + config->set_property("Acquisition_1C.bit_transition_flag", "false"); + } config->set_property("Acquisition_1C.max_dwells", std::to_string(1)); @@ -437,16 +414,11 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter config->set_property("Acquisition_1C.make_two_steps", "false"); config->set_property("Acquisition_1C.second_nbins", std::to_string(4)); config->set_property("Acquisition_1C.second_doppler_step", std::to_string(125)); - //if (FLAGS_plot_acq_grid == true) - // { + config->set_property("Acquisition_1C.dump", "true"); - // } - //else - // { - // config->set_property("Acquisition_1C.dump", "false"); - // } std::string dump_file = std::string("./acquisition_") + std::to_string(cn0) + "_" + std::to_string(iter); config->set_property("Acquisition_1C.dump_filename", dump_file); + config->set_property("Acquisition_1C.dump_channel", std::to_string(dump_channel)); // Set Tracking config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_Tracking"); @@ -510,10 +482,8 @@ int AcquisitionPerformanceTest::run_receiver() 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); - std::cout << "Source created" << std::endl; gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); - std::cout << "Interleaver created" << std::endl; top_block = gr::make_top_block("Acquisition test"); boost::shared_ptr msg_rx = AcqPerfTest_msg_rx_make(channel_internal_queue); @@ -521,10 +491,11 @@ int AcquisitionPerformanceTest::run_receiver() queue = gr::msg_queue::make(0); gnss_synchro = Gnss_Synchro(); init(); - acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 0); + int nsamples = floor(config->property("GNSS-SDR.internal_fs_sps", 2000000) * generated_signal_duration_s); boost::shared_ptr valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 0); acquisition->set_gnss_synchro(&gnss_synchro); acquisition->set_channel(0); acquisition->set_local_code(); @@ -535,22 +506,19 @@ int AcquisitionPerformanceTest::run_receiver() acquisition->connect(top_block); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - acquisition->init(); top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); top_block->connect(gr_interleaved_char_to_complex, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); - std::cout << "Num of realizations: " << num_of_realizations << std::endl; + start_queue(); + start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); - //file_source->close(); elapsed_seconds = end - start; - std::cout << "Acq_delay_samples: " << gnss_synchro.Acq_delay_samples << std::endl; - std::cout << "Acq_doppler_hz: " << gnss_synchro.Acq_doppler_hz << std::endl; - std::cout << "Acq_samplestamp_samples: " << gnss_synchro.Acq_samplestamp_samples << std::endl; + #ifdef OLD_BOOST ch_thread.timed_join(boost::posix_time::seconds(1)); #endif @@ -563,6 +531,7 @@ int AcquisitionPerformanceTest::run_receiver() return 0; } + int AcquisitionPerformanceTest::run_receiver2() { std::shared_ptr control_thread; @@ -592,14 +561,34 @@ int AcquisitionPerformanceTest::run_receiver2() } +int AcquisitionPerformanceTest::count_executions(const std::string& basename, unsigned int sat) +{ + FILE* fp; + std::string argum2 = std::string("/bin/ls ") + basename + "* | grep sat_" + std::to_string(sat) + " | wc -l"; + char buffer[1024]; + fp = popen(&argum2[0], "r"); + int num_executions = 1; + if (fp == NULL) + { + std::cout << "Failed to run command: " << argum2 << std::endl; + return 0; + } + while (fgets(buffer, sizeof(buffer), fp) != NULL) + { + std::string aux = std::string(buffer); + EXPECT_EQ(aux.empty(), false); + num_executions = std::stoi(aux); + } + pclose(fp); + return num_executions; +} + + TEST_F(AcquisitionPerformanceTest, PdvsCn0) { - init(); tracking_true_obs_reader true_trk_data; for (std::vector::const_iterator it = cn0_.cbegin(); it != cn0_.cend(); ++it) { - // Set parameter to sweep - // Do N_iterations of the experiment for (unsigned iter = 0; iter < N_iterations; iter++) { @@ -611,232 +600,167 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) // Generate signal raw signal samples and observations RINEX file generate_signal(); - // Configure the receiver - configure_receiver(*it, iter); - - // remove old files - // FILE* fp2; - // std::string remove_old_files = std::string("/bin/rm ") + basename + "*.mat"; - // fp2 = popen(&remove_old_files[0], "r"); - // pclose(fp2); - - // Run it - run_receiver(); - - // Read and store reference data and results - std::cout << basename << std::endl; - // count executions - FILE* fp; - std::string argum2 = std::string("/bin/ls ") + basename + "* | wc -l"; - char buffer[1024]; - fp = popen(&argum2[0], "r"); - int num_executions = 1; - if (fp == NULL) + std::cout << "Execution for CN0 = " << *it << " dB-Hz" << std::endl; + for (unsigned k = 0; k < 2; k++) { - std::cout << "Failed to run command: " << argum2 << std::endl; - //return -1; - } - while (fgets(buffer, sizeof(buffer), fp) != NULL) - { - std::string aux = std::string(buffer); - EXPECT_EQ(aux.empty(), false); - num_executions = std::stoi(aux); - } - pclose(fp); - int ch = 0; - - arma::vec meas_timestamp_s = arma::zeros(num_executions, 1); - arma::vec meas_doppler = arma::zeros(num_executions, 1); - arma::vec positive_acq = arma::zeros(num_executions, 1); - arma::vec meas_acq_delay_chips = arma::zeros(num_executions, 1); - - double coh_time_ms = config->property("Acquisition_1C.coherent_integration_time_ms", 1); - - std::cout << "Num executions: " << std::endl; - for (int execution = 1; execution <= num_executions; execution++) - { - acquisition_dump_reader acq_dump(basename, FLAGS_acq_test_PRN, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * GPS_L1_CA_CODE_PERIOD * static_cast(coh_time_ms), ch, execution); - if (!acq_dump.read_binary_acq()) - ; - if (acq_dump.positive_acq) + if (k == 0) { - //std::cout << "Meas acq_delay_samples: " << acq_dump.acq_delay_samples << " chips: " << acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS) << std::endl; - meas_timestamp_s(execution - 1) = acq_dump.sample_counter / baseband_sampling_freq; - meas_doppler(execution - 1) = acq_dump.acq_doppler_hz; - meas_acq_delay_chips(execution - 1) = acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS); - positive_acq(execution - 1) = acq_dump.positive_acq; + observed_satellite = FLAGS_acq_test_PRN; } else { - //std::cout << "Failed acquisition." << std::endl; - meas_timestamp_s(execution - 1) = arma::datum::inf; - meas_doppler(execution - 1) = arma::datum::inf; - meas_acq_delay_chips(execution - 1) = arma::datum::inf; - positive_acq(execution - 1) = acq_dump.positive_acq; + observed_satellite = FLAGS_acq_test_fake_PRN; } - } + init(); - std::string true_trk_file = std::string("./gps_l1_ca_obs_prn"); - true_trk_file.append(std::to_string(FLAGS_acq_test_PRN)); - true_trk_file.append(".dat"); - true_trk_data.close_obs_file(); - true_trk_data.open_obs_file(true_trk_file); + // Configure the receiver + configure_receiver(*it, iter); + // Run it + run_receiver(); - // load the true values - long int n_true_epochs = true_trk_data.num_epochs(); + // count executions + int num_executions = count_executions(basename, observed_satellite); - arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); - arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); - arma::vec true_Doppler_Hz = arma::zeros(n_true_epochs, 1); - arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); - arma::vec true_tow_s = arma::zeros(n_true_epochs, 1); + // Read measured data + int ch = config->property("Acquisition_1C.dump_channel", 0); + arma::vec meas_timestamp_s = arma::zeros(num_executions, 1); + arma::vec meas_doppler = arma::zeros(num_executions, 1); + arma::vec positive_acq = arma::zeros(num_executions, 1); + arma::vec meas_acq_delay_chips = arma::zeros(num_executions, 1); - long int epoch_counter = 0; - while (true_trk_data.read_binary_obs()) - { - true_timestamp_s(epoch_counter) = true_trk_data.signal_timestamp_s; - true_acc_carrier_phase_cycles(epoch_counter) = true_trk_data.acc_carrier_phase_cycles; - true_Doppler_Hz(epoch_counter) = true_trk_data.doppler_l1_hz; - true_prn_delay_chips(epoch_counter) = GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips; - true_tow_s(epoch_counter) = true_trk_data.tow; - epoch_counter++; - //std::cout << "True PRN_Delay chips = " << GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips << " at " << true_trk_data.signal_timestamp_s << std::endl; - } - if (epoch_counter > 2) - { - arma::vec true_interpolated_doppler = arma::zeros(num_executions, 1); - arma::vec true_interpolated_prn_delay_chips = arma::zeros(num_executions, 1); - interp1(true_timestamp_s, true_Doppler_Hz, meas_timestamp_s, true_interpolated_doppler); - interp1(true_timestamp_s, true_prn_delay_chips, meas_timestamp_s, true_interpolated_prn_delay_chips); + double coh_time_ms = config->property("Acquisition_1C.coherent_integration_time_ms", 1); - arma::vec doppler_estimation_error = true_interpolated_doppler - meas_doppler; - std::cout << "Doppler estimation error [Hz]: "; - for (int i = 0; i < num_executions - 1; i++) + std::cout << "Num executions: " << num_executions << std::endl; + for (int execution = 1; execution <= num_executions; execution++) { - std::cout << doppler_estimation_error(i) << " "; - } - std::cout << std::endl; - arma::vec delay_estimation_error = true_interpolated_prn_delay_chips - meas_acq_delay_chips; - std::cout << "Delay estimation error [chips]: "; - for (int i = 0; i < num_executions - 1; i++) - { - std::cout << delay_estimation_error(i) << " "; - } - std::cout << std::endl; - - double detected = arma::accu(positive_acq); - std::cout << "Probability of detection for channel=" << ch << ", CN0=" << *it << " dBHz" - << ": " << (num_executions > 0 ? (detected / num_executions) : 0.0) << std::endl; - - arma::vec correct_acq = arma::zeros(num_executions, 1); - double correctly_detected = 0.0; - for (int i = 0; i < num_executions - 1; i++) - - { - if (abs(delay_estimation_error(i)) < 0.5) + acquisition_dump_reader acq_dump(basename, observed_satellite, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * GPS_L1_CA_CODE_PERIOD * static_cast(coh_time_ms), ch, execution); + acq_dump.read_binary_acq(); + if (acq_dump.positive_acq) { - correctly_detected = correctly_detected + 1.0; + //std::cout << "Meas acq_delay_samples: " << acq_dump.acq_delay_samples << " chips: " << acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS) << std::endl; + meas_timestamp_s(execution - 1) = acq_dump.sample_counter / baseband_sampling_freq; + meas_doppler(execution - 1) = acq_dump.acq_doppler_hz; + meas_acq_delay_chips(execution - 1) = acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS); + positive_acq(execution - 1) = acq_dump.positive_acq; + } + else + { + //std::cout << "Failed acquisition." << std::endl; + meas_timestamp_s(execution - 1) = arma::datum::inf; + meas_doppler(execution - 1) = arma::datum::inf; + meas_acq_delay_chips(execution - 1) = arma::datum::inf; + positive_acq(execution - 1) = acq_dump.positive_acq; } } - std::cout << "Probability of correct detection for channel=" << ch << ", CN0=" << *it << " dBHz" - << ": " << (num_executions > 0 ? (correctly_detected / num_executions) : 0.0) << std::endl; - } - else - { - std::cout << "No reference data has been found. Maybe a non-present satellite?" << std::endl; - double wrongly_detected = arma::accu(positive_acq); - std::cout << "Probability of false alarm for channel=" << ch << ", CN0=" << *it << " dBHz" - << ": " << (num_executions > 0 ? (wrongly_detected / num_executions) : 0.0) << std::endl; + // Read reference data + std::string true_trk_file = std::string("./gps_l1_ca_obs_prn"); + true_trk_file.append(std::to_string(observed_satellite)); + true_trk_file.append(".dat"); + true_trk_data.close_obs_file(); + true_trk_data.open_obs_file(true_trk_file); + + // load the true values + long int n_true_epochs = true_trk_data.num_epochs(); + arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); + arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); + arma::vec true_Doppler_Hz = arma::zeros(n_true_epochs, 1); + arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); + arma::vec true_tow_s = arma::zeros(n_true_epochs, 1); + + long int epoch_counter = 0; + int num_clean_executions = 0; + while (true_trk_data.read_binary_obs()) + { + true_timestamp_s(epoch_counter) = true_trk_data.signal_timestamp_s; + true_acc_carrier_phase_cycles(epoch_counter) = true_trk_data.acc_carrier_phase_cycles; + true_Doppler_Hz(epoch_counter) = true_trk_data.doppler_l1_hz; + true_prn_delay_chips(epoch_counter) = GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips; + true_tow_s(epoch_counter) = true_trk_data.tow; + epoch_counter++; + //std::cout << "True PRN_Delay chips = " << GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips << " at " << true_trk_data.signal_timestamp_s << std::endl; + } + + // Process results + arma::vec clean_doppler_estimation_error; + arma::vec clean_delay_estimation_error; + if (epoch_counter > 2) + { + arma::vec true_interpolated_doppler = arma::zeros(num_executions, 1); + arma::vec true_interpolated_prn_delay_chips = arma::zeros(num_executions, 1); + interp1(true_timestamp_s, true_Doppler_Hz, meas_timestamp_s, true_interpolated_doppler); + interp1(true_timestamp_s, true_prn_delay_chips, meas_timestamp_s, true_interpolated_prn_delay_chips); + + arma::vec doppler_estimation_error = true_interpolated_doppler - meas_doppler; + arma::vec delay_estimation_error = true_interpolated_prn_delay_chips - (meas_acq_delay_chips - ((1.0 / baseband_sampling_freq) / GPS_L1_CA_CHIP_PERIOD)); // compensate 1 sample delay + + // Cut measurements without reference + for (unsigned int i = 0; i < num_executions; i++) + { + if (!std::isnan(doppler_estimation_error(i)) and !std::isnan(delay_estimation_error(i))) + { + num_clean_executions++; + } + } + clean_doppler_estimation_error = arma::zeros(num_clean_executions, 1); + clean_delay_estimation_error = arma::zeros(num_clean_executions, 1); + num_clean_executions = 0; + for (unsigned int i = 0; i < num_executions; i++) + { + if (!std::isnan(doppler_estimation_error(i)) and !std::isnan(delay_estimation_error(i))) + { + clean_doppler_estimation_error(num_clean_executions) = doppler_estimation_error(i); + clean_delay_estimation_error(num_clean_executions) = delay_estimation_error(i); + num_clean_executions++; + } + } + + std::cout << "Doppler estimation error [Hz]: "; + for (int i = 0; i < num_executions - 1; i++) + { + std::cout << doppler_estimation_error(i) << " "; + } + std::cout << std::endl; + + std::cout << "Delay estimation error [chips]: "; + for (int i = 0; i < num_executions - 1; i++) + { + std::cout << delay_estimation_error(i) << " "; + } + std::cout << std::endl; + + double detected = arma::accu(positive_acq); + std::cout << TEXT_BOLD_BLACK << "Probability of detection for channel=" << ch << ", CN0=" << *it << " dBHz" + << ": " << (num_executions > 0 ? (detected / num_executions) : 0.0) << TEXT_RESET << std::endl; + } + if (num_clean_executions > 0) + { + arma::vec correct_acq = arma::zeros(num_executions, 1); + double correctly_detected = 0.0; + for (int i = 0; i < num_clean_executions - 1; i++) + + { + if (abs(clean_delay_estimation_error(i)) < 0.5 and abs(clean_doppler_estimation_error(i)) < static_cast(config->property("Acquisition_1C.doppler_step", 1)) / 2.0) + { + correctly_detected = correctly_detected + 1.0; + } + } + std::cout << TEXT_BOLD_BLACK << "Probability of correct detection for channel=" << ch << ", CN0=" << *it << " dBHz" + << ": " << (num_clean_executions > 0 ? (correctly_detected / num_clean_executions) : 0.0) << TEXT_RESET << std::endl; + } + else + { + std::cout << "No reference data has been found. Maybe a non-present satellite?" << std::endl; + + double wrongly_detected = arma::accu(positive_acq); + std::cout << TEXT_BOLD_BLACK << "Probability of false alarm for channel=" << ch << ", CN0=" << *it << " dBHz" + << ": " << (num_executions > 0 ? (wrongly_detected / num_executions) : 0.0) << TEXT_RESET << std::endl; + } + true_trk_data.restart(); } - true_trk_data.restart(); } - + true_trk_data.close_obs_file(); // Compute results } } -//TEST_F(AcquisitionPerformanceTest, ValidationOfResults) -//{ -// std::chrono::time_point start, end; -// std::chrono::duration elapsed_seconds(0.0); -// top_block = gr::make_top_block("Acquisition test"); -// -// double expected_delay_samples = 524; -// double expected_doppler_hz = 1680; -// -// init(); -// -// if (FLAGS_plot_acq_grid == true) -// { -// std::string data_str = "./tmp-acq-gps1"; -// if (boost::filesystem::exists(data_str)) -// { -// boost::filesystem::remove_all(data_str); -// } -// boost::filesystem::create_directory(data_str); -// } -// -// std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 0); -// boost::shared_ptr msg_rx = AcqPerfTest_msg_rx_make(); -// -// ASSERT_NO_THROW({ -// acquisition->set_channel(1); -// }) << "Failure setting channel."; -// -// ASSERT_NO_THROW({ -// acquisition->set_gnss_synchro(&gnss_synchro); -// }) << "Failure setting gnss_synchro."; -// -// ASSERT_NO_THROW({ -// acquisition->set_threshold(0.001); -// }) << "Failure setting threshold."; -// -// ASSERT_NO_THROW({ -// acquisition->set_doppler_max(doppler_max); -// }) << "Failure setting doppler_max."; -// -// ASSERT_NO_THROW({ -// acquisition->set_doppler_step(doppler_step); -// }) << "Failure setting doppler_step."; -// -// ASSERT_NO_THROW({ -// acquisition->connect(top_block); -// }) << "Failure connecting acquisition to the top_block."; -// -// ASSERT_NO_THROW({ -// std::string path = std::string(TEST_PATH); -// std::string file = path + "signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat"; -// const char* file_name = file.c_str(); -// gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(gr_complex), file_name, false); -// top_block->connect(file_source, 0, acquisition->get_left_block(), 0); -// top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); -// }) << "Failure connecting the blocks of acquisition test."; -// -// acquisition->set_local_code(); -// acquisition->set_state(1); // Ensure that acquisition starts at the first sample -// acquisition->init(); -// -// EXPECT_NO_THROW({ -// start = std::chrono::system_clock::now(); -// top_block->run(); // Start threads and wait -// end = std::chrono::system_clock::now(); -// elapsed_seconds = end - start; -// }) << "Failure running the top_block."; -// -// unsigned long int nsamples = gnss_synchro.Acq_samplestamp_samples; -// std::cout << "Acquired " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; -// ASSERT_EQ(1, msg_rx->rx_message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS."; -// -// double delay_error_samples = std::abs(expected_delay_samples - gnss_synchro.Acq_delay_samples); -// float delay_error_chips = static_cast(delay_error_samples * 1023 / 4000); -// double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro.Acq_doppler_hz); -// -// EXPECT_LE(doppler_error_hz, 666) << "Doppler error exceeds the expected value: 666 Hz = 2/(3*integration period)"; -// EXPECT_LT(delay_error_chips, 0.5) << "Delay error exceeds the expected value: 0.5 chips"; -// -// /*if (FLAGS_plot_acq_grid == true) -// { -// plot_grid(); -// }*/ -//} From bc0b267acc4c14c0bc2c08b5b5f4d75b0df127c4 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 26 Jun 2018 08:43:22 +0200 Subject: [PATCH 28/40] Add work on acq performance test --- .../gps_l1_acq_performance_test.cc | 349 ++++++++++-------- 1 file changed, 204 insertions(+), 145 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index 529514c88..bfb6c3974 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -34,6 +34,9 @@ #include "tracking_true_obs_reader.h" #include "true_observables_reader.h" #include "display.h" +#include // for create_directories, exists +//#include // for path, operator<< +#include // for filesystem #include #include #include @@ -118,20 +121,24 @@ protected: stop = false; acquisition = 0; init(); + Pd.resize(cn0_.size()); + for (int i = 0; i < cn0_.size(); i++) Pd[i].reserve(num_thresholds); + Pfa.resize(cn0_.size()); + for (int i = 0; i < cn0_.size(); i++) Pfa[i].reserve(num_thresholds); } ~AcquisitionPerformanceTest() { } - std::vector cn0_ = {38.0, 40.0, 43.0}; + std::vector cn0_ = {35.0, 38.0, 43.0}; int N_iterations = 1; void init(); //void plot_grid(); int configure_generator(double cn0); int generate_signal(); - int configure_receiver(double cn0, unsigned int iter); + int configure_receiver(double cn0, float pfa, unsigned int iter); void start_queue(); void wait_message(); void process_message(); @@ -173,6 +180,16 @@ protected: unsigned int realization_counter; unsigned int observed_satellite = FLAGS_acq_test_PRN; + std::string path_str = "./acq-perf-test"; + + //std::vector> meas_Pd; + //std::vector> meas_Pd_correct; + //std::vector> meas_Pfa; + + int num_thresholds = 1; + std::vector> Pd; + std::vector> Pfa; + private: std::string generator_binary; @@ -293,7 +310,7 @@ int AcquisitionPerformanceTest::generate_signal() } -int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter) +int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsigned int iter) { if (FLAGS_config_file_ptest.empty()) { @@ -392,7 +409,7 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); config->set_property("Acquisition_1C.threshold", std::to_string(threshold)); - if (FLAGS_acq_test_pfa > 0.0) config->set_property("Acquisition_1C.pfa", std::to_string(FLAGS_acq_test_pfa)); + if (FLAGS_acq_test_pfa > 0.0) config->force_set_property("Acquisition_1C.pfa", std::to_string(pfa)); config->set_property("Acquisition_1C.use_CFAR_algorithm", "true"); @@ -416,7 +433,7 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter config->set_property("Acquisition_1C.second_doppler_step", std::to_string(125)); config->set_property("Acquisition_1C.dump", "true"); - std::string dump_file = std::string("./acquisition_") + std::to_string(cn0) + "_" + std::to_string(iter); + std::string dump_file = path_str + std::string("/acquisition_") + std::to_string(cn0) + "_" + std::to_string(iter) + "_" + std::to_string(pfa); config->set_property("Acquisition_1C.dump_filename", dump_file); config->set_property("Acquisition_1C.dump_channel", std::to_string(dump_channel)); @@ -477,8 +494,6 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, unsigned int iter int AcquisitionPerformanceTest::run_receiver() { - std::chrono::time_point start, end; - std::chrono::duration elapsed_seconds(0); 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); @@ -514,10 +529,7 @@ int AcquisitionPerformanceTest::run_receiver() start_queue(); - start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait - end = std::chrono::system_clock::now(); - elapsed_seconds = end - start; #ifdef OLD_BOOST ch_thread.timed_join(boost::posix_time::seconds(1)); @@ -526,8 +538,6 @@ int AcquisitionPerformanceTest::run_receiver() ch_thread.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(50)); #endif - //std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; - return 0; } @@ -587,180 +597,229 @@ int AcquisitionPerformanceTest::count_executions(const std::string& basename, un TEST_F(AcquisitionPerformanceTest, PdvsCn0) { tracking_true_obs_reader true_trk_data; + + if (boost::filesystem::exists(path_str)) + { + boost::filesystem::remove_all(path_str); + } + boost::system::error_code ec; + if (!boost::filesystem::create_directory(path_str, ec)) + { + std::cout << "Could not create the " << path_str << " folder." << std::endl; + // error + } + unsigned int cn0_index = 0; for (std::vector::const_iterator it = cn0_.cbegin(); it != cn0_.cend(); ++it) { // Do N_iterations of the experiment + std::vector pfa_local = {0.01}; //{FLAGS_acq_test_pfa}; //{0.001, 0.01, 0.1, 1}; + std::vector meas_Pd_; + std::vector meas_Pd_correct_; + std::vector meas_Pfa_; for (unsigned iter = 0; iter < N_iterations; iter++) { - std::string basename = std::string("./acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + gnss_synchro.System + "_1C"; + // Set parameter to sweep - // Configure the signal generator - configure_generator(*it); - // Generate signal raw signal samples and observations RINEX file - generate_signal(); - - std::cout << "Execution for CN0 = " << *it << " dB-Hz" << std::endl; - for (unsigned k = 0; k < 2; k++) + for (int pfa_iter = 0; pfa_iter < pfa_local.size(); pfa_iter++) { - if (k == 0) + std::string basename = path_str + std::string("/acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + std::to_string(pfa_local[pfa_iter]) + "_" + gnss_synchro.System + "_1C"; + + // Configure the signal generator + configure_generator(*it); + + // Generate signal raw signal samples and observations RINEX file + generate_signal(); + + std::cout << "Execution for CN0 = " << *it << " dB-Hz" << std::endl; + for (unsigned k = 0; k < 2; k++) { - observed_satellite = FLAGS_acq_test_PRN; - } - else - { - observed_satellite = FLAGS_acq_test_fake_PRN; - } - init(); - - // Configure the receiver - configure_receiver(*it, iter); - - // Run it - run_receiver(); - - // count executions - int num_executions = count_executions(basename, observed_satellite); - - // Read measured data - int ch = config->property("Acquisition_1C.dump_channel", 0); - arma::vec meas_timestamp_s = arma::zeros(num_executions, 1); - arma::vec meas_doppler = arma::zeros(num_executions, 1); - arma::vec positive_acq = arma::zeros(num_executions, 1); - arma::vec meas_acq_delay_chips = arma::zeros(num_executions, 1); - - double coh_time_ms = config->property("Acquisition_1C.coherent_integration_time_ms", 1); - - std::cout << "Num executions: " << num_executions << std::endl; - for (int execution = 1; execution <= num_executions; execution++) - { - acquisition_dump_reader acq_dump(basename, observed_satellite, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * GPS_L1_CA_CODE_PERIOD * static_cast(coh_time_ms), ch, execution); - acq_dump.read_binary_acq(); - if (acq_dump.positive_acq) + if (k == 0) { - //std::cout << "Meas acq_delay_samples: " << acq_dump.acq_delay_samples << " chips: " << acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS) << std::endl; - meas_timestamp_s(execution - 1) = acq_dump.sample_counter / baseband_sampling_freq; - meas_doppler(execution - 1) = acq_dump.acq_doppler_hz; - meas_acq_delay_chips(execution - 1) = acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS); - positive_acq(execution - 1) = acq_dump.positive_acq; + observed_satellite = FLAGS_acq_test_PRN; } else { - //std::cout << "Failed acquisition." << std::endl; - meas_timestamp_s(execution - 1) = arma::datum::inf; - meas_doppler(execution - 1) = arma::datum::inf; - meas_acq_delay_chips(execution - 1) = arma::datum::inf; - positive_acq(execution - 1) = acq_dump.positive_acq; + observed_satellite = FLAGS_acq_test_fake_PRN; } - } + init(); - // Read reference data - std::string true_trk_file = std::string("./gps_l1_ca_obs_prn"); - true_trk_file.append(std::to_string(observed_satellite)); - true_trk_file.append(".dat"); - true_trk_data.close_obs_file(); - true_trk_data.open_obs_file(true_trk_file); + // Configure the receiver + configure_receiver(*it, pfa_local[pfa_iter], iter); - // load the true values - long int n_true_epochs = true_trk_data.num_epochs(); - arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); - arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); - arma::vec true_Doppler_Hz = arma::zeros(n_true_epochs, 1); - arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); - arma::vec true_tow_s = arma::zeros(n_true_epochs, 1); + // Run it + run_receiver(); - long int epoch_counter = 0; - int num_clean_executions = 0; - while (true_trk_data.read_binary_obs()) - { - true_timestamp_s(epoch_counter) = true_trk_data.signal_timestamp_s; - true_acc_carrier_phase_cycles(epoch_counter) = true_trk_data.acc_carrier_phase_cycles; - true_Doppler_Hz(epoch_counter) = true_trk_data.doppler_l1_hz; - true_prn_delay_chips(epoch_counter) = GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips; - true_tow_s(epoch_counter) = true_trk_data.tow; - epoch_counter++; - //std::cout << "True PRN_Delay chips = " << GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips << " at " << true_trk_data.signal_timestamp_s << std::endl; - } + // count executions + int num_executions = count_executions(basename, observed_satellite); - // Process results - arma::vec clean_doppler_estimation_error; - arma::vec clean_delay_estimation_error; - if (epoch_counter > 2) - { - arma::vec true_interpolated_doppler = arma::zeros(num_executions, 1); - arma::vec true_interpolated_prn_delay_chips = arma::zeros(num_executions, 1); - interp1(true_timestamp_s, true_Doppler_Hz, meas_timestamp_s, true_interpolated_doppler); - interp1(true_timestamp_s, true_prn_delay_chips, meas_timestamp_s, true_interpolated_prn_delay_chips); + // Read measured data + int ch = config->property("Acquisition_1C.dump_channel", 0); + arma::vec meas_timestamp_s = arma::zeros(num_executions, 1); + arma::vec meas_doppler = arma::zeros(num_executions, 1); + arma::vec positive_acq = arma::zeros(num_executions, 1); + arma::vec meas_acq_delay_chips = arma::zeros(num_executions, 1); - arma::vec doppler_estimation_error = true_interpolated_doppler - meas_doppler; - arma::vec delay_estimation_error = true_interpolated_prn_delay_chips - (meas_acq_delay_chips - ((1.0 / baseband_sampling_freq) / GPS_L1_CA_CHIP_PERIOD)); // compensate 1 sample delay + double coh_time_ms = config->property("Acquisition_1C.coherent_integration_time_ms", 1); - // Cut measurements without reference - for (unsigned int i = 0; i < num_executions; i++) + std::cout << "Num executions: " << num_executions << std::endl; + for (int execution = 1; execution <= num_executions; execution++) { - if (!std::isnan(doppler_estimation_error(i)) and !std::isnan(delay_estimation_error(i))) + acquisition_dump_reader acq_dump(basename, observed_satellite, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * GPS_L1_CA_CODE_PERIOD * static_cast(coh_time_ms), ch, execution); + acq_dump.read_binary_acq(); + if (acq_dump.positive_acq) { - num_clean_executions++; + //std::cout << "Meas acq_delay_samples: " << acq_dump.acq_delay_samples << " chips: " << acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS) << std::endl; + meas_timestamp_s(execution - 1) = acq_dump.sample_counter / baseband_sampling_freq; + meas_doppler(execution - 1) = acq_dump.acq_doppler_hz; + meas_acq_delay_chips(execution - 1) = acq_dump.acq_delay_samples / (baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD / GPS_L1_CA_CODE_LENGTH_CHIPS); + positive_acq(execution - 1) = acq_dump.positive_acq; } - } - clean_doppler_estimation_error = arma::zeros(num_clean_executions, 1); - clean_delay_estimation_error = arma::zeros(num_clean_executions, 1); - num_clean_executions = 0; - for (unsigned int i = 0; i < num_executions; i++) - { - if (!std::isnan(doppler_estimation_error(i)) and !std::isnan(delay_estimation_error(i))) + else { - clean_doppler_estimation_error(num_clean_executions) = doppler_estimation_error(i); - clean_delay_estimation_error(num_clean_executions) = delay_estimation_error(i); - num_clean_executions++; + //std::cout << "Failed acquisition." << std::endl; + meas_timestamp_s(execution - 1) = arma::datum::inf; + meas_doppler(execution - 1) = arma::datum::inf; + meas_acq_delay_chips(execution - 1) = arma::datum::inf; + positive_acq(execution - 1) = acq_dump.positive_acq; } } - std::cout << "Doppler estimation error [Hz]: "; - for (int i = 0; i < num_executions - 1; i++) + // Read reference data + std::string true_trk_file = std::string("./gps_l1_ca_obs_prn"); + true_trk_file.append(std::to_string(observed_satellite)); + true_trk_file.append(".dat"); + true_trk_data.close_obs_file(); + true_trk_data.open_obs_file(true_trk_file); + + // load the true values + long int n_true_epochs = true_trk_data.num_epochs(); + arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); + arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); + arma::vec true_Doppler_Hz = arma::zeros(n_true_epochs, 1); + arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); + arma::vec true_tow_s = arma::zeros(n_true_epochs, 1); + + long int epoch_counter = 0; + int num_clean_executions = 0; + while (true_trk_data.read_binary_obs()) { - std::cout << doppler_estimation_error(i) << " "; + true_timestamp_s(epoch_counter) = true_trk_data.signal_timestamp_s; + true_acc_carrier_phase_cycles(epoch_counter) = true_trk_data.acc_carrier_phase_cycles; + true_Doppler_Hz(epoch_counter) = true_trk_data.doppler_l1_hz; + true_prn_delay_chips(epoch_counter) = GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips; + true_tow_s(epoch_counter) = true_trk_data.tow; + epoch_counter++; + //std::cout << "True PRN_Delay chips = " << GPS_L1_CA_CODE_LENGTH_CHIPS - true_trk_data.prn_delay_chips << " at " << true_trk_data.signal_timestamp_s << std::endl; } - std::cout << std::endl; - std::cout << "Delay estimation error [chips]: "; - for (int i = 0; i < num_executions - 1; i++) + // Process results + arma::vec clean_doppler_estimation_error; + arma::vec clean_delay_estimation_error; + std::vector meas_Pd_; + std::vector meas_Pd_correct_; + if (epoch_counter > 2) { - std::cout << delay_estimation_error(i) << " "; - } - std::cout << std::endl; + arma::vec true_interpolated_doppler = arma::zeros(num_executions, 1); + arma::vec true_interpolated_prn_delay_chips = arma::zeros(num_executions, 1); + interp1(true_timestamp_s, true_Doppler_Hz, meas_timestamp_s, true_interpolated_doppler); + interp1(true_timestamp_s, true_prn_delay_chips, meas_timestamp_s, true_interpolated_prn_delay_chips); - double detected = arma::accu(positive_acq); - std::cout << TEXT_BOLD_BLACK << "Probability of detection for channel=" << ch << ", CN0=" << *it << " dBHz" - << ": " << (num_executions > 0 ? (detected / num_executions) : 0.0) << TEXT_RESET << std::endl; - } - if (num_clean_executions > 0) - { - arma::vec correct_acq = arma::zeros(num_executions, 1); - double correctly_detected = 0.0; - for (int i = 0; i < num_clean_executions - 1; i++) + arma::vec doppler_estimation_error = true_interpolated_doppler - meas_doppler; + arma::vec delay_estimation_error = true_interpolated_prn_delay_chips - (meas_acq_delay_chips - ((1.0 / baseband_sampling_freq) / GPS_L1_CA_CHIP_PERIOD)); // compensate 1 sample delay - { - if (abs(clean_delay_estimation_error(i)) < 0.5 and abs(clean_doppler_estimation_error(i)) < static_cast(config->property("Acquisition_1C.doppler_step", 1)) / 2.0) + // Cut measurements without reference + for (unsigned int i = 0; i < num_executions; i++) { - correctly_detected = correctly_detected + 1.0; + if (!std::isnan(doppler_estimation_error(i)) and !std::isnan(delay_estimation_error(i))) + { + num_clean_executions++; + } + } + clean_doppler_estimation_error = arma::zeros(num_clean_executions, 1); + clean_delay_estimation_error = arma::zeros(num_clean_executions, 1); + num_clean_executions = 0; + for (unsigned int i = 0; i < num_executions; i++) + { + if (!std::isnan(doppler_estimation_error(i)) and !std::isnan(delay_estimation_error(i))) + { + clean_doppler_estimation_error(num_clean_executions) = doppler_estimation_error(i); + clean_delay_estimation_error(num_clean_executions) = delay_estimation_error(i); + num_clean_executions++; + } + } + + std::cout << "Doppler estimation error [Hz]: "; + for (int i = 0; i < num_executions - 1; i++) + { + std::cout << doppler_estimation_error(i) << " "; + } + std::cout << std::endl; + + std::cout << "Delay estimation error [chips]: "; + for (int i = 0; i < num_executions - 1; i++) + { + std::cout << delay_estimation_error(i) << " "; + } + std::cout << std::endl; + } + if (k == 0) + { + double detected = arma::accu(positive_acq); + if (num_executions > 0) meas_Pd_.push_back(static_cast(detected / num_executions)); + std::cout << TEXT_BOLD_BLACK << "Probability of detection for channel=" << ch << ", CN0=" << *it << " dBHz" + << ": " << (num_executions > 0 ? (detected / num_executions) : 0.0) << TEXT_RESET << std::endl; + } + if (num_clean_executions > 0) + { + arma::vec correct_acq = arma::zeros(num_executions, 1); + double correctly_detected = 0.0; + for (int i = 0; i < num_clean_executions - 1; i++) + + { + if (abs(clean_delay_estimation_error(i)) < 0.5 and abs(clean_doppler_estimation_error(i)) < static_cast(config->property("Acquisition_1C.doppler_step", 1)) / 2.0) + { + correctly_detected = correctly_detected + 1.0; + } + } + std::cout << TEXT_BOLD_BLACK << "Probability of correct detection for channel=" << ch << ", CN0=" << *it << " dBHz" + << ": " << (num_clean_executions > 0 ? (correctly_detected / num_clean_executions) : 0.0) << TEXT_RESET << std::endl; + } + else + { + // std::cout << "No reference data has been found. Maybe a non-present satellite?" << std::endl; + if (k == 1) + { + double wrongly_detected = arma::accu(positive_acq); + if (num_executions > 0) meas_Pfa_.push_back(static_cast(wrongly_detected / num_executions)); + std::cout + << TEXT_BOLD_BLACK << "Probability of false alarm for channel=" << ch << ", CN0=" << *it << " dBHz" + << ": " << (num_executions > 0 ? (wrongly_detected / num_executions) : 0.0) << TEXT_RESET << std::endl; } } - std::cout << TEXT_BOLD_BLACK << "Probability of correct detection for channel=" << ch << ", CN0=" << *it << " dBHz" - << ": " << (num_clean_executions > 0 ? (correctly_detected / num_clean_executions) : 0.0) << TEXT_RESET << std::endl; + true_trk_data.restart(); } - else - { - std::cout << "No reference data has been found. Maybe a non-present satellite?" << std::endl; - double wrongly_detected = arma::accu(positive_acq); - std::cout << TEXT_BOLD_BLACK << "Probability of false alarm for channel=" << ch << ", CN0=" << *it << " dBHz" - << ": " << (num_executions > 0 ? (wrongly_detected / num_executions) : 0.0) << TEXT_RESET << std::endl; - } - true_trk_data.restart(); + float sum_ = static_cast(std::accumulate(meas_Pd_.begin(), meas_Pd_.end(), 0.0)); + Pd[cn0_index][pfa_iter] = sum_ / static_cast(meas_Pd_.size()); + sum_ = static_cast(std::accumulate(meas_Pfa_.begin(), meas_Pfa_.end(), 0.0)); + Pfa[cn0_index][pfa_iter] = sum_ / static_cast(meas_Pfa_.size()); + cn0_index++; } } true_trk_data.close_obs_file(); // Compute results } + unsigned int aux_index = 0; + for (std::vector::const_iterator it = cn0_.cbegin(); it != cn0_.cend(); ++it) + { + std::cout << "Results for CN0 = " << *it << " dBHz:" << std::endl; + std::cout << "Pd = "; + for (int pfa_iter = 0; pfa_iter < 1; pfa_iter++) + { + std::cout << Pd[aux_index][pfa_iter] << " "; + } + std::cout << std::endl; + aux_index++; + } } From 09ef8dc1f1ba13d597cad55e8bd2d1ed095c9a42 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 27 Jun 2018 08:07:42 +0200 Subject: [PATCH 29/40] Add work on acq performance test --- .../gps_l1_acq_performance_test.cc | 300 ++++++------------ 1 file changed, 102 insertions(+), 198 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index bfb6c3974..c9459763d 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -49,6 +49,7 @@ DEFINE_int32(acq_test_PRN, 1, "PRN number"); DEFINE_int32(acq_test_fake_PRN, 33, "Fake PRN number"); DEFINE_int32(acq_test_signal_duration_s, 2, "Generated signal duration"); DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag"); +DEFINE_int32(acq_test_iterations, 1, "Number of iterations"); // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class AcqPerfTest_msg_rx; @@ -122,9 +123,11 @@ protected: acquisition = 0; init(); Pd.resize(cn0_.size()); - for (int i = 0; i < cn0_.size(); i++) Pd[i].reserve(num_thresholds); + for (int i = 0; i < static_cast(cn0_.size()); i++) Pd[i].reserve(num_thresholds); Pfa.resize(cn0_.size()); - for (int i = 0; i < cn0_.size(); i++) Pfa[i].reserve(num_thresholds); + for (int i = 0; i < static_cast(cn0_.size()); i++) Pfa[i].reserve(num_thresholds); + Pd_correct.resize(cn0_.size()); + for (int i = 0; i < static_cast(cn0_.size()); i++) Pd_correct[i].reserve(num_thresholds); } ~AcquisitionPerformanceTest() @@ -132,7 +135,8 @@ protected: } std::vector cn0_ = {35.0, 38.0, 43.0}; - int N_iterations = 1; + std::vector pfa_local = {0.01, 0.1}; //{FLAGS_acq_test_pfa}; //{0.001, 0.01, 0.1, 1}; + int N_iterations = FLAGS_acq_test_iterations; void init(); //void plot_grid(); @@ -144,7 +148,6 @@ protected: void process_message(); void stop_queue(); int run_receiver(); - int run_receiver2(); int count_executions(const std::string& basename, unsigned int sat); void check_results(); @@ -182,13 +185,11 @@ protected: unsigned int observed_satellite = FLAGS_acq_test_PRN; std::string path_str = "./acq-perf-test"; - //std::vector> meas_Pd; - //std::vector> meas_Pd_correct; - //std::vector> meas_Pfa; + int num_thresholds = pfa_local.size(); - int num_thresholds = 1; std::vector> Pd; std::vector> Pfa; + std::vector> Pd_correct; private: @@ -317,91 +318,8 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign config = std::make_shared(); const int sampling_rate_internal = baseband_sampling_freq; - const int number_of_taps = 11; - const int number_of_bands = 2; - const float band1_begin = 0.0; - const float band1_end = 0.48; - const float band2_begin = 0.52; - const float band2_end = 1.0; - const float ampl1_begin = 1.0; - const float ampl1_end = 1.0; - const float ampl2_begin = 0.0; - const float ampl2_end = 0.0; - const float band1_error = 1.0; - const float band2_error = 1.0; - const int grid_density = 16; - - const float zero = 0.0; - - - const float pll_bw_hz = 30.0; - const float dll_bw_hz = 4.0; - const float early_late_space_chips = 0.5; - const float pll_bw_narrow_hz = 20.0; - const float dll_bw_narrow_hz = 2.0; - const int extend_correlation_ms = 1; - - const int display_rate_ms = 500; - const int output_rate_ms = 100; - config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(sampling_rate_internal)); - // Set the assistance system parameters - config->set_property("GNSS-SDR.SUPL_read_gps_assistance_xml", "false"); - config->set_property("GNSS-SDR.SUPL_gps_enabled", "false"); - config->set_property("GNSS-SDR.SUPL_gps_ephemeris_server", "supl.google.com"); - config->set_property("GNSS-SDR.SUPL_gps_ephemeris_port", std::to_string(7275)); - config->set_property("GNSS-SDR.SUPL_gps_acquisition_server", "supl.google.com"); - config->set_property("GNSS-SDR.SUPL_gps_acquisition_port", std::to_string(7275)); - config->set_property("GNSS-SDR.SUPL_MCC", std::to_string(244)); - config->set_property("GNSS-SDR.SUPL_MNS", std::to_string(5)); - config->set_property("GNSS-SDR.SUPL_LAC", "0x59e2"); - config->set_property("GNSS-SDR.SUPL_CI", "0x31b0"); - - // Set the Signal Source - config->set_property("SignalSource.implementation", "File_Signal_Source"); - config->set_property("SignalSource.filename", "./" + filename_raw_data); - config->set_property("SignalSource.sampling_frequency", std::to_string(sampling_rate_internal)); - config->set_property("SignalSource.item_type", "ibyte"); - config->set_property("SignalSource.samples", std::to_string(zero)); - - // Set the Signal Conditioner - config->set_property("SignalConditioner.implementation", "Signal_Conditioner"); - config->set_property("DataTypeAdapter.implementation", "Ibyte_To_Complex"); - //config->set_property("InputFilter.implementation", "Fir_Filter"); - config->set_property("InputFilter.implementation", "Pass_Through"); - config->set_property("InputFilter.dump", "false"); - config->set_property("InputFilter.input_item_type", "gr_complex"); - config->set_property("InputFilter.output_item_type", "gr_complex"); - config->set_property("InputFilter.taps_item_type", "float"); - config->set_property("InputFilter.number_of_taps", std::to_string(number_of_taps)); - config->set_property("InputFilter.number_of_bands", std::to_string(number_of_bands)); - config->set_property("InputFilter.band1_begin", std::to_string(band1_begin)); - config->set_property("InputFilter.band1_end", std::to_string(band1_end)); - config->set_property("InputFilter.band2_begin", std::to_string(band2_begin)); - config->set_property("InputFilter.band2_end", std::to_string(band2_end)); - config->set_property("InputFilter.ampl1_begin", std::to_string(ampl1_begin)); - config->set_property("InputFilter.ampl1_end", std::to_string(ampl1_end)); - config->set_property("InputFilter.ampl2_begin", std::to_string(ampl2_begin)); - config->set_property("InputFilter.ampl2_end", std::to_string(ampl2_end)); - config->set_property("InputFilter.band1_error", std::to_string(band1_error)); - config->set_property("InputFilter.band2_error", std::to_string(band2_error)); - config->set_property("InputFilter.filter_type", "bandpass"); - config->set_property("InputFilter.grid_density", std::to_string(grid_density)); - config->set_property("InputFilter.sampling_frequency", std::to_string(sampling_rate_internal)); - config->set_property("InputFilter.IF", std::to_string(zero)); - config->set_property("Resampler.implementation", "Pass_Through"); - config->set_property("Resampler.dump", "false"); - config->set_property("Resampler.item_type", "gr_complex"); - config->set_property("Resampler.sample_freq_in", std::to_string(sampling_rate_internal)); - config->set_property("Resampler.sample_freq_out", std::to_string(sampling_rate_internal)); - - // Set the number of Channels - config->set_property("Channels_1C.count", std::to_string(number_of_channels)); - config->set_property("Channels.in_acquisition", std::to_string(in_acquisition)); - config->set_property("Channel.signal", "1C"); - //config->set_property("Channel1.satellite", std::to_string(FLAGS_acq_test_PRN)); - // Set Acquisition config->set_property("Acquisition_1C.implementation", implementation); config->set_property("Acquisition_1C.item_type", "gr_complex"); @@ -409,7 +327,7 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); config->set_property("Acquisition_1C.threshold", std::to_string(threshold)); - if (FLAGS_acq_test_pfa > 0.0) config->force_set_property("Acquisition_1C.pfa", std::to_string(pfa)); + if (FLAGS_acq_test_pfa > 0.0) config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); config->set_property("Acquisition_1C.use_CFAR_algorithm", "true"); @@ -437,50 +355,6 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign config->set_property("Acquisition_1C.dump_filename", dump_file); config->set_property("Acquisition_1C.dump_channel", std::to_string(dump_channel)); - // Set Tracking - config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_Tracking"); - //config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_C_Aid_Tracking"); - config->set_property("Tracking_1C.item_type", "gr_complex"); - config->set_property("Tracking_1C.dump", "false"); - config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); - config->set_property("Tracking_1C.pll_bw_hz", std::to_string(pll_bw_hz)); - config->set_property("Tracking_1C.dll_bw_hz", std::to_string(dll_bw_hz)); - config->set_property("Tracking_1C.early_late_space_chips", std::to_string(early_late_space_chips)); - - config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(pll_bw_narrow_hz)); - config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(dll_bw_narrow_hz)); - config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(extend_correlation_ms)); - config->set_property("Tracking_1C.cn0_min", std::to_string(50)); - config->set_property("Tracking_1C.max_lock_fail", std::to_string(1)); - config->set_property("Tracking_1C.cn0_samples", std::to_string(1)); - - // Set Telemetry - config->set_property("TelemetryDecoder_1C.implementation", "GPS_L1_CA_Telemetry_Decoder"); - config->set_property("TelemetryDecoder_1C.dump", "false"); - - // Set Observables - config->set_property("Observables.implementation", "Hybrid_Observables"); - config->set_property("Observables.dump", "false"); - config->set_property("Observables.dump_filename", "./observables.dat"); - - // Set PVT - config->set_property("PVT.implementation", "RTKLIB_PVT"); - config->set_property("PVT.positioning_mode", "PPP_Static"); - config->set_property("PVT.output_rate_ms", std::to_string(output_rate_ms)); - config->set_property("PVT.display_rate_ms", std::to_string(display_rate_ms)); - config->set_property("PVT.dump_filename", "./PVT"); - config->set_property("PVT.nmea_dump_filename", "./gnss_sdr_pvt.nmea"); - config->set_property("PVT.flag_nmea_tty_port", "false"); - config->set_property("PVT.nmea_dump_devname", "/dev/pts/4"); - config->set_property("PVT.flag_rtcm_server", "false"); - config->set_property("PVT.flag_rtcm_tty_port", "false"); - config->set_property("PVT.rtcm_dump_devname", "/dev/pts/1"); - config->set_property("PVT.dump", "false"); - config->set_property("PVT.rinex_version", std::to_string(2)); - config->set_property("PVT.iono_model", "OFF"); - config->set_property("PVT.trop_model", "OFF"); - config->set_property("PVT.AR_GPS", "PPP-AR"); - config_f = 0; } else @@ -542,35 +416,6 @@ int AcquisitionPerformanceTest::run_receiver() } -int AcquisitionPerformanceTest::run_receiver2() -{ - std::shared_ptr control_thread; - if (FLAGS_config_file_ptest.empty()) - { - control_thread = std::make_shared(config); - } - else - { - control_thread = std::make_shared(config_f); - } - - // start receiver - try - { - control_thread->run(); - } - catch (const boost::exception& e) - { - std::cout << "Boost exception: " << boost::diagnostic_information(e); - } - catch (const std::exception& ex) - { - std::cout << "STD exception: " << ex.what(); - } - return 0; -} - - int AcquisitionPerformanceTest::count_executions(const std::string& basename, unsigned int sat) { FILE* fp; @@ -603,35 +448,34 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) boost::filesystem::remove_all(path_str); } boost::system::error_code ec; - if (!boost::filesystem::create_directory(path_str, ec)) - { - std::cout << "Could not create the " << path_str << " folder." << std::endl; - // error - } + ASSERT_TRUE(boost::filesystem::create_directory(path_str, ec)) << "Could not create the " << path_str << " folder."; + unsigned int cn0_index = 0; + //for (unsigned iter = 0; iter < N_iterations; iter++) + //unsigned iter = 0; + //{ for (std::vector::const_iterator it = cn0_.cbegin(); it != cn0_.cend(); ++it) { // Do N_iterations of the experiment - std::vector pfa_local = {0.01}; //{FLAGS_acq_test_pfa}; //{0.001, 0.01, 0.1, 1}; + std::vector meas_Pd_; std::vector meas_Pd_correct_; std::vector meas_Pfa_; - for (unsigned iter = 0; iter < N_iterations; iter++) + + // Set parameter to sweep + std::cout << "Execution for CN0 = " << *it << " dB-Hz" << std::endl; + for (int pfa_iter = 0; pfa_iter < static_cast(pfa_local.size()); pfa_iter++) { - // Set parameter to sweep - - - for (int pfa_iter = 0; pfa_iter < pfa_local.size(); pfa_iter++) + for (int iter = 0; iter < N_iterations; iter++) { std::string basename = path_str + std::string("/acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + std::to_string(pfa_local[pfa_iter]) + "_" + gnss_synchro.System + "_1C"; - // Configure the signal generator configure_generator(*it); // Generate signal raw signal samples and observations RINEX file generate_signal(); - std::cout << "Execution for CN0 = " << *it << " dB-Hz" << std::endl; + //std::cout << "Execution for CN0 = " << *it << " dB-Hz" << std::endl; for (unsigned k = 0; k < 2; k++) { if (k == 0) @@ -716,8 +560,7 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) // Process results arma::vec clean_doppler_estimation_error; arma::vec clean_delay_estimation_error; - std::vector meas_Pd_; - std::vector meas_Pd_correct_; + if (epoch_counter > 2) { arma::vec true_interpolated_doppler = arma::zeros(num_executions, 1); @@ -729,7 +572,7 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) arma::vec delay_estimation_error = true_interpolated_prn_delay_chips - (meas_acq_delay_chips - ((1.0 / baseband_sampling_freq) / GPS_L1_CA_CHIP_PERIOD)); // compensate 1 sample delay // Cut measurements without reference - for (unsigned int i = 0; i < num_executions; i++) + for (int i = 0; i < num_executions; i++) { if (!std::isnan(doppler_estimation_error(i)) and !std::isnan(delay_estimation_error(i))) { @@ -739,7 +582,7 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) clean_doppler_estimation_error = arma::zeros(num_clean_executions, 1); clean_delay_estimation_error = arma::zeros(num_clean_executions, 1); num_clean_executions = 0; - for (unsigned int i = 0; i < num_executions; i++) + for (int i = 0; i < num_executions; i++) { if (!std::isnan(doppler_estimation_error(i)) and !std::isnan(delay_estimation_error(i))) { @@ -766,9 +609,17 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) if (k == 0) { double detected = arma::accu(positive_acq); - if (num_executions > 0) meas_Pd_.push_back(static_cast(detected / num_executions)); + double computed_Pd = detected / static_cast(num_executions); + if (num_executions > 0) + { + meas_Pd_.push_back(computed_Pd); + } + else + { + meas_Pd_.push_back(0.0); + } std::cout << TEXT_BOLD_BLACK << "Probability of detection for channel=" << ch << ", CN0=" << *it << " dBHz" - << ": " << (num_executions > 0 ? (detected / num_executions) : 0.0) << TEXT_RESET << std::endl; + << ": " << (num_executions > 0 ? computed_Pd : 0.0) << TEXT_RESET << std::endl; } if (num_clean_executions > 0) { @@ -782,8 +633,10 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) correctly_detected = correctly_detected + 1.0; } } + double computed_Pd_correct = correctly_detected / static_cast(num_clean_executions); + meas_Pd_correct_.push_back(computed_Pd_correct); std::cout << TEXT_BOLD_BLACK << "Probability of correct detection for channel=" << ch << ", CN0=" << *it << " dBHz" - << ": " << (num_clean_executions > 0 ? (correctly_detected / num_clean_executions) : 0.0) << TEXT_RESET << std::endl; + << ": " << computed_Pd_correct << TEXT_RESET << std::endl; } else { @@ -791,35 +644,86 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) if (k == 1) { double wrongly_detected = arma::accu(positive_acq); - if (num_executions > 0) meas_Pfa_.push_back(static_cast(wrongly_detected / num_executions)); - std::cout - << TEXT_BOLD_BLACK << "Probability of false alarm for channel=" << ch << ", CN0=" << *it << " dBHz" - << ": " << (num_executions > 0 ? (wrongly_detected / num_executions) : 0.0) << TEXT_RESET << std::endl; + double computed_Pfa = wrongly_detected / static_cast(num_executions); + if (num_executions > 0) + { + meas_Pfa_.push_back(computed_Pfa); + } + else + { + meas_Pfa_.push_back(0.0); + } + std::cout << TEXT_BOLD_BLACK << "Probability of false alarm for channel=" << ch << ", CN0=" << *it << " dBHz" + << ": " << (num_executions > 0 ? computed_Pfa : 0.0) << TEXT_RESET << std::endl; } } true_trk_data.restart(); } - - float sum_ = static_cast(std::accumulate(meas_Pd_.begin(), meas_Pd_.end(), 0.0)); - Pd[cn0_index][pfa_iter] = sum_ / static_cast(meas_Pd_.size()); - sum_ = static_cast(std::accumulate(meas_Pfa_.begin(), meas_Pfa_.end(), 0.0)); - Pfa[cn0_index][pfa_iter] = sum_ / static_cast(meas_Pfa_.size()); - cn0_index++; + } + true_trk_data.close_obs_file(); + float sum_pd = static_cast(std::accumulate(meas_Pd_.begin(), meas_Pd_.end(), 0.0)); + float sum_pd_correct = static_cast(std::accumulate(meas_Pd_correct_.begin(), meas_Pd_correct_.end(), 0.0)); + float sum_pfa = static_cast(std::accumulate(meas_Pfa_.begin(), meas_Pfa_.end(), 0.0)); + if (meas_Pd_.size() > 0 and meas_Pfa_.size() > 0) + { + Pd[cn0_index][pfa_iter] = sum_pd / static_cast(meas_Pd_.size()); + Pfa[cn0_index][pfa_iter] = sum_pfa / static_cast(meas_Pfa_.size()); + } + else + { + if (meas_Pd_.size() > 0) + { + Pd[cn0_index][pfa_iter] = sum_pd / static_cast(meas_Pd_.size()); + } + else + { + Pd[cn0_index][pfa_iter] = 0.0; + } + if (meas_Pfa_.size() > 0) + { + Pfa[cn0_index][pfa_iter] = sum_pfa / static_cast(meas_Pfa_.size()); + } + else + { + Pfa[cn0_index][pfa_iter] = 0.0; + } + } + if (meas_Pd_correct_.size() > 0) + { + Pd_correct[cn0_index][pfa_iter] = sum_pd_correct / static_cast(meas_Pd_correct_.size()); + } + else + { + Pd_correct[cn0_index][pfa_iter] = 0.0; } } - true_trk_data.close_obs_file(); - // Compute results + cn0_index++; } + + // Compute results unsigned int aux_index = 0; for (std::vector::const_iterator it = cn0_.cbegin(); it != cn0_.cend(); ++it) { std::cout << "Results for CN0 = " << *it << " dBHz:" << std::endl; std::cout << "Pd = "; - for (int pfa_iter = 0; pfa_iter < 1; pfa_iter++) + for (int pfa_iter = 0; pfa_iter < num_thresholds; pfa_iter++) { std::cout << Pd[aux_index][pfa_iter] << " "; } std::cout << std::endl; + std::cout << "Pd_correct = "; + for (int pfa_iter = 0; pfa_iter < num_thresholds; pfa_iter++) + { + std::cout << Pd_correct[aux_index][pfa_iter] << " "; + } + std::cout << std::endl; + std::cout << "Pfa = "; + for (int pfa_iter = 0; pfa_iter < num_thresholds; pfa_iter++) + { + std::cout << Pfa[aux_index][pfa_iter] << " "; + } + std::cout << std::endl; + aux_index++; } } From 85810daa74f3d4d46d5a50a0dfc59e3cceb84eda Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 28 Jun 2018 09:18:37 +0200 Subject: [PATCH 30/40] Add work on acq performance test --- .../gps_l1_acq_performance_test.cc | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index c9459763d..572fd5d92 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -34,8 +34,7 @@ #include "tracking_true_obs_reader.h" #include "true_observables_reader.h" #include "display.h" -#include // for create_directories, exists -//#include // for path, operator<< +#include // for create_directories, exists #include // for filesystem #include #include @@ -49,7 +48,7 @@ DEFINE_int32(acq_test_PRN, 1, "PRN number"); DEFINE_int32(acq_test_fake_PRN, 33, "Fake PRN number"); DEFINE_int32(acq_test_signal_duration_s, 2, "Generated signal duration"); DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag"); -DEFINE_int32(acq_test_iterations, 1, "Number of iterations"); +DEFINE_int32(acq_test_iterations, 2, "Number of iterations"); // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class AcqPerfTest_msg_rx; @@ -120,7 +119,7 @@ protected: doppler_max = 5000; doppler_step = 125; stop = false; - acquisition = 0; + //acquisition_ = 0; init(); Pd.resize(cn0_.size()); for (int i = 0; i < static_cast(cn0_.size()); i++) Pd[i].reserve(num_thresholds); @@ -134,8 +133,8 @@ protected: { } - std::vector cn0_ = {35.0, 38.0, 43.0}; - std::vector pfa_local = {0.01, 0.1}; //{FLAGS_acq_test_pfa}; //{0.001, 0.01, 0.1, 1}; + std::vector cn0_ = {35.0}; + std::vector pfa_local = {0.0001, 0.001, 0.01, 0.1, 1}; //{FLAGS_acq_test_pfa}; //{0.001, 0.01, 0.1, 1}; int N_iterations = FLAGS_acq_test_iterations; void init(); //void plot_grid(); @@ -327,8 +326,8 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); config->set_property("Acquisition_1C.threshold", std::to_string(threshold)); - if (FLAGS_acq_test_pfa > 0.0) config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); - + //if (FLAGS_acq_test_pfa > 0.0) config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); + config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); config->set_property("Acquisition_1C.use_CFAR_algorithm", "true"); config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); @@ -451,9 +450,6 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) ASSERT_TRUE(boost::filesystem::create_directory(path_str, ec)) << "Could not create the " << path_str << " folder."; unsigned int cn0_index = 0; - //for (unsigned iter = 0; iter < N_iterations; iter++) - //unsigned iter = 0; - //{ for (std::vector::const_iterator it = cn0_.cbegin(); it != cn0_.cend(); ++it) { // Do N_iterations of the experiment @@ -640,11 +636,12 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) } else { - // std::cout << "No reference data has been found. Maybe a non-present satellite?" << std::endl; + //std::cout << "No reference data has been found. Maybe a non-present satellite?" << num_executions << std::endl; if (k == 1) { double wrongly_detected = arma::accu(positive_acq); double computed_Pfa = wrongly_detected / static_cast(num_executions); + std::cout << computed_Pfa << std::endl; if (num_executions > 0) { meas_Pfa_.push_back(computed_Pfa); @@ -696,6 +693,9 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) { Pd_correct[cn0_index][pfa_iter] = 0.0; } + meas_Pd_.clear(); + meas_Pfa_.clear(); + meas_Pd_correct_.clear(); } cn0_index++; } From db5145f1e7e4d1d878e8ecdcbd54f73a73485396 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 28 Jun 2018 09:20:38 +0200 Subject: [PATCH 31/40] Add possibility to override parameters in InMemoryConfiguration class --- src/core/receiver/in_memory_configuration.cc | 7 +++++++ src/core/receiver/in_memory_configuration.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/core/receiver/in_memory_configuration.cc b/src/core/receiver/in_memory_configuration.cc index 6a2ce8bf8..75b520362 100644 --- a/src/core/receiver/in_memory_configuration.cc +++ b/src/core/receiver/in_memory_configuration.cc @@ -117,6 +117,13 @@ void InMemoryConfiguration::set_property(std::string property_name, std::string } +void InMemoryConfiguration::supersede_property(std::string property_name, std::string value) +{ + properties_.erase(property_name); + properties_.insert(std::make_pair(property_name, value)); +} + + bool InMemoryConfiguration::is_present(std::string property_name) { return (properties_.find(property_name) != properties_.end()); diff --git a/src/core/receiver/in_memory_configuration.h b/src/core/receiver/in_memory_configuration.h index 1850a9d41..59c1f1baf 100644 --- a/src/core/receiver/in_memory_configuration.h +++ b/src/core/receiver/in_memory_configuration.h @@ -63,6 +63,7 @@ public: float property(std::string property_name, float default_value); double property(std::string property_name, double default_value); void set_property(std::string property_name, std::string value); + void supersede_property(std::string property_name, std::string value); bool is_present(std::string property_name); private: From 566611fd5e5147f54a5c39c2b1afbca27e0dad6e Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 28 Jun 2018 16:30:36 +0200 Subject: [PATCH 32/40] Add work on acq performance --- .../gps_l1_acq_performance_test.cc | 93 ++++++++++++++++++- 1 file changed, 88 insertions(+), 5 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index 572fd5d92..e6d0e0626 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -34,8 +34,8 @@ #include "tracking_true_obs_reader.h" #include "true_observables_reader.h" #include "display.h" -#include // for create_directories, exists -#include // for filesystem +#include "gnuplot_i.h" +#include #include #include #include @@ -49,6 +49,7 @@ DEFINE_int32(acq_test_fake_PRN, 33, "Fake PRN number"); DEFINE_int32(acq_test_signal_duration_s, 2, "Generated signal duration"); DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag"); DEFINE_int32(acq_test_iterations, 2, "Number of iterations"); +DEFINE_bool(plot_acq_test, false, "Plots results of AcquisitionPerformanceTest with gnuplot"); // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class AcqPerfTest_msg_rx; @@ -133,8 +134,8 @@ protected: { } - std::vector cn0_ = {35.0}; - std::vector pfa_local = {0.0001, 0.001, 0.01, 0.1, 1}; //{FLAGS_acq_test_pfa}; //{0.001, 0.01, 0.1, 1}; + std::vector cn0_ = {35.0, 38.0}; + std::vector pfa_local = {0.001, 0.01, 1}; //{0.0001, 0.001, 0.01, 0.1, 1}; //{FLAGS_acq_test_pfa}; //{0.001, 0.01, 0.1, 1}; int N_iterations = FLAGS_acq_test_iterations; void init(); //void plot_grid(); @@ -149,6 +150,7 @@ protected: int run_receiver(); int count_executions(const std::string& basename, unsigned int sat); void check_results(); + void plot_results(); concurrent_queue channel_internal_queue; @@ -438,7 +440,86 @@ int AcquisitionPerformanceTest::count_executions(const std::string& basename, un } -TEST_F(AcquisitionPerformanceTest, PdvsCn0) +void AcquisitionPerformanceTest::plot_results() +{ + if (FLAGS_plot_acq_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); + + Gnuplot g1("linespoints"); + g1.set_title("Receiver Operating Characteristic for GPS L1 C/A acquisition"); + g1.cmd("set logscale x"); + g1.cmd("set yrange [0:1]"); + g1.cmd("set grid xtics 0.001 0.01 0.1 1"); + g1.cmd("set grid ytics"); + g1.set_grid(); + g1.set_xlabel("Pfa"); + g1.set_ylabel("Pd"); + for (int i = 0; i < static_cast(cn0_.size()); i++) + { + std::vector Pd_i; + std::vector Pfa_i; + for (int k = 0; k < num_thresholds; k++) + { + Pd_i.push_back(Pd[i][k]); + Pfa_i.push_back(Pd[i][k]); + } + g1.plot_xy(Pfa_i, Pd_i, "CN0 = " + std::to_string(static_cast(cn0_[i])) + " dBHz"); + } + g1.set_legend(); + g1.savetops("ROC"); + g1.savetopdf("ROC", 18); + g1.showonscreen(); // window output + + if (Pd_correct[0].size() > 0) + { + Gnuplot g2("linespoints"); + g2.set_title("Receiver Operating Characteristic for GPS L1 C/A correct acquisition"); + g2.cmd("set logscale x"); + g2.set_xlabel("Pfa"); + g2.set_xlabel("Pd"); + g2.set_grid(); + for (int i = 0; i < static_cast(cn0_.size()); i++) + { + std::vector Pd_i_correct; + std::vector Pfa_i; + for (int k = 0; k < num_thresholds; k++) + { + Pd_i_correct.push_back(Pd_correct[i][k]); + Pfa_i.push_back(Pd[i][k]); + } + g2.plot_xy(Pfa_i, Pd_i_correct, "CN0 = " + std::to_string(static_cast(cn0_[i])) + " dBHz"); + } + g2.set_legend(); + g2.savetops("ROC-correct"); + g2.savetopdf("ROC-correct", 18); + g2.showonscreen(); // window output + } + } + catch (const GnuplotException& ge) + { + std::cout << ge.what() << std::endl; + } + } + } +} + + +TEST_F(AcquisitionPerformanceTest, ROC) { tracking_true_obs_reader true_trk_data; @@ -726,4 +807,6 @@ TEST_F(AcquisitionPerformanceTest, PdvsCn0) aux_index++; } + + plot_results(); } From 5b39cc05f6f0de147d429d18f314190f1a2d050f Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 28 Jun 2018 16:31:09 +0200 Subject: [PATCH 33/40] Fix Telemetry test --- .../telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc b/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc index 184ad30c0..fb502d71b 100644 --- a/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc @@ -293,7 +293,7 @@ void GpsL1CATelemetryDecoderTest::check_results(arma::vec& true_time_s, //2. RMSE //arma::vec err = meas_value - true_value_interp + 0.001; - arma::vec err = meas_value - true_value_interp - 0.001; + arma::vec err = meas_value - true_value_interp; // - 0.001; arma::vec err2 = arma::square(err); double rmse = sqrt(arma::mean(err2)); From b0eb9f3aac81935fcf4322bbf275f2d0a80131b5 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Thu, 28 Jun 2018 17:39:37 +0200 Subject: [PATCH 34/40] Adding a parameter to allow the acquisition engine to block the samples flow in stanby mode, very useful in unit testing (disabled by default) --- .../gnuradio_blocks/pcps_acquisition.cc | 14 ++++++++++---- src/algorithms/acquisition/libs/acq_conf.cc | 1 + src/algorithms/acquisition/libs/acq_conf.h | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 76adfc28c..f89c73541 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -683,8 +683,11 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), gr::thread::scoped_lock lk(d_setlock); if (!d_active or d_worker_active) { - d_sample_counter += d_fft_size * ninput_items[0]; - consume_each(ninput_items[0]); + if (!acq_parameters.blocking_on_stanby) + { + d_sample_counter += d_fft_size * ninput_items[0]; + consume_each(ninput_items[0]); + } if (d_step_two) { d_doppler_center_step_two = static_cast(d_gnss_synchro->Acq_doppler_hz); @@ -708,8 +711,11 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), d_input_power = 0.0; d_test_statistics = 0.0; d_state = 1; - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter - consume_each(ninput_items[0]); + if (!acq_parameters.blocking_on_stanby) + { + d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + consume_each(ninput_items[0]); + } break; } diff --git a/src/algorithms/acquisition/libs/acq_conf.cc b/src/algorithms/acquisition/libs/acq_conf.cc index f44f7a15f..996880408 100644 --- a/src/algorithms/acquisition/libs/acq_conf.cc +++ b/src/algorithms/acquisition/libs/acq_conf.cc @@ -50,4 +50,5 @@ Acq_Conf::Acq_Conf() dump_filename = ""; dump_channel = 0; it_size = sizeof(char); + blocking_on_stanby = false; } diff --git a/src/algorithms/acquisition/libs/acq_conf.h b/src/algorithms/acquisition/libs/acq_conf.h index 7abcb2e98..bb939a652 100644 --- a/src/algorithms/acquisition/libs/acq_conf.h +++ b/src/algorithms/acquisition/libs/acq_conf.h @@ -51,6 +51,7 @@ public: bool use_CFAR_algorithm_flag; bool dump; bool blocking; + bool blocking_on_stanby; //enable it only for unit testing to avoid sample consume on idle status bool make_2_steps; std::string dump_filename; unsigned int dump_channel; From c4f3b6ec318988529e992481e3a24b99cb72d26a Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 29 Jun 2018 13:33:53 +0200 Subject: [PATCH 35/40] Add work on Acq perfromance test --- .../gps_l1_acq_performance_test.cc | 162 +++++++++--------- 1 file changed, 85 insertions(+), 77 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index e6d0e0626..87abc2661 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -40,16 +40,17 @@ #include #include -DEFINE_string(config_file_ptest, std::string(""), "File containing the configuration parameters for the position test."); -DEFINE_double(acq_test_threshold, 0.001, "Acquisition threshold"); -DEFINE_double(acq_test_pfa, -1.0, "Set threshold via probability of false alarm"); -DEFINE_int32(acq_test_coherent_time_ms, 10, "Acquisition coherent time, in ms"); -DEFINE_int32(acq_test_PRN, 1, "PRN number"); -DEFINE_int32(acq_test_fake_PRN, 33, "Fake PRN number"); -DEFINE_int32(acq_test_signal_duration_s, 2, "Generated signal duration"); +DEFINE_string(config_file_ptest, std::string(""), "File containing alternative configuration parameters for the position test."); +//DEFINE_double(acq_test_threshold, 0.001, "Acquisition threshold"); +DEFINE_double(acq_test_pfa_init, 1e-5, "Set initial threshold via probability of false alarm"); +DEFINE_int32(acq_test_coherent_time_ms, 1, "Acquisition coherent time, in ms"); +DEFINE_int32(acq_test_PRN, 1, "PRN number of a present satellite"); +DEFINE_int32(acq_test_fake_PRN, 33, "PRN number of a non-present satellite"); +DEFINE_int32(acq_test_signal_duration_s, 1, "Generated signal duration, in s"); DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag"); -DEFINE_int32(acq_test_iterations, 2, "Number of iterations"); -DEFINE_bool(plot_acq_test, false, "Plots results of AcquisitionPerformanceTest with gnuplot"); +DEFINE_int32(acq_test_iterations, 1, "Number of iterations (same signal, diferent noise realization)"); +DEFINE_bool(plot_acq_test, false, "Plots results with gnuplot, if available"); +DEFINE_bool(acq_test_use_CFAR_algorithm, true, "Use CFAR algorithm"); // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class AcqPerfTest_msg_rx; @@ -120,25 +121,33 @@ protected: doppler_max = 5000; doppler_step = 125; stop = false; - //acquisition_ = 0; init(); - Pd.resize(cn0_.size()); - for (int i = 0; i < static_cast(cn0_.size()); i++) Pd[i].reserve(num_thresholds); - Pfa.resize(cn0_.size()); - for (int i = 0; i < static_cast(cn0_.size()); i++) Pfa[i].reserve(num_thresholds); - Pd_correct.resize(cn0_.size()); - for (int i = 0; i < static_cast(cn0_.size()); i++) Pd_correct[i].reserve(num_thresholds); + pfa_vector.push_back(FLAGS_acq_test_pfa_init); + float aux = 1.0; + while ((FLAGS_acq_test_pfa_init * std::pow(10, aux)) < 1) + { + pfa_vector.push_back(FLAGS_acq_test_pfa_init * std::pow(10, aux)); + aux = aux + 1.0; + } + pfa_vector.push_back(1.0); + num_thresholds = pfa_vector.size(); + Pd.resize(cn0_vector.size()); + for (int i = 0; i < static_cast(cn0_vector.size()); i++) Pd[i].reserve(num_thresholds); + Pfa.resize(cn0_vector.size()); + for (int i = 0; i < static_cast(cn0_vector.size()); i++) Pfa[i].reserve(num_thresholds); + Pd_correct.resize(cn0_vector.size()); + for (int i = 0; i < static_cast(cn0_vector.size()); i++) Pd_correct[i].reserve(num_thresholds); } ~AcquisitionPerformanceTest() { } - std::vector cn0_ = {35.0, 38.0}; - std::vector pfa_local = {0.001, 0.01, 1}; //{0.0001, 0.001, 0.01, 0.1, 1}; //{FLAGS_acq_test_pfa}; //{0.001, 0.01, 0.1, 1}; + std::vector cn0_vector = {35.0, 38.0}; + std::vector pfa_vector; + int N_iterations = FLAGS_acq_test_iterations; void init(); - //void plot_grid(); int configure_generator(double cn0); int generate_signal(); @@ -174,25 +183,24 @@ protected: const int coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; const int number_of_channels = 2; const int in_acquisition = 1; - const float threshold = FLAGS_acq_test_threshold; + const float threshold = 0.001; // FLAGS_acq_test_threshold; const int max_dwells = 1; const int dump_channel = 0; int generated_signal_duration_s = FLAGS_acq_test_signal_duration_s; - unsigned int num_of_realizations = (generated_signal_duration_s * 1000) / FLAGS_acq_test_coherent_time_ms; - unsigned int realization_counter; + unsigned int num_of_realizations = ((generated_signal_duration_s * 1000 - FLAGS_acq_test_coherent_time_ms) / FLAGS_acq_test_coherent_time_ms); + unsigned int realization_counter = 0; unsigned int observed_satellite = FLAGS_acq_test_PRN; std::string path_str = "./acq-perf-test"; - int num_thresholds = pfa_local.size(); + int num_thresholds; std::vector> Pd; std::vector> Pfa; std::vector> Pd_correct; - private: std::string generator_binary; std::string p1; @@ -202,15 +210,11 @@ private: std::string p5; std::string p6; - std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; double compute_stdev_precision(const std::vector& vec); double compute_stdev_accuracy(const std::vector& vec, double ref); - - - //std::string generated_kml_file; }; @@ -237,11 +241,7 @@ void AcquisitionPerformanceTest::wait_message() { while (!stop) { - acquisition->reset(); - acquisition->set_state(1); - channel_internal_queue.wait_and_pop(message); - process_message(); } } @@ -252,7 +252,7 @@ void AcquisitionPerformanceTest::process_message() realization_counter++; acquisition->reset(); acquisition->set_state(1); - + std::cout << "Progress: " << round(static_cast(realization_counter) / static_cast(num_of_realizations) * 100.0) << "% \r" << std::flush; if (realization_counter == num_of_realizations) { stop_queue(); @@ -328,9 +328,16 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); config->set_property("Acquisition_1C.threshold", std::to_string(threshold)); - //if (FLAGS_acq_test_pfa > 0.0) config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); + //if (FLAGS_acq_test_pfa_init > 0.0) config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); - config->set_property("Acquisition_1C.use_CFAR_algorithm", "true"); + if (FLAGS_acq_test_use_CFAR_algorithm) + { + config->set_property("Acquisition_1C.use_CFAR_algorithm", "true"); + } + else + { + config->set_property("Acquisition_1C.use_CFAR_algorithm", "false"); + } config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); if (FLAGS_acq_test_bit_transition_flag) @@ -355,6 +362,7 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign std::string dump_file = path_str + std::string("/acquisition_") + std::to_string(cn0) + "_" + std::to_string(iter) + "_" + std::to_string(pfa); config->set_property("Acquisition_1C.dump_filename", dump_file); config->set_property("Acquisition_1C.dump_channel", std::to_string(dump_channel)); + config->set_property("Acquisition_1C.blocking_on_standby", "true"); config_f = 0; } @@ -420,7 +428,7 @@ int AcquisitionPerformanceTest::run_receiver() int AcquisitionPerformanceTest::count_executions(const std::string& basename, unsigned int sat) { FILE* fp; - std::string argum2 = std::string("/bin/ls ") + basename + "* | grep sat_" + std::to_string(sat) + " | wc -l"; + std::string argum2 = std::string("/usr/bin/find ") + path_str + std::string(" -maxdepth 1 -name ") + basename.substr(path_str.length() + 1, basename.length() - path_str.length()) + std::string("* | grep sat_") + std::to_string(sat) + std::string(" | wc -l"); char buffer[1024]; fp = popen(&argum2[0], "r"); int num_executions = 1; @@ -461,15 +469,16 @@ void AcquisitionPerformanceTest::plot_results() Gnuplot::set_GNUPlotPath(gnuplot_path); Gnuplot g1("linespoints"); - g1.set_title("Receiver Operating Characteristic for GPS L1 C/A acquisition"); + g1.set_title("Receiver Operating Characteristic for GPS L1 C/A acquisition, coherent integration time: " + std::to_string(config->property("Acquisition_1C.coherent_integration_time_ms", 1)) + " ms."); g1.cmd("set logscale x"); g1.cmd("set yrange [0:1]"); - g1.cmd("set grid xtics 0.001 0.01 0.1 1"); - g1.cmd("set grid ytics"); - g1.set_grid(); g1.set_xlabel("Pfa"); g1.set_ylabel("Pd"); - for (int i = 0; i < static_cast(cn0_.size()); i++) + g1.cmd("set grid xtics"); + g1.cmd("set grid mytics"); + g1.set_grid(); + g1.cmd("show grid"); + for (int i = 0; i < static_cast(cn0_vector.size()); i++) { std::vector Pd_i; std::vector Pfa_i; @@ -478,37 +487,38 @@ void AcquisitionPerformanceTest::plot_results() Pd_i.push_back(Pd[i][k]); Pfa_i.push_back(Pd[i][k]); } - g1.plot_xy(Pfa_i, Pd_i, "CN0 = " + std::to_string(static_cast(cn0_[i])) + " dBHz"); + g1.plot_xy(Pfa_i, Pd_i, "CN0 = " + std::to_string(static_cast(cn0_vector[i])) + " dBHz"); } g1.set_legend(); g1.savetops("ROC"); g1.savetopdf("ROC", 18); g1.showonscreen(); // window output - if (Pd_correct[0].size() > 0) + Gnuplot g2("linespoints"); + g2.set_title("Receiver Operating Characteristic for GPS L1 C/A valid acquisition, coherent integration time: " + std::to_string(config->property("Acquisition_1C.coherent_integration_time_ms", 1)) + " ms."); + g2.cmd("set logscale x"); + g2.cmd("set yrange [0:1]"); + g1.cmd("set grid xtics"); + g1.cmd("set grid mytics"); + g2.set_xlabel("Pfa"); + g2.set_ylabel("Valid Pd"); + g2.set_grid(); + g2.cmd("show grid"); + for (int i = 0; i < static_cast(cn0_vector.size()); i++) { - Gnuplot g2("linespoints"); - g2.set_title("Receiver Operating Characteristic for GPS L1 C/A correct acquisition"); - g2.cmd("set logscale x"); - g2.set_xlabel("Pfa"); - g2.set_xlabel("Pd"); - g2.set_grid(); - for (int i = 0; i < static_cast(cn0_.size()); i++) + std::vector Pd_i_correct; + std::vector Pfa_i; + for (int k = 0; k < num_thresholds; k++) { - std::vector Pd_i_correct; - std::vector Pfa_i; - for (int k = 0; k < num_thresholds; k++) - { - Pd_i_correct.push_back(Pd_correct[i][k]); - Pfa_i.push_back(Pd[i][k]); - } - g2.plot_xy(Pfa_i, Pd_i_correct, "CN0 = " + std::to_string(static_cast(cn0_[i])) + " dBHz"); + Pd_i_correct.push_back(Pd_correct[i][k]); + Pfa_i.push_back(Pd[i][k]); } - g2.set_legend(); - g2.savetops("ROC-correct"); - g2.savetopdf("ROC-correct", 18); - g2.showonscreen(); // window output + g2.plot_xy(Pfa_i, Pd_i_correct, "CN0 = " + std::to_string(static_cast(cn0_vector[i])) + " dBHz"); } + g2.set_legend(); + g2.savetops("ROC-valid-detection"); + g2.savetopdf("ROC-valid-detection", 18); + g2.showonscreen(); // window output } catch (const GnuplotException& ge) { @@ -531,28 +541,25 @@ TEST_F(AcquisitionPerformanceTest, ROC) ASSERT_TRUE(boost::filesystem::create_directory(path_str, ec)) << "Could not create the " << path_str << " folder."; unsigned int cn0_index = 0; - for (std::vector::const_iterator it = cn0_.cbegin(); it != cn0_.cend(); ++it) + for (std::vector::const_iterator it = cn0_vector.cbegin(); it != cn0_vector.cend(); ++it) { - // Do N_iterations of the experiment - std::vector meas_Pd_; std::vector meas_Pd_correct_; std::vector meas_Pfa_; - // Set parameter to sweep std::cout << "Execution for CN0 = " << *it << " dB-Hz" << std::endl; - for (int pfa_iter = 0; pfa_iter < static_cast(pfa_local.size()); pfa_iter++) + + // Do N_iterations of the experiment + for (int pfa_iter = 0; pfa_iter < static_cast(pfa_vector.size()); pfa_iter++) { + std::cout << "Setting threshold for Pfa = " << pfa_vector[pfa_iter] << std::endl; + // Configure the signal generator + configure_generator(*it); for (int iter = 0; iter < N_iterations; iter++) { - std::string basename = path_str + std::string("/acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + std::to_string(pfa_local[pfa_iter]) + "_" + gnss_synchro.System + "_1C"; - // Configure the signal generator - configure_generator(*it); - // Generate signal raw signal samples and observations RINEX file generate_signal(); - //std::cout << "Execution for CN0 = " << *it << " dB-Hz" << std::endl; for (unsigned k = 0; k < 2; k++) { if (k == 0) @@ -566,12 +573,13 @@ TEST_F(AcquisitionPerformanceTest, ROC) init(); // Configure the receiver - configure_receiver(*it, pfa_local[pfa_iter], iter); + configure_receiver(*it, pfa_vector[pfa_iter], iter); // Run it run_receiver(); // count executions + std::string basename = path_str + std::string("/acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + std::to_string(pfa_vector[pfa_iter]) + "_" + gnss_synchro.System + "_1C"; int num_executions = count_executions(basename, observed_satellite); // Read measured data @@ -669,7 +677,7 @@ TEST_F(AcquisitionPerformanceTest, ROC) } } - std::cout << "Doppler estimation error [Hz]: "; + /* std::cout << "Doppler estimation error [Hz]: "; for (int i = 0; i < num_executions - 1; i++) { std::cout << doppler_estimation_error(i) << " "; @@ -680,8 +688,9 @@ TEST_F(AcquisitionPerformanceTest, ROC) for (int i = 0; i < num_executions - 1; i++) { std::cout << delay_estimation_error(i) << " "; + } - std::cout << std::endl; + std::cout << std::endl; */ } if (k == 0) { @@ -722,7 +731,6 @@ TEST_F(AcquisitionPerformanceTest, ROC) { double wrongly_detected = arma::accu(positive_acq); double computed_Pfa = wrongly_detected / static_cast(num_executions); - std::cout << computed_Pfa << std::endl; if (num_executions > 0) { meas_Pfa_.push_back(computed_Pfa); @@ -783,7 +791,7 @@ TEST_F(AcquisitionPerformanceTest, ROC) // Compute results unsigned int aux_index = 0; - for (std::vector::const_iterator it = cn0_.cbegin(); it != cn0_.cend(); ++it) + for (std::vector::const_iterator it = cn0_vector.cbegin(); it != cn0_vector.cend(); ++it) { std::cout << "Results for CN0 = " << *it << " dBHz:" << std::endl; std::cout << "Pd = "; From 895f8dc75ade8f5eaea30aa4c8dc4dc7e106fad9 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 29 Jun 2018 13:39:17 +0200 Subject: [PATCH 36/40] Expose the blocking_on_standby parameter to the documentation. Useful for unit testing --- .../adapters/galileo_e1_pcps_ambiguous_acquisition.cc | 1 + .../acquisition/adapters/galileo_e5a_pcps_acquisition.cc | 1 + .../acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc | 1 + .../acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc | 1 + .../acquisition/adapters/gps_l1_ca_pcps_acquisition.cc | 1 + .../acquisition/adapters/gps_l2_m_pcps_acquisition.cc | 1 + .../acquisition/adapters/gps_l5i_pcps_acquisition.cc | 1 + .../acquisition/gnuradio_blocks/pcps_acquisition.cc | 4 ++-- src/algorithms/acquisition/libs/acq_conf.cc | 2 +- src/algorithms/acquisition/libs/acq_conf.h | 2 +- 10 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc index 3dedecfff..f377a72c8 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc @@ -104,6 +104,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); + acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc index 203f8b58b..85aaee1d3 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc @@ -106,6 +106,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); + acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); acquisition_ = pcps_make_acquisition(acq_parameters); stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc index 29fc072fb..b654881d7 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc @@ -104,6 +104,7 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); + acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; diff --git a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc index 5222e0ad8..1f5d251fb 100644 --- a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc @@ -103,6 +103,7 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); + acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc index f3bc7dcb2..f5602b1b6 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc @@ -104,6 +104,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( acq_parameters.samples_per_ms = code_length_; acq_parameters.samples_per_code = code_length_; acq_parameters.it_size = item_size_; + acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc index 2da535b82..2fbb72252 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc @@ -103,6 +103,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", true); + acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc index 94d9356ad..da30699fa 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc @@ -102,6 +102,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); + acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index f89c73541..a9d6f8c53 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -683,7 +683,7 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), gr::thread::scoped_lock lk(d_setlock); if (!d_active or d_worker_active) { - if (!acq_parameters.blocking_on_stanby) + if (!acq_parameters.blocking_on_standby) { d_sample_counter += d_fft_size * ninput_items[0]; consume_each(ninput_items[0]); @@ -711,7 +711,7 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), d_input_power = 0.0; d_test_statistics = 0.0; d_state = 1; - if (!acq_parameters.blocking_on_stanby) + if (!acq_parameters.blocking_on_standby) { d_sample_counter += d_fft_size * ninput_items[0]; // sample counter consume_each(ninput_items[0]); diff --git a/src/algorithms/acquisition/libs/acq_conf.cc b/src/algorithms/acquisition/libs/acq_conf.cc index 996880408..ed79db2fa 100644 --- a/src/algorithms/acquisition/libs/acq_conf.cc +++ b/src/algorithms/acquisition/libs/acq_conf.cc @@ -50,5 +50,5 @@ Acq_Conf::Acq_Conf() dump_filename = ""; dump_channel = 0; it_size = sizeof(char); - blocking_on_stanby = false; + blocking_on_standby = false; } diff --git a/src/algorithms/acquisition/libs/acq_conf.h b/src/algorithms/acquisition/libs/acq_conf.h index bb939a652..4707aeba7 100644 --- a/src/algorithms/acquisition/libs/acq_conf.h +++ b/src/algorithms/acquisition/libs/acq_conf.h @@ -51,7 +51,7 @@ public: bool use_CFAR_algorithm_flag; bool dump; bool blocking; - bool blocking_on_stanby; //enable it only for unit testing to avoid sample consume on idle status + bool blocking_on_standby; // enable it only for unit testing to avoid sample consume on idle status bool make_2_steps; std::string dump_filename; unsigned int dump_channel; From 37e1ba8a009bfe042f4f2ac5d77f8eecda05b138 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 29 Jun 2018 20:43:09 +0200 Subject: [PATCH 37/40] Add work on acq performance test --- .../gps_l1_acq_performance_test.cc | 171 +++++++++++++----- 1 file changed, 126 insertions(+), 45 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index 87abc2661..af358b43c 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -40,17 +40,34 @@ #include #include -DEFINE_string(config_file_ptest, std::string(""), "File containing alternative configuration parameters for the position test."); -//DEFINE_double(acq_test_threshold, 0.001, "Acquisition threshold"); -DEFINE_double(acq_test_pfa_init, 1e-5, "Set initial threshold via probability of false alarm"); +DEFINE_string(config_file_ptest, std::string(""), "File containing alternative configuration parameters for the acquisition performance test."); +DEFINE_string(acq_test_input_file, std::string(""), "File containing raw signal data, must be in int8_t format. The signal generator will not be used."); + +DEFINE_int32(acq_test_doppler_max, 5000, "Maximum Doppler, in Hz"); +DEFINE_int32(acq_test_doppler_step, 125, "Doppler step, in Hz."); DEFINE_int32(acq_test_coherent_time_ms, 1, "Acquisition coherent time, in ms"); +DEFINE_int32(acq_test_max_dwells, 1, "Number of non-coherent integrations"); +DEFINE_bool(acq_test_use_CFAR_algorithm, true, "Use CFAR algorithm"); +DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag"); + +DEFINE_int32(acq_test_signal_duration_s, 2, "Generated signal duration, in s"); +DEFINE_int32(acq_test_num_meas, 0, "Number of measurements per run. 0 means the complete file."); +DEFINE_double(acq_test_cn0_init, 33.0, "Initial CN0, in dBHz."); +DEFINE_double(acq_test_cn0_final, 45.0, "Final CN0, in dBHz."); +DEFINE_double(acq_test_cn0_step, 3.0, "CN0 step, in dB."); + +DEFINE_double(acq_test_threshold_init, 11.0, "Initial acquisition threshold"); +DEFINE_double(acq_test_threshold_final, 16.0, "Initial acquisition threshold"); +DEFINE_double(acq_test_threshold_step, 1.0, "Acquisition threshold step"); + +DEFINE_double(acq_test_pfa_init, 1e-5, "Set initial threshold via probability of false alarm. Disable with -1.0"); + DEFINE_int32(acq_test_PRN, 1, "PRN number of a present satellite"); DEFINE_int32(acq_test_fake_PRN, 33, "PRN number of a non-present satellite"); -DEFINE_int32(acq_test_signal_duration_s, 1, "Generated signal duration, in s"); -DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag"); -DEFINE_int32(acq_test_iterations, 1, "Number of iterations (same signal, diferent noise realization)"); + +DEFINE_int32(acq_test_iterations, 1, "Number of iterations (same signal, different noise realization)"); DEFINE_bool(plot_acq_test, false, "Plots results with gnuplot, if available"); -DEFINE_bool(acq_test_use_CFAR_algorithm, true, "Use CFAR algorithm"); +DEFINE_bool(show_plots, true, "Show plots on screen. Disable for non-interactive testing."); // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class AcqPerfTest_msg_rx; @@ -118,19 +135,60 @@ protected: config = std::make_shared(); item_size = sizeof(gr_complex); gnss_synchro = Gnss_Synchro(); - doppler_max = 5000; - doppler_step = 125; + doppler_max = static_cast(FLAGS_acq_test_doppler_max); + doppler_step = static_cast(FLAGS_acq_test_doppler_step); stop = false; - init(); - pfa_vector.push_back(FLAGS_acq_test_pfa_init); - float aux = 1.0; - while ((FLAGS_acq_test_pfa_init * std::pow(10, aux)) < 1) + if (FLAGS_acq_test_input_file.empty()) { - pfa_vector.push_back(FLAGS_acq_test_pfa_init * std::pow(10, aux)); - aux = aux + 1.0; + cn0_vector.push_back(FLAGS_acq_test_cn0_init); + double aux = FLAGS_acq_test_cn0_init + FLAGS_acq_test_cn0_step; + while (aux <= FLAGS_acq_test_cn0_final) + { + cn0_vector.push_back(aux); + aux = aux + FLAGS_acq_test_cn0_step; + } } - pfa_vector.push_back(1.0); + else + { + cn0_vector = {0.0}; + } + init(); + + if (FLAGS_acq_test_pfa_init > 0.0) + { + pfa_vector.push_back(FLAGS_acq_test_pfa_init); + float aux = 1.0; + while ((FLAGS_acq_test_pfa_init * std::pow(10, aux)) < 1) + { + pfa_vector.push_back(FLAGS_acq_test_pfa_init * std::pow(10, aux)); + aux = aux + 1.0; + } + pfa_vector.push_back(1.0); + } + else + { + float aux = static_cast(FLAGS_acq_test_threshold_init); + pfa_vector.push_back(aux); + aux = aux + static_cast(FLAGS_acq_test_threshold_step); + while (aux <= static_cast(FLAGS_acq_test_threshold_final)) + { + pfa_vector.push_back(aux); + aux = aux + static_cast(FLAGS_acq_test_threshold_step); + } + } + num_thresholds = pfa_vector.size(); + + int aux2 = ((generated_signal_duration_s * 1000 - FLAGS_acq_test_coherent_time_ms) / FLAGS_acq_test_coherent_time_ms); + if ((FLAGS_acq_test_num_meas > 0) and (FLAGS_acq_test_num_meas < aux2)) + { + num_of_measurements = static_cast(FLAGS_acq_test_num_meas); + } + else + { + num_of_measurements = static_cast(aux2); + } + Pd.resize(cn0_vector.size()); for (int i = 0; i < static_cast(cn0_vector.size()); i++) Pd[i].reserve(num_thresholds); Pfa.resize(cn0_vector.size()); @@ -143,7 +201,8 @@ protected: { } - std::vector cn0_vector = {35.0, 38.0}; + + std::vector cn0_vector; std::vector pfa_vector; int N_iterations = FLAGS_acq_test_iterations; @@ -181,16 +240,12 @@ protected: const double baseband_sampling_freq = static_cast(FLAGS_fs_gen_sps); const int coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; - const int number_of_channels = 2; const int in_acquisition = 1; - const float threshold = 0.001; // FLAGS_acq_test_threshold; - const int max_dwells = 1; const int dump_channel = 0; int generated_signal_duration_s = FLAGS_acq_test_signal_duration_s; - - unsigned int num_of_realizations = ((generated_signal_duration_s * 1000 - FLAGS_acq_test_coherent_time_ms) / FLAGS_acq_test_coherent_time_ms); - unsigned int realization_counter = 0; + unsigned int num_of_measurements; + unsigned int measurement_counter = 0; unsigned int observed_satellite = FLAGS_acq_test_PRN; std::string path_str = "./acq-perf-test"; @@ -226,7 +281,7 @@ void AcquisitionPerformanceTest::init() signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = observed_satellite; message = 0; - realization_counter = 0; + measurement_counter = 0; } @@ -249,11 +304,11 @@ void AcquisitionPerformanceTest::wait_message() void AcquisitionPerformanceTest::process_message() { - realization_counter++; + measurement_counter++; acquisition->reset(); acquisition->set_state(1); - std::cout << "Progress: " << round(static_cast(realization_counter) / static_cast(num_of_realizations) * 100.0) << "% \r" << std::flush; - if (realization_counter == num_of_realizations) + std::cout << "Progress: " << round(static_cast(measurement_counter) / static_cast(num_of_measurements) * 100.0) << "% \r" << std::flush; + if (measurement_counter == num_of_measurements) { stop_queue(); top_block->stop(); @@ -327,9 +382,12 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max)); config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); - config->set_property("Acquisition_1C.threshold", std::to_string(threshold)); + config->set_property("Acquisition_1C.threshold", std::to_string(pfa)); //if (FLAGS_acq_test_pfa_init > 0.0) config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); - config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); + if (FLAGS_acq_test_pfa_init > 0.0) + { + config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); + } if (FLAGS_acq_test_use_CFAR_algorithm) { config->set_property("Acquisition_1C.use_CFAR_algorithm", "true"); @@ -349,7 +407,7 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign config->set_property("Acquisition_1C.bit_transition_flag", "false"); } - config->set_property("Acquisition_1C.max_dwells", std::to_string(1)); + config->set_property("Acquisition_1C.max_dwells", std::to_string(FLAGS_acq_test_max_dwells)); config->set_property("Acquisition_1C.repeat_satellite", "true"); @@ -377,7 +435,15 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign int AcquisitionPerformanceTest::run_receiver() { - std::string file = "./" + filename_raw_data; + std::string file; + if (FLAGS_acq_test_input_file.empty()) + { + file = "./" + filename_raw_data; + } + else + { + file = FLAGS_acq_test_input_file; + } 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); @@ -469,13 +535,16 @@ void AcquisitionPerformanceTest::plot_results() Gnuplot::set_GNUPlotPath(gnuplot_path); Gnuplot g1("linespoints"); - g1.set_title("Receiver Operating Characteristic for GPS L1 C/A acquisition, coherent integration time: " + std::to_string(config->property("Acquisition_1C.coherent_integration_time_ms", 1)) + " ms."); + g1.cmd("set font \"Times,18\""); + g1.set_title("Receiver Operating Characteristic for GPS L1 C/A acquisition"); + g1.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition_1C.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition_1C.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\""); g1.cmd("set logscale x"); g1.cmd("set yrange [0:1]"); + g1.cmd("set xrange[0.0001:1]"); + g1.cmd("set grid mxtics"); + g1.cmd("set grid ytics"); g1.set_xlabel("Pfa"); g1.set_ylabel("Pd"); - g1.cmd("set grid xtics"); - g1.cmd("set grid mytics"); g1.set_grid(); g1.cmd("show grid"); for (int i = 0; i < static_cast(cn0_vector.size()); i++) @@ -485,21 +554,24 @@ void AcquisitionPerformanceTest::plot_results() for (int k = 0; k < num_thresholds; k++) { Pd_i.push_back(Pd[i][k]); - Pfa_i.push_back(Pd[i][k]); + Pfa_i.push_back(Pfa[i][k]); } g1.plot_xy(Pfa_i, Pd_i, "CN0 = " + std::to_string(static_cast(cn0_vector[i])) + " dBHz"); } g1.set_legend(); g1.savetops("ROC"); g1.savetopdf("ROC", 18); - g1.showonscreen(); // window output + if (FLAGS_show_plots) g1.showonscreen(); // window output Gnuplot g2("linespoints"); - g2.set_title("Receiver Operating Characteristic for GPS L1 C/A valid acquisition, coherent integration time: " + std::to_string(config->property("Acquisition_1C.coherent_integration_time_ms", 1)) + " ms."); + g2.cmd("set font \"Times,18\""); + g2.set_title("Receiver Operating Characteristic for GPS L1 C/A valid acquisition"); + g2.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition_1C.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition_1C.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\""); g2.cmd("set logscale x"); g2.cmd("set yrange [0:1]"); - g1.cmd("set grid xtics"); - g1.cmd("set grid mytics"); + g2.cmd("set xrange[0.0001:1]"); + g2.cmd("set grid mxtics"); + g2.cmd("set grid ytics"); g2.set_xlabel("Pfa"); g2.set_ylabel("Valid Pd"); g2.set_grid(); @@ -511,14 +583,14 @@ void AcquisitionPerformanceTest::plot_results() for (int k = 0; k < num_thresholds; k++) { Pd_i_correct.push_back(Pd_correct[i][k]); - Pfa_i.push_back(Pd[i][k]); + Pfa_i.push_back(Pfa[i][k]); } g2.plot_xy(Pfa_i, Pd_i_correct, "CN0 = " + std::to_string(static_cast(cn0_vector[i])) + " dBHz"); } g2.set_legend(); g2.savetops("ROC-valid-detection"); g2.savetopdf("ROC-valid-detection", 18); - g2.showonscreen(); // window output + if (FLAGS_show_plots) g2.showonscreen(); // window output } catch (const GnuplotException& ge) { @@ -547,18 +619,27 @@ TEST_F(AcquisitionPerformanceTest, ROC) std::vector meas_Pd_correct_; std::vector meas_Pfa_; - std::cout << "Execution for CN0 = " << *it << " dB-Hz" << std::endl; + if (FLAGS_acq_test_input_file.empty()) std::cout << "Execution for CN0 = " << *it << " dB-Hz" << std::endl; // Do N_iterations of the experiment for (int pfa_iter = 0; pfa_iter < static_cast(pfa_vector.size()); pfa_iter++) { - std::cout << "Setting threshold for Pfa = " << pfa_vector[pfa_iter] << std::endl; + if (FLAGS_acq_test_pfa_init > 0.0) + { + std::cout << "Setting threshold for Pfa = " << pfa_vector[pfa_iter] << std::endl; + } + else + { + std::cout << "Setting threshold to " << pfa_vector[pfa_iter] << std::endl; + } + // Configure the signal generator - configure_generator(*it); + if (FLAGS_acq_test_input_file.empty()) configure_generator(*it); + for (int iter = 0; iter < N_iterations; iter++) { // Generate signal raw signal samples and observations RINEX file - generate_signal(); + if (FLAGS_acq_test_input_file.empty()) generate_signal(); for (unsigned k = 0; k < 2; k++) { From 4a9cf9db6021345f10d08f166ca0d08d499654c5 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 29 Jun 2018 21:22:20 +0200 Subject: [PATCH 38/40] Fix typo --- .../acquisition/gps_l1_acq_performance_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index af358b43c..e85263f31 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -57,7 +57,7 @@ DEFINE_double(acq_test_cn0_final, 45.0, "Final CN0, in dBHz."); DEFINE_double(acq_test_cn0_step, 3.0, "CN0 step, in dB."); DEFINE_double(acq_test_threshold_init, 11.0, "Initial acquisition threshold"); -DEFINE_double(acq_test_threshold_final, 16.0, "Initial acquisition threshold"); +DEFINE_double(acq_test_threshold_final, 16.0, "Final acquisition threshold"); DEFINE_double(acq_test_threshold_step, 1.0, "Acquisition threshold step"); DEFINE_double(acq_test_pfa_init, 1e-5, "Set initial threshold via probability of false alarm. Disable with -1.0"); From ccacc9fe3e620f8a9f2da94f64601dde4f146b6e Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 29 Jun 2018 21:53:39 +0200 Subject: [PATCH 39/40] Share flag --noshow_plots for non-interactive testing --- src/tests/common-files/gnuplot_i.h | 27 ++++++++++--------- src/tests/system-tests/obs_system_test.cc | 6 ++--- src/tests/system-tests/position_test.cc | 9 ++++--- .../unit-tests/arithmetic/fft_length_test.cc | 4 +-- ...ileo_e1_pcps_ambiguous_acquisition_test.cc | 2 +- .../gps_l1_acq_performance_test.cc | 1 - .../gps_l1_ca_pcps_acquisition_test.cc | 2 +- .../gps_l2_m_pcps_acquisition_test.cc | 2 +- ...gps_l1_ca_dll_pll_tracking_pull-in_test.cc | 8 +++--- .../gps_l1_ca_dll_pll_tracking_test.cc | 14 +++++----- 10 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index 67e6fb1f8..afafef972 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -47,7 +47,7 @@ #ifndef GNSS_SDR_GNUPLOT_I_H_ #define GNSS_SDR_GNUPLOT_I_H_ - +#include #include #include #include @@ -61,6 +61,7 @@ #include // for std::list #include +DEFINE_bool(show_plots, true, "Show plots on screen. Disable for non-interactive testing."); #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) //defined for 32 and 64-bit environments @@ -2089,19 +2090,19 @@ std::string Gnuplot::create_tmpfile(std::ofstream &tmp) throw GnuplotException(except.str()); } -// int mkstemp(char *name); -// shall replace the contents of the string pointed to by "name" by a unique -// filename, and return a file descriptor for the file open for reading and -// writing. Otherwise, -1 shall be returned if no suitable file could be -// created. The string in template should look like a filename with six -// trailing 'X' s; mkstemp() replaces each 'X' with a character from the -// portable filename character set. The characters are chosen such that the -// resulting name does not duplicate the name of an existing file at the -// time of a call to mkstemp() + // int mkstemp(char *name); + // shall replace the contents of the string pointed to by "name" by a unique + // filename, and return a file descriptor for the file open for reading and + // writing. Otherwise, -1 shall be returned if no suitable file could be + // created. The string in template should look like a filename with six + // trailing 'X' s; mkstemp() replaces each 'X' with a character from the + // portable filename character set. The characters are chosen such that the + // resulting name does not duplicate the name of an existing file at the + // time of a call to mkstemp() -// -// open temporary files for output -// + // + // open temporary files for output + // #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) if (_mktemp(name) == NULL) diff --git a/src/tests/system-tests/obs_system_test.cc b/src/tests/system-tests/obs_system_test.cc index 2ce3bea48..391c2a969 100644 --- a/src/tests/system-tests/obs_system_test.cc +++ b/src/tests/system-tests/obs_system_test.cc @@ -620,7 +620,7 @@ void ObsSystemTest::compute_pseudorange_error( } g1.savetops("Pseudorange_error_" + signal_name); g1.savetopdf("Pseudorange_error_" + signal_name, 18); - g1.showonscreen(); // window output + if (FLAGS_show_plots) g1.showonscreen(); // window output } catch (const GnuplotException& ge) { @@ -711,7 +711,7 @@ void ObsSystemTest::compute_carrierphase_error( } g1.savetops("Carrier_phase_error_" + signal_name); g1.savetopdf("Carrier_phase_error_" + signal_name, 18); - g1.showonscreen(); // window output + if (FLAGS_show_plots) g1.showonscreen(); // window output } catch (const GnuplotException& ge) { @@ -802,7 +802,7 @@ void ObsSystemTest::compute_doppler_error( } g1.savetops("Doppler_error_" + signal_name); g1.savetopdf("Doppler_error_" + signal_name, 18); - g1.showonscreen(); // window output + if (FLAGS_show_plots) g1.showonscreen(); // window output } catch (const GnuplotException& ge) { diff --git a/src/tests/system-tests/position_test.cc b/src/tests/system-tests/position_test.cc index 857b2f489..98a6d0dba 100644 --- a/src/tests/system-tests/position_test.cc +++ b/src/tests/system-tests/position_test.cc @@ -336,7 +336,7 @@ int StaticPositionSystemTest::configure_receiver() config->set_property("Channel.signal", "1C"); // Set Acquisition - config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Tong_Acquisition"); + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Acquisition"); config->set_property("Acquisition_1C.item_type", "gr_complex"); config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); config->set_property("Acquisition_1C.threshold", std::to_string(threshold)); @@ -347,6 +347,9 @@ int StaticPositionSystemTest::configure_receiver() config->set_property("Acquisition_1C.tong_init_val", std::to_string(tong_init_val)); config->set_property("Acquisition_1C.tong_max_val", std::to_string(tong_max_val)); config->set_property("Acquisition_1C.tong_max_dwells", std::to_string(tong_max_dwells)); + config->set_property("Acquisition_1C.dump", "false); + config->set_property("Acquisition_1C.dump_filename", "./acquisition"); + config->set_property("Acquisition_1C.dump_channel", "1"); // Set Tracking config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_Tracking"); @@ -632,7 +635,7 @@ void StaticPositionSystemTest::print_results(const std::vector& east, g1.savetops("Position_test_2D"); g1.savetopdf("Position_test_2D", 18); - g1.showonscreen(); // window output + if (FLAGS_show_plots) g1.showonscreen(); // window output Gnuplot g2("points"); g2.set_title("3D precision"); @@ -653,7 +656,7 @@ void StaticPositionSystemTest::print_results(const std::vector& east, g2.savetops("Position_test_3D"); g2.savetopdf("Position_test_3D"); - g2.showonscreen(); // window output + if (FLAGS_show_plots) g2.showonscreen(); // window output } catch (const GnuplotException& ge) { diff --git a/src/tests/unit-tests/arithmetic/fft_length_test.cc b/src/tests/unit-tests/arithmetic/fft_length_test.cc index 7cf674c24..78961dd2b 100644 --- a/src/tests/unit-tests/arithmetic/fft_length_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_length_test.cc @@ -124,7 +124,7 @@ TEST(FFTLengthTest, MeasureExecutionTime) g1.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); g1.savetops("FFT_execution_times_extended"); g1.savetopdf("FFT_execution_times_extended", 18); - g1.showonscreen(); // window output + if (FLAGS_show_plots) g1.showonscreen(); // window output Gnuplot g2("linespoints"); g2.set_title("FFT execution times for different lengths (up to 2^{14}=16384)"); @@ -136,7 +136,7 @@ TEST(FFTLengthTest, MeasureExecutionTime) g2.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); g2.savetops("FFT_execution_times"); g2.savetopdf("FFT_execution_times", 18); - g2.showonscreen(); // window output + if (FLAGS_show_plots) g2.showonscreen(); // window output } catch (const GnuplotException& ge) { diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc index 522637c9a..d4477ee8d 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc @@ -209,7 +209,7 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::plot_grid() g1.savetops("Galileo_E1_acq_grid"); g1.savetopdf("Galileo_E1_acq_grid"); - g1.showonscreen(); + if (FLAGS_show_plots) g1.showonscreen(); } catch (const GnuplotException& ge) { diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index e85263f31..a92c228b9 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -67,7 +67,6 @@ DEFINE_int32(acq_test_fake_PRN, 33, "PRN number of a non-present satellite"); DEFINE_int32(acq_test_iterations, 1, "Number of iterations (same signal, different noise realization)"); DEFINE_bool(plot_acq_test, false, "Plots results with gnuplot, if available"); -DEFINE_bool(show_plots, true, "Show plots on screen. Disable for non-interactive testing."); // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class AcqPerfTest_msg_rx; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc index 332dcc0e4..e9ee38210 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc @@ -210,7 +210,7 @@ void GpsL1CaPcpsAcquisitionTest::plot_grid() g1.savetops("GPS_L1_acq_grid"); g1.savetopdf("GPS_L1_acq_grid"); - g1.showonscreen(); + if (FLAGS_show_plots) g1.showonscreen(); } catch (const GnuplotException &ge) { diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc index 9d6caf0e6..7092fac26 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc @@ -213,7 +213,7 @@ void GpsL2MPcpsAcquisitionTest::plot_grid() g1.savetops("GPS_L2CM_acq_grid"); g1.savetopdf("GPS_L2CM_acq_grid"); - g1.showonscreen(); + if (FLAGS_show_plots) g1.showonscreen(); } catch (const GnuplotException &ge) { diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc index 7a11f3178..4122f54c6 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc @@ -482,7 +482,7 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) if (FLAGS_plot_detail_level >= 2) { Gnuplot g1("linespoints"); - g1.showonscreen(); // window output + if (FLAGS_show_plots) g1.showonscreen(); // window output g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " Hz" + "GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g1.set_grid(); g1.set_xlabel("Time [s]"); @@ -496,7 +496,7 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) //g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18); Gnuplot g2("points"); - g2.showonscreen(); // window output + if (FLAGS_show_plots) g2.showonscreen(); // window output g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " Hz" + "GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g2.set_grid(); g2.set_xlabel("Inphase"); @@ -519,7 +519,7 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) g3.set_legend(); //g3.savetops("CN0_output"); //g3.savetopdf("CN0_output", 18); - g3.showonscreen(); // window output + if (FLAGS_show_plots) g3.showonscreen(); // window output } } catch (const GnuplotException& ge) @@ -568,6 +568,6 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) g4.set_legend(); g4.savetops("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx))))); g4.savetopdf("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))), 12); - g4.showonscreen(); // window output + if (FLAGS_show_plots) g4.showonscreen(); // window output } } diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index 0fac7c6d3..523be87a3 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -795,7 +795,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) { Gnuplot g1("linespoints"); - g1.showonscreen(); // window output + if (FLAGS_show_plots) g1.showonscreen(); // window output g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz" + "GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g1.set_grid(); g1.set_xlabel("Time [s]"); @@ -809,7 +809,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18); } Gnuplot g2("points"); - g2.showonscreen(); // window output + if (FLAGS_show_plots) g2.showonscreen(); // window output g2.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), ceil(static_cast(generator_CN0_values.size()) / 2)); for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) @@ -840,7 +840,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g3.set_legend(); g3.savetops("CN0_output"); g3.savetopdf("CN0_output", 18); - g3.showonscreen(); // window output + if (FLAGS_show_plots) g3.showonscreen(); // window output } //PLOT ERROR FIGURES (only if it is used the signal generator) @@ -849,7 +849,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) if (FLAGS_plot_detail_level >= 1) { Gnuplot g5("points"); - g5.showonscreen(); // window output + if (FLAGS_show_plots) g5.showonscreen(); // window output g5.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g5.set_grid(); g5.set_xlabel("Time [s]"); @@ -874,7 +874,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) Gnuplot g6("points"); - g6.showonscreen(); // window output + if (FLAGS_show_plots) g6.showonscreen(); // window output g6.set_title("Accumulated carrier phase error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g6.set_grid(); g6.set_xlabel("Time [s]"); @@ -898,7 +898,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g6.savetopdf("Carrier_phase_error_output", 18); Gnuplot g4("points"); - g4.showonscreen(); // window output + if (FLAGS_show_plots) g4.showonscreen(); // window output g4.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), ceil(static_cast(generator_CN0_values.size()) / 2)); for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values_sweep_copy.at(config_idx).size(); current_cn0_idx++) @@ -942,7 +942,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) //plot metrics Gnuplot g7("linespoints"); - g7.showonscreen(); // window output + if (FLAGS_show_plots) g7.showonscreen(); // window output g7.set_title("Doppler error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g7.set_grid(); g7.set_xlabel("CN0 [dB-Hz]"); From 224e798ba363e78675b6f933767711333ad59758 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 29 Jun 2018 21:57:20 +0200 Subject: [PATCH 40/40] Fix typo --- src/tests/system-tests/position_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/system-tests/position_test.cc b/src/tests/system-tests/position_test.cc index 98a6d0dba..00e64ccad 100644 --- a/src/tests/system-tests/position_test.cc +++ b/src/tests/system-tests/position_test.cc @@ -347,7 +347,7 @@ int StaticPositionSystemTest::configure_receiver() config->set_property("Acquisition_1C.tong_init_val", std::to_string(tong_init_val)); config->set_property("Acquisition_1C.tong_max_val", std::to_string(tong_max_val)); config->set_property("Acquisition_1C.tong_max_dwells", std::to_string(tong_max_dwells)); - config->set_property("Acquisition_1C.dump", "false); + config->set_property("Acquisition_1C.dump", "false"); config->set_property("Acquisition_1C.dump_filename", "./acquisition"); config->set_property("Acquisition_1C.dump_channel", "1");