From dda18336468f470d837800dd976c5b13a316ed8a Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 20 Dec 2016 21:43:19 +0100 Subject: [PATCH 01/15] Add example of gnss-sim usage --- src/tests/CMakeLists.txt | 40 +++++++++++++++++++++-- src/tests/system-tests/trk_system_test.cc | 37 +++++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 src/tests/system-tests/trk_system_test.cc diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index a62f113ef..74e655692 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -35,15 +35,18 @@ if(GTEST_INCLUDE_DIRS) set(GTEST_DIR_LOCAL true) endif(GTEST_INCLUDE_DIRS) +set(GTEST_COMPILER -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}) +set(TOOLCHAIN_ARG "") + if(NOT ${GTEST_DIR_LOCAL}) # if GTEST_DIR is not defined, we download and build it set(gtest_RELEASE 1.8.0) - set(TOOLCHAIN_ARG "") - set(GTEST_COMPILER -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}) + if(EXISTS $ENV{OECORE_TARGET_SYSROOT}) set(GTEST_COMPILER "") set(TOOLCHAIN_ARG -DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/Toolchains/oe-sdk_cross.cmake) endif(EXISTS $ENV{OECORE_TARGET_SYSROOT}) + ExternalProject_Add( gtest-${gtest_RELEASE} GIT_REPOSITORY https://github.com/google/googletest @@ -130,6 +133,26 @@ if (ENABLE_CUDA) add_definitions(-DCUDA_BLOCKS_TEST=1) endif(ENABLE_CUDA) +################################################################################ +# Optional generator +################################################################################ +if(ENABLE_SW_GENERATOR) + ExternalProject_Add( + gnss-sim + GIT_REPOSITORY https://bitbucket.org/jarribas/gnss-simulator + GIT_TAG master + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gnss-sim + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim + CMAKE_ARGS ${GTEST_COMPILER} ${TOOLCHAIN_ARG} + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" + ) + set(SW_GENERATOR_BIN ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim/gnss_sim) + add_definitions(-DSW_GENERATOR_BIN="${SW_GENERATOR_BIN}") + add_definitions(-DDEFAULT_RINEX_NAV="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/brdc3540.14n") +endif(ENABLE_SW_GENERATOR) + add_definitions(-DTEST_PATH="${CMAKE_SOURCE_DIR}/src/tests/") include_directories( @@ -429,4 +452,17 @@ if(ENABLE_SYSTEM_TESTING) COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_SOURCE_DIR}/install/$ ) + + add_executable(trk_system_test + ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/trk_system_test.cc ) + if(NOT ${GTEST_DIR_LOCAL}) + add_dependencies(trk_system_test gtest-${gtest_RELEASE}) + else(NOT ${GTEST_DIR_LOCAL}) + add_dependencies(trk_system_test gtest) + endif(NOT ${GTEST_DIR_LOCAL}) + add_custom_command(TARGET trk_system_test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy $ + ${CMAKE_SOURCE_DIR}/install/$ + ) + endif(ENABLE_SYSTEM_TESTING) diff --git a/src/tests/system-tests/trk_system_test.cc b/src/tests/system-tests/trk_system_test.cc new file mode 100644 index 000000000..70898c469 --- /dev/null +++ b/src/tests/system-tests/trk_system_test.cc @@ -0,0 +1,37 @@ + +#include +#include +#include +#include +//#include +//#include +//include + + + +int main() +{ + pid_t wait_result; + int child_status; + + // Configure signal + std::string str = std::string(SW_GENERATOR_BIN); + std::string p1 = std::string("-rinex_nav_file=") + std::string(DEFAULT_RINEX_NAV); + std::string p2 = std::string("-static_position=30.286502,120.032669,100,40"); + + char *const parmList[] = { &str[0], &str[0], &p1[0], &p2[0], NULL }; + int pid; + if ((pid = fork()) == -1) + perror("fork error"); + else if (pid == 0) + { + execv(&str[0], parmList); + std::cout << "Return not expected. Must be an execv error." << std::endl; + std::terminate(); + } + + wait_result = waitpid(pid, &child_status, 0); + std::cout << "Signal and Observables RINEX files created." << std::endl; + + return 0; +} From 211b7b34c04d905d1780afa209a82c68a8b85468 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 21 Dec 2016 14:21:52 +0100 Subject: [PATCH 02/15] Embed the whole system in a test --- src/tests/CMakeLists.txt | 7 + src/tests/system-tests/trk_system_test.cc | 300 +++++++++++++++++++++- 2 files changed, 297 insertions(+), 10 deletions(-) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 74e655692..d46113690 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -151,6 +151,8 @@ if(ENABLE_SW_GENERATOR) set(SW_GENERATOR_BIN ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim/gnss_sim) add_definitions(-DSW_GENERATOR_BIN="${SW_GENERATOR_BIN}") add_definitions(-DDEFAULT_RINEX_NAV="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/brdc3540.14n") + add_definitions(-DDEFAULT_POSITION_FILE="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/circle.csv") + endif(ENABLE_SW_GENERATOR) add_definitions(-DTEST_PATH="${CMAKE_SOURCE_DIR}/src/tests/") @@ -460,6 +462,11 @@ if(ENABLE_SYSTEM_TESTING) else(NOT ${GTEST_DIR_LOCAL}) add_dependencies(trk_system_test gtest) endif(NOT ${GTEST_DIR_LOCAL}) + target_link_libraries(trk_system_test ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${GTEST_LIBRARIES} + gnss_sp_libs + gnss_rx) add_custom_command(TARGET trk_system_test POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_SOURCE_DIR}/install/$ diff --git a/src/tests/system-tests/trk_system_test.cc b/src/tests/system-tests/trk_system_test.cc index 70898c469..51e120e23 100644 --- a/src/tests/system-tests/trk_system_test.cc +++ b/src/tests/system-tests/trk_system_test.cc @@ -3,35 +3,315 @@ #include #include #include -//#include -//#include -//include +#include +#include +#include +#include "control_thread.h" +#include "concurrent_map.h" +#include "concurrent_queue.h" +#include "in_memory_configuration.h" +// For GPS NAVIGATION (L1) +concurrent_queue global_gps_acq_assist_queue; +concurrent_map global_gps_acq_assist_map; +class Trk_System_Test: public ::testing::Test +{ +public: + std::string generator_binary; + std::string p1; + std::string p2_static; + std::string p2_dynamic; + std::string p3; + std::string p4; + std::string p5; -int main() + const int baseband_sampling_freq = 2.6e6; + + std::string filename_rinex_obs = "sim.16o"; + std::string filename_raw_data = "signal_out.bin"; + + int configure_generator(); + int generate_signal(); + int configure_receiver(); + int run_receiver(); + int check_results(); + + std::shared_ptr config; +}; + +int Trk_System_Test::configure_generator() +{ + // Configure signal + generator_binary = std::string(SW_GENERATOR_BIN); + p1 = std::string("-rinex_nav_file=") + std::string(DEFAULT_RINEX_NAV); + p2_static = std::string("-static_position=30.286502,120.032669,100,1000"); + p2_dynamic = std::string("-obs_pos_file=") + std::string(DEFAULT_POSITION_FILE); // Observer positions file, in .csv or .nmea format" + p3 = std::string("-rinex_obs_file=") + filename_rinex_obs; // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + 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 Trk_System_Test::generate_signal() { pid_t wait_result; int child_status; - // Configure signal - std::string str = std::string(SW_GENERATOR_BIN); - std::string p1 = std::string("-rinex_nav_file=") + std::string(DEFAULT_RINEX_NAV); - std::string p2 = std::string("-static_position=30.286502,120.032669,100,40"); + char *const parmList[] = { &generator_binary[0], &generator_binary[0], &p1[0], &p2_static[0], &p3[0], &p4[0], &p5[0], NULL }; - char *const parmList[] = { &str[0], &str[0], &p1[0], &p2[0], NULL }; int pid; if ((pid = fork()) == -1) perror("fork error"); else if (pid == 0) { - execv(&str[0], parmList); + 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); std::cout << "Signal and Observables RINEX files created." << std::endl; + return 0; +} + +int Trk_System_Test::configure_receiver() +{ + config = std::make_shared(); + + const double central_freq = 1575420000.0; + const int sampling_rate_internal = baseband_sampling_freq; + const double gain_dB = 40.0; + + const int number_of_taps = 11; + const int number_of_bands = 2; + const float band1_begin = 0.0; + const float band1_end = 0.48; + const float band2_begin = 0.52; + const float band2_end = 1.0; + const float ampl1_begin = 1.0; + const float ampl1_end = 1.0; + const float ampl2_begin = 0.0; + const float ampl2_end = 0.0; + const float band1_error = 1.0; + const float band2_error = 1.0; + const int grid_density = 16; + const int decimation_factor = 1; + + const float zero = 0.0; + const int number_of_channels = 8; + const int in_acquisition = 1; + + const float threshold = 0.01; + const float doppler_max = 8000.0; + const float doppler_step = 500.0; + const int max_dwells = 1; + const int tong_init_val = 2; + const int tong_max_val = 10; + const int tong_max_dwells = 30; + const int coherent_integration_time_ms = 1; + + const float pll_bw_hz = 30.0; + const float dll_bw_hz = 4.0; + const float early_late_space_chips = 0.5; + + const int display_rate_ms = 500; + const int output_rate_ms = 100; + const int averaging_depth = 10; + + bool false_bool = false; + + config->set_property("GNSS-SDR.internal_fs_hz", std::to_string(sampling_rate_internal)); + + // Set the assistance system parameters + config->set_property("GNSS-SDR.SUPL_read_gps_assistance_xml", "false"); + config->set_property("GNSS-SDR.SUPL_gps_enabled", "false"); + config->set_property("GNSS-SDR.SUPL_gps_ephemeris_server", "supl.google.com"); + config->set_property("GNSS-SDR.SUPL_gps_ephemeris_port", std::to_string(7275)); + config->set_property("GNSS-SDR.SUPL_gps_acquisition_server", "supl.google.com"); + config->set_property("GNSS-SDR.SUPL_gps_acquisition_port", std::to_string(7275)); + config->set_property("GNSS-SDR.SUPL_MCC", std::to_string(244)); + config->set_property("GNSS-SDR.SUPL_MNS", std::to_string(5)); + config->set_property("GNSS-SDR.SUPL_LAC", "0x59e2"); + config->set_property("GNSS-SDR.SUPL_CI", "0x31b0"); + + // Set the Signal Source + config->set_property("SignalSource.implementation", "File_Signal_Source"); + config->set_property("SignalSource.filename", "./" + filename_raw_data); + config->set_property("SignalSource.sampling_frequency", std::to_string(sampling_rate_internal)); + config->set_property("SignalSource.item_type", "ibyte"); + config->set_property("SignalSource.samples", std::to_string(zero)); + + // Set the Signal Conditioner + config->set_property("SignalConditioner.implementation", "Signal_Conditioner"); + config->set_property("DataTypeAdapter.implementation", "Ibyte_To_Complex"); + config->set_property("InputFilter.implementation", "Fir_Filter"); + config->set_property("InputFilter.dump", "false"); + config->set_property("InputFilter.input_item_type", "gr_complex"); + config->set_property("InputFilter.output_item_type", "gr_complex"); + config->set_property("InputFilter.taps_item_type", "float"); + config->set_property("InputFilter.number_of_taps", std::to_string(number_of_taps)); + config->set_property("InputFilter.number_of_bands", std::to_string(number_of_bands)); + config->set_property("InputFilter.band1_begin", std::to_string(band1_begin)); + config->set_property("InputFilter.band1_end", std::to_string(band1_end)); + config->set_property("InputFilter.band2_begin", std::to_string(band2_begin)); + config->set_property("InputFilter.band2_end", std::to_string(band2_end)); + config->set_property("InputFilter.ampl1_begin", std::to_string(ampl1_begin)); + config->set_property("InputFilter.ampl1_end", std::to_string(ampl1_end)); + config->set_property("InputFilter.ampl2_begin", std::to_string(ampl2_begin)); + config->set_property("InputFilter.ampl2_end", std::to_string(ampl2_end)); + config->set_property("InputFilter.band1_error", std::to_string(band1_error)); + config->set_property("InputFilter.band2_error", std::to_string(band2_error)); + config->set_property("InputFilter.filter_type", "bandpass"); + config->set_property("InputFilter.grid_density", std::to_string(grid_density)); + config->set_property("InputFilter.sampling_frequency", std::to_string(sampling_rate_internal)); + config->set_property("InputFilter.IF", std::to_string(zero)); + config->set_property("Resampler.implementation", "Pass_Through"); + config->set_property("Resampler.dump", "false"); + config->set_property("Resampler.item_type", "gr_complex"); + config->set_property("Resampler.sample_freq_in", std::to_string(sampling_rate_internal)); + config->set_property("Resampler.sample_freq_out", std::to_string(sampling_rate_internal)); + + // Set the number of Channels + config->set_property("Channels_1C.count", std::to_string(number_of_channels)); + config->set_property("Channels.in_acquisition", std::to_string(in_acquisition)); + config->set_property("Channel.signal", "1C"); + + // Set Acquisition + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Tong_Acquisition"); + config->set_property("Acquisition_1C.item_type", "gr_complex"); + config->set_property("Acquisition_1C.if", std::to_string(zero)); + config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); + config->set_property("Acquisition_1C.threshold", std::to_string(threshold)); + config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max)); + config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); + config->set_property("Acquisition_1C.bit_transition_flag", "false"); + config->set_property("Acquisition_1C.max_dwells", std::to_string(max_dwells)); + config->set_property("Acquisition_1C.tong_init_val", std::to_string(tong_init_val)); + config->set_property("Acquisition_1C.tong_max_val", std::to_string(tong_max_val)); + config->set_property("Acquisition_1C.tong_max_dwells", std::to_string(tong_max_dwells)); + + // Set Tracking + config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_Tracking"); + config->set_property("Tracking_1C.item_type", "gr_complex"); + config->set_property("Tracking_1C.if", std::to_string(zero)); + config->set_property("Tracking_1C.dump", "false"); + config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); + config->set_property("Tracking_1C.pll_bw_hz", std::to_string(pll_bw_hz)); + config->set_property("Tracking_1C.dll_bw_hz", std::to_string(dll_bw_hz)); + config->set_property("Tracking_1C.early_late_space_chips", std::to_string(early_late_space_chips)); + + // Set Telemetry + config->set_property("TelemetryDecoder_1C.implementation", "GPS_L1_CA_Telemetry_Decoder"); + config->set_property("TelemetryDecoder_1C.dump", "false"); + config->set_property("TelemetryDecoder_1C.decimation_factor", std::to_string(decimation_factor)); + + // Set Observables + config->set_property("Observables.implementation", "GPS_L1_CA_Observables"); + config->set_property("Observables.dump", "false"); + config->set_property("Observables.dump_filename", "./observables.dat"); + + // Set PVT + config->set_property("PVT.implementation", "GPS_L1_CA_PVT"); + config->set_property("PVT.averaging_depth", std::to_string(averaging_depth)); + config->set_property("PVT.flag_averaging", "true"); + config->set_property("PVT.output_rate_ms", std::to_string(output_rate_ms)); + config->set_property("PVT.display_rate_ms", std::to_string(display_rate_ms)); + config->set_property("PVT.dump_filename", "./PVT"); + config->set_property("PVT.nmea_dump_filename", "./gnss_sdr_pvt.nmea"); + config->set_property("PVT.flag_nmea_tty_port", "false"); + config->set_property("PVT.nmea_dump_devname", "/dev/pts/4"); + config->set_property("PVT.flag_rtcm_server", "false"); + config->set_property("PVT.flag_rtcm_tty_port", "false"); + config->set_property("PVT.rtcm_dump_devname", "/dev/pts/1"); + config->set_property("PVT.dump", "false"); return 0; } + +int Trk_System_Test::run_receiver() +{ + std::shared_ptr control_thread; + control_thread = std::make_shared(config); + // start receiver + try + { + control_thread->run(); + } + catch( boost::exception & e ) + { + std::cout << "Boost exception: " << boost::diagnostic_information(e); + } + catch(std::exception const& ex) + { + std::cout << "STD exception: " << ex.what(); + } + return 0; +} + + +int Trk_System_Test::check_results() +{ + // Open reference RINEX observables file + + // Open generated RINEX observables file + + // Read reference pseudoranges from a given satellite + + // Read obtained pseudoranges from a given satellite + + // Compute pseudorange error + + // Read reference carrier phase from a given satellite + + // Read obtained carrier phase from a given satellite + + // Compute carrier phase error + return 0; +} + + +TEST_F(Trk_System_Test, Tracking_system_test) +{ + // Configure the signal generator + configure_generator(); + + // Generate signal raw signal samples and observations RINEX file + generate_signal(); + + // Configure receiver + configure_receiver(); + + // Run the receiver + run_receiver(); + + // Check results + check_results(); +} + + +int main(int argc, char **argv) +{ + std::cout << "Running Tracking 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 2744a263441bb0d32992135a13f242f718cb1b9f Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 21 Dec 2016 15:43:00 +0100 Subject: [PATCH 03/15] Configure RINEX version via configuration This supersedes the value passed by the --RINEX_version flag. Useful for system testing --- src/algorithms/PVT/adapters/gps_l1_ca_pvt.cc | 10 +++++++--- .../PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.cc | 13 +++++++------ .../PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.h | 11 +++++++---- src/algorithms/PVT/libs/rinex_printer.cc | 9 ++++++++- src/algorithms/PVT/libs/rinex_printer.h | 2 +- src/tests/system-tests/trk_system_test.cc | 3 ++- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/algorithms/PVT/adapters/gps_l1_ca_pvt.cc b/src/algorithms/PVT/adapters/gps_l1_ca_pvt.cc index a881d27bc..ba244b5ae 100644 --- a/src/algorithms/PVT/adapters/gps_l1_ca_pvt.cc +++ b/src/algorithms/PVT/adapters/gps_l1_ca_pvt.cc @@ -103,6 +103,10 @@ GpsL1CaPvt::GpsL1CaPvt(ConfigurationInterface* configuration, //std::string ref_time_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_time_xml", ref_time_default_xml_filename); //std::string ref_location_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_location_xml", ref_location_default_xml_filename); + // RINEX version + int conf_rinex_version; + conf_rinex_version = configuration->property(role + ".rinex_version", 0); + // make PVT object pvt_ = gps_l1_ca_make_pvt_cc(in_streams_, dump_, @@ -119,7 +123,8 @@ GpsL1CaPvt::GpsL1CaPvt(ConfigurationInterface* configuration, rtcm_tcp_port, rtcm_station_id, rtcm_msg_rate_ms, - rtcm_dump_devname ); + rtcm_dump_devname, + conf_rinex_version ); DLOG(INFO) << "pvt(" << pvt_->unique_id() << ")"; } @@ -129,7 +134,7 @@ bool GpsL1CaPvt::save_assistance_to_XML() { // return variable (true == succeeded) bool ret = false; - + LOG(INFO) << "SUPL: Try to save GPS ephemeris to XML file " << eph_xml_filename_; std::map eph_map = pvt_->get_GPS_L1_ephemeris_map(); @@ -243,4 +248,3 @@ gr::basic_block_sptr GpsL1CaPvt::get_right_block() { return pvt_; } - diff --git a/src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.cc index 83804b97d..44dbc4bfc 100644 --- a/src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.cc @@ -58,7 +58,8 @@ gps_l1_ca_make_pvt_cc(unsigned int nchannels, unsigned short rtcm_tcp_port, unsigned short rtcm_station_id, std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname) + std::string rtcm_dump_devname, + int rinex_version) { return gps_l1_ca_pvt_cc_sptr(new gps_l1_ca_pvt_cc(nchannels, dump, @@ -75,7 +76,8 @@ gps_l1_ca_make_pvt_cc(unsigned int nchannels, rtcm_tcp_port, rtcm_station_id, rtcm_msg_rate_ms, - rtcm_dump_devname)); + rtcm_dump_devname, + rinex_version)); } @@ -208,7 +210,8 @@ gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels, unsigned short rtcm_tcp_port, unsigned short rtcm_station_id, std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname) : + std::string rtcm_dump_devname, + int rinex_version) : gr::block("gps_l1_ca_pvt_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)), gr::io_signature::make(0, 0, sizeof(gr_complex)) ) { @@ -280,7 +283,7 @@ gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels, b_rinex_header_written = false; b_rinex_header_updated = false; b_rinex_sbs_header_written = false; - rp = std::make_shared(); + rp = std::make_shared(rinex_version); // ############# ENABLE DATA FILE LOG ################# if (d_dump == true) @@ -496,5 +499,3 @@ int gps_l1_ca_pvt_cc::general_work (int noutput_items __attribute__((unused)), g consume_each(1); //one by one return 1; } - - diff --git a/src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.h b/src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.h index f2234b1d9..07f9d8607 100644 --- a/src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.h +++ b/src/algorithms/PVT/gnuradio_blocks/gps_l1_ca_pvt_cc.h @@ -63,7 +63,8 @@ gps_l1_ca_pvt_cc_sptr gps_l1_ca_make_pvt_cc(unsigned int n_channels, unsigned short rtcm_tcp_port, unsigned short rtcm_station_id, std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname + std::string rtcm_dump_devname, + int rinex_version ); /*! @@ -87,7 +88,8 @@ private: unsigned short rtcm_tcp_port, unsigned short rtcm_station_id, std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname); + std::string rtcm_dump_devname, + int rinex_version); gps_l1_ca_pvt_cc(unsigned int nchannels, bool dump, std::string dump_filename, @@ -103,7 +105,8 @@ private: unsigned short rtcm_tcp_port, unsigned short rtcm_station_id, std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname); + std::string rtcm_dump_devname, + int rinex_version); void msg_handler_telemetry(pmt::pmt_t msg); @@ -157,7 +160,7 @@ public: * It is used to save the assistance data at the receiver shutdown */ std::map get_GPS_L1_ephemeris_map(); - + ~gps_l1_ca_pvt_cc (); //!< Default destructor int general_work (int noutput_items, gr_vector_int &ninput_items, diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 71cf04bf3..51d1bad0c 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -51,7 +51,7 @@ using google::LogMessage; DEFINE_string(RINEX_version, "3.02", "Specifies the RINEX version (2.11 or 3.02)"); -Rinex_Printer::Rinex_Printer() +Rinex_Printer::Rinex_Printer(int conf_version) { navfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_GPS_NAV"); obsfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_OBS"); @@ -179,6 +179,13 @@ Rinex_Printer::Rinex_Printer() stringVersion = "3.02"; } + if(conf_version != 0) + { + if(conf_version == 2) + version = 2; + stringVersion = "2.11"; + } + numberTypesObservations = 4; // Number of available types of observable in the system } diff --git a/src/algorithms/PVT/libs/rinex_printer.h b/src/algorithms/PVT/libs/rinex_printer.h index f90a2f5e4..0d1dc940e 100644 --- a/src/algorithms/PVT/libs/rinex_printer.h +++ b/src/algorithms/PVT/libs/rinex_printer.h @@ -78,7 +78,7 @@ public: /*! * \brief Default constructor. Creates GPS Navigation and Observables RINEX files and their headers */ - Rinex_Printer(); + Rinex_Printer(int version = 0); /*! * \brief Default destructor. Closes GPS Navigation and Observables RINEX files diff --git a/src/tests/system-tests/trk_system_test.cc b/src/tests/system-tests/trk_system_test.cc index 51e120e23..51e5c017b 100644 --- a/src/tests/system-tests/trk_system_test.cc +++ b/src/tests/system-tests/trk_system_test.cc @@ -116,7 +116,7 @@ int Trk_System_Test::configure_receiver() const float early_late_space_chips = 0.5; const int display_rate_ms = 500; - const int output_rate_ms = 100; + const int output_rate_ms = 1000; const int averaging_depth = 10; bool false_bool = false; @@ -225,6 +225,7 @@ int Trk_System_Test::configure_receiver() config->set_property("PVT.flag_rtcm_tty_port", "false"); config->set_property("PVT.rtcm_dump_devname", "/dev/pts/1"); config->set_property("PVT.dump", "false"); + config->set_property("PVT.rinex_version", std::to_string(2)); return 0; } From cdf7fcfa99f31a0991eed0856a29c46ba1e1a3e4 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 21 Dec 2016 18:52:45 +0100 Subject: [PATCH 04/15] Add GPSTk as an optional analysis tool --- src/tests/CMakeLists.txt | 30 ++++++++++++++++++++--- src/tests/system-tests/trk_system_test.cc | 3 +++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index d46113690..9c086a6c2 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -152,7 +152,29 @@ if(ENABLE_SW_GENERATOR) add_definitions(-DSW_GENERATOR_BIN="${SW_GENERATOR_BIN}") add_definitions(-DDEFAULT_RINEX_NAV="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/brdc3540.14n") add_definitions(-DDEFAULT_POSITION_FILE="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/circle.csv") - + set(gpstk_RELEASE "2.5") + set(gpstk_md5 "9d79f6838d274f5edfd46c780a6b1b72") + ExternalProject_Add( + gpstk-${gpstk_RELEASE} + URL https://sourceforge.net/projects/gpstk/files/gpstk/${gpstk_RELEASE}/gpstk-${gpstk_RELEASE}.src.tar.gz + URL_MD5 ${gpstk_md5} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk + BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk + CONFIGURE_COMMAND "" + BUILD_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk/script_gpstk.sh -c + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" + ) + set(GPSTK_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk/dev/install/include CACHE PATH "Local GPSTK headers" + ) + add_library(gpstk UNKNOWN IMPORTED) + set_property(TARGET gpstk PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk/dev/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_SHARED_LIBRARY_SUFFIX}) + add_dependencies(gpstk gpstk-${gpstk_RELEASE}) + set(GPSTK_BINDIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk/dev/install/bin/ ) + add_definitions(-DGPSTK_BINDIR="${GPSTK_BINDIR}") + set(gpstk_libs gpstk) endif(ENABLE_SW_GENERATOR) add_definitions(-DTEST_PATH="${CMAKE_SOURCE_DIR}/src/tests/") @@ -458,15 +480,17 @@ if(ENABLE_SYSTEM_TESTING) add_executable(trk_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/trk_system_test.cc ) if(NOT ${GTEST_DIR_LOCAL}) - add_dependencies(trk_system_test gtest-${gtest_RELEASE}) + add_dependencies(trk_system_test gtest-${gtest_RELEASE} ) else(NOT ${GTEST_DIR_LOCAL}) add_dependencies(trk_system_test gtest) endif(NOT ${GTEST_DIR_LOCAL}) + include_directories(${GPSTK_INCLUDE_DIRS}) target_link_libraries(trk_system_test ${GFlags_LIBS} ${GLOG_LIBRARIES} ${GTEST_LIBRARIES} gnss_sp_libs - gnss_rx) + gnss_rx + ${gpstk_libs}) add_custom_command(TARGET trk_system_test POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_SOURCE_DIR}/install/$ diff --git a/src/tests/system-tests/trk_system_test.cc b/src/tests/system-tests/trk_system_test.cc index 51e5c017b..26d5d2400 100644 --- a/src/tests/system-tests/trk_system_test.cc +++ b/src/tests/system-tests/trk_system_test.cc @@ -6,6 +6,7 @@ #include #include #include +#include "RinexUtilities.hpp" #include "control_thread.h" #include "concurrent_map.h" #include "concurrent_queue.h" @@ -257,6 +258,8 @@ int Trk_System_Test::check_results() // Open generated RINEX observables file + // Time alignment! + // Read reference pseudoranges from a given satellite // Read obtained pseudoranges from a given satellite From 7f9d3c385dbe2cb2c0e91974af2735d1f7a2559b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 22 Dec 2016 01:35:31 +0100 Subject: [PATCH 05/15] Simple example of GPSTk usage --- src/tests/CMakeLists.txt | 4 ++ src/tests/system-tests/trk_system_test.cc | 47 ++++++++++++++++++----- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 9c086a6c2..02d972f90 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -152,6 +152,10 @@ if(ENABLE_SW_GENERATOR) add_definitions(-DSW_GENERATOR_BIN="${SW_GENERATOR_BIN}") add_definitions(-DDEFAULT_RINEX_NAV="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/brdc3540.14n") add_definitions(-DDEFAULT_POSITION_FILE="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/circle.csv") + + ################################################################################ + # Local installation of GPSTk http://www.gpstk.org/ + ################################################################################ set(gpstk_RELEASE "2.5") set(gpstk_md5 "9d79f6838d274f5edfd46c780a6b1b72") ExternalProject_Add( diff --git a/src/tests/system-tests/trk_system_test.cc b/src/tests/system-tests/trk_system_test.cc index 26d5d2400..527af63b4 100644 --- a/src/tests/system-tests/trk_system_test.cc +++ b/src/tests/system-tests/trk_system_test.cc @@ -12,6 +12,8 @@ #include "concurrent_queue.h" #include "in_memory_configuration.h" + + // For GPS NAVIGATION (L1) concurrent_queue global_gps_acq_assist_queue; concurrent_map global_gps_acq_assist_map; @@ -37,14 +39,36 @@ public: int configure_receiver(); int run_receiver(); int 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. std::shared_ptr config; }; + +bool Trk_System_Test::check_valid_rinex_nav(std::string filename) +{ + bool res = false; + res = gpstk::isRinexNavFile(filename); + return res; +} + + +bool Trk_System_Test::check_valid_rinex_obs(std::string filename) +{ + bool res = false; + res = gpstk::isRinexObsFile(filename); + return res; +} + + int Trk_System_Test::configure_generator() { // Configure signal generator_binary = std::string(SW_GENERATOR_BIN); + + EXPECT_EQ(true, check_valid_rinex_nav(std::string(DEFAULT_RINEX_NAV))); + p1 = std::string("-rinex_nav_file=") + std::string(DEFAULT_RINEX_NAV); p2_static = std::string("-static_position=30.286502,120.032669,100,1000"); p2_dynamic = std::string("-obs_pos_file=") + std::string(DEFAULT_POSITION_FILE); // Observer positions file, in .csv or .nmea format" @@ -54,6 +78,7 @@ int Trk_System_Test::configure_generator() return 0; } + int Trk_System_Test::generate_signal() { pid_t wait_result; @@ -65,17 +90,20 @@ int Trk_System_Test::generate_signal() 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(); - } + { + 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); + + EXPECT_EQ(true, check_valid_rinex_obs(filename_rinex_obs)); std::cout << "Signal and Observables RINEX files created." << std::endl; return 0; } + int Trk_System_Test::configure_receiver() { config = std::make_shared(); @@ -231,6 +259,7 @@ int Trk_System_Test::configure_receiver() return 0; } + int Trk_System_Test::run_receiver() { std::shared_ptr control_thread; @@ -238,15 +267,15 @@ int Trk_System_Test::run_receiver() // start receiver try { - control_thread->run(); + control_thread->run(); } catch( boost::exception & e ) { - std::cout << "Boost exception: " << boost::diagnostic_information(e); + std::cout << "Boost exception: " << boost::diagnostic_information(e); } catch(std::exception const& ex) { - std::cout << "STD exception: " << ex.what(); + std::cout << "STD exception: " << ex.what(); } return 0; } @@ -300,7 +329,7 @@ int main(int argc, char **argv) int res = 0; try { - testing::InitGoogleTest(&argc, argv); + testing::InitGoogleTest(&argc, argv); } catch(...) {} // catch the "testing::internal::::ClassUniqueToAlwaysTrue" from gtest From 2c393af75a39eff98a9a010009a904c450518fc3 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 22 Dec 2016 16:58:09 +0100 Subject: [PATCH 06/15] Add RINEX validations --- src/tests/system-tests/trk_system_test.cc | 119 ++++++++++++++++++---- 1 file changed, 102 insertions(+), 17 deletions(-) diff --git a/src/tests/system-tests/trk_system_test.cc b/src/tests/system-tests/trk_system_test.cc index 527af63b4..f9f972e69 100644 --- a/src/tests/system-tests/trk_system_test.cc +++ b/src/tests/system-tests/trk_system_test.cc @@ -1,8 +1,11 @@ -#include -#include -#include #include +#include +#include +#include +#include +#include +#include #include #include #include @@ -12,7 +15,12 @@ #include "concurrent_queue.h" #include "in_memory_configuration.h" - +DEFINE_string(generator_binary, std::string(SW_GENERATOR_BIN), "Path of Software Geenrator binary"); +DEFINE_string(rinex_nav_file, std::string(DEFAULT_RINEX_NAV), "Input RINEX navigation file"); +DEFINE_int32(duration, 100, "Duration of the experiment [in seconds]"); +DEFINE_string(static_position, "30.286502,120.032669,100", "Static receiver position [log,lat,height]"); +DEFINE_string(filename_rinex_obs, "sim.16o", "Filename of output RINEX navigation file"); +DEFINE_string(filename_raw_data, "signal_out.bin", "Filename of output raw data file"); // For GPS NAVIGATION (L1) concurrent_queue global_gps_acq_assist_queue; @@ -31,18 +39,19 @@ public: const int baseband_sampling_freq = 2.6e6; - std::string filename_rinex_obs = "sim.16o"; - std::string filename_raw_data = "signal_out.bin"; + 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(); - int check_results(); + 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. std::shared_ptr config; + std::string generated_rinex_obs; }; @@ -64,16 +73,14 @@ bool Trk_System_Test::check_valid_rinex_obs(std::string filename) int Trk_System_Test::configure_generator() { - // Configure signal - generator_binary = std::string(SW_GENERATOR_BIN); + // Configure signal generator + generator_binary = FLAGS_generator_binary; - EXPECT_EQ(true, check_valid_rinex_nav(std::string(DEFAULT_RINEX_NAV))); - - p1 = std::string("-rinex_nav_file=") + std::string(DEFAULT_RINEX_NAV); - p2_static = std::string("-static_position=30.286502,120.032669,100,1000"); + p1 = std::string("-rinex_nav_file=") + FLAGS_rinex_nav_file; + p2_static = std::string("-static_position=") + FLAGS_static_position + std::string(",") + std::to_string(FLAGS_duration * 10); p2_dynamic = std::string("-obs_pos_file=") + std::string(DEFAULT_POSITION_FILE); // Observer positions file, in .csv or .nmea format" - p3 = std::string("-rinex_obs_file=") + filename_rinex_obs; // RINEX 2.10 observation file output - p4 = std::string("-sig_out_file=") + filename_raw_data; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + 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; } @@ -277,16 +284,79 @@ int Trk_System_Test::run_receiver() { std::cout << "STD exception: " << ex.what(); } + + // Get the name of the RINEX obs file generated by the receiver + FILE *fp; + std::string argum2 = std::string("/bin/ls *O | tail -1"); + char buffer[1035]; + fp = popen(&argum2[0], "r"); + if (fp == NULL) + { + printf("Failed to run command\n" ); + } + char * without_trailing; + while (fgets(buffer, sizeof(buffer), fp) != NULL) + { + std::string aux = std::string(buffer); + without_trailing = strtok(&aux[0], "\n"); + } + generated_rinex_obs = std::string(without_trailing); + pclose(fp); return 0; } -int Trk_System_Test::check_results() +void Trk_System_Test::check_results() { // Open reference RINEX observables file + pid_t wait_result; + int child_status; + std::string RinDump = std::string("RinDump"); + std::string path_RinDump = std::string(GPSTK_BINDIR) + RinDump; + std::string arg1 = std::string("--obs"); + std::string arg2 = std::string("./") + FLAGS_filename_rinex_obs; + std::string arg3 = std::string("9"); + std::string arg4 = std::string("C1C"); + std::string arg5 = std::string("--headless"); + + FILE *fp; + FILE *fp2; + int status; + char buffer[1035]; + + /* Open the command for reading. */ + std::string argum = path_RinDump + " " + arg1 + " " + arg2 + " " + arg3 + " " + arg4 + " " + arg5; + + fp = popen(&argum[0], "r"); + if (fp == NULL) + { + printf("Failed to run command\n" ); + } + + /* Read the output a line at a time - output it. */ + while (fgets(buffer, sizeof(buffer), fp) != NULL) + { + printf("Reading line: %s", buffer); + } + pclose(fp); // Open generated RINEX observables file + std::string arg2_gen = "./" + generated_rinex_obs; + std::string argum2 = path_RinDump + " " + arg1 + " " + arg2_gen + " " + arg3 + " " + arg4 + " " + arg5; + fp2 = popen(&argum2[0], "r"); + if (fp2 == NULL) + { + printf("Failed to run command\n" ); + } + + /* Read the output a line at a time - output it. */ + while (fgets(buffer, sizeof(buffer), fp2) != NULL) + { + printf("Reading generated line: %s", buffer); + } + + pclose(fp2); // Time alignment! // Read reference pseudoranges from a given satellite @@ -300,24 +370,39 @@ int Trk_System_Test::check_results() // Read obtained carrier phase from a given satellite // Compute carrier phase error - return 0; + //return 0; } TEST_F(Trk_System_Test, Tracking_system_test) { + std::cout << "Validating input RINEX nav file: " << FLAGS_rinex_nav_file << " ..." << std::endl; + bool is_rinex_nav_valid = check_valid_rinex_nav(FLAGS_rinex_nav_file); + ASSERT_EQ(true, is_rinex_nav_valid); + std::cout << "The file is valid." << std::endl; + // Configure the signal generator configure_generator(); // Generate signal raw signal samples and observations RINEX file 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); + ASSERT_EQ(true, is_gen_rinex_obs_valid); + std::cout << "The file is valid." << std::endl; + // Configure receiver configure_receiver(); // Run the receiver run_receiver(); + std::cout << "Validating RINEX obs file obtained by GNSS-SDR: " << generated_rinex_obs << " ..." << std::endl; + is_gen_rinex_obs_valid = check_valid_rinex_obs( "./" + generated_rinex_obs); + ASSERT_EQ(true, is_gen_rinex_obs_valid); + std::cout << "The file is valid." << std::endl; + // Check results check_results(); } From cd1adc33c7ec6c8a108630c63bf49c2e76ff7d20 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 23 Dec 2016 08:49:49 +0100 Subject: [PATCH 07/15] Usign GPSTk to read observables --- src/tests/system-tests/trk_system_test.cc | 197 ++++++++++++++++++---- 1 file changed, 165 insertions(+), 32 deletions(-) diff --git a/src/tests/system-tests/trk_system_test.cc b/src/tests/system-tests/trk_system_test.cc index f9f972e69..073273140 100644 --- a/src/tests/system-tests/trk_system_test.cc +++ b/src/tests/system-tests/trk_system_test.cc @@ -1,3 +1,34 @@ +/*! + * \file trk_system_test.cc + * \brief This class implements a test for the validation of generated observables. + * \author Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 (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 @@ -15,6 +46,12 @@ #include "concurrent_queue.h" #include "in_memory_configuration.h" +#include "Rinex3ObsBase.hpp" +#include "Rinex3ObsData.hpp" +#include "Rinex3ObsHeader.hpp" +#include "Rinex3ObsStream.hpp" + + DEFINE_string(generator_binary, std::string(SW_GENERATOR_BIN), "Path of Software Geenrator binary"); DEFINE_string(rinex_nav_file, std::string(DEFAULT_RINEX_NAV), "Input RINEX navigation file"); DEFINE_int32(duration, 100, "Duration of the experiment [in seconds]"); @@ -292,7 +329,7 @@ int Trk_System_Test::run_receiver() fp = popen(&argum2[0], "r"); if (fp == NULL) { - printf("Failed to run command\n" ); + std::cout << "Failed to run command: " << argum2 << std::endl; } char * without_trailing; while (fgets(buffer, sizeof(buffer), fp) != NULL) @@ -319,44 +356,140 @@ void Trk_System_Test::check_results() std::string arg4 = std::string("C1C"); std::string arg5 = std::string("--headless"); - FILE *fp; - FILE *fp2; - int status; - char buffer[1035]; + 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; - /* Open the command for reading. */ - std::string argum = path_RinDump + " " + arg1 + " " + arg2 + " " + arg3 + " " + arg4 + " " + arg5; + gpstk::RinexDatum dataobj; - fp = popen(&argum[0], "r"); - if (fp == NULL) - { - printf("Failed to run command\n" ); - } + r_ref >> r_ref_header; - /* Read the output a line at a time - output it. */ - while (fgets(buffer, sizeof(buffer), fp) != NULL) - { - printf("Reading line: %s", buffer); - } - pclose(fp); + std::vector typelist = r_ref_header.obsTypeList; + + std::vector::iterator it; + for(it = typelist.begin(); it != typelist.end(); it++) + { + gpstk::RinexObsID id = *it; + std::cout << "ID: " << id.asString() << std::endl; + } + + //int indexC1_ref( r_ref_header.getObsIndex( "C1" ) ); + //int indexL1_ref( r_ref_header.getObsIndex( "L1P" ) ); + std::cout << r_ref_header.stringSystemNumObs << std::endl; + + for (int myprn = 1; myprn < 33; myprn++) + { + gpstk::SatID prn( myprn, gpstk::SatID::systemGPS ); + while (r_ref >> r_ref_data) + { + std::cout << r_ref_data.time << " " << std::endl; + + + gpstk::Rinex3ObsData::DataMap::iterator pointer = r_ref_data.obs.find(prn); + if( pointer == r_ref_data.obs.end() ) + { + std::cout << "PRN " << myprn << " not in view " << std::endl; + } + else + { + // Get P1, P2 and L1 observations + // Here there are three equivalent ways to get the RinexDatum + // from the RinexObsData object + + // The first one is a fast but DANGEROUS method, because there + // is a chance of unawarely change the contents of "roe.obs". + // ----------------------------------------------------------- + //dataobj = r_ref_data.obs[prn][indexC1_ref]; + //double C1 = dataobj.data; + + // The second method is secure but a little slower. + // This should be your preferred method + // ----------------------------------------------------------- + dataobj = r_ref_data.getObs(prn, "P1", r_ref_header); + double P1 = dataobj.data; + std::cout << P1 << " " << std::endl; + + //dataobj = r_ref_data.getObs(prn, "L1", r_ref_header); + //double L1 = dataobj.data; + + gpstk::CommonTime time = r_ref_data.time; + //std::cout << time.getSecondOfDay() << std::endl; + + + + + + std::cout << " PRN " << myprn << std::endl; + + } // End of 'if( pointer == roe.obs.end() )' + + } + } + } // End of 'try' block + catch(gpstk::FFStreamError& e) + { + std::cout << e; + exit(1); + } + catch(gpstk::Exception& e) + { + std::cout << e; + exit(1); + } + catch (...) + { + std::cout << "unknown error. I don't feel so well..." << std::endl; + exit(1); + } +// FILE *fp; +// FILE *fp2; +// int status; +// char buffer[1035]; +// +// /* Open the command for reading. */ +// std::string argum = path_RinDump + " " + arg1 + " " + arg2 + " " + arg3 + " " + arg4 + " " + arg5; +// +// fp = popen(&argum[0], "r"); +// if (fp == NULL) +// { +// std::cout << "Failed to run command: " << argum << std::endl; +// } +// +// /* Read the output a line at a time - output it. */ +// while (fgets(buffer, sizeof(buffer), fp) != NULL) +// { +// printf("Reading line: %s", buffer); +// } +// pclose(fp); // Open generated RINEX observables file - std::string arg2_gen = "./" + generated_rinex_obs; - std::string argum2 = path_RinDump + " " + arg1 + " " + arg2_gen + " " + arg3 + " " + arg4 + " " + arg5; + std::string arg2_gen = std::string("./") + generated_rinex_obs; + gpstk::Rinex3ObsStream r_meas(arg2_gen); + gpstk::Rinex3ObsData r_meas_data; + gpstk::Rinex3ObsHeader r_meas_header; - fp2 = popen(&argum2[0], "r"); - if (fp2 == NULL) - { - printf("Failed to run command\n" ); - } + r_meas >> r_meas_header; - /* Read the output a line at a time - output it. */ - while (fgets(buffer, sizeof(buffer), fp2) != NULL) - { - printf("Reading generated line: %s", buffer); - } - - pclose(fp2); + //int indexC1_meas( r_meas_header.getObsIndex( "C1" ) ); + //int indexL1_meas( r_meas_header.getObsIndex( "L1" ) ); +// std::string argum2 = path_RinDump + " " + arg1 + " " + arg2_gen + " " + arg3 + " " + arg4 + " " + arg5; +// +// fp2 = popen(&argum2[0], "r"); +// if (fp2 == NULL) +// { +// printf("Failed to run command\n" ); +// } +// +// /* Read the output a line at a time - output it. */ +// while (fgets(buffer, sizeof(buffer), fp2) != NULL) +// { +// printf("Reading generated line: %s", buffer); +// } +// +// pclose(fp2); // Time alignment! // Read reference pseudoranges from a given satellite From 4c8a74936c09c8200d4fcb4412292938db9a0bc0 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 23 Dec 2016 13:45:02 +0100 Subject: [PATCH 08/15] Read both RINEX obs files --- src/tests/system-tests/trk_system_test.cc | 226 +++++++++++----------- 1 file changed, 109 insertions(+), 117 deletions(-) diff --git a/src/tests/system-tests/trk_system_test.cc b/src/tests/system-tests/trk_system_test.cc index 073273140..d223229f7 100644 --- a/src/tests/system-tests/trk_system_test.cc +++ b/src/tests/system-tests/trk_system_test.cc @@ -345,89 +345,56 @@ int Trk_System_Test::run_receiver() void Trk_System_Test::check_results() { - // Open reference RINEX observables file - pid_t wait_result; - int child_status; - std::string RinDump = std::string("RinDump"); - std::string path_RinDump = std::string(GPSTK_BINDIR) + RinDump; - std::string arg1 = std::string("--obs"); - std::string arg2 = std::string("./") + FLAGS_filename_rinex_obs; - std::string arg3 = std::string("9"); - std::string arg4 = std::string("C1C"); - std::string arg5 = std::string("--headless"); + std::vector> > pseudorange_ref(33); + std::vector> > carrierphase_ref(33); + std::vector> > pseudorange_meas(33); + std::vector> > carrierphase_meas(33); + + // Open 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::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; + gpstk::RinexDatum dataobj; - r_ref >> r_ref_header; - - std::vector typelist = r_ref_header.obsTypeList; - - std::vector::iterator it; - for(it = typelist.begin(); it != typelist.end(); it++) - { - gpstk::RinexObsID id = *it; - std::cout << "ID: " << id.asString() << std::endl; - } - - //int indexC1_ref( r_ref_header.getObsIndex( "C1" ) ); - //int indexL1_ref( r_ref_header.getObsIndex( "L1P" ) ); - std::cout << r_ref_header.stringSystemNumObs << std::endl; + 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 ); + //std::cout << " PRN " << myprn << std::endl; + gpstk::CommonTime time = r_ref_data.time; + //std::cout << time << " " << std::endl; + double sow(static_cast(time).sow); + //std::cout << "Time: " << sow << std::endl; + + gpstk::Rinex3ObsData::DataMap::iterator pointer = r_ref_data.obs.find(prn); + if( pointer == r_ref_data.obs.end() ) { - gpstk::SatID prn( myprn, gpstk::SatID::systemGPS ); - while (r_ref >> r_ref_data) - { - std::cout << r_ref_data.time << " " << std::endl; - - - gpstk::Rinex3ObsData::DataMap::iterator pointer = r_ref_data.obs.find(prn); - if( pointer == r_ref_data.obs.end() ) - { - std::cout << "PRN " << myprn << " not in view " << std::endl; - } - else - { - // Get P1, P2 and L1 observations - // Here there are three equivalent ways to get the RinexDatum - // from the RinexObsData object - - // The first one is a fast but DANGEROUS method, because there - // is a chance of unawarely change the contents of "roe.obs". - // ----------------------------------------------------------- - //dataobj = r_ref_data.obs[prn][indexC1_ref]; - //double C1 = dataobj.data; - - // The second method is secure but a little slower. - // This should be your preferred method - // ----------------------------------------------------------- - dataobj = r_ref_data.getObs(prn, "P1", r_ref_header); - double P1 = dataobj.data; - std::cout << P1 << " " << std::endl; - - //dataobj = r_ref_data.getObs(prn, "L1", r_ref_header); - //double L1 = dataobj.data; - - gpstk::CommonTime time = r_ref_data.time; - //std::cout << time.getSecondOfDay() << std::endl; - - - - - - std::cout << " PRN " << myprn << std::endl; - - } // End of 'if( pointer == roe.obs.end() )' - - } + // PRN not present; do nothing } + else + { + dataobj = r_ref_data.getObs(prn, "P1", r_ref_header); + double P1 = dataobj.data; + std::map pseudo; + 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::map carrier; + carrier[sow]= L1; + carrierphase_ref.at(myprn).push_back(carrier); + } // End of 'if( pointer == roe.obs.end() )' + } // end for + } // end while } // End of 'try' block catch(gpstk::FFStreamError& e) { @@ -444,52 +411,77 @@ void Trk_System_Test::check_results() std::cout << "unknown error. I don't feel so well..." << std::endl; exit(1); } -// FILE *fp; -// FILE *fp2; -// int status; -// char buffer[1035]; -// -// /* Open the command for reading. */ -// std::string argum = path_RinDump + " " + arg1 + " " + arg2 + " " + arg3 + " " + arg4 + " " + arg5; -// -// fp = popen(&argum[0], "r"); -// if (fp == NULL) -// { -// std::cout << "Failed to run command: " << argum << std::endl; -// } -// -// /* Read the output a line at a time - output it. */ -// while (fgets(buffer, sizeof(buffer), fp) != NULL) -// { -// printf("Reading line: %s", buffer); -// } -// pclose(fp); - // Open generated RINEX observables file - std::string arg2_gen = std::string("./") + generated_rinex_obs; - gpstk::Rinex3ObsStream r_meas(arg2_gen); - gpstk::Rinex3ObsData r_meas_data; - gpstk::Rinex3ObsHeader r_meas_header; + // Example: count observations per sat: + std::vector> >::iterator iter; + int prn_id=0; + for(iter = pseudorange_ref.begin(); iter != pseudorange_ref.end(); iter++) + { + double size_v = iter->size(); + std::cout << "Size for sat " << prn_id << ": " << size_v << std::endl; + prn_id++; + } - r_meas >> r_meas_header; + // Open GNSS-SDR-generated RINEX observables file + try + { + std::string arg2_gen = std::string("./") + generated_rinex_obs; + gpstk::Rinex3ObsStream r_meas(arg2_gen); + 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 ); + //std::cout << " PRN " << myprn << std::endl; + gpstk::CommonTime time = r_meas_data.time; + //std::cout << time << " " << std::endl; + double sow(static_cast(time).sow); + //std::cout << "Time: " << sow << std::endl; + + 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, "C1", r_meas_header); + double P1 = dataobj.data; + std::map pseudo; + 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::map carrier; + carrier[sow]= L1; + carrierphase_meas.at(myprn).push_back(carrier); + } // End of 'if( pointer == roe.obs.end() )' + } // end for + } // end while + } // End of 'try' block + catch(gpstk::FFStreamError& e) + { + std::cout << e; + exit(1); + } + catch(gpstk::Exception& e) + { + std::cout << e; + exit(1); + } + catch (...) + { + std::cout << "unknown error. I don't feel so well..." << std::endl; + exit(1); + } - //int indexC1_meas( r_meas_header.getObsIndex( "C1" ) ); - //int indexL1_meas( r_meas_header.getObsIndex( "L1" ) ); -// std::string argum2 = path_RinDump + " " + arg1 + " " + arg2_gen + " " + arg3 + " " + arg4 + " " + arg5; -// -// fp2 = popen(&argum2[0], "r"); -// if (fp2 == NULL) -// { -// printf("Failed to run command\n" ); -// } -// -// /* Read the output a line at a time - output it. */ -// while (fgets(buffer, sizeof(buffer), fp2) != NULL) -// { -// printf("Reading generated line: %s", buffer); -// } -// -// pclose(fp2); // Time alignment! // Read reference pseudoranges from a given satellite From c2c96e53914a7e64dbedd3a7afbfe2410e83c8b2 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 24 Dec 2016 15:58:04 +0100 Subject: [PATCH 09/15] read and compare measurements --- src/tests/system-tests/trk_system_test.cc | 262 ++++++++++++++-------- 1 file changed, 171 insertions(+), 91 deletions(-) diff --git a/src/tests/system-tests/trk_system_test.cc b/src/tests/system-tests/trk_system_test.cc index d223229f7..6af4a87fd 100644 --- a/src/tests/system-tests/trk_system_test.cc +++ b/src/tests/system-tests/trk_system_test.cc @@ -321,7 +321,6 @@ int Trk_System_Test::run_receiver() { std::cout << "STD exception: " << ex.what(); } - // Get the name of the RINEX obs file generated by the receiver FILE *fp; std::string argum2 = std::string("/bin/ls *O | tail -1"); @@ -339,62 +338,58 @@ int Trk_System_Test::run_receiver() } generated_rinex_obs = std::string(without_trailing); pclose(fp); + return 0; } void Trk_System_Test::check_results() { - std::vector> > pseudorange_ref(33); - std::vector> > carrierphase_ref(33); + std::vector> > pseudorange_ref(33); + std::vector> > carrierphase_ref(33); - std::vector> > pseudorange_meas(33); - std::vector> > carrierphase_meas(33); + std::vector> > pseudorange_meas(33); + std::vector> > carrierphase_meas(33); - // Open reference RINEX observables file + // 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::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; + gpstk::RinexDatum dataobj; - r_ref >> r_ref_header; + 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 ); - //std::cout << " PRN " << myprn << std::endl; - gpstk::CommonTime time = r_ref_data.time; - //std::cout << time << " " << std::endl; - double sow(static_cast(time).sow); - //std::cout << "Time: " << sow << std::endl; - - gpstk::Rinex3ObsData::DataMap::iterator pointer = r_ref_data.obs.find(prn); - if( pointer == r_ref_data.obs.end() ) + while (r_ref >> r_ref_data) { - // PRN not present; do nothing - } - else - { - dataobj = r_ref_data.getObs(prn, "P1", r_ref_header); - double P1 = dataobj.data; - std::map pseudo; - pseudo[sow] = P1; - pseudorange_ref.at(myprn).push_back(pseudo); + 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); - dataobj = r_ref_data.getObs(prn, "L1C", r_ref_header); - double L1 = dataobj.data; - std::map carrier; - carrier[sow]= L1; - carrierphase_ref.at(myprn).push_back(carrier); - } // End of 'if( pointer == roe.obs.end() )' - } // end for - } // end while + 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, "P1", 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); + } // End of 'if( pointer == roe.obs.end() )' + } // end for + } // end while } // End of 'try' block catch(gpstk::FFStreamError& e) { @@ -413,58 +408,54 @@ void Trk_System_Test::check_results() } // Example: count observations per sat: - std::vector> >::iterator iter; + /* std::vector> >::iterator iter; int prn_id=0; for(iter = pseudorange_ref.begin(); iter != pseudorange_ref.end(); iter++) - { - double size_v = iter->size(); - std::cout << "Size for sat " << prn_id << ": " << size_v << std::endl; - prn_id++; - } + { + double size_v = iter->size(); + std::cout << "Size for sat " << prn_id << ": " << size_v << std::endl; + prn_id++; + }*/ - // Open GNSS-SDR-generated RINEX observables file + // Open and read GNSS-SDR-generated RINEX observables file try { - std::string arg2_gen = std::string("./") + generated_rinex_obs; - gpstk::Rinex3ObsStream r_meas(arg2_gen); - gpstk::Rinex3ObsData r_meas_data; - gpstk::Rinex3ObsHeader r_meas_header; - gpstk::RinexDatum dataobj; + std::string arg2_gen = std::string("./") + 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; + 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 ); - //std::cout << " PRN " << myprn << std::endl; - gpstk::CommonTime time = r_meas_data.time; - //std::cout << time << " " << std::endl; - double sow(static_cast(time).sow); - //std::cout << "Time: " << sow << std::endl; - - gpstk::Rinex3ObsData::DataMap::iterator pointer = r_meas_data.obs.find(prn); - if( pointer == r_meas_data.obs.end() ) + while (r_meas >> r_meas_data) { - // PRN not present; do nothing - } - else - { - dataobj = r_meas_data.getObs(prn, "C1", r_meas_header); - double P1 = dataobj.data; - std::map pseudo; - pseudo[sow] = P1; - pseudorange_meas.at(myprn).push_back(pseudo); + 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); - dataobj = r_meas_data.getObs(prn, "L1C", r_meas_header); - double L1 = dataobj.data; - std::map carrier; - carrier[sow]= L1; - carrierphase_meas.at(myprn).push_back(carrier); - } // End of 'if( pointer == roe.obs.end() )' - } // end for - } // end while + 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, "C1", 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); + } // End of 'if( pointer == roe.obs.end() )' + } // end for + } // end while } // End of 'try' block catch(gpstk::FFStreamError& e) { @@ -482,19 +473,108 @@ void Trk_System_Test::check_results() exit(1); } - // Time alignment! + // Time alignment + std::vector> > pseudorange_ref_aligned(33); + std::vector> > carrierphase_ref_aligned(33); - // Read reference pseudoranges from a given satellite + std::vector> >::iterator iter; + std::vector>::iterator it; + std::vector>::iterator it2; - // Read obtained pseudoranges from a given satellite + std::vector> pr_diff(33); + std::vector> cp_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.001) // store measures closer than 1 ms. + { + pseudorange_ref_aligned.at(prn_id).push_back(*it); + pr_diff.at(prn_id).push_back(it->second - it2->second ); + } + } + } + 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.001) // store measures closer than 1 ms. + { + carrierphase_ref_aligned.at(prn_id).push_back(*it); + cp_diff.at(prn_id).push_back(it->second - it2->second ); + } + } + } + prn_id++; + } // Compute pseudorange error + prn_id = 0; + 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++) + { + //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; + std::cout << "-- Mean pseudorange difference for sat " << prn_id << ": " << mean_diff << std::endl; + } + else + { + mean_diff = 0.0; + } - // Read reference carrier phase from a given satellite - - // Read obtained carrier phase from a given satellite + prn_id++; + } // Compute carrier phase error + prn_id = 0; + 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++) + { + //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; + std::cout << "-- Mean carrier phase difference for sat " << prn_id << ": " << mean_diff << std::endl; + } + else + { + mean_diff = 0.0; + } + + prn_id++; + } + //return 0; } From 1eb75e01708ecfeac0be4a9ed26cc66e1b03542b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 24 Dec 2016 19:51:13 +0100 Subject: [PATCH 10/15] Add Doppler observables --- src/tests/system-tests/trk_system_test.cc | 57 +++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/tests/system-tests/trk_system_test.cc b/src/tests/system-tests/trk_system_test.cc index 6af4a87fd..a28220a27 100644 --- a/src/tests/system-tests/trk_system_test.cc +++ b/src/tests/system-tests/trk_system_test.cc @@ -347,9 +347,11 @@ void Trk_System_Test::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 @@ -387,6 +389,11 @@ void Trk_System_Test::check_results() 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 @@ -453,6 +460,11 @@ void Trk_System_Test::check_results() 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, L1); + doppler_meas.at(myprn).push_back(doppler); } // End of 'if( pointer == roe.obs.end() )' } // end for } // end while @@ -476,6 +488,7 @@ void Trk_System_Test::check_results() // 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; @@ -483,6 +496,7 @@ void Trk_System_Test::check_results() 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; @@ -522,6 +536,23 @@ void Trk_System_Test::check_results() } 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.001) // store measures closer than 1 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; @@ -575,6 +606,32 @@ void Trk_System_Test::check_results() prn_id++; } + // Compute doppler error + prn_id = 0; + 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; + std::cout << "-- Mean Doppler difference for sat " << prn_id << ": " << mean_diff << std::endl; + } + else + { + mean_diff = 0.0; + } + + prn_id++; + } + //return 0; } From c3e545ecfd053fb25bec0d48fa294e68c8c22a51 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 25 Dec 2016 12:10:15 +0100 Subject: [PATCH 11/15] Compute error stdev for pseudorange diff and Doppler --- src/tests/system-tests/trk_system_test.cc | 29 ++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/tests/system-tests/trk_system_test.cc b/src/tests/system-tests/trk_system_test.cc index a28220a27..cba9c6ef9 100644 --- a/src/tests/system-tests/trk_system_test.cc +++ b/src/tests/system-tests/trk_system_test.cc @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -458,12 +459,12 @@ void Trk_System_Test::check_results() dataobj = r_meas_data.getObs(prn, "L1C", r_meas_header); double L1 = dataobj.data; - std::pair carrier(sow,L1); + 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, L1); + std::pair doppler(sow, D1); doppler_meas.at(myprn).push_back(doppler); } // End of 'if( pointer == roe.obs.end() )' } // end for @@ -531,6 +532,7 @@ void Trk_System_Test::check_results() { 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 << std::endl; } } } @@ -556,6 +558,7 @@ void Trk_System_Test::check_results() // 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 @@ -570,6 +573,7 @@ void Trk_System_Test::check_results() 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 << std::endl; } else @@ -579,6 +583,15 @@ void Trk_System_Test::check_results() prn_id++; } + double sum_ = std::accumulate(mean_pr_diff_v.begin(), mean_pr_diff_v.end(), 0.0); + double mean_ = sum_ / mean_pr_diff_v.size(); + std::vector diff_pr(mean_pr_diff_v.size()); + std::transform(mean_pr_diff_v.begin(), mean_pr_diff_v.end(), diff_pr.begin(), + std::bind2nd(std::minus(), mean_)); + double sq_sum_pr = std::inner_product(diff_pr.begin(), diff_pr.end(), diff_pr.begin(), 0.0); + double stdev_pr = std::sqrt(sq_sum_pr / mean_pr_diff_v.size()); + std::cout << "Pseudorange diff error stdev = " << stdev_pr << " [m]" << std::endl; + ASSERT_LT(stdev_pr, 1.0); // Compute carrier phase error prn_id = 0; @@ -608,6 +621,7 @@ void Trk_System_Test::check_results() // 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 @@ -622,6 +636,7 @@ void Trk_System_Test::check_results() 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 << std::endl; } else @@ -631,7 +646,15 @@ void Trk_System_Test::check_results() prn_id++; } - + sum_ = std::accumulate(mean_doppler_v.begin(), mean_doppler_v.end(), 0.0); + mean_ = sum_ /mean_doppler_v.size(); + std::vector diff_dp(mean_doppler_v.size()); + std::transform(mean_doppler_v.begin(), mean_doppler_v.end(), diff_dp.begin(), + std::bind2nd(std::minus(), mean_)); + double sq_sum_dp = std::inner_product(diff_dp.begin(), diff_dp.end(), diff_dp.begin(), 0.0); + double stdev_dp = std::sqrt(sq_sum_dp / mean_doppler_v.size()); + std::cout << "Doppler error stdev = " << stdev_dp << " [Hz]" << std::endl; + ASSERT_LT(stdev_dp, 1.0); //return 0; } From 19bc085e8904ea9d921dd5f98ef088e134df77d6 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 25 Dec 2016 12:49:14 +0100 Subject: [PATCH 12/15] Change name to obs_gps_l1_system_test --- src/tests/CMakeLists.txt | 26 +++++++-------- ...stem_test.cc => obs_gps_l1_system_test.cc} | 33 +++++++------------ 2 files changed, 24 insertions(+), 35 deletions(-) rename src/tests/system-tests/{trk_system_test.cc => obs_gps_l1_system_test.cc} (96%) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 02d972f90..f08fccc10 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -481,23 +481,23 @@ if(ENABLE_SYSTEM_TESTING) ${CMAKE_SOURCE_DIR}/install/$ ) - add_executable(trk_system_test - ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/trk_system_test.cc ) + add_executable(obs_gps_l1_system_test + ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_system_test.cc ) if(NOT ${GTEST_DIR_LOCAL}) - add_dependencies(trk_system_test gtest-${gtest_RELEASE} ) + add_dependencies(obs_gps_l1_system_test gtest-${gtest_RELEASE} ) else(NOT ${GTEST_DIR_LOCAL}) - add_dependencies(trk_system_test gtest) + add_dependencies(obs_gps_l1_system_test gtest) endif(NOT ${GTEST_DIR_LOCAL}) include_directories(${GPSTK_INCLUDE_DIRS}) - target_link_libraries(trk_system_test ${GFlags_LIBS} - ${GLOG_LIBRARIES} - ${GTEST_LIBRARIES} - gnss_sp_libs - gnss_rx - ${gpstk_libs}) - add_custom_command(TARGET trk_system_test POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ - ${CMAKE_SOURCE_DIR}/install/$ + target_link_libraries(obs_gps_l1_system_test ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${GTEST_LIBRARIES} + gnss_sp_libs + gnss_rx + ${gpstk_libs}) + add_custom_command(TARGET obs_gps_l1_system_test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy $ + ${CMAKE_SOURCE_DIR}/install/$ ) endif(ENABLE_SYSTEM_TESTING) diff --git a/src/tests/system-tests/trk_system_test.cc b/src/tests/system-tests/obs_gps_l1_system_test.cc similarity index 96% rename from src/tests/system-tests/trk_system_test.cc rename to src/tests/system-tests/obs_gps_l1_system_test.cc index cba9c6ef9..0eee934a9 100644 --- a/src/tests/system-tests/trk_system_test.cc +++ b/src/tests/system-tests/obs_gps_l1_system_test.cc @@ -1,5 +1,5 @@ /*! - * \file trk_system_test.cc + * \file obs_gps_l1_system_test.cc * \brief This class implements a test for the validation of generated observables. * \author Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es * @@ -64,7 +64,7 @@ DEFINE_string(filename_raw_data, "signal_out.bin", "Filename of output raw data concurrent_queue global_gps_acq_assist_queue; concurrent_map global_gps_acq_assist_map; -class Trk_System_Test: public ::testing::Test +class Obs_Gps_L1_System_Test: public ::testing::Test { public: std::string generator_binary; @@ -93,7 +93,7 @@ public: }; -bool Trk_System_Test::check_valid_rinex_nav(std::string filename) +bool Obs_Gps_L1_System_Test::check_valid_rinex_nav(std::string filename) { bool res = false; res = gpstk::isRinexNavFile(filename); @@ -101,7 +101,7 @@ bool Trk_System_Test::check_valid_rinex_nav(std::string filename) } -bool Trk_System_Test::check_valid_rinex_obs(std::string filename) +bool Obs_Gps_L1_System_Test::check_valid_rinex_obs(std::string filename) { bool res = false; res = gpstk::isRinexObsFile(filename); @@ -109,7 +109,7 @@ bool Trk_System_Test::check_valid_rinex_obs(std::string filename) } -int Trk_System_Test::configure_generator() +int Obs_Gps_L1_System_Test::configure_generator() { // Configure signal generator generator_binary = FLAGS_generator_binary; @@ -124,7 +124,7 @@ int Trk_System_Test::configure_generator() } -int Trk_System_Test::generate_signal() +int Obs_Gps_L1_System_Test::generate_signal() { pid_t wait_result; int child_status; @@ -149,7 +149,7 @@ int Trk_System_Test::generate_signal() } -int Trk_System_Test::configure_receiver() +int Obs_Gps_L1_System_Test::configure_receiver() { config = std::make_shared(); @@ -305,7 +305,7 @@ int Trk_System_Test::configure_receiver() } -int Trk_System_Test::run_receiver() +int Obs_Gps_L1_System_Test::run_receiver() { std::shared_ptr control_thread; control_thread = std::make_shared(config); @@ -344,7 +344,7 @@ int Trk_System_Test::run_receiver() } -void Trk_System_Test::check_results() +void Obs_Gps_L1_System_Test::check_results() { std::vector> > pseudorange_ref(33); std::vector> > carrierphase_ref(33); @@ -415,17 +415,6 @@ void Trk_System_Test::check_results() exit(1); } - // Example: count observations per sat: - /* std::vector> >::iterator iter; - int prn_id=0; - for(iter = pseudorange_ref.begin(); iter != pseudorange_ref.end(); iter++) - { - double size_v = iter->size(); - std::cout << "Size for sat " << prn_id << ": " << size_v << std::endl; - prn_id++; - }*/ - - // Open and read GNSS-SDR-generated RINEX observables file try { std::string arg2_gen = std::string("./") + generated_rinex_obs; @@ -659,7 +648,7 @@ void Trk_System_Test::check_results() } -TEST_F(Trk_System_Test, Tracking_system_test) +TEST_F(Obs_Gps_L1_System_Test, Observables_system_test) { std::cout << "Validating input RINEX nav file: " << FLAGS_rinex_nav_file << " ..." << std::endl; bool is_rinex_nav_valid = check_valid_rinex_nav(FLAGS_rinex_nav_file); @@ -695,7 +684,7 @@ TEST_F(Trk_System_Test, Tracking_system_test) int main(int argc, char **argv) { - std::cout << "Running Tracking validation test..." << std::endl; + std::cout << "Running Observables validation test..." << std::endl; int res = 0; try { From f12e8b97f4335d10ade1195ebc29de2da772d84e Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 25 Dec 2016 13:45:06 +0100 Subject: [PATCH 13/15] Better way to compute stdev --- .../system-tests/obs_gps_l1_system_test.cc | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/tests/system-tests/obs_gps_l1_system_test.cc b/src/tests/system-tests/obs_gps_l1_system_test.cc index 0eee934a9..cc7807df0 100644 --- a/src/tests/system-tests/obs_gps_l1_system_test.cc +++ b/src/tests/system-tests/obs_gps_l1_system_test.cc @@ -555,7 +555,6 @@ void Obs_Gps_L1_System_Test::check_results() 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; } @@ -574,11 +573,11 @@ void Obs_Gps_L1_System_Test::check_results() } double sum_ = std::accumulate(mean_pr_diff_v.begin(), mean_pr_diff_v.end(), 0.0); double mean_ = sum_ / mean_pr_diff_v.size(); - std::vector diff_pr(mean_pr_diff_v.size()); - std::transform(mean_pr_diff_v.begin(), mean_pr_diff_v.end(), diff_pr.begin(), - std::bind2nd(std::minus(), mean_)); - double sq_sum_pr = std::inner_product(diff_pr.begin(), diff_pr.end(), diff_pr.begin(), 0.0); - double stdev_pr = std::sqrt(sq_sum_pr / mean_pr_diff_v.size()); + double accum = 0.0; + std::for_each (std::begin(mean_pr_diff_v), std::end(mean_pr_diff_v), [&](const double d) { + accum += (d - mean_) * (d - mean_); + }); + double stdev_pr = std::sqrt(accum / (mean_pr_diff_v.size() - 1)); std::cout << "Pseudorange diff error stdev = " << stdev_pr << " [m]" << std::endl; ASSERT_LT(stdev_pr, 1.0); @@ -591,7 +590,6 @@ void Obs_Gps_L1_System_Test::check_results() 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; } @@ -608,7 +606,7 @@ void Obs_Gps_L1_System_Test::check_results() prn_id++; } - // Compute doppler error + // Compute Doppler error prn_id = 0; std::vector mean_doppler_v; for(iter_diff = doppler_diff.begin(); iter_diff != doppler_diff.end(); iter_diff++) @@ -636,15 +634,14 @@ void Obs_Gps_L1_System_Test::check_results() prn_id++; } sum_ = std::accumulate(mean_doppler_v.begin(), mean_doppler_v.end(), 0.0); - mean_ = sum_ /mean_doppler_v.size(); - std::vector diff_dp(mean_doppler_v.size()); - std::transform(mean_doppler_v.begin(), mean_doppler_v.end(), diff_dp.begin(), - std::bind2nd(std::minus(), mean_)); - double sq_sum_dp = std::inner_product(diff_dp.begin(), diff_dp.end(), diff_dp.begin(), 0.0); - double stdev_dp = std::sqrt(sq_sum_dp / mean_doppler_v.size()); + mean_ = sum_ / mean_doppler_v.size(); + accum = 0.0; + std::for_each (std::begin(mean_doppler_v), std::end(mean_doppler_v), [&](const double d) { + accum += (d - mean_) * (d - mean_); + }); + double stdev_dp = std::sqrt(accum / (mean_doppler_v.size() - 1)); std::cout << "Doppler error stdev = " << stdev_dp << " [Hz]" << std::endl; ASSERT_LT(stdev_dp, 1.0); - //return 0; } From 166ec3622a4d1af54b398aac91a1039dc747a404 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 30 Dec 2016 13:36:28 +0100 Subject: [PATCH 14/15] Update GPSTk detection --- cmake/Modules/FindGPSTK.cmake | 67 ++--------------------------------- 1 file changed, 2 insertions(+), 65 deletions(-) diff --git a/cmake/Modules/FindGPSTK.cmake b/cmake/Modules/FindGPSTK.cmake index 9529154f9..fffe17877 100644 --- a/cmake/Modules/FindGPSTK.cmake +++ b/cmake/Modules/FindGPSTK.cmake @@ -1,87 +1,24 @@ # - Find gpstk library # Find the native gpstk includes and library # This module defines -# GPSTK_INCLUDE_DIR, where to find tiff.h, etc. +# GPSTK_INCLUDE_DIR, where to find Rinex3ObsBase.hpp, etc. # GPSTK_LIBRARIES, libraries to link against to use GPSTK. # GPSTK_FOUND, If false, do not try to use GPSTK. # also defined, but not for general use are # GPSTK_LIBRARY, where to find the GPSTK library. -FIND_PATH(GPSTK_INCLUDE_DIR gpstk/Matrix.hpp) -FIND_PATH(GEOMATICS_INCLUDE_DIR gpstk/random.hpp) -FIND_PATH(PROCFRAME_INCLUDE_DIR gpstk/SolverWMS.hpp) -FIND_PATH(VDRAW_INCLUDE_DIR gpstk/Layout.hpp) -FIND_PATH(VPLOT_INCLUDE_DIR gpstk/ScatterPlot.hpp) -FIND_PATH(RXIO_INCLUDE_DIR gpstk/EphReader.hpp) +FIND_PATH(GPSTK_INCLUDE_DIR Rinex3ObsBase.hpp) SET(GPSTK_NAMES ${GPSTK_NAMES} gpstk libgpstk) FIND_LIBRARY(GPSTK_LIBRARY NAMES ${GPSTK_NAMES} ) -SET(GEOMATICS_NAMES ${GEOMATICS_NAMES} geomatics libgeomatics) -FIND_LIBRARY(GEOMATICS_LIBRARY NAMES ${GEOMATICS_NAMES} ) - -SET(PROCFRAME_NAMES ${PROCFRAME_NAMES} procframe libprocframe) -FIND_LIBRARY(PROCFRAME_LIBRARY NAMES ${PROCFRAME_NAMES} ) - -SET(VDRAW_NAMES ${VDRAW_NAMES} vdraw libvdraw) -FIND_LIBRARY(VDRAW_LIBRARY NAMES ${VDRAW_NAMES} ) - -SET(VPLOT_NAMES ${VPLOT_NAMES} vplot libvplot) -FIND_LIBRARY(VPLOT_LIBRARY NAMES ${VPLOT_NAMES} ) - -SET(RXIO_NAMES ${RXIO_NAMES} rxio librxio) -FIND_LIBRARY(RXIO_LIBRARY NAMES ${RXIO_NAMES} ) - # handle the QUIETLY and REQUIRED arguments and set GPSTK_FOUND to TRUE if # all listed variables are TRUE INCLUDE(FindPackageHandleStandardArgs) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(GPSTK DEFAULT_MSG GPSTK_LIBRARY GPSTK_INCLUDE_DIR) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(GEOMATICS DEFAULT_MSG GEOMATICS_LIBRARY GEOMATICS_INCLUDE_DIR) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(PROCFRAME DEFAULT_MSG PROCFRAME_LIBRARY PROCFRAME_INCLUDE_DIR) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(VDRAW DEFAULT_MSG VDRAW_LIBRARY VDRAW_INCLUDE_DIR) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(VPLOT DEFAULT_MSG VPLOT_LIBRARY VPLOT_INCLUDE_DIR) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(RXIO DEFAULT_MSG RXIO_LIBRARY RXIO_INCLUDE_DIR) - IF(GPSTK_FOUND) SET( GPSTK_LIBRARIES ${GPSTK_LIBRARY} ) ENDIF(GPSTK_FOUND) -IF(GEOMATICS_FOUND) - SET( GEOMATICS_LIBRARIES ${GEOMATICS_LIBRARY} ) -ENDIF(GEOMATICS_FOUND) - -IF(PROCFRAME_FOUND) - SET( PROCFRAME_LIBRARIES ${PROCFRAME_LIBRARY} ) -ENDIF(PROCFRAME_FOUND) - -IF(VDRAW_FOUND) - SET( VDRAW_LIBRARIES ${VDRAW_LIBRARY} ) -ENDIF(VDRAW_FOUND) - -IF(VPLOT_FOUND) - SET( VPLOT_LIBRARIES ${VPLOT_LIBRARY} ) -ENDIF(VPLOT_FOUND) - -IF(RXIO_FOUND) - SET( RXIO_LIBRARIES ${RXIO_LIBRARY} ) -ENDIF(RXIO_FOUND) - MARK_AS_ADVANCED(GPSTK_INCLUDE_DIR GPSTK_LIBRARY) - -MARK_AS_ADVANCED(GEOMATICS_INCLUDE_DIR GEOMATICS_LIBRARY) - -MARK_AS_ADVANCED(PROCFRAME_INCLUDE_DIR PROCFRAME_LIBRARY) - -MARK_AS_ADVANCED(VDRAW_INCLUDE_DIR VDRAW_LIBRARY) - -MARK_AS_ADVANCED(VPLOT_INCLUDE_DIR VPLOT_LIBRARY) - -MARK_AS_ADVANCED(RXIO_INCLUDE_DIR RXIO_LIBRARY) - - From 7df15841b446485b3339cd31da0173b31d555a75 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 30 Dec 2016 14:36:41 +0100 Subject: [PATCH 15/15] Use GPSTk if found, let the user change that with -DENABLE_OWN_GPSTK=ON Add diff stdev error computation for carrier phase --- src/tests/CMakeLists.txt | 92 ++++++++++--------- .../system-tests/obs_gps_l1_system_test.cc | 12 ++- 2 files changed, 61 insertions(+), 43 deletions(-) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index f08fccc10..71aae6c90 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -136,6 +136,7 @@ endif(ENABLE_CUDA) ################################################################################ # Optional generator ################################################################################ +option(ENABLE_OWN_GPSTK "Download, build and link GPSTk for system tests" OFF) if(ENABLE_SW_GENERATOR) ExternalProject_Add( gnss-sim @@ -156,31 +157,38 @@ if(ENABLE_SW_GENERATOR) ################################################################################ # Local installation of GPSTk http://www.gpstk.org/ ################################################################################ - set(gpstk_RELEASE "2.5") - set(gpstk_md5 "9d79f6838d274f5edfd46c780a6b1b72") - ExternalProject_Add( - gpstk-${gpstk_RELEASE} - URL https://sourceforge.net/projects/gpstk/files/gpstk/${gpstk_RELEASE}/gpstk-${gpstk_RELEASE}.src.tar.gz - URL_MD5 ${gpstk_md5} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk - BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk - CONFIGURE_COMMAND "" - BUILD_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk/script_gpstk.sh -c - UPDATE_COMMAND "" - PATCH_COMMAND "" - INSTALL_COMMAND "" - ) - set(GPSTK_INCLUDE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk/dev/install/include CACHE PATH "Local GPSTK headers" - ) - add_library(gpstk UNKNOWN IMPORTED) - set_property(TARGET gpstk PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk/dev/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_SHARED_LIBRARY_SUFFIX}) - add_dependencies(gpstk gpstk-${gpstk_RELEASE}) - set(GPSTK_BINDIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk/dev/install/bin/ ) - add_definitions(-DGPSTK_BINDIR="${GPSTK_BINDIR}") - set(gpstk_libs gpstk) + find_package(GPSTK) + if(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) + set(gpstk_RELEASE "2.5") + set(gpstk_md5 "9d79f6838d274f5edfd46c780a6b1b72") + ExternalProject_Add( + gpstk-${gpstk_RELEASE} + URL https://sourceforge.net/projects/gpstk/files/gpstk/${gpstk_RELEASE}/gpstk-${gpstk_RELEASE}.src.tar.gz + URL_MD5 ${gpstk_md5} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk + BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk + CONFIGURE_COMMAND "" + BUILD_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk/script_gpstk.sh -c + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" + ) + set(GPSTK_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk/dev/install/include CACHE PATH "Local GPSTK headers") + add_library(gpstk UNKNOWN IMPORTED) + set_property(TARGET gpstk PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk/dev/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_SHARED_LIBRARY_SUFFIX}) + add_dependencies(gpstk gpstk-${gpstk_RELEASE}) + set(GPSTK_BINDIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk/dev/install/bin/ ) + add_definitions(-DGPSTK_BINDIR="${GPSTK_BINDIR}") + set(gpstk_libs gpstk) + else(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) + set(gpstk_libs ${GPSTK_LIBRARIES}) + set(GPSTK_INCLUDE_DIRS ${GPSTK_INCLUDE_DIR}) + set(GPSTK_BINDIR ${GPSTK_LIBRARY}/../bin/ ) + add_definitions(-DGPSTK_BINDIR="${GPSTK_BINDIR}") + endif(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) endif(ENABLE_SW_GENERATOR) + add_definitions(-DTEST_PATH="${CMAKE_SOURCE_DIR}/src/tests/") include_directories( @@ -481,23 +489,23 @@ if(ENABLE_SYSTEM_TESTING) ${CMAKE_SOURCE_DIR}/install/$ ) - add_executable(obs_gps_l1_system_test - ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_system_test.cc ) - if(NOT ${GTEST_DIR_LOCAL}) - add_dependencies(obs_gps_l1_system_test gtest-${gtest_RELEASE} ) - else(NOT ${GTEST_DIR_LOCAL}) - add_dependencies(obs_gps_l1_system_test gtest) - endif(NOT ${GTEST_DIR_LOCAL}) - include_directories(${GPSTK_INCLUDE_DIRS}) - target_link_libraries(obs_gps_l1_system_test ${GFlags_LIBS} - ${GLOG_LIBRARIES} - ${GTEST_LIBRARIES} - gnss_sp_libs - gnss_rx - ${gpstk_libs}) - add_custom_command(TARGET obs_gps_l1_system_test POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ - ${CMAKE_SOURCE_DIR}/install/$ - ) - + if(ENABLE_SW_GENERATOR) + add_executable(obs_gps_l1_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_system_test.cc ) + if(NOT ${GTEST_DIR_LOCAL}) + add_dependencies(obs_gps_l1_system_test gtest-${gtest_RELEASE} ) + else(NOT ${GTEST_DIR_LOCAL}) + add_dependencies(obs_gps_l1_system_test gtest) + endif(NOT ${GTEST_DIR_LOCAL}) + include_directories(${GPSTK_INCLUDE_DIRS}) + target_link_libraries(obs_gps_l1_system_test ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${GTEST_LIBRARIES} + gnss_sp_libs + gnss_rx + ${gpstk_libs}) + add_custom_command(TARGET obs_gps_l1_system_test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy $ + ${CMAKE_SOURCE_DIR}/install/$ + ) + endif(ENABLE_SW_GENERATOR) endif(ENABLE_SYSTEM_TESTING) diff --git a/src/tests/system-tests/obs_gps_l1_system_test.cc b/src/tests/system-tests/obs_gps_l1_system_test.cc index cc7807df0..b45a773be 100644 --- a/src/tests/system-tests/obs_gps_l1_system_test.cc +++ b/src/tests/system-tests/obs_gps_l1_system_test.cc @@ -583,6 +583,7 @@ void Obs_Gps_L1_System_Test::check_results() // 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 @@ -596,6 +597,7 @@ void Obs_Gps_L1_System_Test::check_results() 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 << std::endl; } else @@ -605,6 +607,14 @@ void Obs_Gps_L1_System_Test::check_results() prn_id++; } + sum_ = std::accumulate(mean_cp_diff_v.begin(), mean_cp_diff_v.end(), 0.0); + mean_ = sum_ / mean_cp_diff_v.size(); + accum = 0.0; + std::for_each (std::begin(mean_cp_diff_v), std::end(mean_cp_diff_v), [&](const double d) { + accum += (d - mean_) * (d - mean_); + }); + double stdev_cp = std::sqrt(accum / (mean_cp_diff_v.size() - 1)); + std::cout << "Carrier phase diff error stdev = " << stdev_cp << " whole cycles (19 cm)" << std::endl; // Compute Doppler error prn_id = 0; @@ -656,7 +666,7 @@ TEST_F(Obs_Gps_L1_System_Test, Observables_system_test) configure_generator(); // Generate signal raw signal samples and observations RINEX file - generate_signal(); + //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);