From ae7a6d686ebf5f0ca948023b0bc909dd462cb8ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Cebri=C3=A1n=20Juan?= Date: Tue, 6 Nov 2018 18:19:17 +0100 Subject: [PATCH 1/4] Record Speed and Course over ground in GPX output --- src/algorithms/PVT/libs/gpx_printer.cc | 31 +++++++++++++++++--------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/algorithms/PVT/libs/gpx_printer.cc b/src/algorithms/PVT/libs/gpx_printer.cc index f0b4b3ff3..1861139be 100644 --- a/src/algorithms/PVT/libs/gpx_printer.cc +++ b/src/algorithms/PVT/libs/gpx_printer.cc @@ -138,13 +138,15 @@ bool Gpx_Printer::set_headers(std::string filename, bool time_tag_name) gpx_file << std::setprecision(14); gpx_file << "" << std::endl << "" << std::endl - << "" << std::endl - << indent << "Position fixes computed by GNSS-SDR v" << GNSS_SDR_VERSION << "" << std::endl - << indent << "GNSS-SDR position log generated at " << pt << " (local time)" << std::endl - << indent << "" << std::endl; + << indent << "xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v2 http://www.garmin.com/xmlschemas/TrackPointExtensionv2.xsd\"" << std::endl + << indent << "xmlns=\"http://www.topografix.com/GPX/1/1\"" << std::endl + << indent << "xmlns:gpxx=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3\"" << std::endl + << indent << "xmlns:gpxtpx=\"http://www.garmin.com/xmlschemas/TrackPointExtension/v2\"" << std::endl + << indent << "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" << std::endl + << indent << "" << std::endl + << indent << indent << "Position fixes computed by GNSS-SDR v" << GNSS_SDR_VERSION << "" << std::endl + << indent << indent << "GNSS-SDR position log generated at " << pt << " (local time)" << std::endl + << indent << indent << "" << std::endl; return true; } else @@ -164,6 +166,9 @@ bool Gpx_Printer::print_position(const std::shared_ptr& position, positions_printed = true; std::shared_ptr position_ = position; + double speed_over_ground = position_->get_speed_over_ground(); // expressed in m/s + double course_over_ground = position_->get_course_over_ground(); // expressed in deg + double hdop = position_->get_hdop(); double vdop = position_->get_vdop(); double pdop = position_->get_pdop(); @@ -187,9 +192,13 @@ bool Gpx_Printer::print_position(const std::shared_ptr& position, if (gpx_file.is_open()) { - gpx_file << indent << indent << "" << height << "" + gpx_file << indent << indent << indent << "" << height << "" << "" - << "" << hdop << "" << vdop << "" << pdop << "" << std::endl; + << "" << hdop << "" << vdop << "" << pdop << "" + << "" + << "" << speed_over_ground << "" + << "" << course_over_ground << "" + << "" << std::endl; return true; } else @@ -203,8 +212,8 @@ bool Gpx_Printer::close_file() { if (gpx_file.is_open()) { - gpx_file << indent << "" << std::endl - << "" << std::endl + gpx_file << indent << indent << "" << std::endl + << indent << "" << std::endl << ""; gpx_file.close(); return true; From 686305da7174f26b8903a7c49c9bbf35cf09bb10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Cebri=C3=A1n=20Juan?= Date: Wed, 7 Nov 2018 14:01:46 +0100 Subject: [PATCH 2/4] Improve maintainability of indentation in KML files --- src/algorithms/PVT/libs/kml_printer.cc | 55 +++++++++++++------------- src/algorithms/PVT/libs/kml_printer.h | 1 + 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/algorithms/PVT/libs/kml_printer.cc b/src/algorithms/PVT/libs/kml_printer.cc index 4ebfcb970..ddbbd9159 100644 --- a/src/algorithms/PVT/libs/kml_printer.cc +++ b/src/algorithms/PVT/libs/kml_printer.cc @@ -43,6 +43,7 @@ using google::LogMessage; Kml_Printer::Kml_Printer(const std::string& base_path) { positions_printed = false; + indent = " "; kml_base_path = base_path; boost::filesystem::path full_path(boost::filesystem::current_path()); const boost::filesystem::path p(kml_base_path); @@ -135,28 +136,27 @@ bool Kml_Printer::set_headers(std::string filename, bool time_tag_name) kml_file << std::setprecision(14); kml_file << "" << std::endl << "" << std::endl - << " " << std::endl - << " GNSS Track" << std::endl - << " GNSS-SDR Receiver position log file created at " << pt - << " " << std::endl - << "" << std::endl - << "" << std::endl - << "GNSS-SDR PVT" << std::endl - << "GNSS-SDR position log" << std::endl - << "#yellowLineGreenPoly" << std::endl - << "" << std::endl - << "0" << std::endl - << "1" << std::endl - << "absolute" << std::endl - << "" << std::endl; + << indent << "" << std::endl + << indent << indent << "GNSS Track" << std::endl + << indent << indent << "GNSS-SDR Receiver position log file created at " << pt << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << indent << "GNSS-SDR PVT" << std::endl + << indent << indent << indent << "GNSS-SDR position log" << std::endl + << indent << indent << indent << "#yellowLineGreenPoly" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "0" << std::endl + << indent << indent << indent << indent << "1" << std::endl + << indent << indent << indent << indent << "absolute" << std::endl + << indent << indent << indent << indent << "" << std::endl; return true; } else @@ -192,7 +192,8 @@ bool Kml_Printer::print_position(const std::shared_ptr& position, if (kml_file.is_open()) { - kml_file << longitude << "," << latitude << "," << height << std::endl; + kml_file << indent << indent << indent << indent << indent + << longitude << "," << latitude << "," << height << std::endl; return true; } else @@ -206,10 +207,10 @@ bool Kml_Printer::close_file() { if (kml_file.is_open()) { - kml_file << "" << std::endl - << "" << std::endl - << "" << std::endl - << "" << std::endl + kml_file << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << "" << std::endl << ""; kml_file.close(); return true; diff --git a/src/algorithms/PVT/libs/kml_printer.h b/src/algorithms/PVT/libs/kml_printer.h index 9aed7c02c..c7f725e0b 100644 --- a/src/algorithms/PVT/libs/kml_printer.h +++ b/src/algorithms/PVT/libs/kml_printer.h @@ -50,6 +50,7 @@ private: std::ofstream kml_file; bool positions_printed; std::string kml_filename; + std::string indent; std::string kml_base_path; public: From 0e00b5eaa4c3b886d663531c25a6f82a079a0ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Cebri=C3=A1n=20Juan?= Date: Thu, 8 Nov 2018 03:44:31 +0100 Subject: [PATCH 3/4] Record Time, Speed over ground, Course over ground and Dilution of precision in KML output --- src/algorithms/PVT/libs/kml_printer.cc | 138 ++++++++++++++++++++++--- src/algorithms/PVT/libs/kml_printer.h | 10 +- 2 files changed, 128 insertions(+), 20 deletions(-) diff --git a/src/algorithms/PVT/libs/kml_printer.cc b/src/algorithms/PVT/libs/kml_printer.cc index ddbbd9159..fb742b385 100644 --- a/src/algorithms/PVT/libs/kml_printer.cc +++ b/src/algorithms/PVT/libs/kml_printer.cc @@ -2,6 +2,7 @@ * \file kml_printer.cc * \brief Implementation of a class that prints PVT information to a kml file * \author Javier Arribas, 2011. jarribas(at)cttc.es + * Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com * * * ------------------------------------------------------------------------- @@ -75,6 +76,14 @@ Kml_Printer::Kml_Printer(const std::string& base_path) } kml_base_path = kml_base_path + boost::filesystem::path::preferred_separator; + + boost::filesystem::path tmp_base_path = boost::filesystem::temp_directory_path(); + boost::filesystem::path tmp_filename = boost::filesystem::unique_path(); + boost::filesystem::path tmp_file = tmp_base_path / tmp_filename; + + tmp_file_str = tmp_file.string(); + + point_id = 0; } @@ -128,17 +137,61 @@ bool Kml_Printer::set_headers(std::string filename, bool time_tag_name) kml_filename = kml_base_path + kml_filename; kml_file.open(kml_filename.c_str()); - if (kml_file.is_open()) + tmp_file.open(tmp_file_str.c_str()); + + if (kml_file.is_open() && tmp_file.is_open()) { DLOG(INFO) << "KML printer writing on " << filename.c_str(); // Set iostream numeric format and precision kml_file.setf(kml_file.fixed, kml_file.floatfield); kml_file << std::setprecision(14); + + tmp_file.setf(tmp_file.fixed, tmp_file.floatfield); + tmp_file << std::setprecision(14); + kml_file << "" << std::endl - << "" << std::endl + << "" << std::endl << indent << "" << std::endl << indent << indent << "GNSS Track" << std::endl - << indent << indent << "GNSS-SDR Receiver position log file created at " << pt << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << indent << indent << "GNSS-SDR Receiver position log file created at " << pt << "" << std::endl + << indent << indent << indent << indent << "https://gnss-sdr.org/" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << "]]>" << std::endl + << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "normal" << std::endl + << indent << indent << indent << indent << "#track_n" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "highlight" << std::endl + << indent << indent << indent << indent << "#track_h" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << "" << std::endl << indent << indent << "" << std::endl - << indent << indent << "" << std::endl - << indent << indent << indent << "GNSS-SDR PVT" << std::endl - << indent << indent << indent << "GNSS-SDR position log" << std::endl - << indent << indent << indent << "#yellowLineGreenPoly" << std::endl - << indent << indent << indent << "" << std::endl - << indent << indent << indent << indent << "0" << std::endl - << indent << indent << indent << indent << "1" << std::endl - << indent << indent << indent << indent << "absolute" << std::endl - << indent << indent << indent << indent << "" << std::endl; + << indent << indent << "" << std::endl + << indent << indent << indent << "Points" << std::endl; + return true; } else @@ -167,7 +214,7 @@ bool Kml_Printer::set_headers(std::string filename, bool time_tag_name) } -bool Kml_Printer::print_position(const std::shared_ptr& position, bool print_average_values) +bool Kml_Printer::print_position(const std::shared_ptr& position, bool print_average_values) { double latitude; double longitude; @@ -175,7 +222,18 @@ bool Kml_Printer::print_position(const std::shared_ptr& position, positions_printed = true; - std::shared_ptr position_ = position; + std::shared_ptr position_ = position; + + double speed_over_ground = position_->get_speed_over_ground(); // expressed in m/s + double course_over_ground = position_->get_course_over_ground(); // expressed in deg + + double hdop = position_->get_hdop(); + double vdop = position_->get_vdop(); + double pdop = position_->get_pdop(); + std::string utc_time = to_iso_extended_string(position_->get_position_UTC_time()); + if (utc_time.length() < 23) utc_time += "."; + utc_time.resize(23, '0'); // time up to ms + utc_time.append("Z"); // UTC time zone if (print_average_values == false) { @@ -190,10 +248,38 @@ bool Kml_Printer::print_position(const std::shared_ptr& position, height = position_->get_avg_height(); } - if (kml_file.is_open()) + if (kml_file.is_open() && tmp_file.is_open()) { - kml_file << indent << indent << indent << indent << indent + point_id++; + kml_file << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "" << point_id << "" << std::endl + << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << indent << indent << "Time:" << utc_time << "" << std::endl + << indent << indent << indent << indent << indent << indent << "Longitude:" << longitude << "deg" << std::endl + << indent << indent << indent << indent << indent << indent << "Latitude:" << latitude << "deg" << std::endl + << indent << indent << indent << indent << indent << indent << "Altitude:" << height << "m" << std::endl + << indent << indent << indent << indent << indent << indent << "Speed:" << speed_over_ground << "m/s" << std::endl + << indent << indent << indent << indent << indent << indent << "Course:" << course_over_ground << "deg" << std::endl + << indent << indent << indent << indent << indent << indent << "HDOP:" << hdop << "" << std::endl + << indent << indent << indent << indent << indent << indent << "VDOP:" << vdop << "" << std::endl + << indent << indent << indent << indent << indent << indent << "PDOP:" << pdop << "" << std::endl + << indent << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "]]>" << std::endl + << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << indent << "" << utc_time << "" << std::endl + << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "#track" << std::endl + << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << indent << "absolute" << std::endl + << indent << indent << indent << indent << indent << "" << longitude << "," << latitude << "," << height << "" << std::endl + << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << "" << std::endl; + + tmp_file << indent << indent << indent << indent << indent << longitude << "," << latitude << "," << height << std::endl; + return true; } else @@ -205,14 +291,32 @@ bool Kml_Printer::print_position(const std::shared_ptr& position, bool Kml_Printer::close_file() { - if (kml_file.is_open()) + if (kml_file.is_open() && tmp_file.is_open()) { + tmp_file.close(); + + kml_file << indent << indent << "" + << indent << indent << "" << std::endl + << indent << indent << indent << "Path" << std::endl + << indent << indent << indent << "#yellowLineGreenPoly" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "0" << std::endl + << indent << indent << indent << indent << "1" << std::endl + << indent << indent << indent << indent << "absolute" << std::endl + << indent << indent << indent << indent << "" << std::endl; + + // Copy the contents of tmp_file into kml_file + std::ifstream src(tmp_file_str, std::ios::binary); + kml_file << src.rdbuf(); + kml_file << indent << indent << indent << indent << "" << std::endl << indent << indent << indent << "" << std::endl << indent << indent << "" << std::endl << indent << "" << std::endl << ""; + kml_file.close(); + return true; } else diff --git a/src/algorithms/PVT/libs/kml_printer.h b/src/algorithms/PVT/libs/kml_printer.h index c7f725e0b..27225df7a 100644 --- a/src/algorithms/PVT/libs/kml_printer.h +++ b/src/algorithms/PVT/libs/kml_printer.h @@ -2,7 +2,7 @@ * \file kml_printer.h * \brief Interface of a class that prints PVT information to a kml file * \author Javier Arribas, 2011. jarribas(at)cttc.es - * + * Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com * * ------------------------------------------------------------------------- * @@ -34,6 +34,7 @@ #define GNSS_SDR_KML_PRINTER_H_ #include "pvt_solution.h" +#include "rtklib_solver.h" #include #include #include @@ -48,16 +49,19 @@ class Kml_Printer { private: std::ofstream kml_file; + std::ofstream tmp_file; bool positions_printed; std::string kml_filename; - std::string indent; std::string kml_base_path; + std::string tmp_file_str; + unsigned int point_id; + std::string indent; public: Kml_Printer(const std::string& base_path = std::string(".")); ~Kml_Printer(); bool set_headers(std::string filename, bool time_tag_name = true); - bool print_position(const std::shared_ptr& position, bool print_average_values); + bool print_position(const std::shared_ptr& position, bool print_average_values); bool close_file(); }; From 2db629a6c1f75f72444ffd1b1a1fd4765c00228a Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 9 Nov 2018 12:14:05 +0100 Subject: [PATCH 4/4] Remove old KML reader --- .../system-tests/libs/position_test_flags.h | 1 - src/tests/system-tests/position_test.cc | 127 +++++------------- 2 files changed, 31 insertions(+), 97 deletions(-) diff --git a/src/tests/system-tests/libs/position_test_flags.h b/src/tests/system-tests/libs/position_test_flags.h index cf33c344f..1ebe296e6 100644 --- a/src/tests/system-tests/libs/position_test_flags.h +++ b/src/tests/system-tests/libs/position_test_flags.h @@ -37,7 +37,6 @@ DEFINE_string(config_file_ptest, std::string(""), "File containing the configuration parameters for the position test."); DEFINE_bool(plot_position_test, false, "Plots results of with gnuplot"); DEFINE_bool(static_scenario, true, "Compute figures of merit for static user position (DRMS, CEP, etc..)"); -DEFINE_bool(use_pvt_solver_dump, false, "Use PVT solver binary dump or fall back to KML PVT file (contains only position information)"); DEFINE_bool(use_ref_motion_file, false, "Enable or disable the use of a reference file containing the true receiver position, velocity and acceleration."); DEFINE_int32(ref_motion_file_type, 1, "Type of reference motion file: 1- Spirent CSV motion file"); DEFINE_string(ref_motion_filename, std::string("motion.csv"), "Path and filename for the reference motion file"); diff --git a/src/tests/system-tests/position_test.cc b/src/tests/system-tests/position_test.cc index 1a4c5e780..f030130e1 100644 --- a/src/tests/system-tests/position_test.cc +++ b/src/tests/system-tests/position_test.cc @@ -455,107 +455,42 @@ void PositionSystemTest::check_results() ref_R_eb_e.insert_cols(0, true_r_eb_e); arma::vec ref_r_enu = {0, 0, 0}; cart2utm(true_r_eb_e, utm_zone, ref_r_enu); - if (!FLAGS_use_pvt_solver_dump) + + rtklib_solver_dump_reader pvt_reader; + pvt_reader.open_obs_file(FLAGS_pvt_solver_dump_filename); + int64_t n_epochs = pvt_reader.num_epochs(); + R_eb_e = arma::zeros(3, n_epochs); + V_eb_e = arma::zeros(3, n_epochs); + LLH = arma::zeros(3, n_epochs); + receiver_time_s = arma::zeros(n_epochs, 1); + int64_t current_epoch = 0; + while (pvt_reader.read_binary_obs()) { - //fall back to read receiver KML output (position only) - std::fstream myfile(PositionSystemTest::generated_kml_file, std::ios_base::in); - ASSERT_TRUE(myfile.is_open()) << "No valid kml file could be opened"; - std::string line; - // Skip header - std::getline(myfile, line); - bool is_header = true; - while (is_header) - { - std::getline(myfile, line); - ASSERT_FALSE(myfile.eof()) << "No valid kml file found."; - std::size_t found = line.find(""); - if (found != std::string::npos) is_header = false; - } - bool is_data = true; - //read data - int64_t current_epoch = 0; - while (is_data) - { - if (!std::getline(myfile, line)) - { - is_data = false; - break; - } - std::size_t found = line.find(""); - if (found != std::string::npos) - is_data = false; - else - { - std::string str2; - std::istringstream iss(line); - double value; - double lat = 0.0; - double longitude = 0.0; - double h = 0.0; - for (int i = 0; i < 3; i++) - { - std::getline(iss, str2, ','); - value = std::stod(str2); - if (i == 0) longitude = value; - if (i == 1) lat = value; - if (i == 2) h = value; - } + receiver_time_s(current_epoch) = pvt_reader.RX_time - pvt_reader.clk_offset_s; + R_eb_e(0, current_epoch) = pvt_reader.rr[0]; + R_eb_e(1, current_epoch) = pvt_reader.rr[1]; + R_eb_e(2, current_epoch) = pvt_reader.rr[2]; + V_eb_e(0, current_epoch) = pvt_reader.rr[3]; + V_eb_e(1, current_epoch) = pvt_reader.rr[4]; + V_eb_e(2, current_epoch) = pvt_reader.rr[5]; + LLH(0, current_epoch) = pvt_reader.latitude; + LLH(1, current_epoch) = pvt_reader.longitude; + LLH(2, current_epoch) = pvt_reader.height; - arma::vec tmp_v_ecef; - arma::vec tmp_r_ecef; - pv_Geo_to_ECEF(degtorad(lat), degtorad(longitude), h, arma::vec{0, 0, 0}, tmp_r_ecef, tmp_v_ecef); - R_eb_e.insert_cols(current_epoch, tmp_r_ecef); - arma::vec tmp_r_enu = {0, 0, 0}; - cart2utm(tmp_r_ecef, utm_zone, tmp_r_enu); - R_eb_enu.insert_cols(current_epoch, tmp_r_enu); - // std::cout << "lat = " << lat << ", longitude = " << longitude << " h = " << h << std::endl; - // std::cout << "E = " << east << ", N = " << north << " U = " << up << std::endl; - // getchar(); - } - } - myfile.close(); - ASSERT_FALSE(R_eb_e.n_cols == 0) << "KML file is empty"; - } - else - { - //use complete binary dump from pvt solver - rtklib_solver_dump_reader pvt_reader; - pvt_reader.open_obs_file(FLAGS_pvt_solver_dump_filename); - int64_t n_epochs = pvt_reader.num_epochs(); - R_eb_e = arma::zeros(3, n_epochs); - V_eb_e = arma::zeros(3, n_epochs); - LLH = arma::zeros(3, n_epochs); - receiver_time_s = arma::zeros(n_epochs, 1); - int64_t current_epoch = 0; - while (pvt_reader.read_binary_obs()) - { - receiver_time_s(current_epoch) = pvt_reader.RX_time - pvt_reader.clk_offset_s; - R_eb_e(0, current_epoch) = pvt_reader.rr[0]; - R_eb_e(1, current_epoch) = pvt_reader.rr[1]; - R_eb_e(2, current_epoch) = pvt_reader.rr[2]; - V_eb_e(0, current_epoch) = pvt_reader.rr[3]; - V_eb_e(1, current_epoch) = pvt_reader.rr[4]; - V_eb_e(2, current_epoch) = pvt_reader.rr[5]; - LLH(0, current_epoch) = pvt_reader.latitude; - LLH(1, current_epoch) = pvt_reader.longitude; - LLH(2, current_epoch) = pvt_reader.height; - - arma::vec tmp_r_enu = {0, 0, 0}; - cart2utm(R_eb_e.col(current_epoch), utm_zone, tmp_r_enu); - R_eb_enu.insert_cols(current_epoch, tmp_r_enu); - - //debug check - // std::cout << "t1: " << pvt_reader.RX_time << std::endl; - // std::cout << "t2: " << pvt_reader.TOW_at_current_symbol_ms << std::endl; - // std::cout << "offset: " << pvt_reader.clk_offset_s << std::endl; - // getchar(); - current_epoch++; - } - ASSERT_FALSE(current_epoch == 0) << "PVT dump is empty"; + arma::vec tmp_r_enu = {0, 0, 0}; + cart2utm(R_eb_e.col(current_epoch), utm_zone, tmp_r_enu); + R_eb_enu.insert_cols(current_epoch, tmp_r_enu); + + // debug check + // std::cout << "t1: " << pvt_reader.RX_time << std::endl; + // std::cout << "t2: " << pvt_reader.TOW_at_current_symbol_ms << std::endl; + // std::cout << "offset: " << pvt_reader.clk_offset_s << std::endl; + // getchar(); + current_epoch++; } + ASSERT_FALSE(current_epoch == 0) << "PVT dump is empty"; // compute results - if (FLAGS_static_scenario) { double sigma_E_2_precision = arma::var(R_eb_enu.row(0));