From e88447675d36c4b2297a7fd91a1d9b2ea1ef9769 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Tue, 17 Jul 2018 18:31:55 +0200 Subject: [PATCH] Improving tracking and observables unit test plots --- .../observables/hybrid_observables_test.cc | 93 ++++++++++++++++++- .../gps_l1_ca_dll_pll_tracking_test.cc | 60 ++++++++++-- 2 files changed, 140 insertions(+), 13 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc index f93f780cc..a3247d2a5 100644 --- a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc @@ -58,6 +58,8 @@ #include "signal_generator_flags.h" #include "gnss_sdr_sample_counter.h" #include +#include "test_flags.h" +#include "gnuplot_i.h" // ######## GNURADIO BLOCK MESSAGE RECEVER FOR TRACKING MESSAGES ######### @@ -183,6 +185,7 @@ public: int configure_generator(); int generate_signal(); + bool save_mat_xy(std::vector& x, std::vector& y, std::string filename); void check_results_carrier_phase( arma::mat& true_ch0, arma::mat& true_ch1, @@ -283,10 +286,12 @@ void HybridObservablesTest::configure_receiver() config->set_property("Tracking_1C.item_type", "gr_complex"); config->set_property("Tracking_1C.dump", "true"); config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); - config->set_property("Tracking_1C.pll_bw_hz", "35.0"); - config->set_property("Tracking_1C.dll_bw_hz", "0.5"); + config->set_property("Tracking_1C.pll_bw_hz", "5.0"); + config->set_property("Tracking_1C.dll_bw_hz", "0.20"); + config->set_property("Tracking_1C.pll_bw_narrow_hz", "1.0"); + config->set_property("Tracking_1C.dll_bw_narrow_hz", "0.1"); + config->set_property("Tracking_1C.extend_correlation_symbols", "20"); config->set_property("Tracking_1C.early_late_space_chips", "0.5"); - config->set_property("Tracking_1C.unified", "true"); config->set_property("TelemetryDecoder_1C.dump", "true"); config->set_property("Observables.dump", "true"); @@ -384,6 +389,41 @@ void HybridObservablesTest::check_results_carrier_phase( } +bool HybridObservablesTest::save_mat_xy(std::vector& x, std::vector& y, std::string filename) +{ + try + { + // WRITE MAT FILE + mat_t* matfp; + matvar_t* matvar; + filename.append(".mat"); + std::cout << "save_mat_xy write " << filename << std::endl; + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT5); + if (reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, x.size()}; + matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &x[0], 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &y[0], 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + else + { + std::cout << "save_mat_xy: error creating file" << std::endl; + } + Mat_Close(matfp); + return true; + } + catch (const std::exception& ex) + { + std::cout << "save_mat_xy: " << ex.what() << std::endl; + return false; + } +} + void HybridObservablesTest::check_results_code_psudorange( arma::mat& true_ch0, arma::mat& true_ch1, @@ -397,7 +437,12 @@ void HybridObservablesTest::check_results_code_psudorange( int size1 = measured_ch0.col(0).n_rows; int size2 = measured_ch1.col(0).n_rows; double t1 = std::min(measured_ch0(size1 - 1, 0), measured_ch1(size2 - 1, 0)); + arma::vec t = arma::linspace(t0, t1, floor((t1 - t0) * 1e3)); + //conversion between arma::vec and std:vector + arma::vec t_from_start = arma::linspace(0, t1 - t0, floor((t1 - t0) * 1e3)); + std::vector time_vector(t_from_start.colptr(0), t_from_start.colptr(0) + t_from_start.n_rows); + arma::vec true_ch0_dist_interp; arma::vec true_ch1_dist_interp; @@ -438,6 +483,31 @@ void HybridObservablesTest::check_results_code_psudorange( << " [meters]" << std::endl; std::cout.precision(ss); + //plots + + Gnuplot g3("linespoints"); + g3.set_title("Delta Pseudorange error [m]"); + g3.set_grid(); + g3.set_xlabel("Time [s]"); + g3.set_ylabel("Pseudorange error [m]"); + //conversion between arma::vec and std:vector + std::vector range_error_m(err.colptr(0), err.colptr(0) + err.n_rows); + g3.cmd("set key box opaque"); + g3.plot_xy(time_vector, range_error_m, + "Delta pseudorrange error"); + g3.set_legend(); + g3.savetops("Delta_pseudorrange_error"); + g3.savetopdf("Delta_pseudorrange_error", 18); + if (FLAGS_show_plots) + { + g3.showonscreen(); // window output + } + else + { + g3.disablescreen(); + } + + //check results against the test tolerance ASSERT_LT(rmse, 0.5); ASSERT_LT(error_mean, 0.5); ASSERT_GT(error_mean, -0.5); @@ -468,7 +538,7 @@ TEST_F(HybridObservablesTest, ValidationOfResults) tracking_true_obs_reader true_obs_data_ch1; int test_satellite_PRN = FLAGS_test_satellite_PRN; int test_satellite_PRN2 = FLAGS_test_satellite_PRN2; - std::cout << "Testing satellite PRNs " << test_satellite_PRN << "," << test_satellite_PRN << std::endl; + std::cout << "Testing satellite PRNs " << test_satellite_PRN << "," << test_satellite_PRN2 << 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"); @@ -700,6 +770,21 @@ TEST_F(HybridObservablesTest, ValidationOfResults) } //Cut measurement initial transitory of the measurements + + double initial_transitory_s = 30.0; + + index = arma::find(measured_ch0.col(0) >= (measured_ch0(0, 0) + initial_transitory_s), 1, "first"); + if ((index.size() > 0) and (index(0) > 0)) + { + measured_ch0.shed_rows(0, index(0)); + } + index = arma::find(measured_ch1.col(0) >= (measured_ch1(0, 0) + initial_transitory_s), 1, "first"); + if ((index.size() > 0) and (index(0) > 0)) + { + measured_ch1.shed_rows(0, index(0)); + } + + index = arma::find(measured_ch0.col(0) >= true_ch0(0, 0), 1, "first"); if ((index.size() > 0) and (index(0) > 0)) { 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 3b1a84c07..fc414de2d 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 @@ -540,6 +540,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std::vector> doppler_error_sweep; std::vector> code_phase_error_sweep; + std::vector> code_phase_error_meters_sweep; std::vector> acc_carrier_phase_error_sweep; std::vector mean_doppler_error; @@ -697,6 +698,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) { std::vector doppler_error_hz; std::vector code_phase_error_chips; + std::vector code_phase_error_meters; std::vector acc_carrier_phase_hz; try @@ -745,6 +747,10 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) rmse_doppler.push_back(rmse); 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, rmse); + for (unsigned int ii = 0; ii < code_phase_error_chips.size(); ii++) + { + code_phase_error_meters.push_back(GPS_L1_CA_CHIP_PERIOD * code_phase_error_chips.at(ii) * GPS_C_m_s); + } mean_code_phase_error.push_back(mean_error); std_dev_code_phase_error.push_back(std_dev_error); rmse_code_phase.push_back(rmse); @@ -760,6 +766,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) doppler_error_sweep.push_back(doppler_error_hz); code_phase_error_sweep.push_back(code_phase_error_chips); + code_phase_error_meters_sweep.push_back(code_phase_error_meters); acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz); } else @@ -921,13 +928,48 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) } save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_sweep.at(current_cn0_idx), - "Code_error_" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + + "Code_error_chips" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx))); } g5.set_legend(); g5.set_legend(); - g5.savetops("Code_error_output"); - g5.savetopdf("Code_error_output", 18); + g5.savetops("Code_error_chips"); + g5.savetopdf("Code_error_chips", 18); + + Gnuplot g5b("points"); + if (FLAGS_show_plots) + { + g5b.showonscreen(); // window output + } + else + { + g5b.disablescreen(); + } + g5b.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) + ")"); + g5b.set_grid(); + g5b.set_xlabel("Time [s]"); + g5b.set_ylabel("Code delay error [meters]"); + + + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values_sweep_copy.at(config_idx).size(); current_cn0_idx++) + { + try + { + g5b.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_meters_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) + { + } + save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), + code_phase_error_sweep.at(current_cn0_idx), + "Code_error_meters" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + + std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx))); + } + g5b.set_legend(); + g5b.set_legend(); + g5b.savetops("Code_error_meters"); + g5b.savetopdf("Code_error_meters", 18); Gnuplot g6("points"); @@ -957,13 +999,13 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) } save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), acc_carrier_phase_error_sweep.at(current_cn0_idx), - "Carrier_phase_error_output" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + + "Carrier_phase_error" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx))); } g6.set_legend(); g6.set_legend(); - g6.savetops("Carrier_phase_error_output"); - g6.savetopdf("Carrier_phase_error_output", 18); + g6.savetops("Acc_carrier_phase_error_cycles"); + g6.savetopdf("Acc_carrier_phase_error_cycles", 18); Gnuplot g4("points"); if (FLAGS_show_plots) @@ -995,12 +1037,12 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), doppler_error_sweep.at(current_cn0_idx), - "Doppler_error_output" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + + "Doppler_error" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx))); } g4.unset_multiplot(); - g4.savetops("Doppler_error_output"); - g4.savetopdf("Doppler_error_output", 18); + g4.savetops("Doppler_error_hz"); + g4.savetopdf("Doppler_error_hz", 18); } } }