From 0531c0a0ed19580baa510881dd61e4e430102e0b Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 30 Oct 2017 17:47:55 +0100 Subject: [PATCH 01/20] Observables system test GNSS-SDR space Added a new observables system test --- src/tests/CMakeLists.txt | 14 + .../obs_gps_l1_space_system_test.cc | 573 ++++++++++++++++++ 2 files changed, 587 insertions(+) create mode 100644 src/tests/system-tests/obs_gps_l1_space_system_test.cc diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 651713998..5d988c58d 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -483,10 +483,13 @@ if(ENABLE_SYSTEM_TESTING) if(GPSTK_FOUND OR OWN_GPSTK) add_executable(obs_gps_l1_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_system_test.cc) + add_executable(obs_gps_l1_space_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_space_system_test.cc) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(obs_gps_l1_system_test gtest-${gtest_RELEASE} ) + add_dependencies(obs_gps_l1_space_system_test gtest-${gtest_RELEASE} ) else(NOT ${GTEST_DIR_LOCAL}) add_dependencies(obs_gps_l1_system_test gtest) + add_dependencies(obs_gps_l1_space_system_test gtest) endif(NOT ${GTEST_DIR_LOCAL}) include_directories(${GPSTK_INCLUDE_DIRS}) target_link_libraries(obs_gps_l1_system_test ${GFlags_LIBS} @@ -495,6 +498,13 @@ if(ENABLE_SYSTEM_TESTING) gnss_sp_libs gnss_rx ${gpstk_libs}) + + target_link_libraries(obs_gps_l1_space_system_test ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${GTEST_LIBRARIES} + gnss_sp_libs + gnss_rx + ${gpstk_libs}) if(ENABLE_INSTALL_TESTS) if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) @@ -505,6 +515,10 @@ if(ENABLE_SYSTEM_TESTING) add_custom_command(TARGET obs_gps_l1_system_test POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_SOURCE_DIR}/install/$ ) + add_custom_command(TARGET obs_gps_l1_space_system_test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy $ + ${CMAKE_SOURCE_DIR}/install/$ ) + endif(ENABLE_INSTALL_TESTS) endif(GPSTK_FOUND OR OWN_GPSTK) endif(ENABLE_SYSTEM_TESTING_EXTRA) diff --git a/src/tests/system-tests/obs_gps_l1_space_system_test.cc b/src/tests/system-tests/obs_gps_l1_space_system_test.cc new file mode 100644 index 000000000..69c21a5a3 --- /dev/null +++ b/src/tests/system-tests/obs_gps_l1_space_system_test.cc @@ -0,0 +1,573 @@ +/*! + * \file obs_gps_l1_space_system_test.cc + * \brief This class implements a test for the validation of generated observables. + * \author Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es + * Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "RinexUtilities.hpp" +#include "Rinex3ObsBase.hpp" +#include "Rinex3ObsData.hpp" +#include "Rinex3ObsHeader.hpp" +#include "Rinex3ObsStream.hpp" +#include "concurrent_map.h" +#include "concurrent_queue.h" +#include "control_thread.h" +#include "file_configuration.h" +#include "signal_generator_flags.h" + + +// For GPS NAVIGATION (L1) +concurrent_queue global_gps_acq_assist_queue; +concurrent_map global_gps_acq_assist_map; + +DEFINE_string(configuration_file_space, "./default_configuration.conf", "Path of configuration file"); + +class ObsGpsL1SpaceSystemTest: public ::testing::Test +{ +public: + //std::string generator_binary; + //std::string p1; + //std::string p2; + //std::string p3; + //std::string p4; + //std::string p5; + + //const double baseband_sampling_freq = 2.6e6; + + std::string filename_rinex_obs = FLAGS_filename_rinex_obs; + //std::string filename_raw_data = FLAGS_filename_raw_data; + std::string generated_rinex_obs; + std::string configuration_file_ = FLAGS_configuration_file_space; + //int configure_generator(); + //int generate_signal(); + int configure_receiver(); + int run_receiver(); + void check_results(); + bool check_valid_rinex_nav(std::string filename); // return true if the file is a valid Rinex navigation file. + bool check_valid_rinex_obs(std::string filename); // return true if the file is a valid Rinex observation file. + double compute_stdev(const std::vector & vec); + + std::shared_ptr config; +}; + + +bool ObsGpsL1SpaceSystemTest::check_valid_rinex_nav(std::string filename) +{ + bool res = false; + res = gpstk::isRinexNavFile(filename); + return res; +} + + +double ObsGpsL1SpaceSystemTest::compute_stdev(const std::vector & vec) +{ + double sum__ = std::accumulate(vec.begin(), vec.end(), 0.0); + double mean__ = sum__ / vec.size(); + double accum__ = 0.0; + std::for_each (std::begin(vec), std::end(vec), [&](const double d) { + accum__ += (d - mean__) * (d - mean__); + }); + double stdev__ = std::sqrt(accum__ / (vec.size() - 1)); + return stdev__; +} + + +bool ObsGpsL1SpaceSystemTest::check_valid_rinex_obs(std::string filename) +{ + bool res = false; + res = gpstk::isRinex3ObsFile(filename); + return res; +} + +/* +int ObsGpsL1SpaceSystemTest::configure_generator() +{ + // Configure signal generator + generator_binary = FLAGS_generator_binary; + + p1 = std::string("-rinex_nav_file=") + FLAGS_rinex_nav_file; + if(FLAGS_dynamic_position.empty()) + { + p2 = std::string("-static_position=") + FLAGS_static_position + std::string(",") + std::to_string(std::min(FLAGS_duration * 10, 3000)); + if(FLAGS_duration > 300) std::cout << "WARNING: Duration has been set to its maximum value of 300 s" << std::endl; + } + else + { + p2 = std::string("-obs_pos_file=") + std::string(FLAGS_dynamic_position); + } + p3 = std::string("-rinex_obs_file=") + FLAGS_filename_rinex_obs; // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); //Baseband sampling frequency [MSps] + return 0; +} +*/ +/* +int ObsGpsL1SpaceSystemTest::generate_signal() +{ + pid_t wait_result; + int child_status; + + char *const parmList[] = { &generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0], NULL }; + + int pid; + if ((pid = fork()) == -1) + perror("fork 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"); + EXPECT_EQ(true, check_valid_rinex_obs(filename_rinex_obs)); + std::cout << "Signal and Observables RINEX files created." << std::endl; + return 0; +} +*/ + +int ObsGpsL1SpaceSystemTest::configure_receiver() +{ + config = std::make_shared(configuration_file_); + return 0; +} + + +int ObsGpsL1SpaceSystemTest::run_receiver() +{ + std::shared_ptr control_thread; + control_thread = std::make_shared(config); + // 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(); + } + // Get the name of the RINEX obs file generated by the receiver + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + FILE *fp; + std::string argum2 = std::string("/bin/ls *O | grep GSDR | tail -1"); + char buffer[1035]; + fp = popen(&argum2[0], "r"); + 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); + ObsGpsL1SpaceSystemTest::generated_rinex_obs = aux.erase(aux.length() - 1, 1); + } + pclose(fp); + return 0; +} + + +void ObsGpsL1SpaceSystemTest::check_results() +{ + std::vector> > pseudorange_ref(33); + std::vector> > carrierphase_ref(33); + std::vector> > doppler_ref(33); + + std::vector> > pseudorange_meas(33); + std::vector> > carrierphase_meas(33); + std::vector> > doppler_meas(33); + + // Open and read reference RINEX observables file + try + { + gpstk::Rinex3ObsStream r_ref(FLAGS_filename_rinex_obs); + r_ref.exceptions(std::ios::failbit); + gpstk::Rinex3ObsData r_ref_data; + gpstk::Rinex3ObsHeader r_ref_header; + + gpstk::RinexDatum dataobj; + + r_ref >> r_ref_header; + + while (r_ref >> r_ref_data) + { + for (int myprn = 1; myprn < 33; myprn++) + { + gpstk::SatID prn( myprn, gpstk::SatID::systemGPS ); + gpstk::CommonTime time = r_ref_data.time; + double sow(static_cast(time).sow); + + gpstk::Rinex3ObsData::DataMap::iterator pointer = r_ref_data.obs.find(prn); + if( pointer == r_ref_data.obs.end() ) + { + // PRN not present; do nothing + } + else + { + dataobj = r_ref_data.getObs(prn, "C1C", r_ref_header); + double P1 = dataobj.data; + std::pair pseudo(sow,P1); + pseudorange_ref.at(myprn).push_back(pseudo); + + dataobj = r_ref_data.getObs(prn, "L1C", r_ref_header); + double L1 = dataobj.data; + std::pair carrier(sow, L1); + carrierphase_ref.at(myprn).push_back(carrier); + + dataobj = r_ref_data.getObs(prn, "D1C", r_ref_header); + double D1 = dataobj.data; + std::pair doppler(sow, D1); + doppler_ref.at(myprn).push_back(doppler); + } // End of 'if( pointer == roe.obs.end() )' + } // end for + } // end while + } // End of 'try' block + catch(const gpstk::FFStreamError& e) + { + std::cout << e; + exit(1); + } + catch(const gpstk::Exception& e) + { + std::cout << e; + exit(1); + } + catch (...) + { + std::cout << "unknown error. I don't feel so well..." << std::endl; + exit(1); + } + + try + { + std::string arg2_gen = std::string("./") + ObsGpsL1SpaceSystemTest::generated_rinex_obs; + gpstk::Rinex3ObsStream r_meas(arg2_gen); + r_meas.exceptions(std::ios::failbit); + gpstk::Rinex3ObsData r_meas_data; + gpstk::Rinex3ObsHeader r_meas_header; + gpstk::RinexDatum dataobj; + + r_meas >> r_meas_header; + + while (r_meas >> r_meas_data) + { + for (int myprn = 1; myprn < 33; myprn++) + { + gpstk::SatID prn( myprn, gpstk::SatID::systemGPS ); + gpstk::CommonTime time = r_meas_data.time; + double sow(static_cast(time).sow); + + gpstk::Rinex3ObsData::DataMap::iterator pointer = r_meas_data.obs.find(prn); + if( pointer == r_meas_data.obs.end() ) + { + // PRN not present; do nothing + } + else + { + dataobj = r_meas_data.getObs(prn, "C1C", r_meas_header); + double P1 = dataobj.data; + std::pair pseudo(sow, P1); + pseudorange_meas.at(myprn).push_back(pseudo); + + dataobj = r_meas_data.getObs(prn, "L1C", r_meas_header); + double L1 = dataobj.data; + std::pair carrier(sow, L1); + carrierphase_meas.at(myprn).push_back(carrier); + + dataobj = r_meas_data.getObs(prn, "D1C", r_meas_header); + double D1 = dataobj.data; + std::pair doppler(sow, D1); + doppler_meas.at(myprn).push_back(doppler); + } // End of 'if( pointer == roe.obs.end() )' + } // end for + } // end while + } // End of 'try' block + catch(const gpstk::FFStreamError& e) + { + std::cout << e; + exit(1); + } + catch(const gpstk::Exception& e) + { + std::cout << e; + exit(1); + } + catch (...) + { + std::cout << "unknown error. I don't feel so well..." << std::endl; + exit(1); + } + + // Time alignment + std::vector> > pseudorange_ref_aligned(33); + std::vector> > carrierphase_ref_aligned(33); + std::vector> > doppler_ref_aligned(33); + + std::vector> >::iterator iter; + std::vector>::iterator it; + std::vector>::iterator it2; + + std::vector> pr_diff(33); + std::vector> cp_diff(33); + std::vector> doppler_diff(33); + + std::vector>::iterator iter_diff; + std::vector::iterator iter_v; + + int prn_id = 0; + for(iter = pseudorange_ref.begin(); iter != pseudorange_ref.end(); iter++) + { + for(it = iter->begin(); it != iter->end(); it++) + { + // If a measure exists for this sow, store it + for(it2 = pseudorange_meas.at(prn_id).begin(); it2 != pseudorange_meas.at(prn_id).end(); it2++) + { + if(std::abs(it->first - it2->first) < 0.01) // store measures closer than 10 ms. + { + pseudorange_ref_aligned.at(prn_id).push_back(*it); + pr_diff.at(prn_id).push_back(it->second - it2->second ); + //std::cout << "Sat " << prn_id << ": " << "PR_ref=" << it->second << " PR_meas=" << it2->second << " Diff:" << it->second - it2->second << std::endl; + } + } + } + prn_id++; + } + + prn_id = 0; + for(iter = carrierphase_ref.begin(); iter != carrierphase_ref.end(); iter++) + { + for(it = iter->begin(); it != iter->end(); it++) + { + // If a measure exists for this sow, store it + for(it2 = carrierphase_meas.at(prn_id).begin(); it2 != carrierphase_meas.at(prn_id).end(); it2++) + { + if(std::abs(it->first - it2->first) < 0.01) // store measures closer than 10 ms. + { + carrierphase_ref_aligned.at(prn_id).push_back(*it); + cp_diff.at(prn_id).push_back(it->second - it2->second ); + // std::cout << "Sat " << prn_id << ": " << "Carrier_ref=" << it->second << " Carrier_meas=" << it2->second << " Diff:" << it->second - it2->second << std::endl; + } + } + } + prn_id++; + } + prn_id = 0; + for(iter = doppler_ref.begin(); iter != doppler_ref.end(); iter++) + { + for(it = iter->begin(); it != iter->end(); it++) + { + // If a measure exists for this sow, store it + for(it2 = doppler_meas.at(prn_id).begin(); it2 != doppler_meas.at(prn_id).end(); it2++) + { + if(std::abs(it->first - it2->first) < 0.01) // store measures closer than 10 ms. + { + doppler_ref_aligned.at(prn_id).push_back(*it); + doppler_diff.at(prn_id).push_back(it->second - it2->second ); + } + } + } + prn_id++; + } + + // Compute pseudorange error + prn_id = 0; + std::vector mean_pr_diff_v; + for(iter_diff = pr_diff.begin(); iter_diff != pr_diff.end(); iter_diff++) + { + // For each satellite with reference and measurements aligned in time + int number_obs = 0; + double mean_diff = 0.0; + for(iter_v = iter_diff->begin(); iter_v != iter_diff->end(); iter_v++) + { + mean_diff = mean_diff + *iter_v; + number_obs = number_obs + 1; + } + if(number_obs > 0) + { + mean_diff = mean_diff / number_obs; + mean_pr_diff_v.push_back(mean_diff); + std::cout << "-- Mean pseudorange difference for sat " << prn_id << ": " << mean_diff; + double stdev_ = compute_stdev(*iter_diff); + std::cout << " +/- " << stdev_ ; + std::cout << " [m]" << std::endl; + } + else + { + mean_diff = 0.0; + } + + prn_id++; + } + double stdev_pr = compute_stdev(mean_pr_diff_v); + std::cout << "Pseudorange diff error stdev = " << stdev_pr << " [m]" << std::endl; + ASSERT_LT(stdev_pr, 10.0); + + // Compute carrier phase error + prn_id = 0; + std::vector mean_cp_diff_v; + for(iter_diff = cp_diff.begin(); iter_diff != cp_diff.end(); iter_diff++) + { + // For each satellite with reference and measurements aligned in time + int number_obs = 0; + double mean_diff = 0.0; + for(iter_v = iter_diff->begin(); iter_v != iter_diff->end(); iter_v++) + { + mean_diff = mean_diff + *iter_v; + number_obs = number_obs + 1; + } + if(number_obs > 0) + { + mean_diff = mean_diff / number_obs; + mean_cp_diff_v.push_back(mean_diff); + std::cout << "-- Mean carrier phase difference for sat " << prn_id << ": " << mean_diff; + double stdev_pr_ = compute_stdev(*iter_diff); + std::cout << " +/- " << stdev_pr_ << " whole cycles (19 cm)" << std::endl; + } + else + { + mean_diff = 0.0; + } + + prn_id++; + } + + // Compute Doppler error + prn_id = 0; + std::vector mean_doppler_v; + for(iter_diff = doppler_diff.begin(); iter_diff != doppler_diff.end(); iter_diff++) + { + // For each satellite with reference and measurements aligned in time + int number_obs = 0; + double mean_diff = 0.0; + for(iter_v = iter_diff->begin(); iter_v != iter_diff->end(); iter_v++) + { + //std::cout << *iter_v << std::endl; + mean_diff = mean_diff + *iter_v; + number_obs = number_obs + 1; + } + if(number_obs > 0) + { + mean_diff = mean_diff / number_obs; + mean_doppler_v.push_back(mean_diff); + std::cout << "-- Mean Doppler difference for sat " << prn_id << ": " << mean_diff << " [Hz]" << std::endl; + } + else + { + mean_diff = 0.0; + } + + prn_id++; + } + + double stdev_dp = compute_stdev(mean_doppler_v); + std::cout << "Doppler error stdev = " << stdev_dp << " [Hz]" << std::endl; + ASSERT_LT(stdev_dp, 10.0); +} + + +TEST_F(ObsGpsL1SpaceSystemTest, Observables_system_test) +{ + std::cout << "Validating input RINEX obs (TRUE) file: " << filename_rinex_obs << " ..." << std::endl; + bool is_rinex_obs_valid = check_valid_rinex_obs(filename_rinex_obs); + ASSERT_EQ(true, is_rinex_obs_valid) << "The RINEX observation file " << filename_rinex_obs << " is not well formed."; + std::cout << "The file is valid." << std::endl; + + // Configure the signal generator + //configure_generator(); + + // Generate signal raw signal samples and observations RINEX file + /* + if(!FLAGS_disable_generator) + { + generate_signal(); + } + + std::cout << "Validating generated reference RINEX obs file: " << FLAGS_filename_rinex_obs << " ..." << std::endl; + bool is_gen_rinex_obs_valid = check_valid_rinex_obs( "./" + FLAGS_filename_rinex_obs); + EXPECT_EQ(true, is_gen_rinex_obs_valid) << "The RINEX observation file " << FLAGS_filename_rinex_obs << ", generated by gnss-sim, is not well formed."; + std::cout << "The file is valid." << std::endl; + */ + // Configure receiver + configure_receiver(); + + // Run the receiver + ASSERT_EQ( run_receiver(), 0) << "Problem executing the software-defined signal generator"; + + std::cout << "Validating RINEX obs file obtained by GNSS-SDR: " << ObsGpsL1SpaceSystemTest::generated_rinex_obs << " ..." << std::endl; + bool is_gen_rinex_obs_valid = check_valid_rinex_obs( "./" + ObsGpsL1SpaceSystemTest::generated_rinex_obs); + ASSERT_EQ(true, is_gen_rinex_obs_valid) << "The RINEX observation file " << ObsGpsL1SpaceSystemTest::generated_rinex_obs << ", generated by GNSS-SDR, is not well formed."; + std::cout << "The file is valid." << std::endl; + + // Check results + check_results(); +} + + +int main(int argc, char **argv) +{ + std::cout << "Running GNSS-SDR in Space Observables validation test..." << std::endl; + int res = 0; + try + { + testing::InitGoogleTest(&argc, argv); + } + catch(...) {} // catch the "testing::internal::::ClassUniqueToAlwaysTrue" from gtest + + google::ParseCommandLineFlags(&argc, &argv, true); + google::InitGoogleLogging(argv[0]); + + // Run the Tests + try + { + res = RUN_ALL_TESTS(); + } + catch(...) + { + LOG(WARNING) << "Unexpected catch"; + } + google::ShutDownCommandLineFlags(); + return res; +} From dcedbf25d76e53bebc2d59a4ad3868e511139530 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 31 Oct 2017 17:01:56 +0100 Subject: [PATCH 02/20] Improving gps_l1_obs_space_system_test Improved checking algorithm --- .../obs_gps_l1_space_system_test.cc | 109 +++--------------- 1 file changed, 19 insertions(+), 90 deletions(-) diff --git a/src/tests/system-tests/obs_gps_l1_space_system_test.cc b/src/tests/system-tests/obs_gps_l1_space_system_test.cc index 69c21a5a3..db1785136 100644 --- a/src/tests/system-tests/obs_gps_l1_space_system_test.cc +++ b/src/tests/system-tests/obs_gps_l1_space_system_test.cc @@ -63,40 +63,19 @@ DEFINE_string(configuration_file_space, "./default_configuration.conf", "Path of class ObsGpsL1SpaceSystemTest: public ::testing::Test { public: - //std::string generator_binary; - //std::string p1; - //std::string p2; - //std::string p3; - //std::string p4; - //std::string p5; - - //const double baseband_sampling_freq = 2.6e6; - std::string filename_rinex_obs = FLAGS_filename_rinex_obs; - //std::string filename_raw_data = FLAGS_filename_raw_data; std::string generated_rinex_obs; std::string configuration_file_ = FLAGS_configuration_file_space; - //int configure_generator(); - //int generate_signal(); int configure_receiver(); int run_receiver(); void check_results(); - bool check_valid_rinex_nav(std::string filename); // return true if the file is a valid Rinex navigation file. - bool check_valid_rinex_obs(std::string filename); // return true if the file is a valid Rinex observation file. + bool check_valid_rinex_obs(std::string filename, int rinex_ver); // return true if the file is a valid Rinex observation file. double compute_stdev(const std::vector & vec); std::shared_ptr config; }; -bool ObsGpsL1SpaceSystemTest::check_valid_rinex_nav(std::string filename) -{ - bool res = false; - res = gpstk::isRinexNavFile(filename); - return res; -} - - double ObsGpsL1SpaceSystemTest::compute_stdev(const std::vector & vec) { double sum__ = std::accumulate(vec.begin(), vec.end(), 0.0); @@ -110,64 +89,29 @@ double ObsGpsL1SpaceSystemTest::compute_stdev(const std::vector & vec) } -bool ObsGpsL1SpaceSystemTest::check_valid_rinex_obs(std::string filename) +bool ObsGpsL1SpaceSystemTest::check_valid_rinex_obs(std::string filename, int rinex_ver) { bool res = false; - res = gpstk::isRinex3ObsFile(filename); + if(rinex_ver == 2) + { + res = gpstk::isRinexObsFile(filename); + } + if(rinex_ver == 3) + { + res = gpstk::isRinex3ObsFile(filename); + } return res; } -/* -int ObsGpsL1SpaceSystemTest::configure_generator() -{ - // Configure signal generator - generator_binary = FLAGS_generator_binary; - - p1 = std::string("-rinex_nav_file=") + FLAGS_rinex_nav_file; - if(FLAGS_dynamic_position.empty()) - { - p2 = std::string("-static_position=") + FLAGS_static_position + std::string(",") + std::to_string(std::min(FLAGS_duration * 10, 3000)); - if(FLAGS_duration > 300) std::cout << "WARNING: Duration has been set to its maximum value of 300 s" << std::endl; - } - else - { - p2 = std::string("-obs_pos_file=") + std::string(FLAGS_dynamic_position); - } - p3 = std::string("-rinex_obs_file=") + FLAGS_filename_rinex_obs; // RINEX 2.10 observation file output - p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples - p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); //Baseband sampling frequency [MSps] - return 0; -} -*/ -/* -int ObsGpsL1SpaceSystemTest::generate_signal() -{ - pid_t wait_result; - int child_status; - - char *const parmList[] = { &generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0], NULL }; - - int pid; - if ((pid = fork()) == -1) - perror("fork 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"); - EXPECT_EQ(true, check_valid_rinex_obs(filename_rinex_obs)); - std::cout << "Signal and Observables RINEX files created." << std::endl; - return 0; -} -*/ - int ObsGpsL1SpaceSystemTest::configure_receiver() { config = std::make_shared(configuration_file_); + int d_rinex_ver = config->property("PVT.rinex_version", 0); + if(d_rinex_ver != 2) + { + std::cout << "Invalid RINEX version. Set PVT.rinex_ver=2 in configuration file." << std::endl; + std::cout << "GPSTk does not work with RINEX v. 3.02." << std::endl; + } return 0; } @@ -511,25 +455,10 @@ void ObsGpsL1SpaceSystemTest::check_results() TEST_F(ObsGpsL1SpaceSystemTest, Observables_system_test) { std::cout << "Validating input RINEX obs (TRUE) file: " << filename_rinex_obs << " ..." << std::endl; - bool is_rinex_obs_valid = check_valid_rinex_obs(filename_rinex_obs); - ASSERT_EQ(true, is_rinex_obs_valid) << "The RINEX observation file " << filename_rinex_obs << " is not well formed."; + bool is_rinex_obs_valid = check_valid_rinex_obs(filename_rinex_obs, 3); + ASSERT_EQ(true, is_rinex_obs_valid) << "The RINEX observation file " << filename_rinex_obs << " is not well formed. Only RINEX v. 3.00 files are allowed"; std::cout << "The file is valid." << std::endl; - // Configure the signal generator - //configure_generator(); - - // Generate signal raw signal samples and observations RINEX file - /* - if(!FLAGS_disable_generator) - { - generate_signal(); - } - - std::cout << "Validating generated reference RINEX obs file: " << FLAGS_filename_rinex_obs << " ..." << std::endl; - bool is_gen_rinex_obs_valid = check_valid_rinex_obs( "./" + FLAGS_filename_rinex_obs); - EXPECT_EQ(true, is_gen_rinex_obs_valid) << "The RINEX observation file " << FLAGS_filename_rinex_obs << ", generated by gnss-sim, is not well formed."; - std::cout << "The file is valid." << std::endl; - */ // Configure receiver configure_receiver(); @@ -537,7 +466,7 @@ TEST_F(ObsGpsL1SpaceSystemTest, Observables_system_test) ASSERT_EQ( run_receiver(), 0) << "Problem executing the software-defined signal generator"; std::cout << "Validating RINEX obs file obtained by GNSS-SDR: " << ObsGpsL1SpaceSystemTest::generated_rinex_obs << " ..." << std::endl; - bool is_gen_rinex_obs_valid = check_valid_rinex_obs( "./" + ObsGpsL1SpaceSystemTest::generated_rinex_obs); + bool is_gen_rinex_obs_valid = check_valid_rinex_obs( "./" + ObsGpsL1SpaceSystemTest::generated_rinex_obs, 2); ASSERT_EQ(true, is_gen_rinex_obs_valid) << "The RINEX observation file " << ObsGpsL1SpaceSystemTest::generated_rinex_obs << ", generated by GNSS-SDR, is not well formed."; std::cout << "The file is valid." << std::endl; From dceb15acdc4d8783434cbb26daea9251318c0d5d Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Tue, 31 Oct 2017 20:28:34 +0100 Subject: [PATCH 03/20] Baseband downconverting PulseBlanking Added an IF to baseband downconverting stage previous to the pulse blanking filter --- .../adapters/pulse_blanking_filter.cc | 26 +++++++++++++++++-- .../adapters/pulse_blanking_filter.h | 2 ++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc index e6bcc2632..454434baa 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc @@ -32,6 +32,7 @@ #include #include #include "configuration_interface.h" +#include using google::LogMessage; @@ -71,7 +72,13 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration, item_size = sizeof(gr_complex); //avoids uninitialization input_size_ = sizeof(gr_complex); //avoids uninitialization } - + float default_if = 0.0; + float if_ = config_->property(role_ + ".if", default_if); + if (if_ > 0.0) + { + const std::vector taps = { 1.0 }; //All-pass filter + freq_xlating_ = gr::filter::freq_xlating_fir_filter_ccf::make(1, taps, if_, config_->property("SignalSource.sampling_frequency", 2000000)); + } if (dump_) { DLOG(INFO) << "Dumping output into file " << dump_filename_; @@ -95,6 +102,10 @@ void PulseBlankingFilter::connect(gr::top_block_sptr top_block) { top_block->connect(pulse_blanking_cc_, 0, file_sink_, 0); } + if (config_->property(role_ + ".if", 0.0) > 0.0) + { + top_block->connect(freq_xlating_, 0, pulse_blanking_cc_, 0); + } } else @@ -113,6 +124,10 @@ void PulseBlankingFilter::disconnect(gr::top_block_sptr top_block) { top_block->disconnect(pulse_blanking_cc_, 0, file_sink_, 0); } + if (config_->property(role_ + ".if", 0.0) > 0.0) + { + top_block->disconnect(freq_xlating_, 0, pulse_blanking_cc_, 0); + } } else { @@ -125,7 +140,14 @@ gr::basic_block_sptr PulseBlankingFilter::get_left_block() { if (input_item_type_.compare("gr_complex") == 0) { - return pulse_blanking_cc_; + if (config_->property(role_ + ".if", 0.0) > 0.0) + { + return freq_xlating_; + } + else + { + return pulse_blanking_cc_; + } } else { diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h index 18b040bcc..238636f28 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h @@ -35,6 +35,7 @@ #include #include #include +#include #include "gnss_block_interface.h" #include "pulse_blanking_cc.h" @@ -82,6 +83,7 @@ private: unsigned int out_streams_; gr::blocks::file_sink::sptr file_sink_; pulse_blanking_cc_sptr pulse_blanking_cc_; + gr::filter::freq_xlating_fir_filter_ccf::sptr freq_xlating_; }; #endif // GNSS_SDR_PULSE_BLANKING_FILTER_H_ From 5958d11fd115355a22b2a86ee53e2dcee2af7a1d Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Tue, 31 Oct 2017 20:28:34 +0100 Subject: [PATCH 04/20] Baseband downconverting PulseBlanking Added an IF to baseband downconverting stage previous to the pulse blanking filter --- .../adapters/pulse_blanking_filter.cc | 31 +++++++++++++++++-- .../adapters/pulse_blanking_filter.h | 2 ++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc index e6bcc2632..cc0b02bed 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc @@ -30,7 +30,9 @@ #include "pulse_blanking_filter.h" #include +#include #include +#include #include "configuration_interface.h" using google::LogMessage; @@ -71,7 +73,17 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration, item_size = sizeof(gr_complex); //avoids uninitialization input_size_ = sizeof(gr_complex); //avoids uninitialization } - + float default_if = 0.0; + float if_ = config_->property(role_ + ".if", default_if); + if (if_ > 0.0) + { + double default_bw = 2000000.0; + double bw_ = config_->property(role_ + ".bw", default_bw); + double default_tw = bw_ / 15.0; + double tw_ = config_->property(role_ + ".tw", default_tw); + const std::vector taps = gr::filter::firdes::low_pass(1.0, config_->property("SignalSource.sampling_frequency", 2000000.0), bw_ / 2.0, tw_); + freq_xlating_ = gr::filter::freq_xlating_fir_filter_ccf::make(1, taps, if_, config_->property("SignalSource.sampling_frequency", 2000000.0)); + } if (dump_) { DLOG(INFO) << "Dumping output into file " << dump_filename_; @@ -95,6 +107,10 @@ void PulseBlankingFilter::connect(gr::top_block_sptr top_block) { top_block->connect(pulse_blanking_cc_, 0, file_sink_, 0); } + if (config_->property(role_ + ".if", 0.0) > 0.0) + { + top_block->connect(freq_xlating_, 0, pulse_blanking_cc_, 0); + } } else @@ -113,6 +129,10 @@ void PulseBlankingFilter::disconnect(gr::top_block_sptr top_block) { top_block->disconnect(pulse_blanking_cc_, 0, file_sink_, 0); } + if (config_->property(role_ + ".if", 0.0) > 0.0) + { + top_block->disconnect(freq_xlating_, 0, pulse_blanking_cc_, 0); + } } else { @@ -125,7 +145,14 @@ gr::basic_block_sptr PulseBlankingFilter::get_left_block() { if (input_item_type_.compare("gr_complex") == 0) { - return pulse_blanking_cc_; + if (config_->property(role_ + ".if", 0.0) > 0.0) + { + return freq_xlating_; + } + else + { + return pulse_blanking_cc_; + } } else { diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h index 18b040bcc..238636f28 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h @@ -35,6 +35,7 @@ #include #include #include +#include #include "gnss_block_interface.h" #include "pulse_blanking_cc.h" @@ -82,6 +83,7 @@ private: unsigned int out_streams_; gr::blocks::file_sink::sptr file_sink_; pulse_blanking_cc_sptr pulse_blanking_cc_; + gr::filter::freq_xlating_fir_filter_ccf::sptr freq_xlating_; }; #endif // GNSS_SDR_PULSE_BLANKING_FILTER_H_ From 03f7cf0b07054a0e429a7542ac62cd53f81e1366 Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 6 Nov 2017 10:32:11 +0100 Subject: [PATCH 05/20] Add lowpass filtering Lowpass filtering implementation in freq_xlating --- .../adapters/freq_xlating_fir_filter.cc | 89 ++++++++++--------- .../adapters/pulse_blanking_filter.cc | 18 ++-- .../adapters/pulse_blanking_filter.h | 1 - 3 files changed, 58 insertions(+), 50 deletions(-) diff --git a/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc index d5690f07e..8af287d6f 100644 --- a/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc +++ b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include "configuration_interface.h" @@ -343,8 +344,8 @@ void FreqXlatingFirFilter::init() std::string default_output_item_type = "gr_complex"; std::string default_taps_item_type = "float"; std::string default_dump_filename = "../data/input_filter.dat"; - double default_intermediate_freq = 0; - double default_sampling_freq = 4000000; + double default_intermediate_freq = 0.0; + double default_sampling_freq = 4000000.0; int default_number_of_taps = 6; unsigned int default_number_of_bands = 2; std::vector default_bands = { 0.0, 0.4, 0.6, 1.0 }; @@ -364,46 +365,54 @@ void FreqXlatingFirFilter::init() sampling_freq_ = config_->property(role_ + ".sampling_frequency", default_sampling_freq); int number_of_taps = config_->property(role_ + ".number_of_taps", default_number_of_taps); unsigned int number_of_bands = config_->property(role_ + ".number_of_bands", default_number_of_bands); - - std::vector bands; - std::vector ampl; - std::vector error_w; - std::string option; - double option_value; - - for (unsigned int i = 0; i < number_of_bands; i++) - { - option = ".band" + boost::lexical_cast(i + 1) + "_begin"; - option_value = config_->property(role_ + option, default_bands[i]); - bands.push_back(option_value); - - option = ".band" + boost::lexical_cast(i + 1) + "_end"; - option_value = config_->property(role_ + option, default_bands[i]); - bands.push_back(option_value); - - option = ".ampl" + boost::lexical_cast(i + 1) + "_begin"; - option_value = config_->property(role_ + option, default_bands[i]); - ampl.push_back(option_value); - - option = ".ampl" + boost::lexical_cast(i + 1) + "_end"; - option_value = config_->property(role_ + option, default_bands[i]); - ampl.push_back(option_value); - - option = ".band" + boost::lexical_cast(i + 1) + "_error"; - option_value = config_->property(role_ + option, default_bands[i]); - error_w.push_back(option_value); - } - std::string filter_type = config_->property(role_ + ".filter_type", default_filter_type); - int grid_density = config_->property(role_ + ".grid_density", default_grid_density); - std::vector taps_d = gr::filter::pm_remez(number_of_taps - 1, bands, ampl, - error_w, filter_type, grid_density); - - taps_.reserve(taps_d.size()); - for (std::vector::iterator it = taps_d.begin(); it != taps_d.end(); it++) + if(filter_type.compare("lowpass") != 0) { - taps_.push_back(float(*it)); - //std::cout<<"TAP="< taps_d; + std::vector bands; + std::vector ampl; + std::vector error_w; + std::string option; + double option_value; + + for (unsigned int i = 0; i < number_of_bands; i++) + { + option = ".band" + boost::lexical_cast(i + 1) + "_begin"; + option_value = config_->property(role_ + option, default_bands[i]); + bands.push_back(option_value); + + option = ".band" + boost::lexical_cast(i + 1) + "_end"; + option_value = config_->property(role_ + option, default_bands[i]); + bands.push_back(option_value); + + option = ".ampl" + boost::lexical_cast(i + 1) + "_begin"; + option_value = config_->property(role_ + option, default_bands[i]); + ampl.push_back(option_value); + + option = ".ampl" + boost::lexical_cast(i + 1) + "_end"; + option_value = config_->property(role_ + option, default_bands[i]); + ampl.push_back(option_value); + + option = ".band" + boost::lexical_cast(i + 1) + "_error"; + option_value = config_->property(role_ + option, default_bands[i]); + error_w.push_back(option_value); + } + + int grid_density = config_->property(role_ + ".grid_density", default_grid_density); + taps_d = gr::filter::pm_remez(number_of_taps - 1, bands, ampl, error_w, filter_type, grid_density); + taps_.reserve(taps_d.size()); + for (std::vector::iterator it = taps_d.begin(); it != taps_d.end(); it++) + { + taps_.push_back(static_cast(*it)); + } } + else + { + double default_bw = 2000000.0; + double bw_ = config_->property(role_ + ".bw", default_bw); + double default_tw = bw_ / 20.0; + double tw_ = config_->property(role_ + ".tw", default_tw); + taps_ = gr::filter::firdes::low_pass(1.0, sampling_freq_, bw_ / 2.0, tw_); + } } diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc index 89a2ff0ac..ea16bd231 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc @@ -28,13 +28,13 @@ * ------------------------------------------------------------------------- */ -#include "pulse_blanking_filter.h" #include #include +#include #include #include #include "configuration_interface.h" -#include +#include "pulse_blanking_filter.h" using google::LogMessage; @@ -74,13 +74,13 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration, item_size = sizeof(gr_complex); //avoids uninitialization input_size_ = sizeof(gr_complex); //avoids uninitialization } - float default_if = 0.0; - float if_ = config_->property(role_ + ".if", default_if); - if (if_ > 0.0) + double default_if = 0.0; + double if_ = config_->property(role_ + ".if", default_if); + if (std::abs(if_) > 1.0) { double default_bw = 2000000.0; double bw_ = config_->property(role_ + ".bw", default_bw); - double default_tw = bw_ / 15.0; + double default_tw = bw_ / 20.0; double tw_ = config_->property(role_ + ".tw", default_tw); const std::vector taps = gr::filter::firdes::low_pass(1.0, config_->property("SignalSource.sampling_frequency", 2000000.0), bw_ / 2.0, tw_); freq_xlating_ = gr::filter::freq_xlating_fir_filter_ccf::make(1, taps, if_, config_->property("SignalSource.sampling_frequency", 2000000.0)); @@ -108,7 +108,7 @@ void PulseBlankingFilter::connect(gr::top_block_sptr top_block) { top_block->connect(pulse_blanking_cc_, 0, file_sink_, 0); } - if (config_->property(role_ + ".if", 0.0) > 0.0) + if (std::abs(config_->property(role_ + ".if", 0.0)) > 1.0) { top_block->connect(freq_xlating_, 0, pulse_blanking_cc_, 0); } @@ -130,7 +130,7 @@ void PulseBlankingFilter::disconnect(gr::top_block_sptr top_block) { top_block->disconnect(pulse_blanking_cc_, 0, file_sink_, 0); } - if (config_->property(role_ + ".if", 0.0) > 0.0) + if (std::abs(config_->property(role_ + ".if", 0.0)) > 1.0) { top_block->disconnect(freq_xlating_, 0, pulse_blanking_cc_, 0); } @@ -146,7 +146,7 @@ gr::basic_block_sptr PulseBlankingFilter::get_left_block() { if (input_item_type_.compare("gr_complex") == 0) { - if (config_->property(role_ + ".if", 0.0) > 0.0) + if (std::abs(config_->property(role_ + ".if", 0.0)) > 1.0) { return freq_xlating_; } diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h index 238636f28..e0748a9d2 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h @@ -33,7 +33,6 @@ #define GNSS_SDR_PULSE_BLANKING_FILTER_H_ #include -#include #include #include #include "gnss_block_interface.h" From a8ff283bacd0d26691691c7474436cb299feba2b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 6 Nov 2017 19:03:01 +0100 Subject: [PATCH 06/20] Call the Intermediate Frequency parameter "IF" for consistency with the freq_xlating_fir_filter block --- src/algorithms/input_filter/adapters/pulse_blanking_filter.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc index 8d3111dc9..e262e3abf 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc @@ -75,7 +75,8 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration, input_size_ = sizeof(gr_complex); //avoids uninitialization } double default_if = 0.0; - double if_ = config_->property(role_ + ".if", default_if); + double if_aux = config_->property(role_ + ".if", default_if); + double if_ = config_->property(role_ + ".IF", if_aux); if (std::abs(if_) > 1.0) { double default_sampling_freq = 4000000.0; From 8fa965c75cda21c3e676f1c9011b79e62dc67dd8 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 6 Nov 2017 19:27:41 +0100 Subject: [PATCH 07/20] Change parameter bw to be the cut-off frequency --- src/algorithms/input_filter/adapters/pulse_blanking_filter.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc index e262e3abf..9c1c18b82 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc @@ -83,9 +83,9 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration, double sampling_freq_ = config_->property(role_ + ".sampling_frequency", default_sampling_freq); double default_bw = 2000000.0; double bw_ = config_->property(role_ + ".bw", default_bw); - double default_tw = bw_ / 20.0; + double default_tw = bw_ / 10.0; double tw_ = config_->property(role_ + ".tw", default_tw); - const std::vector taps = gr::filter::firdes::low_pass(1.0, sampling_freq_, bw_ / 2.0, tw_); + const std::vector taps = gr::filter::firdes::low_pass(1.0, sampling_freq_, bw_ , tw_); freq_xlating_ = gr::filter::freq_xlating_fir_filter_ccf::make(1, taps, if_, sampling_freq_); } if (dump_) From 09e9220764feca3c0653fd9d314e5863f11271d7 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 6 Nov 2017 23:53:05 +0100 Subject: [PATCH 08/20] Add pull request template --- docs/PULL_REQUEST_TEMPLATE.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 docs/PULL_REQUEST_TEMPLATE.md diff --git a/docs/PULL_REQUEST_TEMPLATE.md b/docs/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..b4e04e2c1 --- /dev/null +++ b/docs/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,11 @@ +:+1::tada: Hello, and thanks for contributing to [GNSS-SDR](http://gnss-sdr.org)! :tada::+1: + +Before submitting your pull request, please make sure the following is done: + 1. You undertake the [Contributor Covenant Code of Conduct](https://github.com/gnss-sdr/gnss-sdr/blob/master/CODE_OF_CONDUCT.md). + 2. If you are a first-time contributor, after your pull request you will be asked to sign an Individual Contributor License Agreement ([CLA](https://en.wikipedia.org/wiki/Contributor_License_Agreement)) before your code gets accepted into `master`. This license is for your protection as a Contributor as well as for the protection of [CTTC](http://www.cttc.es/); it does not change your rights to use your own contributions for any other purpose. Except for the license granted therein to CTTC and recipients of software distributed by CTTC, you reserve all right, title, and interest in and to your contributions. The information you provide in that CLA will be maintained in accordance with [CTTC's privacy policy](http://www.cttc.es/privacy/). + 3. You have read the [Contributing Guidelines](https://github.com/gnss-sdr/gnss-sdr/blob/master/CONTRIBUTING.md). + 4. You have read the [coding style guide](http://gnss-sdr.org/coding-style/). + 5. You have forked the [gnss-sdr upstream repository](https://github.com/gnss-sdr/gnss-sdr) and have created your branch from `next` (or any other currently living branch in the upstream repository). + 6. Please include a description of your changes here. + +**Please feel free to delete this line and the above text once you have read it and in case you want to go on with your pull request.** \ No newline at end of file From 10bbe2a267c7a5eb92036b88d80a3dd1d1ddffab Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 7 Nov 2017 09:20:06 +0100 Subject: [PATCH 09/20] Avoid IF parameter ambiguity Added a new boolean for proper instantiation and connection of the internal blocks --- .../input_filter/adapters/pulse_blanking_filter.cc | 8 +++++--- .../input_filter/adapters/pulse_blanking_filter.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc index 9c1c18b82..07c543a92 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc @@ -44,6 +44,7 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration, out_streams_(out_streams) { size_t item_size; + xlat_ = false; std::string default_input_item_type = "gr_complex"; std::string default_output_item_type = "gr_complex"; std::string default_dump_filename = "../data/input_filter.dat"; @@ -79,6 +80,7 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration, double if_ = config_->property(role_ + ".IF", if_aux); if (std::abs(if_) > 1.0) { + xlat_ = true; double default_sampling_freq = 4000000.0; double sampling_freq_ = config_->property(role_ + ".sampling_frequency", default_sampling_freq); double default_bw = 2000000.0; @@ -111,7 +113,7 @@ void PulseBlankingFilter::connect(gr::top_block_sptr top_block) { top_block->connect(pulse_blanking_cc_, 0, file_sink_, 0); } - if (std::abs(config_->property(role_ + ".if", 0.0)) > 1.0) + if (xlat_) { top_block->connect(freq_xlating_, 0, pulse_blanking_cc_, 0); } @@ -133,7 +135,7 @@ void PulseBlankingFilter::disconnect(gr::top_block_sptr top_block) { top_block->disconnect(pulse_blanking_cc_, 0, file_sink_, 0); } - if (std::abs(config_->property(role_ + ".if", 0.0)) > 1.0) + if (xlat_) { top_block->disconnect(freq_xlating_, 0, pulse_blanking_cc_, 0); } @@ -149,7 +151,7 @@ gr::basic_block_sptr PulseBlankingFilter::get_left_block() { if (input_item_type_.compare("gr_complex") == 0) { - if (std::abs(config_->property(role_ + ".if", 0.0)) > 1.0) + if (xlat_) { return freq_xlating_; } diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h index e0748a9d2..8c5211c64 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h @@ -73,6 +73,7 @@ public: private: ConfigurationInterface* config_; bool dump_; + bool xlat_; std::string dump_filename_; std::string input_item_type_; size_t input_size_; From 829071369dfed3d4045ee8fc1eaa56796c6cf309 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 7 Nov 2017 10:34:49 +0100 Subject: [PATCH 10/20] Changes in cut-off frequency and transition width parameters --- .../input_filter/adapters/freq_xlating_fir_filter.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc index d52b4ad51..a62d179f1 100644 --- a/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc +++ b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc @@ -412,8 +412,8 @@ void FreqXlatingFirFilter::init() { double default_bw = 2000000.0; double bw_ = config_->property(role_ + ".bw", default_bw); - double default_tw = bw_ / 20.0; + double default_tw = bw_ / 10.0; double tw_ = config_->property(role_ + ".tw", default_tw); - taps_ = gr::filter::firdes::low_pass(1.0, sampling_freq_, bw_ / 2.0, tw_); + taps_ = gr::filter::firdes::low_pass(1.0, sampling_freq_, bw_, tw_); } } From 6798f45df6172b0cc7b40018f34dca55e4403402 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 8 Nov 2017 11:41:15 +0100 Subject: [PATCH 11/20] Added L1, E1, L5, E5 obs system test --- src/tests/CMakeLists.txt | 14 +- .../obs_gps_l1_space_system_test.cc | 502 ------------- .../system-tests/obs_space_system_test.cc | 681 ++++++++++++++++++ 3 files changed, 688 insertions(+), 509 deletions(-) delete mode 100644 src/tests/system-tests/obs_gps_l1_space_system_test.cc create mode 100644 src/tests/system-tests/obs_space_system_test.cc diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 2f2ee15a9..fd5aed1fa 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -479,13 +479,13 @@ if(ENABLE_SYSTEM_TESTING) if(GPSTK_FOUND OR OWN_GPSTK) add_executable(obs_gps_l1_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_system_test.cc) - add_executable(obs_gps_l1_space_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_space_system_test.cc) + add_executable(obs_space_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_space_system_test.cc) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(obs_gps_l1_system_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION} ) - add_dependencies(obs_gps_l1_space_system_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION} ) + add_dependencies(obs_space_system_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION} ) else(NOT ${GTEST_DIR_LOCAL}) add_dependencies(obs_gps_l1_system_test gtest) - add_dependencies(obs_gps_l1_space_system_test gtest) + add_dependencies(obs_space_system_test gtest) endif(NOT ${GTEST_DIR_LOCAL}) include_directories(${GPSTK_INCLUDE_DIRS} ${GPSTK_INCLUDE_DIRS}/gpstk) target_link_libraries(obs_gps_l1_system_test ${GFlags_LIBS} @@ -495,7 +495,7 @@ if(ENABLE_SYSTEM_TESTING) gnss_rx ${gpstk_libs}) - target_link_libraries(obs_gps_l1_space_system_test ${GFlags_LIBS} + target_link_libraries(obs_space_system_test ${GFlags_LIBS} ${GLOG_LIBRARIES} ${GTEST_LIBRARIES} gnss_sp_libs @@ -511,9 +511,9 @@ if(ENABLE_SYSTEM_TESTING) add_custom_command(TARGET obs_gps_l1_system_test POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_SOURCE_DIR}/install/$ ) - add_custom_command(TARGET obs_gps_l1_space_system_test POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ - ${CMAKE_SOURCE_DIR}/install/$ ) + add_custom_command(TARGET obs_space_system_test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy $ + ${CMAKE_SOURCE_DIR}/install/$ ) endif(ENABLE_INSTALL_TESTS) endif(GPSTK_FOUND OR OWN_GPSTK) diff --git a/src/tests/system-tests/obs_gps_l1_space_system_test.cc b/src/tests/system-tests/obs_gps_l1_space_system_test.cc deleted file mode 100644 index 6a17e0ba6..000000000 --- a/src/tests/system-tests/obs_gps_l1_space_system_test.cc +++ /dev/null @@ -1,502 +0,0 @@ -/*! - * \file obs_gps_l1_space_system_test.cc - * \brief This class implements a test for the validation of generated observables. - * \author Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es - * Antonio Ramos, 2017. antonio.ramos(at)cttc.es - * - * - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) - * - * GNSS-SDR is a software defined Global Navigation - * Satellite Systems receiver - * - * This file is part of GNSS-SDR. - * - * GNSS-SDR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNSS-SDR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . - * - * ------------------------------------------------------------------------- - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "concurrent_map.h" -#include "concurrent_queue.h" -#include "control_thread.h" -#include "file_configuration.h" -#include "signal_generator_flags.h" - - -// For GPS NAVIGATION (L1) -concurrent_queue global_gps_acq_assist_queue; -concurrent_map global_gps_acq_assist_map; - -DEFINE_string(configuration_file_space, "./default_configuration.conf", "Path of configuration file"); - -class ObsGpsL1SpaceSystemTest: public ::testing::Test -{ -public: - std::string filename_rinex_obs = FLAGS_filename_rinex_obs; - std::string generated_rinex_obs; - std::string configuration_file_ = FLAGS_configuration_file_space; - int configure_receiver(); - int run_receiver(); - void check_results(); - bool check_valid_rinex_obs(std::string filename, int rinex_ver); // return true if the file is a valid Rinex observation file. - double compute_stdev(const std::vector & vec); - - std::shared_ptr config; -}; - - -double ObsGpsL1SpaceSystemTest::compute_stdev(const std::vector & vec) -{ - double sum__ = std::accumulate(vec.begin(), vec.end(), 0.0); - double mean__ = sum__ / vec.size(); - double accum__ = 0.0; - std::for_each (std::begin(vec), std::end(vec), [&](const double d) { - accum__ += (d - mean__) * (d - mean__); - }); - double stdev__ = std::sqrt(accum__ / (vec.size() - 1)); - return stdev__; -} - - -bool ObsGpsL1SpaceSystemTest::check_valid_rinex_obs(std::string filename, int rinex_ver) -{ - bool res = false; - if(rinex_ver == 2) - { - res = gpstk::isRinexObsFile(filename); - } - if(rinex_ver == 3) - { - res = gpstk::isRinex3ObsFile(filename); - } - return res; -} - -int ObsGpsL1SpaceSystemTest::configure_receiver() -{ - config = std::make_shared(configuration_file_); - int d_rinex_ver = config->property("PVT.rinex_version", 0); - if(d_rinex_ver != 2) - { - std::cout << "Invalid RINEX version. Set PVT.rinex_ver=2 in configuration file." << std::endl; - std::cout << "GPSTk does not work with RINEX v. 3.02." << std::endl; - } - return 0; -} - - -int ObsGpsL1SpaceSystemTest::run_receiver() -{ - std::shared_ptr control_thread; - control_thread = std::make_shared(config); - // 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(); - } - // Get the name of the RINEX obs file generated by the receiver - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); - FILE *fp; - std::string argum2 = std::string("/bin/ls *O | grep GSDR | tail -1"); - char buffer[1035]; - fp = popen(&argum2[0], "r"); - 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); - ObsGpsL1SpaceSystemTest::generated_rinex_obs = aux.erase(aux.length() - 1, 1); - } - pclose(fp); - return 0; -} - - -void ObsGpsL1SpaceSystemTest::check_results() -{ - std::vector> > pseudorange_ref(33); - std::vector> > carrierphase_ref(33); - std::vector> > doppler_ref(33); - - std::vector> > pseudorange_meas(33); - std::vector> > carrierphase_meas(33); - std::vector> > doppler_meas(33); - - // Open and read reference RINEX observables file - try - { - gpstk::Rinex3ObsStream r_ref(FLAGS_filename_rinex_obs); - r_ref.exceptions(std::ios::failbit); - gpstk::Rinex3ObsData r_ref_data; - gpstk::Rinex3ObsHeader r_ref_header; - - gpstk::RinexDatum dataobj; - - r_ref >> r_ref_header; - - while (r_ref >> r_ref_data) - { - for (int myprn = 1; myprn < 33; myprn++) - { - gpstk::SatID prn( myprn, gpstk::SatID::systemGPS ); - gpstk::CommonTime time = r_ref_data.time; - double sow(static_cast(time).sow); - - gpstk::Rinex3ObsData::DataMap::iterator pointer = r_ref_data.obs.find(prn); - if( pointer == r_ref_data.obs.end() ) - { - // PRN not present; do nothing - } - else - { - dataobj = r_ref_data.getObs(prn, "C1C", r_ref_header); - double P1 = dataobj.data; - std::pair pseudo(sow,P1); - pseudorange_ref.at(myprn).push_back(pseudo); - - dataobj = r_ref_data.getObs(prn, "L1C", r_ref_header); - double L1 = dataobj.data; - std::pair carrier(sow, L1); - carrierphase_ref.at(myprn).push_back(carrier); - - dataobj = r_ref_data.getObs(prn, "D1C", r_ref_header); - double D1 = dataobj.data; - std::pair doppler(sow, D1); - doppler_ref.at(myprn).push_back(doppler); - } // End of 'if( pointer == roe.obs.end() )' - } // end for - } // end while - } // End of 'try' block - catch(const gpstk::FFStreamError& e) - { - std::cout << e; - exit(1); - } - catch(const gpstk::Exception& e) - { - std::cout << e; - exit(1); - } - catch (...) - { - std::cout << "unknown error. I don't feel so well..." << std::endl; - exit(1); - } - - try - { - std::string arg2_gen = std::string("./") + ObsGpsL1SpaceSystemTest::generated_rinex_obs; - gpstk::Rinex3ObsStream r_meas(arg2_gen); - r_meas.exceptions(std::ios::failbit); - gpstk::Rinex3ObsData r_meas_data; - gpstk::Rinex3ObsHeader r_meas_header; - gpstk::RinexDatum dataobj; - - r_meas >> r_meas_header; - - while (r_meas >> r_meas_data) - { - for (int myprn = 1; myprn < 33; myprn++) - { - gpstk::SatID prn( myprn, gpstk::SatID::systemGPS ); - gpstk::CommonTime time = r_meas_data.time; - double sow(static_cast(time).sow); - - gpstk::Rinex3ObsData::DataMap::iterator pointer = r_meas_data.obs.find(prn); - if( pointer == r_meas_data.obs.end() ) - { - // PRN not present; do nothing - } - else - { - dataobj = r_meas_data.getObs(prn, "C1C", r_meas_header); - double P1 = dataobj.data; - std::pair pseudo(sow, P1); - pseudorange_meas.at(myprn).push_back(pseudo); - - dataobj = r_meas_data.getObs(prn, "L1C", r_meas_header); - double L1 = dataobj.data; - std::pair carrier(sow, L1); - carrierphase_meas.at(myprn).push_back(carrier); - - dataobj = r_meas_data.getObs(prn, "D1C", r_meas_header); - double D1 = dataobj.data; - std::pair doppler(sow, D1); - doppler_meas.at(myprn).push_back(doppler); - } // End of 'if( pointer == roe.obs.end() )' - } // end for - } // end while - } // End of 'try' block - catch(const gpstk::FFStreamError& e) - { - std::cout << e; - exit(1); - } - catch(const gpstk::Exception& e) - { - std::cout << e; - exit(1); - } - catch (...) - { - std::cout << "unknown error. I don't feel so well..." << std::endl; - exit(1); - } - - // Time alignment - std::vector> > pseudorange_ref_aligned(33); - std::vector> > carrierphase_ref_aligned(33); - std::vector> > doppler_ref_aligned(33); - - std::vector> >::iterator iter; - std::vector>::iterator it; - std::vector>::iterator it2; - - std::vector> pr_diff(33); - std::vector> cp_diff(33); - std::vector> doppler_diff(33); - - std::vector>::iterator iter_diff; - std::vector::iterator iter_v; - - int prn_id = 0; - for(iter = pseudorange_ref.begin(); iter != pseudorange_ref.end(); iter++) - { - for(it = iter->begin(); it != iter->end(); it++) - { - // If a measure exists for this sow, store it - for(it2 = pseudorange_meas.at(prn_id).begin(); it2 != pseudorange_meas.at(prn_id).end(); it2++) - { - if(std::abs(it->first - it2->first) < 0.01) // store measures closer than 10 ms. - { - pseudorange_ref_aligned.at(prn_id).push_back(*it); - pr_diff.at(prn_id).push_back(it->second - it2->second ); - //std::cout << "Sat " << prn_id << ": " << "PR_ref=" << it->second << " PR_meas=" << it2->second << " Diff:" << it->second - it2->second << std::endl; - } - } - } - prn_id++; - } - - prn_id = 0; - for(iter = carrierphase_ref.begin(); iter != carrierphase_ref.end(); iter++) - { - for(it = iter->begin(); it != iter->end(); it++) - { - // If a measure exists for this sow, store it - for(it2 = carrierphase_meas.at(prn_id).begin(); it2 != carrierphase_meas.at(prn_id).end(); it2++) - { - if(std::abs(it->first - it2->first) < 0.01) // store measures closer than 10 ms. - { - carrierphase_ref_aligned.at(prn_id).push_back(*it); - cp_diff.at(prn_id).push_back(it->second - it2->second ); - // std::cout << "Sat " << prn_id << ": " << "Carrier_ref=" << it->second << " Carrier_meas=" << it2->second << " Diff:" << it->second - it2->second << std::endl; - } - } - } - prn_id++; - } - prn_id = 0; - for(iter = doppler_ref.begin(); iter != doppler_ref.end(); iter++) - { - for(it = iter->begin(); it != iter->end(); it++) - { - // If a measure exists for this sow, store it - for(it2 = doppler_meas.at(prn_id).begin(); it2 != doppler_meas.at(prn_id).end(); it2++) - { - if(std::abs(it->first - it2->first) < 0.01) // store measures closer than 10 ms. - { - doppler_ref_aligned.at(prn_id).push_back(*it); - doppler_diff.at(prn_id).push_back(it->second - it2->second ); - } - } - } - prn_id++; - } - - // Compute pseudorange error - prn_id = 0; - std::vector mean_pr_diff_v; - for(iter_diff = pr_diff.begin(); iter_diff != pr_diff.end(); iter_diff++) - { - // For each satellite with reference and measurements aligned in time - int number_obs = 0; - double mean_diff = 0.0; - for(iter_v = iter_diff->begin(); iter_v != iter_diff->end(); iter_v++) - { - mean_diff = mean_diff + *iter_v; - number_obs = number_obs + 1; - } - if(number_obs > 0) - { - mean_diff = mean_diff / number_obs; - mean_pr_diff_v.push_back(mean_diff); - std::cout << "-- Mean pseudorange difference for sat " << prn_id << ": " << mean_diff; - double stdev_ = compute_stdev(*iter_diff); - std::cout << " +/- " << stdev_ ; - std::cout << " [m]" << std::endl; - } - else - { - mean_diff = 0.0; - } - - prn_id++; - } - double stdev_pr = compute_stdev(mean_pr_diff_v); - std::cout << "Pseudorange diff error stdev = " << stdev_pr << " [m]" << std::endl; - ASSERT_LT(stdev_pr, 10.0); - - // Compute carrier phase error - prn_id = 0; - std::vector mean_cp_diff_v; - for(iter_diff = cp_diff.begin(); iter_diff != cp_diff.end(); iter_diff++) - { - // For each satellite with reference and measurements aligned in time - int number_obs = 0; - double mean_diff = 0.0; - for(iter_v = iter_diff->begin(); iter_v != iter_diff->end(); iter_v++) - { - mean_diff = mean_diff + *iter_v; - number_obs = number_obs + 1; - } - if(number_obs > 0) - { - mean_diff = mean_diff / number_obs; - mean_cp_diff_v.push_back(mean_diff); - std::cout << "-- Mean carrier phase difference for sat " << prn_id << ": " << mean_diff; - double stdev_pr_ = compute_stdev(*iter_diff); - std::cout << " +/- " << stdev_pr_ << " whole cycles (19 cm)" << std::endl; - } - else - { - mean_diff = 0.0; - } - - prn_id++; - } - - // Compute Doppler error - prn_id = 0; - std::vector mean_doppler_v; - for(iter_diff = doppler_diff.begin(); iter_diff != doppler_diff.end(); iter_diff++) - { - // For each satellite with reference and measurements aligned in time - int number_obs = 0; - double mean_diff = 0.0; - for(iter_v = iter_diff->begin(); iter_v != iter_diff->end(); iter_v++) - { - //std::cout << *iter_v << std::endl; - mean_diff = mean_diff + *iter_v; - number_obs = number_obs + 1; - } - if(number_obs > 0) - { - mean_diff = mean_diff / number_obs; - mean_doppler_v.push_back(mean_diff); - std::cout << "-- Mean Doppler difference for sat " << prn_id << ": " << mean_diff << " [Hz]" << std::endl; - } - else - { - mean_diff = 0.0; - } - - prn_id++; - } - - double stdev_dp = compute_stdev(mean_doppler_v); - std::cout << "Doppler error stdev = " << stdev_dp << " [Hz]" << std::endl; - ASSERT_LT(stdev_dp, 10.0); -} - - -TEST_F(ObsGpsL1SpaceSystemTest, Observables_system_test) -{ - std::cout << "Validating input RINEX obs (TRUE) file: " << filename_rinex_obs << " ..." << std::endl; - bool is_rinex_obs_valid = check_valid_rinex_obs(filename_rinex_obs, 3); - ASSERT_EQ(true, is_rinex_obs_valid) << "The RINEX observation file " << filename_rinex_obs << " is not well formed. Only RINEX v. 3.00 files are allowed"; - std::cout << "The file is valid." << std::endl; - - // Configure receiver - configure_receiver(); - - // Run the receiver - ASSERT_EQ( run_receiver(), 0) << "Problem executing the software-defined signal generator"; - - std::cout << "Validating RINEX obs file obtained by GNSS-SDR: " << ObsGpsL1SpaceSystemTest::generated_rinex_obs << " ..." << std::endl; - bool is_gen_rinex_obs_valid = check_valid_rinex_obs( "./" + ObsGpsL1SpaceSystemTest::generated_rinex_obs, 2); - ASSERT_EQ(true, is_gen_rinex_obs_valid) << "The RINEX observation file " << ObsGpsL1SpaceSystemTest::generated_rinex_obs << ", generated by GNSS-SDR, is not well formed."; - std::cout << "The file is valid." << std::endl; - - // Check results - check_results(); -} - - -int main(int argc, char **argv) -{ - std::cout << "Running GNSS-SDR in Space Observables validation test..." << std::endl; - int res = 0; - try - { - testing::InitGoogleTest(&argc, argv); - } - catch(...) {} // catch the "testing::internal::::ClassUniqueToAlwaysTrue" from gtest - - google::ParseCommandLineFlags(&argc, &argv, true); - google::InitGoogleLogging(argv[0]); - - // Run the Tests - try - { - res = RUN_ALL_TESTS(); - } - catch(...) - { - LOG(WARNING) << "Unexpected catch"; - } - google::ShutDownCommandLineFlags(); - return res; -} diff --git a/src/tests/system-tests/obs_space_system_test.cc b/src/tests/system-tests/obs_space_system_test.cc new file mode 100644 index 000000000..a227733f1 --- /dev/null +++ b/src/tests/system-tests/obs_space_system_test.cc @@ -0,0 +1,681 @@ +/*! + * \file obs_space_system_test.cc + * \brief This class implements a test for the validation of generated observables. + * \author Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es + * Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "concurrent_map.h" +#include "concurrent_queue.h" +#include "control_thread.h" +#include "file_configuration.h" + +// For GPS NAVIGATION (L1) +concurrent_queue global_gps_acq_assist_queue; +concurrent_map global_gps_acq_assist_map; + +DEFINE_string(configuration_file, "./default_configuration.conf", "Path of configuration file"); +DEFINE_string(filename_rinex_true, "./default_rinex.txt", "Path of RINEX true observations"); +DEFINE_string(filename_rinex_obs, "default_string", "Path of RINEX true observations"); +DEFINE_double(pr_error_mean_max, 50.0, "Maximum mean error in pseudorange"); +DEFINE_double(pr_error_std_max, 50.0, "Maximum standard deviation in pseudorange"); +DEFINE_double(cp_error_mean_max, 50.0, "Maximum mean error in carrier phase"); +DEFINE_double(cp_error_std_max, 50.0, "Maximum standard deviation in carrier phase"); +DEFINE_double(dp_error_mean_max, 5.0, "Maximum mean error in Doppler frequency"); +DEFINE_double(dp_error_std_max, 10.0, "Maximum standard deviation in Doppler frequency"); + +class ObsSpaceSystemTest: public ::testing::Test +{ +public: + int configure_receiver(); + int run_receiver(); + void check_results(); + bool check_valid_rinex_obs(std::string filename, int rinex_ver); // return true if the file is a valid Rinex observation file. + void read_rinex_files( + std::vector& pseudorange_ref, + std::vector& carrierphase_ref, + std::vector& doppler_ref, + std::vector& pseudorange_meas, + std::vector& carrierphase_meas, + std::vector& doppler_meas, + int signal_type); + void time_alignment_diff( + std::vector& ref, + std::vector& meas, + std::vector& diff); + void compute_pseudorange_error(std::vector& diff, + double error_th_mean, double error_th_std); + void compute_carrierphase_error( + std::vector& diff, + double error_th_mean, double error_th_std); + void compute_doppler_error( + std::vector& diff, + double error_th_mean, double error_th_std); + std::string filename_rinex_obs = FLAGS_filename_rinex_true; + std::string generated_rinex_obs = FLAGS_filename_rinex_obs; + std::string configuration_file_ = FLAGS_configuration_file; + std::shared_ptr config; + bool gps_1C = false; + bool gps_L5 = false; + bool gal_1B = false; + bool gal_E5a = false; + bool internal_rinex_generation = false; + + /****************/ + const int num_prn_gps = 33; + const int num_prn_gal = 31; + + double pseudorange_error_th_mean = FLAGS_pr_error_mean_max; + double pseudorange_error_th_std= FLAGS_pr_error_std_max; + double carrierphase_error_th_mean = FLAGS_cp_error_mean_max; + double carrierphase_error_th_std = FLAGS_cp_error_std_max; + double doppler_error_th_mean = FLAGS_dp_error_mean_max; + double doppler_error_th_std = FLAGS_dp_error_std_max; + +}; + + +bool ObsSpaceSystemTest::check_valid_rinex_obs(std::string filename, int rinex_ver) +{ + bool res = false; + if(rinex_ver == 2) + { + res = gpstk::isRinexObsFile(filename); + } + if(rinex_ver == 3) + { + res = gpstk::isRinex3ObsFile(filename); + } + return res; +} + +void ObsSpaceSystemTest::read_rinex_files( + std::vector& pseudorange_ref, + std::vector& carrierphase_ref, + std::vector& doppler_ref, + std::vector& pseudorange_meas, + std::vector& carrierphase_meas, + std::vector& doppler_meas, + int signal_type) +{ + bool ref_exist = false; + bool meas_exist = false; + gpstk::SatID::SatelliteSystem sat_type = gpstk::SatID::systemUnknown; + int max_prn = 0; + std::string pr_string; + std::string cp_string; + std::string dp_string; + std::string signal_type_string; + + switch(signal_type) + { + case 0: //GPS L1 + + sat_type = gpstk::SatID::systemGPS; + max_prn = num_prn_gps; + pr_string = "C1C"; + cp_string = "L1C"; + dp_string = "D1C"; + signal_type_string = "GPS L1 C/A"; + break; + + case 1: //Galileo E1B + + sat_type = gpstk::SatID::systemGalileo; + max_prn = num_prn_gal; + pr_string = "C1B"; + cp_string = "L1B"; + dp_string = "D1B"; + signal_type_string = "Galileo E1B"; + break; + + case 2: //GPS L5 + + sat_type = gpstk::SatID::systemGPS; + max_prn = num_prn_gps; + pr_string = "C5X"; + cp_string = "L5X"; + dp_string = "D5X"; + signal_type_string = "GPS L5"; + break; + + case 3: //Galileo E5a + + sat_type = gpstk::SatID::systemGalileo; + max_prn = num_prn_gal; + pr_string = "C5X"; + cp_string = "L5X"; + dp_string = "D5X"; + signal_type_string = "Galileo E5a"; + break; + } + + // Open and read reference RINEX observables file + std::cout << "Read: RINEX " << signal_type_string << " True" << std::endl; + try + { + gpstk::Rinex3ObsStream r_ref(filename_rinex_obs); + r_ref.exceptions(std::ios::failbit); + gpstk::Rinex3ObsData r_ref_data; + gpstk::Rinex3ObsHeader r_ref_header; + gpstk::RinexDatum dataobj; + r_ref >> r_ref_header; + + while (r_ref >> r_ref_data) + { + for (int myprn = 1; myprn < max_prn; myprn++) + { + gpstk::SatID prn( myprn, sat_type); + gpstk::CommonTime time = r_ref_data.time; + double sow(static_cast(time).sow); + gpstk::Rinex3ObsData::DataMap::iterator pointer = r_ref_data.obs.find(prn); + if( pointer == r_ref_data.obs.end() ) + { + // PRN not present; do nothing + } + else + { + dataobj = r_ref_data.getObs(prn, pr_string, r_ref_header); + double P1 = dataobj.data; + pseudorange_ref.at(myprn).insert_rows(pseudorange_ref.at(myprn).n_rows, arma::rowvec({sow, P1})); + + dataobj = r_ref_data.getObs(prn, cp_string, r_ref_header); + double L1 = dataobj.data; + carrierphase_ref.at(myprn).insert_rows(carrierphase_ref.at(myprn).n_rows, arma::rowvec({sow, L1})); + + dataobj = r_ref_data.getObs(prn, dp_string, r_ref_header); + double D1 = dataobj.data; + doppler_ref.at(myprn).insert_rows(doppler_ref.at(myprn).n_rows, arma::rowvec({sow, D1})); + + ref_exist = true; + } // End of 'if( pointer == roe.obs.end() )' + } // end for + } // end while + } // End of 'try' block + catch(const gpstk::FFStreamError& e) + { + std::cout << e; + exit(1); + } + catch(const gpstk::Exception& e) + { + std::cout << e; + exit(1); + } + catch (...) + { + std::cout << "unknown error. I don't feel so well..." << std::endl; + exit(1); + } + + // Open and read measured RINEX observables file + std::cout << "Read: RINEX "<< signal_type_string << " measures" << std::endl; + try + { + std::string arg2_gen; + if(internal_rinex_generation) + { + arg2_gen = std::string("./") + generated_rinex_obs; + } + else + { + arg2_gen = generated_rinex_obs; + } + gpstk::Rinex3ObsStream r_meas(arg2_gen); + r_meas.exceptions(std::ios::failbit); + gpstk::Rinex3ObsData r_meas_data; + gpstk::Rinex3ObsHeader r_meas_header; + gpstk::RinexDatum dataobj; + r_meas >> r_meas_header; + + while (r_meas >> r_meas_data) + { + for (int myprn = 1; myprn < max_prn; myprn++) + { + gpstk::SatID prn( myprn, sat_type); + gpstk::CommonTime time = r_meas_data.time; + double sow(static_cast(time).sow); + gpstk::Rinex3ObsData::DataMap::iterator pointer = r_meas_data.obs.find(prn); + if( pointer == r_meas_data.obs.end() ) + { + // PRN not present; do nothing + } + else + { + dataobj = r_meas_data.getObs(prn, pr_string, r_meas_header); + double P1 = dataobj.data; + pseudorange_meas.at(myprn).insert_rows(pseudorange_meas.at(myprn).n_rows, arma::rowvec({sow, P1})); + + dataobj = r_meas_data.getObs(prn, cp_string, r_meas_header); + double L1 = dataobj.data; + carrierphase_meas.at(myprn).insert_rows(carrierphase_meas.at(myprn).n_rows, arma::rowvec({sow, L1})); + + dataobj = r_meas_data.getObs(prn, dp_string, r_meas_header); + double D1 = dataobj.data; + doppler_meas.at(myprn).insert_rows(doppler_meas.at(myprn).n_rows, arma::rowvec({sow, D1})); + + meas_exist = true; + } // End of 'if( pointer == roe.obs.end() )' + } // end for + } // end while + } // End of 'try' block + catch(const gpstk::FFStreamError& e) + { + std::cout << e; + exit(1); + } + catch(const gpstk::Exception& e) + { + std::cout << e; + exit(1); + } + catch (...) + { + std::cout << "unknown error. I don't feel so well..." << std::endl; + exit(1); + } + EXPECT_TRUE(ref_exist) << "RINEX reference file does not contain " << signal_type_string << " information"; + EXPECT_TRUE(meas_exist) << "RINEX generated file does not contain " << signal_type_string << " information"; +} + +void ObsSpaceSystemTest::time_alignment_diff( + std::vector& ref, + std::vector& meas, + std::vector& diff) +{ + std::vector::iterator iter_ref; + std::vector::iterator iter_meas; + std::vector::iterator iter_diff; + arma::mat mat_aux; + + iter_ref = ref.begin(); + iter_diff = diff.begin(); + for(iter_meas = meas.begin(); iter_meas != meas.end(); iter_meas++) + { + if( !iter_meas->is_empty() && !iter_ref->is_empty() ) + { + arma::uvec index_ = arma::find(iter_meas->col(0) > iter_ref->at(0, 0)); + arma::uword index_min = arma::min(index_); + index_ = arma::find(iter_meas->col(0) < iter_ref->at(iter_ref->n_rows - 1, 0)); + arma::uword index_max = arma::max(index_); + mat_aux = iter_meas->rows(index_min, index_max); + arma::vec ref_aligned; + arma::interp1(iter_ref->col(0), iter_ref->col(1), mat_aux.col(0), ref_aligned); + *iter_diff = ref_aligned - mat_aux.col(1); + } + iter_ref++; + iter_diff++; + } +} + +int ObsSpaceSystemTest::configure_receiver() +{ + config = std::make_shared(configuration_file_); + int d_rinex_ver = config->property("PVT.rinex_version", 0); + if(d_rinex_ver != 2) + { + std::cout << "Invalid RINEX version. Set PVT.rinex_version=2 in configuration file." << std::endl; + std::cout << "GPSTk does not work with RINEX v. 3.02." << std::endl; + } + if( config->property("Channels_1C.count", 0) > 0 ) + {gps_1C = true;} + if( config->property("Channels_1B.count", 0) > 0 ) + {gal_1B = true;} + if( config->property("Channels_5X.count", 0) > 0 ) + {gal_E5a = true;} + if( config->property("Channels_7X.count", 0) > 0 ) //NOT DEFINITIVE!!!!! + {gps_L5 = true;} + + return 0; +} + +int ObsSpaceSystemTest::run_receiver() +{ + std::shared_ptr control_thread; + control_thread = std::make_shared(config); + // 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(); + } + // Get the name of the RINEX obs file generated by the receiver + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + FILE *fp; + std::string argum2 = std::string("/bin/ls *O | grep GSDR | tail -1"); + char buffer[1035]; + fp = popen(&argum2[0], "r"); + 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); + generated_rinex_obs = aux.erase(aux.length() - 1, 1); + internal_rinex_generation = true; + } + pclose(fp); + return 0; +} + +void ObsSpaceSystemTest::compute_pseudorange_error( + std::vector& diff, + double error_th_mean, double error_th_std) +{ + int prn_id = 0; + std::vector::iterator iter_diff; + for(iter_diff = diff.begin(); iter_diff != diff.end(); iter_diff++) + { + if(!iter_diff->is_empty()) + { + double d_mean = arma::mean(*iter_diff); + double d_stddev = arma::stddev(*iter_diff); + std::cout << "-- Mean pseudorange difference for sat " << prn_id << ": " << d_mean; + std::cout << " +/- " << d_stddev; + std::cout << " [m]" << std::endl; + EXPECT_LT(d_mean, error_th_mean); + EXPECT_LT(d_stddev, error_th_std); + } + prn_id++; + } +} + +void ObsSpaceSystemTest::compute_carrierphase_error( + std::vector& diff, + double error_th_mean, double error_th_std) +{ + int prn_id = 0; + std::vector::iterator iter_diff; + for(iter_diff = diff.begin(); iter_diff != diff.end(); iter_diff++) + { + if(!iter_diff->is_empty()) + { + double d_mean = arma::mean(*iter_diff); + double d_stddev = arma::stddev(*iter_diff); + std::cout << "-- Mean carrier phase difference for sat " << prn_id << ": " << d_mean; + std::cout << " +/- " << d_stddev; + std::cout << " whole cycles" << std::endl; + EXPECT_LT(d_mean, error_th_mean); + EXPECT_LT(d_stddev, error_th_std); + } + prn_id++; + } +} + +void ObsSpaceSystemTest::compute_doppler_error( + std::vector& diff, + double error_th_mean, double error_th_std) +{ + int prn_id = 0; + std::vector::iterator iter_diff; + for(iter_diff = diff.begin(); iter_diff != diff.end(); iter_diff++) + { + if(!iter_diff->is_empty()) + { + double d_mean = arma::mean(*iter_diff); + double d_stddev = arma::stddev(*iter_diff); + std::cout << "-- Mean Doppler difference for sat " << prn_id << ": " << d_mean; + std::cout << " +/- " << d_stddev; + std::cout << " [Hz]" << std::endl; + EXPECT_LT(d_mean, error_th_mean); + EXPECT_LT(d_stddev, error_th_std); + } + prn_id++; + } +} +void ObsSpaceSystemTest::check_results() +{ + if(gps_1C) + { + std::vector pseudorange_ref(num_prn_gps); + std::vector carrierphase_ref(num_prn_gps); + std::vector doppler_ref(num_prn_gps); + + std::vector pseudorange_meas(num_prn_gps); + std::vector carrierphase_meas(num_prn_gps); + std::vector doppler_meas(num_prn_gps); + + read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, 0); + + // Time alignment and difference computation + + std::vector pr_diff(num_prn_gps); + std::vector cp_diff(num_prn_gps); + std::vector dp_diff(num_prn_gps); + time_alignment_diff(pseudorange_ref, pseudorange_meas, pr_diff); + time_alignment_diff(carrierphase_ref, carrierphase_meas, cp_diff); + time_alignment_diff(doppler_ref, doppler_meas, dp_diff); + + // Results + std::cout << "GPS L1 C/A obs. results" << std::endl; + + // Compute pseudorange error + + compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std); + + // Compute carrier phase error + + compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std); + + // Compute Doppler error + + compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std); + } + if(gps_L5) + { + std::vector pseudorange_ref(num_prn_gps); + std::vector carrierphase_ref(num_prn_gps); + std::vector doppler_ref(num_prn_gps); + + std::vector pseudorange_meas(num_prn_gps); + std::vector carrierphase_meas(num_prn_gps); + std::vector doppler_meas(num_prn_gps); + + read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, 2); + + // Time alignment and difference computation + + std::vector pr_diff(num_prn_gps); + std::vector cp_diff(num_prn_gps); + std::vector dp_diff(num_prn_gps); + time_alignment_diff(pseudorange_ref, pseudorange_meas, pr_diff); + time_alignment_diff(carrierphase_ref, carrierphase_meas, cp_diff); + time_alignment_diff(doppler_ref, doppler_meas, dp_diff); + + // Results + std::cout << "GPS L5 obs. results" << std::endl; + + // Compute pseudorange error + + compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std); + + // Compute carrier phase error + + compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std); + + // Compute Doppler error + + compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std); + } + if(gal_1B) + { + std::vector pseudorange_ref(num_prn_gal); + std::vector carrierphase_ref(num_prn_gal); + std::vector doppler_ref(num_prn_gal); + + std::vector pseudorange_meas(num_prn_gal); + std::vector carrierphase_meas(num_prn_gal); + std::vector doppler_meas(num_prn_gal); + + read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, 1); + + // Time alignment and difference computation + + std::vector pr_diff(num_prn_gal); + std::vector cp_diff(num_prn_gal); + std::vector dp_diff(num_prn_gal); + time_alignment_diff(pseudorange_ref, pseudorange_meas, pr_diff); + time_alignment_diff(carrierphase_ref, carrierphase_meas, cp_diff); + time_alignment_diff(doppler_ref, doppler_meas, dp_diff); + + // Results + std::cout << "Galileo E1B obs. results" << std::endl; + + // Compute pseudorange error + + compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std); + + // Compute carrier phase error + + compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std); + + // Compute Doppler error + + compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std); + } + if(gal_E5a) + { + std::vector pseudorange_ref(num_prn_gal); + std::vector carrierphase_ref(num_prn_gal); + std::vector doppler_ref(num_prn_gal); + + std::vector pseudorange_meas(num_prn_gal); + std::vector carrierphase_meas(num_prn_gal); + std::vector doppler_meas(num_prn_gal); + + read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, 3); + + // Time alignment and difference computation + + std::vector pr_diff(num_prn_gal); + std::vector cp_diff(num_prn_gal); + std::vector dp_diff(num_prn_gal); + time_alignment_diff(pseudorange_ref, pseudorange_meas, pr_diff); + time_alignment_diff(carrierphase_ref, carrierphase_meas, cp_diff); + time_alignment_diff(doppler_ref, doppler_meas, dp_diff); + + // Results + std::cout << "Galileo E5a obs. results" << std::endl; + + // Compute pseudorange error + + compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std); + + // Compute carrier phase error + + compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std); + + // Compute Doppler error + + compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std); + } +} + + +TEST_F(ObsSpaceSystemTest, Observables_system_test) +{ + std::cout << "Validating input RINEX obs (TRUE) file: " << filename_rinex_obs << " ..." << std::endl; + bool is_rinex_obs_valid = check_valid_rinex_obs(filename_rinex_obs, 3); + ASSERT_EQ(true, is_rinex_obs_valid) << "The RINEX observation file " << filename_rinex_obs << " is not well formed. Only RINEX v. 3.00 files are allowed"; + std::cout << "The file is valid." << std::endl; + // Configure receiver + configure_receiver(); + if(generated_rinex_obs.compare("default_string") == 0) + { + // Run the receiver + ASSERT_EQ( run_receiver(), 0) << "Problem executing the software-defined signal generator"; + } + std::cout << "Validating RINEX obs file obtained by GNSS-SDR: " << generated_rinex_obs << " ..." << std::endl; + bool is_gen_rinex_obs_valid = false; + if(internal_rinex_generation) + { + is_gen_rinex_obs_valid = check_valid_rinex_obs( "./" + generated_rinex_obs, 2); + } + else + { + is_gen_rinex_obs_valid = check_valid_rinex_obs(generated_rinex_obs, 2); + } + ASSERT_EQ(true, is_gen_rinex_obs_valid) << "The RINEX observation file " << generated_rinex_obs << ", generated by GNSS-SDR, is not well formed."; + std::cout << "The file is valid." << std::endl; + // Check results + check_results(); +} + + +int main(int argc, char **argv) +{ + std::cout << "Running GNSS-SDR in Space Observables validation test..." << std::endl; + int res = 0; + try + { + testing::InitGoogleTest(&argc, argv); + } + catch(...) {} // catch the "testing::internal::::ClassUniqueToAlwaysTrue" from gtest + + google::ParseCommandLineFlags(&argc, &argv, true); + google::InitGoogleLogging(argv[0]); + + // Run the Tests + try + { + res = RUN_ALL_TESTS(); + } + catch(...) + { + LOG(WARNING) << "Unexpected catch"; + } + google::ShutDownCommandLineFlags(); + return res; +} From 4b9c2268917c970c75160d728d790f19d53ac05a Mon Sep 17 00:00:00 2001 From: Damian Miralles Date: Fri, 3 Nov 2017 16:26:03 -0600 Subject: [PATCH 12/20] bugfix: Fixes bugs in RINEX and RTCM generators Remove dependency of t_b in P_1 for GLONASS GNAV Ephemeris and cleaned RINEX line for nav messages generation --- conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf | 2 +- src/algorithms/PVT/libs/rinex_printer.cc | 3 ++- src/core/system_parameters/rtcm.cc | 4 ++-- src/utils/matlab/plot_acq_grid_gsoc_glonass.m | 6 +++--- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf b/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf index 353ce620a..4f1610ef3 100644 --- a/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf +++ b/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf @@ -43,7 +43,7 @@ Acquisition_1G.pfa=0.0001 Acquisition_1G.if=0 Acquisition_1G.doppler_max=10000 Acquisition_1G.doppler_step=250 -Acquisition_1G.dump=false; +Acquisition_1G.dump=true; Acquisition_1G.dump_filename=/archive/glo_acquisition.dat ;Acquisition_1G.coherent_integration_time_ms=10 diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index e0c72cabd..0f51c6106 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -2931,7 +2931,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::mapsecond.d_gamma_n, 18, 2); line += std::string(1, ' '); //TODO need to define this here. what is nd - line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_t_k + p_utc_time.date().day()*86400, 18, 2); + line += Rinex_Printer::doub2for(glonass_gnav_ephemeris_iter->second.d_t_k + p_utc_time.date().day_of_week()*86400, 18, 2); } Rinex_Printer::lengthCheck(line); out << line << std::endl; @@ -3015,6 +3015,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(Rtcm::bin_to_uint(message_bin.substr(index, 1))); index += 1; - glonass_gnav_eph.d_t_b = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 7)))*glonass_gnav_eph.d_P_1*60.0; + glonass_gnav_eph.d_t_b = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 7)))*15*60.0; index += 7; // TODO Check for type spec for intS24 @@ -4385,7 +4385,7 @@ int Rtcm::set_DF109(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) int Rtcm::set_DF110(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) { - unsigned int t_b = static_cast(std::round(glonass_gnav_eph.d_t_b/(glonass_gnav_eph.d_P_1*60))); + unsigned int t_b = static_cast(std::round(glonass_gnav_eph.d_t_b/(15*60))); DF110 = std::bitset<7>(t_b); return 0; } diff --git a/src/utils/matlab/plot_acq_grid_gsoc_glonass.m b/src/utils/matlab/plot_acq_grid_gsoc_glonass.m index 385a53030..9742e5107 100644 --- a/src/utils/matlab/plot_acq_grid_gsoc_glonass.m +++ b/src/utils/matlab/plot_acq_grid_gsoc_glonass.m @@ -35,13 +35,13 @@ function plot_acq_grid_gsoc_glonass(sat) -file=['acquisition_R_1G_sat_' num2str(sat) '_doppler_0.dat']; +file=['/archive/acquisition_R_1G_sat_' num2str(sat) '_doppler_0.dat']; % sampling_freq_Hz=62316000 -sampling_freq_Hz=31.75e6 +sampling_freq_Hz=6.625e6 Doppler_max_Hz = 10000 Doppler_min_Hz = -10000 -Doppler_step_Hz = 500 +Doppler_step_Hz = 250 % read files From 994233b9f7f6a6092dd4668c2f717f8d4ab66026 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 10 Nov 2017 09:25:18 +0100 Subject: [PATCH 13/20] Change test name --- src/tests/CMakeLists.txt | 14 +++++------ ...pace_system_test.cc => obs_system_test.cc} | 24 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) rename src/tests/system-tests/{obs_space_system_test.cc => obs_system_test.cc} (97%) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index fd5aed1fa..0783209c8 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -479,13 +479,13 @@ if(ENABLE_SYSTEM_TESTING) if(GPSTK_FOUND OR OWN_GPSTK) add_executable(obs_gps_l1_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_system_test.cc) - add_executable(obs_space_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_space_system_test.cc) + add_executable(obs_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_system_test.cc) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(obs_gps_l1_system_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION} ) - add_dependencies(obs_space_system_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION} ) + add_dependencies(obs_system_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION} ) else(NOT ${GTEST_DIR_LOCAL}) add_dependencies(obs_gps_l1_system_test gtest) - add_dependencies(obs_space_system_test gtest) + add_dependencies(obs_system_test gtest) endif(NOT ${GTEST_DIR_LOCAL}) include_directories(${GPSTK_INCLUDE_DIRS} ${GPSTK_INCLUDE_DIRS}/gpstk) target_link_libraries(obs_gps_l1_system_test ${GFlags_LIBS} @@ -495,7 +495,7 @@ if(ENABLE_SYSTEM_TESTING) gnss_rx ${gpstk_libs}) - target_link_libraries(obs_space_system_test ${GFlags_LIBS} + target_link_libraries(obs_system_test ${GFlags_LIBS} ${GLOG_LIBRARIES} ${GTEST_LIBRARIES} gnss_sp_libs @@ -511,9 +511,9 @@ if(ENABLE_SYSTEM_TESTING) add_custom_command(TARGET obs_gps_l1_system_test POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_SOURCE_DIR}/install/$ ) - add_custom_command(TARGET obs_space_system_test POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ - ${CMAKE_SOURCE_DIR}/install/$ ) + add_custom_command(TARGET obs_system_test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy $ + ${CMAKE_SOURCE_DIR}/install/$ ) endif(ENABLE_INSTALL_TESTS) endif(GPSTK_FOUND OR OWN_GPSTK) diff --git a/src/tests/system-tests/obs_space_system_test.cc b/src/tests/system-tests/obs_system_test.cc similarity index 97% rename from src/tests/system-tests/obs_space_system_test.cc rename to src/tests/system-tests/obs_system_test.cc index a227733f1..cb82f302c 100644 --- a/src/tests/system-tests/obs_space_system_test.cc +++ b/src/tests/system-tests/obs_system_test.cc @@ -1,5 +1,5 @@ /*! - * \file obs_space_system_test.cc + * \file obs_system_test.cc * \brief This class implements a test for the validation of generated observables. * \author Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es * Antonio Ramos, 2017. antonio.ramos(at)cttc.es @@ -67,7 +67,7 @@ DEFINE_double(cp_error_std_max, 50.0, "Maximum standard deviation in carrier pha DEFINE_double(dp_error_mean_max, 5.0, "Maximum mean error in Doppler frequency"); DEFINE_double(dp_error_std_max, 10.0, "Maximum standard deviation in Doppler frequency"); -class ObsSpaceSystemTest: public ::testing::Test +class ObsSystemTest: public ::testing::Test { public: int configure_receiver(); @@ -118,7 +118,7 @@ public: }; -bool ObsSpaceSystemTest::check_valid_rinex_obs(std::string filename, int rinex_ver) +bool ObsSystemTest::check_valid_rinex_obs(std::string filename, int rinex_ver) { bool res = false; if(rinex_ver == 2) @@ -132,7 +132,7 @@ bool ObsSpaceSystemTest::check_valid_rinex_obs(std::string filename, int rinex_v return res; } -void ObsSpaceSystemTest::read_rinex_files( +void ObsSystemTest::read_rinex_files( std::vector& pseudorange_ref, std::vector& carrierphase_ref, std::vector& doppler_ref, @@ -321,7 +321,7 @@ void ObsSpaceSystemTest::read_rinex_files( EXPECT_TRUE(meas_exist) << "RINEX generated file does not contain " << signal_type_string << " information"; } -void ObsSpaceSystemTest::time_alignment_diff( +void ObsSystemTest::time_alignment_diff( std::vector& ref, std::vector& meas, std::vector& diff) @@ -351,7 +351,7 @@ void ObsSpaceSystemTest::time_alignment_diff( } } -int ObsSpaceSystemTest::configure_receiver() +int ObsSystemTest::configure_receiver() { config = std::make_shared(configuration_file_); int d_rinex_ver = config->property("PVT.rinex_version", 0); @@ -372,7 +372,7 @@ int ObsSpaceSystemTest::configure_receiver() return 0; } -int ObsSpaceSystemTest::run_receiver() +int ObsSystemTest::run_receiver() { std::shared_ptr control_thread; control_thread = std::make_shared(config); @@ -410,7 +410,7 @@ int ObsSpaceSystemTest::run_receiver() return 0; } -void ObsSpaceSystemTest::compute_pseudorange_error( +void ObsSystemTest::compute_pseudorange_error( std::vector& diff, double error_th_mean, double error_th_std) { @@ -432,7 +432,7 @@ void ObsSpaceSystemTest::compute_pseudorange_error( } } -void ObsSpaceSystemTest::compute_carrierphase_error( +void ObsSystemTest::compute_carrierphase_error( std::vector& diff, double error_th_mean, double error_th_std) { @@ -454,7 +454,7 @@ void ObsSpaceSystemTest::compute_carrierphase_error( } } -void ObsSpaceSystemTest::compute_doppler_error( +void ObsSystemTest::compute_doppler_error( std::vector& diff, double error_th_mean, double error_th_std) { @@ -475,7 +475,7 @@ void ObsSpaceSystemTest::compute_doppler_error( prn_id++; } } -void ObsSpaceSystemTest::check_results() +void ObsSystemTest::check_results() { if(gps_1C) { @@ -624,7 +624,7 @@ void ObsSpaceSystemTest::check_results() } -TEST_F(ObsSpaceSystemTest, Observables_system_test) +TEST_F(ObsSystemTest, Observables_system_test) { std::cout << "Validating input RINEX obs (TRUE) file: " << filename_rinex_obs << " ..." << std::endl; bool is_rinex_obs_valid = check_valid_rinex_obs(filename_rinex_obs, 3); From 1b98e7dcadec0acfcca8258167bd4749c7506ea8 Mon Sep 17 00:00:00 2001 From: Damian Miralles Date: Thu, 9 Nov 2017 11:39:09 -0800 Subject: [PATCH 14/20] position fix: First combined GPS + GLONASS position solution First positon fix using a combination of GLONASS and GPS data in GNSS-SDR. The position solution may need further testing but initial results are looking quite promising. --- conf/gnss-sdr_GPS_GLONASS_L1_CA_ibyte.conf | 126 ++++++++++++++++++ .../glonass_gnav_ephemeris.cc | 5 +- 2 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 conf/gnss-sdr_GPS_GLONASS_L1_CA_ibyte.conf diff --git a/conf/gnss-sdr_GPS_GLONASS_L1_CA_ibyte.conf b/conf/gnss-sdr_GPS_GLONASS_L1_CA_ibyte.conf new file mode 100644 index 000000000..156f52741 --- /dev/null +++ b/conf/gnss-sdr_GPS_GLONASS_L1_CA_ibyte.conf @@ -0,0 +1,126 @@ +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +GNSS-SDR.internal_fs_sps=6625000 +Receiver.sources_count=2 +SignalSource.repeat=false + +;######### SIGNAL_SOURCE CONFIG ############ +SignalSource0.implementation=File_Signal_Source +SignalSource0.filename=/archive/NT1065_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE +SignalSource0.item_type=ibyte +SignalSource0.sampling_frequency=6625000 +SignalSource0.samples=0 +SignalSource0.dump=false; +SignalSource0.dump_filename=/archive/signal_glonass.bin + +SignalSource1.implementation=File_Signal_Source +SignalSource1.filename=/archive/NT1065_GLONASS_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE +SignalSource1.item_type=ibyte +SignalSource1.sampling_frequency=6625000 +SignalSource1.samples=0 +SignalSource1.dump=false; +SignalSource1.dump_filename=/archive/signal_glonass.bin + +;######### SIGNAL_CONDITIONER CONFIG ############ +SignalConditioner0.implementation=Signal_Conditioner +DataTypeAdapter0.implementation=Ibyte_To_Complex +InputFilter0.implementation=Pass_Through +InputFilter0.item_type=gr_complex +Resampler0.implementation=Direct_Resampler +Resampler0.sample_freq_in=6625000 +Resampler0.sample_freq_out=6625000 +Resampler0.item_type=gr_complex + +SignalConditioner1.implementation=Signal_Conditioner +DataTypeAdapter1.implementation=Ibyte_To_Complex +InputFilter1.implementation=Pass_Through +InputFilter1.item_type=gr_complex +Resampler1.implementation=Direct_Resampler +Resampler1.sample_freq_in=6625000 +Resampler1.sample_freq_out=6625000 +Resampler1.item_type=gr_complex + +;######### CHANNELS GLOBAL CONFIG ############ +Channels.in_acquisition=1 +Channels_1G.count=5 +Channels_1C.count=5 + +;# Defining GLONASS satellites +Channel0.RF_channel_ID=0 +Channel1.RF_channel_ID=0 +Channel2.RF_channel_ID=0 +Channel3.RF_channel_ID=0 +Channel4.RF_channel_ID=0 +Channel5.RF_channel_ID=1 +Channel6.RF_channel_ID=1 +Channel7.RF_channel_ID=1 +Channel8.RF_channel_ID=1 +Channel9.RF_channel_ID=1 + + +;######### ACQUISITION GLOBAL CONFIG ############ +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +Acquisition_1C.item_type=gr_complex +Acquisition_1C.threshold=0.0 +Acquisition_1C.pfa=0.00001 +Acquisition_1C.if=0 +Acquisition_1C.doppler_max=10000 +Acquisition_1C.doppler_step=250 +Acquisition_1C.dump=false; +Acquisition_1C.dump_filename=/archive/gps_acquisition.dat +;Acquisition_1C.coherent_integration_time_ms=10 + +Acquisition_1G.implementation=GLONASS_L1_CA_PCPS_Acquisition +Acquisition_1G.item_type=gr_complex +Acquisition_1G.threshold=0.0 +Acquisition_1G.pfa=0.00001 +Acquisition_1G.if=0 +Acquisition_1G.doppler_max=10000 +Acquisition_1G.doppler_step=250 +Acquisition_1G.dump=false; +Acquisition_1G.dump_filename=/archive/glo_acquisition.dat +;Acquisition_1G.coherent_integration_time_ms=10 + +;######### TRACKING GLOBAL CONFIG ############ +Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking +Tracking_1C.item_type=gr_complex +Tracking_1C.if=0 +Tracking_1C.early_late_space_chips=0.5 +Tracking_1C.pll_bw_hz=20.0; +Tracking_1C.dll_bw_hz=2.0; +Tracking_1C.dump=true; +Tracking_1C.dump_filename=/archive/gps_tracking_ch_ + +Tracking_1G.implementation=GLONASS_L1_CA_DLL_PLL_Tracking +Tracking_1G.item_type=gr_complex +Tracking_1G.if=0 +Tracking_1G.early_late_space_chips=0.5 +Tracking_1G.pll_bw_hz=25.0; +Tracking_1G.dll_bw_hz=3.0; +Tracking_1G.dump=true; +Tracking_1G.dump_filename=/archive/glo_tracking_ch_ + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder +TelemetryDecoder_1G.implementation=GLONASS_L1_CA_Telemetry_Decoder + +;######### OBSERVABLES CONFIG ############ +Observables.implementation=Hybrid_Observables +Observables.dump=true; +Observables.dump_filename=/archive/gnss_observables.dat + +;######### PVT CONFIG ############ +PVT.implementation=RTKLIB_PVT +PVT.output_rate_ms=100 +PVT.display_rate_ms=500 +PVT.trop_model=Saastamoinen +PVT.flag_rtcm_server=true +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 +PVT.rtcm_tcp_port=2101 +PVT.rtcm_MT1019_rate_ms=5000 +PVT.rtcm_MT1045_rate_ms=5000 +PVT.rtcm_MT1097_rate_ms=1000 +PVT.rtcm_MT1077_rate_ms=1000 +PVT.rinex_version=2 diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.cc b/src/core/system_parameters/glonass_gnav_ephemeris.cc index 278cd5053..91a147621 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.cc +++ b/src/core/system_parameters/glonass_gnav_ephemeris.cc @@ -113,8 +113,7 @@ void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_cor { double tod = 0.0; double dayofweek = 0.0; - double utcsu2utc = 3*3600; - double glot2utcsu = 3*3600; + double glot2utc = 3*3600; double days = 0.0; double total_sec = 0.0, sec_of_day = 0.0; int i = 0; @@ -123,7 +122,7 @@ void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_cor // tk is relative to UTC(SU) + 3.00 hrs, so we need to convert to utc and add corrections // tk plus 10 sec is the true tod since get_TOW is called when in str5 - tod = tod_offset - glot2utcsu - utcsu2utc; + tod = tod_offset - glot2utc ; boost::posix_time::time_duration t(0, 0, tod); From f55f3d34a686d0a4021482101bb061a979343580 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 10 Nov 2017 10:46:53 +0100 Subject: [PATCH 15/20] Print test results in file in a more elegant way --- src/tests/system-tests/position_test.cc | 70 ++++++++++-------- src/tests/system-tests/ttff_gps_l1.cc | 96 ++++++++----------------- 2 files changed, 70 insertions(+), 96 deletions(-) diff --git a/src/tests/system-tests/position_test.cc b/src/tests/system-tests/position_test.cc index c139216e5..0b3cd098d 100644 --- a/src/tests/system-tests/position_test.cc +++ b/src/tests/system-tests/position_test.cc @@ -60,6 +60,13 @@ concurrent_map global_gps_acq_assist_map; class StaticPositionSystemTest: public ::testing::Test { public: + int configure_generator(); + int generate_signal(); + int configure_receiver(); + int run_receiver(); + void check_results(); + +private: std::string generator_binary; std::string p1; std::string p2; @@ -72,12 +79,6 @@ public: std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; - int configure_generator(); - int generate_signal(); - - int configure_receiver(); - int run_receiver(); - void check_results(); void print_results(const std::vector & east, const std::vector & north, const std::vector & up); @@ -88,13 +89,12 @@ public: void geodetic2Enu(const double latitude, const double longitude, const double altitude, double* east, double* north, double* up); + void geodetic2Ecef(const double latitude, const double longitude, const double altitude, + double* x, double* y, double* z); + std::shared_ptr config; std::shared_ptr config_f; std::string generated_kml_file; - -private: - void geodetic2Ecef(const double latitude, const double longitude, const double altitude, - double* x, double* y, double* z); }; @@ -521,29 +521,41 @@ void StaticPositionSystemTest::check_results() double sum__u = std::accumulate(pos_u.begin(), pos_u.end(), 0.0); double mean__u = sum__u / pos_u.size(); + std::stringstream stm; + std::ofstream position_test_file; + if(FLAGS_config_file_ptest.empty()) { - std::cout << "---- ACCURACY ----" << std::endl; - std::cout << "2DRMS = " << 2 * sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl; - std::cout << "DRMS = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl; - std::cout << "CEP = " << 0.62 * compute_stdev_accuracy(pos_n, 0.0) + 0.56 * compute_stdev_accuracy(pos_e, 0.0) << " [m]" << std::endl; - std::cout << "99% SAS = " << 1.122 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; - std::cout << "90% SAS = " << 0.833 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; - std::cout << "MRSE = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; - std::cout << "SEP = " << 0.51 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; - std::cout << "Bias 2D = " << sqrt(std::pow(mean__e, 2.0) + std::pow(mean__n, 2.0)) << " [m]" << std::endl; - std::cout << "Bias 3D = " << sqrt(std::pow(mean__e, 2.0) + std::pow(mean__n, 2.0) + std::pow(mean__u, 2.0)) << " [m]" << std::endl; - std::cout << std::endl; + stm << "---- ACCURACY ----" << std::endl; + stm << "2DRMS = " << 2 * sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl; + stm << "DRMS = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl; + stm << "CEP = " << 0.62 * compute_stdev_accuracy(pos_n, 0.0) + 0.56 * compute_stdev_accuracy(pos_e, 0.0) << " [m]" << std::endl; + stm << "99% SAS = " << 1.122 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; + stm << "90% SAS = " << 0.833 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; + stm << "MRSE = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; + stm << "SEP = " << 0.51 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; + stm << "Bias 2D = " << sqrt(std::pow(mean__e, 2.0) + std::pow(mean__n, 2.0)) << " [m]" << std::endl; + stm << "Bias 3D = " << sqrt(std::pow(mean__e, 2.0) + std::pow(mean__n, 2.0) + std::pow(mean__u, 2.0)) << " [m]" << std::endl; + stm << std::endl; } - std::cout << "---- PRECISION ----" << std::endl; - std::cout << "2DRMS = " << 2 * sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl; - std::cout << "DRMS = " << sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl; - std::cout << "CEP = " << 0.62 * compute_stdev_precision(pos_n) + 0.56 * compute_stdev_precision(pos_e) << " [m]" << std::endl; - std::cout << "99% SAS = " << 1.122 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; - std::cout << "90% SAS = " << 0.833 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; - std::cout << "MRSE = " << sqrt(sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; - std::cout << "SEP = " << 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; + stm << "---- PRECISION ----" << std::endl; + stm << "2DRMS = " << 2 * sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl; + stm << "DRMS = " << sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl; + stm << "CEP = " << 0.62 * compute_stdev_precision(pos_n) + 0.56 * compute_stdev_precision(pos_e) << " [m]" << std::endl; + stm << "99% SAS = " << 1.122 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; + stm << "90% SAS = " << 0.833 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; + stm << "MRSE = " << sqrt(sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; + stm << "SEP = " << 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; + + std::cout << stm.rdbuf(); + std::string output_filename = "position_test_output_" + StaticPositionSystemTest::generated_kml_file.erase(StaticPositionSystemTest::generated_kml_file.length() - 3,3) + "txt"; + position_test_file.open(output_filename.c_str()); + if(position_test_file.is_open()) + { + position_test_file << stm.str(); + position_test_file.close(); + } // Sanity Check double precision_SEP = 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision); diff --git a/src/tests/system-tests/ttff_gps_l1.cc b/src/tests/system-tests/ttff_gps_l1.cc index 0a1047005..fb6eabcf1 100644 --- a/src/tests/system-tests/ttff_gps_l1.cc +++ b/src/tests/system-tests/ttff_gps_l1.cc @@ -359,96 +359,58 @@ void TfttGpsL1CATest::print_TTFF_report(const std::vector & ttff_v, std: std::string default_str = "default"; source = config_->property("SignalSource.implementation", default_str); - if (ttff_report_file.is_open()) - { - ttff_report_file << "---------------------------" << std::endl; - ttff_report_file << " Time-To-First-Fix Report" << std::endl; - ttff_report_file << "---------------------------" << std::endl; - ttff_report_file << "Initial receiver status: "; - if (read_ephemeris) - { - ttff_report_file << "Hot start." << std::endl; - } - else - { - ttff_report_file << "Cold start." << std::endl; - } - ttff_report_file << "A-GNSS: "; - if (agnss && read_ephemeris) - { - ttff_report_file << "Enabled." << std::endl; - } - else - { - ttff_report_file << "Disabled." << std::endl; - } - ttff_report_file << "Valid measurements (" << ttff.size() << "/" << FLAGS_num_measurements << "): "; - for(double ttff_ : ttff) ttff_report_file << ttff_ << " "; - ttff_report_file << std::endl; - ttff_report_file << "TTFF mean: " << mean << " [s]" << std::endl; - if (ttff.size() > 0) - { - ttff_report_file << "TTFF max: " << *max_ttff << " [s]" << std::endl; - ttff_report_file << "TTFF min: " << *min_ttff << " [s]" << std::endl; - } - ttff_report_file << "TTFF stdev: " << stdev << " [s]" << std::endl; - ttff_report_file << "Operating System: " << std::string(HOST_SYSTEM) << std::endl; - ttff_report_file << "Navigation mode: " << "3D" << std::endl; + std::stringstream stm; - if(source.compare("UHD_Signal_Source")) - { - ttff_report_file << "Source: File" << std::endl; - } - else - { - ttff_report_file << "Source: Live" << std::endl; - } - ttff_report_file << "---------------------------" << std::endl; - } - ttff_report_file.close(); - std::cout << "---------------------------" << std::endl; - std::cout << " Time-To-First-Fix Report" << std::endl; - std::cout << "---------------------------" << std::endl; - std::cout << "Initial receiver status: "; + stm << "---------------------------" << std::endl; + stm << " Time-To-First-Fix Report" << std::endl; + stm << "---------------------------" << std::endl; + stm << "Initial receiver status: "; if (read_ephemeris) { - std::cout << "Hot start." << std::endl; + stm << "Hot start." << std::endl; } else { - std::cout << "Cold start." << std::endl; + stm << "Cold start." << std::endl; } - std::cout << "A-GNSS: "; + stm << "A-GNSS: "; if (agnss && read_ephemeris) { - std::cout << "Enabled." << std::endl; + stm << "Enabled." << std::endl; } else { - std::cout << "Disabled." << std::endl; + stm << "Disabled." << std::endl; } - std::cout << "Valid measurements (" << ttff.size() << "/" << FLAGS_num_measurements << "): "; - for(double ttff_ : ttff) std::cout << ttff_ << " "; - std::cout << std::endl; - std::cout << "TTFF mean: " << mean << " [s]" << std::endl; + stm << "Valid measurements (" << ttff.size() << "/" << FLAGS_num_measurements << "): "; + for(double ttff_ : ttff) stm << ttff_ << " "; + stm << std::endl; + stm << "TTFF mean: " << mean << " [s]" << std::endl; if (ttff.size() > 0) { - std::cout << "TTFF max: " << *max_ttff << " [s]" << std::endl; - std::cout << "TTFF min: " << *min_ttff << " [s]" << std::endl; + stm << "TTFF max: " << *max_ttff << " [s]" << std::endl; + stm << "TTFF min: " << *min_ttff << " [s]" << std::endl; } - std::cout << "TTFF stdev: " << stdev << " [s]" << std::endl; - std::cout << "Operating System: " << std::string(HOST_SYSTEM) << std::endl; - std::cout << "Navigation mode: " << "3D" << std::endl; + stm << "TTFF stdev: " << stdev << " [s]" << std::endl; + stm << "Operating System: " << std::string(HOST_SYSTEM) << std::endl; + stm << "Navigation mode: " << "3D" << std::endl; if(source.compare("UHD_Signal_Source")) { - std::cout << "Source: File" << std::endl; + stm << "Source: File" << std::endl; } else { - std::cout << "Source: Live" << std::endl; + stm << "Source: Live" << std::endl; + } + stm << "---------------------------" << std::endl; + + std::cout << stm.rdbuf(); + if (ttff_report_file.is_open()) + { + ttff_report_file << stm.str(); + ttff_report_file.close(); } - std::cout << "---------------------------" << std::endl; } From b838d5d34c3288d689643949eadcebeaa26fb201 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 10 Nov 2017 12:04:21 +0100 Subject: [PATCH 16/20] Improved pseudorange error computation --- src/tests/system-tests/obs_system_test.cc | 153 +++++++++++++++++++--- 1 file changed, 133 insertions(+), 20 deletions(-) diff --git a/src/tests/system-tests/obs_system_test.cc b/src/tests/system-tests/obs_system_test.cc index cb82f302c..b5e291e90 100644 --- a/src/tests/system-tests/obs_system_test.cc +++ b/src/tests/system-tests/obs_system_test.cc @@ -60,12 +60,12 @@ concurrent_map global_gps_acq_assist_map; DEFINE_string(configuration_file, "./default_configuration.conf", "Path of configuration file"); DEFINE_string(filename_rinex_true, "./default_rinex.txt", "Path of RINEX true observations"); DEFINE_string(filename_rinex_obs, "default_string", "Path of RINEX true observations"); -DEFINE_double(pr_error_mean_max, 50.0, "Maximum mean error in pseudorange"); -DEFINE_double(pr_error_std_max, 50.0, "Maximum standard deviation in pseudorange"); -DEFINE_double(cp_error_mean_max, 50.0, "Maximum mean error in carrier phase"); -DEFINE_double(cp_error_std_max, 50.0, "Maximum standard deviation in carrier phase"); -DEFINE_double(dp_error_mean_max, 5.0, "Maximum mean error in Doppler frequency"); -DEFINE_double(dp_error_std_max, 10.0, "Maximum standard deviation in Doppler frequency"); +DEFINE_double(pr_error_mean_max, 25.0, "Maximum mean error in pseudorange"); +DEFINE_double(pr_error_std_max, 5.0, "Maximum standard deviation in pseudorange"); +DEFINE_double(cp_error_mean_max, 5.0, "Maximum mean error in carrier phase"); +DEFINE_double(cp_error_std_max, 2.5, "Maximum standard deviation in carrier phase"); +DEFINE_double(dp_error_mean_max, 50.0, "Maximum mean error in Doppler frequency"); +DEFINE_double(dp_error_std_max, 15.0, "Maximum standard deviation in Doppler frequency"); class ObsSystemTest: public ::testing::Test { @@ -81,11 +81,21 @@ public: std::vector& pseudorange_meas, std::vector& carrierphase_meas, std::vector& doppler_meas, + arma::mat& sow_prn_ref, int signal_type); void time_alignment_diff( std::vector& ref, std::vector& meas, std::vector& diff); + void time_alignment_diff_cp( + std::vector& ref, + std::vector& meas, + std::vector& diff); + void time_alignment_diff_pr( + std::vector& ref, + std::vector& meas, + std::vector& diff, + arma::mat& sow_prn_ref); void compute_pseudorange_error(std::vector& diff, double error_th_mean, double error_th_std); void compute_carrierphase_error( @@ -139,6 +149,7 @@ void ObsSystemTest::read_rinex_files( std::vector& pseudorange_meas, std::vector& carrierphase_meas, std::vector& doppler_meas, + arma::mat& sow_prn_ref, int signal_type) { bool ref_exist = false; @@ -149,6 +160,7 @@ void ObsSystemTest::read_rinex_files( std::string cp_string; std::string dp_string; std::string signal_type_string; + sow_prn_ref.reset(); switch(signal_type) { @@ -273,7 +285,11 @@ void ObsSystemTest::read_rinex_files( while (r_meas >> r_meas_data) { - for (int myprn = 1; myprn < max_prn; myprn++) + double pr_min = 0.0; + double sow_insert = 0.0; + double prn_min = 0.0; + bool set_pr_min = true; + for (int myprn = 1; myprn < max_prn; myprn++) { gpstk::SatID prn( myprn, sat_type); gpstk::CommonTime time = r_meas_data.time; @@ -288,6 +304,13 @@ void ObsSystemTest::read_rinex_files( dataobj = r_meas_data.getObs(prn, pr_string, r_meas_header); double P1 = dataobj.data; pseudorange_meas.at(myprn).insert_rows(pseudorange_meas.at(myprn).n_rows, arma::rowvec({sow, P1})); + if(set_pr_min || (P1 < pr_min)) + { + set_pr_min = false; + pr_min = P1; + sow_insert = sow; + prn_min = static_cast(myprn); + } dataobj = r_meas_data.getObs(prn, cp_string, r_meas_header); double L1 = dataobj.data; @@ -300,6 +323,7 @@ void ObsSystemTest::read_rinex_files( meas_exist = true; } // End of 'if( pointer == roe.obs.end() )' } // end for + sow_prn_ref.insert_rows(sow_prn_ref.n_rows, arma::rowvec({sow_insert, pr_min, prn_min})); } // end while } // End of 'try' block catch(const gpstk::FFStreamError& e) @@ -351,6 +375,94 @@ void ObsSystemTest::time_alignment_diff( } } +void ObsSystemTest::time_alignment_diff_cp( + std::vector& ref, + std::vector& meas, + std::vector& diff) +{ + std::vector::iterator iter_ref; + std::vector::iterator iter_meas; + std::vector::iterator iter_diff; + arma::mat mat_aux; + + iter_ref = ref.begin(); + iter_diff = diff.begin(); + for(iter_meas = meas.begin(); iter_meas != meas.end(); iter_meas++) + { + if( !iter_meas->is_empty() && !iter_ref->is_empty() ) + { + arma::uvec index_ = arma::find(iter_meas->col(0) > iter_ref->at(0, 0)); + arma::uword index_min = arma::min(index_); + index_ = arma::find(iter_meas->col(0) < iter_ref->at(iter_ref->n_rows - 1, 0)); + arma::uword index_max = arma::max(index_); + mat_aux = iter_meas->rows(index_min, index_max); + mat_aux.col(1) -= arma::min(mat_aux.col(1)); + arma::vec ref_aligned; + arma::interp1(iter_ref->col(0), iter_ref->col(1), mat_aux.col(0), ref_aligned); + ref_aligned -= arma::min(ref_aligned); + *iter_diff = ref_aligned - mat_aux.col(1); + } + iter_ref++; + iter_diff++; + } +} + + +void ObsSystemTest::time_alignment_diff_pr( + std::vector& ref, + std::vector& meas, + std::vector& diff, + arma::mat& sow_prn_ref) +{ + std::vector::iterator iter_ref; + std::vector::iterator iter_meas; + std::vector::iterator iter_diff; + arma::mat mat_aux; + arma::vec subtraction_meas; + arma::vec subtraction_ref; + + arma::mat subtraction_pr_ref = sow_prn_ref; + arma::vec::iterator iter_vec0 = subtraction_pr_ref.begin_col(0); + arma::vec::iterator iter_vec1 = subtraction_pr_ref.begin_col(1); + arma::vec::iterator iter_vec2 = subtraction_pr_ref.begin_col(2); + + for(iter_vec1 = subtraction_pr_ref.begin_col(1); iter_vec1 != subtraction_pr_ref.end_col(1); iter_vec1++) + { + arma::vec aux_pr; //vector with only 1 element + arma::vec aux_sow = {*iter_vec0}; //vector with only 1 element + arma::interp1(ref.at(static_cast(*iter_vec2)).col(0), + ref.at(static_cast(*iter_vec2)).col(1), + aux_sow, + aux_pr); + *iter_vec1 = aux_pr(0); + iter_vec0++; + iter_vec2++; + } + + iter_ref = ref.begin(); + iter_diff = diff.begin(); + for(iter_meas = meas.begin(); iter_meas != meas.end(); iter_meas++) + { + if( !iter_meas->is_empty() && !iter_ref->is_empty() ) + { + arma::uvec index_ = arma::find(iter_meas->col(0) > iter_ref->at(0, 0)); + arma::uword index_min = arma::min(index_); + index_ = arma::find(iter_meas->col(0) < iter_ref->at(iter_ref->n_rows - 1, 0)); + arma::uword index_max = arma::max(index_); + mat_aux = iter_meas->rows(index_min, index_max); + arma::interp1(sow_prn_ref.col(0), sow_prn_ref.col(1), mat_aux.col(0), subtraction_meas); + mat_aux.col(1) -= subtraction_meas; + arma::vec ref_aligned; + arma::interp1(iter_ref->col(0), iter_ref->col(1), mat_aux.col(0), ref_aligned); + arma::interp1(subtraction_pr_ref.col(0), subtraction_pr_ref.col(1), mat_aux.col(0), subtraction_ref); + ref_aligned -= subtraction_ref; + *iter_diff = ref_aligned - mat_aux.col(1); + } + iter_ref++; + iter_diff++; + } +} + int ObsSystemTest::configure_receiver() { config = std::make_shared(configuration_file_); @@ -477,7 +589,8 @@ void ObsSystemTest::compute_doppler_error( } void ObsSystemTest::check_results() { - if(gps_1C) + arma::mat sow_prn_ref; + if(gps_1C) { std::vector pseudorange_ref(num_prn_gps); std::vector carrierphase_ref(num_prn_gps); @@ -487,15 +600,15 @@ void ObsSystemTest::check_results() std::vector carrierphase_meas(num_prn_gps); std::vector doppler_meas(num_prn_gps); - read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, 0); + read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, sow_prn_ref, 0); // Time alignment and difference computation std::vector pr_diff(num_prn_gps); std::vector cp_diff(num_prn_gps); std::vector dp_diff(num_prn_gps); - time_alignment_diff(pseudorange_ref, pseudorange_meas, pr_diff); - time_alignment_diff(carrierphase_ref, carrierphase_meas, cp_diff); + time_alignment_diff_pr(pseudorange_ref, pseudorange_meas, pr_diff, sow_prn_ref); + time_alignment_diff_cp(carrierphase_ref, carrierphase_meas, cp_diff); time_alignment_diff(doppler_ref, doppler_meas, dp_diff); // Results @@ -523,15 +636,15 @@ void ObsSystemTest::check_results() std::vector carrierphase_meas(num_prn_gps); std::vector doppler_meas(num_prn_gps); - read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, 2); + read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, sow_prn_ref, 2); // Time alignment and difference computation std::vector pr_diff(num_prn_gps); std::vector cp_diff(num_prn_gps); std::vector dp_diff(num_prn_gps); - time_alignment_diff(pseudorange_ref, pseudorange_meas, pr_diff); - time_alignment_diff(carrierphase_ref, carrierphase_meas, cp_diff); + time_alignment_diff_pr(pseudorange_ref, pseudorange_meas, pr_diff, sow_prn_ref); + time_alignment_diff_cp(carrierphase_ref, carrierphase_meas, cp_diff); time_alignment_diff(doppler_ref, doppler_meas, dp_diff); // Results @@ -559,15 +672,15 @@ void ObsSystemTest::check_results() std::vector carrierphase_meas(num_prn_gal); std::vector doppler_meas(num_prn_gal); - read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, 1); + read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, sow_prn_ref, 1); // Time alignment and difference computation std::vector pr_diff(num_prn_gal); std::vector cp_diff(num_prn_gal); std::vector dp_diff(num_prn_gal); - time_alignment_diff(pseudorange_ref, pseudorange_meas, pr_diff); - time_alignment_diff(carrierphase_ref, carrierphase_meas, cp_diff); + time_alignment_diff_pr(pseudorange_ref, pseudorange_meas, pr_diff, sow_prn_ref); + time_alignment_diff_cp(carrierphase_ref, carrierphase_meas, cp_diff); time_alignment_diff(doppler_ref, doppler_meas, dp_diff); // Results @@ -595,15 +708,15 @@ void ObsSystemTest::check_results() std::vector carrierphase_meas(num_prn_gal); std::vector doppler_meas(num_prn_gal); - read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, 3); + read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, sow_prn_ref, 3); // Time alignment and difference computation std::vector pr_diff(num_prn_gal); std::vector cp_diff(num_prn_gal); std::vector dp_diff(num_prn_gal); - time_alignment_diff(pseudorange_ref, pseudorange_meas, pr_diff); - time_alignment_diff(carrierphase_ref, carrierphase_meas, cp_diff); + time_alignment_diff_pr(pseudorange_ref, pseudorange_meas, pr_diff, sow_prn_ref); + time_alignment_diff_cp(carrierphase_ref, carrierphase_meas, cp_diff); time_alignment_diff(doppler_ref, doppler_meas, dp_diff); // Results From 6e878920d51c93555b2756c95678bdbc37b990e0 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 10 Nov 2017 12:34:20 +0100 Subject: [PATCH 17/20] Avoid working with optional testing executables from old builds If the testing flags are switched ON and then OFF, optional executables are deleted from the install folder. If the flag is switched to ON again, executables are rebuild and copied to the install folder. --- src/tests/CMakeLists.txt | 46 ++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 8464e5199..54ff6e386 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -410,13 +410,20 @@ if(ENABLE_SYSTEM_TESTING) set(HOST_SYSTEM "MacOS") endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") add_definitions(-DHOST_SYSTEM="${HOST_SYSTEM}") - add_executable(ttff - ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/ttff_gps_l1.cc ) + set(TTFF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/ttff_gps_l1.cc) + + # Ensure that ttff is rebuild if was previously built and then removed + if(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/ttff) + execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${TTFF_SOURCES}) + endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/ttff) + + add_executable(ttff ${TTFF_SOURCES} ) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(ttff gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) else(NOT ${GTEST_DIR_LOCAL}) add_dependencies(ttff gtest) endif(NOT ${GTEST_DIR_LOCAL}) + target_link_libraries(ttff ${Boost_LIBRARIES} ${GFlags_LIBS} @@ -444,8 +451,12 @@ if(ENABLE_SYSTEM_TESTING) endif(ENABLE_INSTALL_TESTS) if(ENABLE_SYSTEM_TESTING_EXTRA) - add_executable(position_test - ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/position_test.cc ) + set(POSITION_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/position_test.cc) + # Ensure that position_test is rebuild if was previously built and then removed + if(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) + execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${POSITION_TEST_SOURCES}) + endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) + add_executable(position_test ${POSITION_TEST_SOURCES}) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(position_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) else(NOT ${GTEST_DIR_LOCAL}) @@ -478,7 +489,12 @@ if(ENABLE_SYSTEM_TESTING) endif(ENABLE_INSTALL_TESTS) if(GPSTK_FOUND OR OWN_GPSTK) - add_executable(obs_gps_l1_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_system_test.cc) + set(OBS_GPS_L1_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_system_test.cc) + # Ensure that obs_gps_l1_system_test is rebuild if was previously built and then removed + if(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) + execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${OBS_GPS_L1_TEST_SOURCES}) + endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) + add_executable(obs_gps_l1_system_test ${OBS_GPS_L1_TEST_SOURCES}) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(obs_gps_l1_system_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION} ) else(NOT ${GTEST_DIR_LOCAL}) @@ -503,8 +519,26 @@ if(ENABLE_SYSTEM_TESTING) ${CMAKE_SOURCE_DIR}/install/$ ) endif(ENABLE_INSTALL_TESTS) endif(GPSTK_FOUND OR OWN_GPSTK) + else(ENABLE_SYSTEM_TESTING_EXTRA) + # Avoid working with old executables if they were switched ON and then OFF + if(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) + file(REMOVE ${CMAKE_SOURCE_DIR}/install/position_test) + endif(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) + if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) + file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) + endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) endif(ENABLE_SYSTEM_TESTING_EXTRA) - +else(ENABLE_SYSTEM_TESTING) + # Avoid working with old executables if they were switched ON and then OFF + if(EXISTS ${CMAKE_SOURCE_DIR}/install/ttff) + file(REMOVE ${CMAKE_SOURCE_DIR}/install/ttff) + endif(EXISTS ${CMAKE_SOURCE_DIR}/install/ttff) + if(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) + file(REMOVE ${CMAKE_SOURCE_DIR}/install/position_test) + endif(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) + if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) + file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) + endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) endif(ENABLE_SYSTEM_TESTING) From baf2afdd3eeee4d1c4fe6cc9f51ceb486cac7419 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 10 Nov 2017 14:12:25 +0100 Subject: [PATCH 18/20] Added GnuPlot to observables system test --- src/tests/system-tests/obs_system_test.cc | 188 +++++++++++++++++++--- 1 file changed, 162 insertions(+), 26 deletions(-) diff --git a/src/tests/system-tests/obs_system_test.cc b/src/tests/system-tests/obs_system_test.cc index b5e291e90..47a46e7dd 100644 --- a/src/tests/system-tests/obs_system_test.cc +++ b/src/tests/system-tests/obs_system_test.cc @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -48,6 +49,8 @@ #include #include #include +#include "gnuplot_i.h" +#include "test_flags.h" #include "concurrent_map.h" #include "concurrent_queue.h" #include "control_thread.h" @@ -66,6 +69,7 @@ DEFINE_double(cp_error_mean_max, 5.0, "Maximum mean error in carrier phase"); DEFINE_double(cp_error_std_max, 2.5, "Maximum standard deviation in carrier phase"); DEFINE_double(dp_error_mean_max, 50.0, "Maximum mean error in Doppler frequency"); DEFINE_double(dp_error_std_max, 15.0, "Maximum standard deviation in Doppler frequency"); +DEFINE_bool(plot_obs_sys_test, false, "Plots results of ObsSystemTest with gnuplot"); class ObsSystemTest: public ::testing::Test { @@ -97,13 +101,16 @@ public: std::vector& diff, arma::mat& sow_prn_ref); void compute_pseudorange_error(std::vector& diff, - double error_th_mean, double error_th_std); + double error_th_mean, double error_th_std, + std::string signal_name); void compute_carrierphase_error( std::vector& diff, - double error_th_mean, double error_th_std); + double error_th_mean, double error_th_std, + std::string signal_name); void compute_doppler_error( std::vector& diff, - double error_th_mean, double error_th_std); + double error_th_mean, double error_th_std, + std::string signal_name); std::string filename_rinex_obs = FLAGS_filename_rinex_true; std::string generated_rinex_obs = FLAGS_filename_rinex_obs; std::string configuration_file_ = FLAGS_configuration_file; @@ -466,12 +473,7 @@ void ObsSystemTest::time_alignment_diff_pr( int ObsSystemTest::configure_receiver() { config = std::make_shared(configuration_file_); - int d_rinex_ver = config->property("PVT.rinex_version", 0); - if(d_rinex_ver != 2) - { - std::cout << "Invalid RINEX version. Set PVT.rinex_version=2 in configuration file." << std::endl; - std::cout << "GPSTk does not work with RINEX v. 3.02." << std::endl; - } + if( config->property("Channels_1C.count", 0) > 0 ) {gps_1C = true;} if( config->property("Channels_1B.count", 0) > 0 ) @@ -524,16 +526,23 @@ int ObsSystemTest::run_receiver() void ObsSystemTest::compute_pseudorange_error( std::vector& diff, - double error_th_mean, double error_th_std) + double error_th_mean, double error_th_std, + std::string signal_name) { int prn_id = 0; std::vector::iterator iter_diff; + std::vector means; + std::vector stddevs; + std::vector prns; for(iter_diff = diff.begin(); iter_diff != diff.end(); iter_diff++) { if(!iter_diff->is_empty()) { double d_mean = arma::mean(*iter_diff); + means.push_back(d_mean); double d_stddev = arma::stddev(*iter_diff); + stddevs.push_back(d_stddev); + prns.push_back(static_cast(prn_id)); std::cout << "-- Mean pseudorange difference for sat " << prn_id << ": " << d_mean; std::cout << " +/- " << d_stddev; std::cout << " [m]" << std::endl; @@ -542,20 +551,62 @@ void ObsSystemTest::compute_pseudorange_error( } prn_id++; } + if(FLAGS_plot_obs_sys_test == true) + { + const std::string gnuplot_executable(FLAGS_gnuplot_executable); + if(gnuplot_executable.empty()) + { + std::cout << "WARNING: Although the flag plot_obs_sys_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(signal_name + " Pseudorange error"); + g1.set_grid(); + g1.set_xlabel("PRN"); + g1.set_ylabel("Pseudorange error [m]"); + g1.plot_xy(prns, means, "Mean"); + g1.plot_xy(prns, stddevs, "Standard deviation"); + //g1.savetops("FFT_execution_times_extended"); + //g1.savetopdf("FFT_execution_times_extended", 18); + g1.showonscreen(); // window output + } + catch (const GnuplotException & ge) + { + std::cout << ge.what() << std::endl; + } + } + } } void ObsSystemTest::compute_carrierphase_error( std::vector& diff, - double error_th_mean, double error_th_std) + double error_th_mean, double error_th_std, + std::string signal_name) { int prn_id = 0; + std::vector means; + std::vector stddevs; + std::vector prns; std::vector::iterator iter_diff; for(iter_diff = diff.begin(); iter_diff != diff.end(); iter_diff++) { if(!iter_diff->is_empty()) { double d_mean = arma::mean(*iter_diff); + means.push_back(d_mean); double d_stddev = arma::stddev(*iter_diff); + stddevs.push_back(d_stddev); + prns.push_back(static_cast(prn_id)); std::cout << "-- Mean carrier phase difference for sat " << prn_id << ": " << d_mean; std::cout << " +/- " << d_stddev; std::cout << " whole cycles" << std::endl; @@ -564,20 +615,62 @@ void ObsSystemTest::compute_carrierphase_error( } prn_id++; } + if(FLAGS_plot_obs_sys_test == true) + { + const std::string gnuplot_executable(FLAGS_gnuplot_executable); + if(gnuplot_executable.empty()) + { + std::cout << "WARNING: Although the flag plot_obs_sys_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(signal_name + " Carrier phase error"); + g1.set_grid(); + g1.set_xlabel("PRN"); + g1.set_ylabel("Carrier phase error [whole cycles]"); + g1.plot_xy(prns, means, "Mean"); + g1.plot_xy(prns, stddevs, "Standard deviation"); + //g1.savetops("FFT_execution_times_extended"); + //g1.savetopdf("FFT_execution_times_extended", 18); + g1.showonscreen(); // window output + } + catch (const GnuplotException & ge) + { + std::cout << ge.what() << std::endl; + } + } + } } void ObsSystemTest::compute_doppler_error( std::vector& diff, - double error_th_mean, double error_th_std) + double error_th_mean, double error_th_std, + std::string signal_name) { int prn_id = 0; + std::vector means; + std::vector stddevs; + std::vector prns; std::vector::iterator iter_diff; for(iter_diff = diff.begin(); iter_diff != diff.end(); iter_diff++) { if(!iter_diff->is_empty()) { double d_mean = arma::mean(*iter_diff); + means.push_back(d_mean); double d_stddev = arma::stddev(*iter_diff); + stddevs.push_back(d_stddev); + prns.push_back(static_cast(prn_id)); std::cout << "-- Mean Doppler difference for sat " << prn_id << ": " << d_mean; std::cout << " +/- " << d_stddev; std::cout << " [Hz]" << std::endl; @@ -586,6 +679,41 @@ void ObsSystemTest::compute_doppler_error( } prn_id++; } + if(FLAGS_plot_obs_sys_test == true) + { + const std::string gnuplot_executable(FLAGS_gnuplot_executable); + if(gnuplot_executable.empty()) + { + std::cout << "WARNING: Although the flag plot_obs_sys_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(signal_name + " Doppler error"); + g1.set_grid(); + g1.set_xlabel("PRN"); + g1.set_ylabel("Doppler error [Hz]"); + g1.plot_xy(prns, means, "Mean"); + g1.plot_xy(prns, stddevs, "Standard deviation"); + //g1.savetops("FFT_execution_times_extended"); + //g1.savetopdf("FFT_execution_times_extended", 18); + g1.showonscreen(); // window output + } + catch (const GnuplotException & ge) + { + std::cout << ge.what() << std::endl; + } + } + } } void ObsSystemTest::check_results() { @@ -612,19 +740,21 @@ void ObsSystemTest::check_results() time_alignment_diff(doppler_ref, doppler_meas, dp_diff); // Results + std::cout << std::endl; + std::cout << std::endl; std::cout << "GPS L1 C/A obs. results" << std::endl; // Compute pseudorange error - compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std); + compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std, "GPS L1 C/A"); // Compute carrier phase error - compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std); + compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std, "GPS L1 C/A"); // Compute Doppler error - compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std); + compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std, "GPS L1 C/A"); } if(gps_L5) { @@ -648,19 +778,21 @@ void ObsSystemTest::check_results() time_alignment_diff(doppler_ref, doppler_meas, dp_diff); // Results + std::cout << std::endl; + std::cout << std::endl; std::cout << "GPS L5 obs. results" << std::endl; // Compute pseudorange error - compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std); + compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std, "GPS L5"); // Compute carrier phase error - compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std); + compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std, "GPS L5"); // Compute Doppler error - compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std); + compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std, "GPS L5"); } if(gal_1B) { @@ -684,19 +816,21 @@ void ObsSystemTest::check_results() time_alignment_diff(doppler_ref, doppler_meas, dp_diff); // Results + std::cout << std::endl; + std::cout << std::endl; std::cout << "Galileo E1B obs. results" << std::endl; // Compute pseudorange error - compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std); + compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std, "Galileo E1B"); // Compute carrier phase error - compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std); + compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std, "Galileo E1B"); // Compute Doppler error - compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std); + compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std, "Galileo E1B"); } if(gal_E5a) { @@ -720,19 +854,21 @@ void ObsSystemTest::check_results() time_alignment_diff(doppler_ref, doppler_meas, dp_diff); // Results + std::cout << std::endl; + std::cout << std::endl; std::cout << "Galileo E5a obs. results" << std::endl; // Compute pseudorange error - compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std); + compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std, "Galileo E5a"); // Compute carrier phase error - compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std); + compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std, "Galileo E5a"); // Compute Doppler error - compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std); + compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std, "Galileo E5a"); } } @@ -754,11 +890,11 @@ TEST_F(ObsSystemTest, Observables_system_test) bool is_gen_rinex_obs_valid = false; if(internal_rinex_generation) { - is_gen_rinex_obs_valid = check_valid_rinex_obs( "./" + generated_rinex_obs, 2); + is_gen_rinex_obs_valid = check_valid_rinex_obs( "./" + generated_rinex_obs, config->property("PVT.rinex_version", 3)); } else { - is_gen_rinex_obs_valid = check_valid_rinex_obs(generated_rinex_obs, 2); + is_gen_rinex_obs_valid = check_valid_rinex_obs(generated_rinex_obs, config->property("PVT.rinex_version", 3)); } ASSERT_EQ(true, is_gen_rinex_obs_valid) << "The RINEX observation file " << generated_rinex_obs << ", generated by GNSS-SDR, is not well formed."; std::cout << "The file is valid." << std::endl; From 218844cce5f083f818f9eaac361405b9ac8971a2 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 10 Nov 2017 14:38:16 +0100 Subject: [PATCH 19/20] Minor changes in RINEX printer version setting --- src/algorithms/PVT/libs/rinex_printer.cc | 16 ++++++++-------- src/tests/system-tests/obs_system_test.cc | 22 +++++++++++----------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 7de3391c9..6c993fecc 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -409,8 +409,8 @@ std::string Rinex_Printer::getLocalTime() void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) { std::string line; - stringVersion = "3.02"; - version = 3; + //stringVersion = "3.02"; + //version = 3; // -------- Line 1 line = std::string(5, ' '); @@ -815,8 +815,8 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, co void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac) { std::string line; - stringVersion = "3.02"; - version = 3; + //stringVersion = "3.02"; + //version = 3; // -------- Line 1 line = std::string(5, ' '); @@ -2909,11 +2909,11 @@ void Rinex_Printer::rinex_obs_header(std::fstream & out, const Gps_Ephemeris & e void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& eph, const double d_TOW_first_observation, const std::string bands) { std::string line; - version = 3; + //version = 3; // -------- Line 1 line = std::string(5, ' '); - line += "3.02"; + line += stringVersion; line += std::string(11, ' '); line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); line += satelliteSystem["Galileo"]; @@ -3171,11 +3171,11 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps { if(galileo_eph.e_1){} // avoid warning, not needed std::string line; - version = 3; + //version = 3; // -------- Line 1 line = std::string(5, ' '); - line += "3.02"; + line += stringVersion; line += std::string(11, ' '); line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); line += satelliteSystem["Mixed"]; diff --git a/src/tests/system-tests/obs_system_test.cc b/src/tests/system-tests/obs_system_test.cc index 47a46e7dd..1a9d990fb 100644 --- a/src/tests/system-tests/obs_system_test.cc +++ b/src/tests/system-tests/obs_system_test.cc @@ -67,8 +67,8 @@ DEFINE_double(pr_error_mean_max, 25.0, "Maximum mean error in pseudorange"); DEFINE_double(pr_error_std_max, 5.0, "Maximum standard deviation in pseudorange"); DEFINE_double(cp_error_mean_max, 5.0, "Maximum mean error in carrier phase"); DEFINE_double(cp_error_std_max, 2.5, "Maximum standard deviation in carrier phase"); -DEFINE_double(dp_error_mean_max, 50.0, "Maximum mean error in Doppler frequency"); -DEFINE_double(dp_error_std_max, 15.0, "Maximum standard deviation in Doppler frequency"); +DEFINE_double(dp_error_mean_max, 75.0, "Maximum mean error in Doppler frequency"); +DEFINE_double(dp_error_std_max, 25.0, "Maximum standard deviation in Doppler frequency"); DEFINE_bool(plot_obs_sys_test, false, "Plots results of ObsSystemTest with gnuplot"); class ObsSystemTest: public ::testing::Test @@ -538,12 +538,12 @@ void ObsSystemTest::compute_pseudorange_error( { if(!iter_diff->is_empty()) { - double d_mean = arma::mean(*iter_diff); + double d_mean = std::sqrt(arma::mean(arma::square(*iter_diff))); means.push_back(d_mean); double d_stddev = arma::stddev(*iter_diff); stddevs.push_back(d_stddev); prns.push_back(static_cast(prn_id)); - std::cout << "-- Mean pseudorange difference for sat " << prn_id << ": " << d_mean; + std::cout << "-- RMS pseudorange difference for sat " << prn_id << ": " << d_mean; std::cout << " +/- " << d_stddev; std::cout << " [m]" << std::endl; EXPECT_LT(d_mean, error_th_mean); @@ -574,7 +574,7 @@ void ObsSystemTest::compute_pseudorange_error( g1.set_grid(); g1.set_xlabel("PRN"); g1.set_ylabel("Pseudorange error [m]"); - g1.plot_xy(prns, means, "Mean"); + g1.plot_xy(prns, means, "RMS error"); g1.plot_xy(prns, stddevs, "Standard deviation"); //g1.savetops("FFT_execution_times_extended"); //g1.savetopdf("FFT_execution_times_extended", 18); @@ -602,12 +602,12 @@ void ObsSystemTest::compute_carrierphase_error( { if(!iter_diff->is_empty()) { - double d_mean = arma::mean(*iter_diff); + double d_mean = std::sqrt(arma::mean(arma::square(*iter_diff))); means.push_back(d_mean); double d_stddev = arma::stddev(*iter_diff); stddevs.push_back(d_stddev); prns.push_back(static_cast(prn_id)); - std::cout << "-- Mean carrier phase difference for sat " << prn_id << ": " << d_mean; + std::cout << "-- RMS carrier phase difference for sat " << prn_id << ": " << d_mean; std::cout << " +/- " << d_stddev; std::cout << " whole cycles" << std::endl; EXPECT_LT(d_mean, error_th_mean); @@ -638,7 +638,7 @@ void ObsSystemTest::compute_carrierphase_error( g1.set_grid(); g1.set_xlabel("PRN"); g1.set_ylabel("Carrier phase error [whole cycles]"); - g1.plot_xy(prns, means, "Mean"); + g1.plot_xy(prns, means, "RMS error"); g1.plot_xy(prns, stddevs, "Standard deviation"); //g1.savetops("FFT_execution_times_extended"); //g1.savetopdf("FFT_execution_times_extended", 18); @@ -666,12 +666,12 @@ void ObsSystemTest::compute_doppler_error( { if(!iter_diff->is_empty()) { - double d_mean = arma::mean(*iter_diff); + double d_mean = std::sqrt(arma::mean(arma::square(*iter_diff))); means.push_back(d_mean); double d_stddev = arma::stddev(*iter_diff); stddevs.push_back(d_stddev); prns.push_back(static_cast(prn_id)); - std::cout << "-- Mean Doppler difference for sat " << prn_id << ": " << d_mean; + std::cout << "-- RMS Doppler difference for sat " << prn_id << ": " << d_mean; std::cout << " +/- " << d_stddev; std::cout << " [Hz]" << std::endl; EXPECT_LT(d_mean, error_th_mean); @@ -702,7 +702,7 @@ void ObsSystemTest::compute_doppler_error( g1.set_grid(); g1.set_xlabel("PRN"); g1.set_ylabel("Doppler error [Hz]"); - g1.plot_xy(prns, means, "Mean"); + g1.plot_xy(prns, means, "RMS error"); g1.plot_xy(prns, stddevs, "Standard deviation"); //g1.savetops("FFT_execution_times_extended"); //g1.savetopdf("FFT_execution_times_extended", 18); From 05247ea4be9c46abbedf49d1430b15630ac77de3 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 11 Nov 2017 10:27:02 +0100 Subject: [PATCH 20/20] Remove repeated line --- src/tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index a7ce8ed34..2bafedc98 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -530,10 +530,10 @@ if(ENABLE_SYSTEM_TESTING) file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) install(TARGETS obs_gps_l1_system_test RUNTIME DESTINATION bin COMPONENT "obs_gps_l1_system_test") + if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test) file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_system_test) endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test) - install(TARGETS obs_gps_l1_system_test RUNTIME DESTINATION bin COMPONENT "obs_gps_l1_system_test") install(TARGETS obs_system_test RUNTIME DESTINATION bin COMPONENT "obs_system_test") else(ENABLE_INSTALL_TESTS) add_custom_command(TARGET obs_gps_l1_system_test POST_BUILD