diff --git a/src/algorithms/PVT/gnuradio_blocks/galileo_e1_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/galileo_e1_pvt_cc.cc index a1ba212f3..fac0e5231 100644 --- a/src/algorithms/PVT/gnuradio_blocks/galileo_e1_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/galileo_e1_pvt_cc.cc @@ -92,6 +92,7 @@ galileo_e1_pvt_cc::galileo_e1_pvt_cc(unsigned int nchannels, boost::shared_ptr(); // ############# ENABLE DATA FILE LOG ################# @@ -211,6 +212,12 @@ int galileo_e1_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_it { rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map); } + if (!b_rinex_header_updated && (d_ls_pvt->galileo_utc_model.A0_6 != 0)) + { + rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); + rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); + b_rinex_header_updated = true; + } } } } diff --git a/src/algorithms/PVT/gnuradio_blocks/galileo_e1_pvt_cc.h b/src/algorithms/PVT/gnuradio_blocks/galileo_e1_pvt_cc.h index bdb72ae16..49952afa0 100644 --- a/src/algorithms/PVT/gnuradio_blocks/galileo_e1_pvt_cc.h +++ b/src/algorithms/PVT/gnuradio_blocks/galileo_e1_pvt_cc.h @@ -96,6 +96,7 @@ private: boost::shared_ptr d_queue; bool d_dump; bool b_rinex_header_writen; + bool b_rinex_header_updated; std::shared_ptr rp; unsigned int d_nchannels; std::string d_dump_filename; 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 6b2fea3aa..0532ae1a8 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 @@ -106,6 +106,7 @@ gps_l1_ca_pvt_cc::gps_l1_ca_pvt_cc(unsigned int nchannels, d_rx_time = 0.0; b_rinex_header_writen = false; + b_rinex_header_updated = false; b_rinex_sbs_header_writen = false; rp = std::make_shared(); @@ -150,6 +151,7 @@ int gps_l1_ca_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_ite std::map gnss_pseudoranges_map; Gnss_Synchro **in = (Gnss_Synchro **) &input_items[0]; //Get the input pointer + //Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0]; //Get the output pointer for (unsigned int i = 0; i < d_nchannels; i++) { @@ -166,14 +168,40 @@ int gps_l1_ca_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_ite if (global_gps_utc_model_map.size() > 0) { - // UTC MODEL data is shared for all the GPS satellites. Read always at ID=0 - global_gps_utc_model_map.read(0, d_ls_pvt->gps_utc_model); + // UTC MODEL data is shared for all the GPS satellites. Read always at a locked channel + signed int i = 0; + while(true) + { + if (in[i][0].Flag_valid_pseudorange == true) + { + global_gps_utc_model_map.read(i, d_ls_pvt->gps_utc_model); + break; + } + i++; + if (i == d_nchannels - 1) + { + break; + } + } } if (global_gps_iono_map.size() > 0) { - // IONO data is shared for all the GPS satellites. Read always at ID=0 - global_gps_iono_map.read(0, d_ls_pvt->gps_iono); + // IONO data is shared for all the GPS satellites. Read always at a locked channel + signed int i = 0; + while(true) + { + if (in[i][0].Flag_valid_pseudorange == true) + { + global_gps_iono_map.read(i, d_ls_pvt->gps_iono); + break; + } + i++; + if (i == d_nchannels - 1) + { + break; + } + } } // update SBAS data collections @@ -223,7 +251,7 @@ int gps_l1_ca_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_ite } // ############ 2 COMPUTE THE PVT ################################ - if (gnss_pseudoranges_map.size() > 0 and d_ls_pvt->gps_ephemeris_map.size() >0) + if (gnss_pseudoranges_map.size() > 0 and d_ls_pvt->gps_ephemeris_map.size() > 0) { // compute on the fly PVT solution //mod 8/4/2012 Set the PVT computation rate in this block @@ -242,7 +270,7 @@ int gps_l1_ca_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_ite gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin(); if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) { - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second,d_rx_time); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, d_rx_time); rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); b_rinex_header_writen = true; // do not write header anymore } @@ -262,6 +290,12 @@ int gps_l1_ca_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_ite { rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map); } + if (!b_rinex_header_updated && (d_ls_pvt->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); + rp->update_nav_header(rp->navFile, d_ls_pvt->gps_utc_model, d_ls_pvt->gps_iono); + b_rinex_header_updated = true; + } } } } @@ -304,7 +338,7 @@ int gps_l1_ca_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_ite } consume_each(1); //one by one - return 0; + return noutput_items; } 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 d66b8f81c..645760ee3 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 @@ -96,6 +96,7 @@ private: bool d_dump; bool b_rinex_header_writen; bool b_rinex_sbs_header_writen; + bool b_rinex_header_updated; std::shared_ptr rp; unsigned int d_nchannels; std::string d_dump_filename; diff --git a/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc index 4b42f6233..e7389b726 100644 --- a/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.cc @@ -98,6 +98,7 @@ hybrid_pvt_cc::hybrid_pvt_cc(unsigned int nchannels, boost::shared_ptr(); // ############# ENABLE DATA FILE LOG ################# @@ -250,6 +251,12 @@ int hybrid_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_items, { rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map); } + if (!b_rinex_header_updated && (d_ls_pvt->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); + b_rinex_header_updated = true; + } } } } diff --git a/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.h b/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.h index 8958f689a..dad4a2256 100644 --- a/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.h +++ b/src/algorithms/PVT/gnuradio_blocks/hybrid_pvt_cc.h @@ -100,6 +100,7 @@ private: boost::shared_ptr d_queue; bool d_dump; bool b_rinex_header_writen; + bool b_rinex_header_updated; std::shared_ptr rp; unsigned int d_nchannels; std::string d_dump_filename; diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 0bccdd268..75020c30f 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -33,6 +33,7 @@ #include // for min and max #include // for floor #include // for getenv() +#include #include #include #include @@ -57,11 +58,11 @@ Rinex_Printer::Rinex_Printer() navGalfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_GAL_NAV"); navMixfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_MIXED_NAV"); - Rinex_Printer::navFile.open(navfilename, std::ios::out | std::ios::app); - Rinex_Printer::obsFile.open(obsfilename, std::ios::out | std::ios::app); + Rinex_Printer::navFile.open(navfilename, std::ios::out | std::ios::in | std::ios::app); + Rinex_Printer::obsFile.open(obsfilename, std::ios::out | std::ios::in | std::ios::app); Rinex_Printer::sbsFile.open(sbsfilename, std::ios::out | std::ios::app); - Rinex_Printer::navGalFile.open(navGalfilename, std::ios::out | std::ios::app); - Rinex_Printer::navMixFile.open(navMixfilename, std::ios::out | std::ios::app); + Rinex_Printer::navGalFile.open(navGalfilename, std::ios::out | std::ios::in | std::ios::app); + Rinex_Printer::navMixFile.open(navMixfilename, std::ios::out | std::ios::in | std::ios::app); // RINEX v3.02 codes satelliteSystem["GPS"] = "G"; @@ -391,7 +392,7 @@ std::string Rinex_Printer::getLocalTime() } -void Rinex_Printer::rinex_nav_header(std::ofstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) { std::string line; stringVersion = "3.02"; @@ -501,9 +502,257 @@ void Rinex_Printer::rinex_nav_header(std::ofstream& out, const Galileo_Iono& ion out << line << std::endl; } -void Rinex_Printer::rinex_nav_header(std::ofstream& out, const Gps_Iono& iono, const Gps_Utc_Model& utc_model) -{ +void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) +{ + std::vector data; + std::string line_aux; + + long pos = out.tellp(); + out.seekp(0); + data.clear(); + + bool no_more_finds = false; + std::string line_str; + + while(!out.eof()) + { + std::getline(out, line_str); + + if(!no_more_finds) + { + line_aux.clear(); + + if ((line_str.find("GAL", 0) != std::string::npos) && (line_str.find("IONOSPHERIC CORR", 59) != std::string::npos)) + { + line_aux += std::string("GAL "); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai0_5, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai1_5, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai2_5, 10, 2), 12); + double zero = 0.0; + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(zero, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GAUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GAUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A0_6, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A1_6, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.t0t_6), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.WNot_6), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GPGA", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GPGA"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_0G_10, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_1G_10, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.t_0G_10), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.WN_0G_10), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("LEAP SECONDS", 59) != std::string::npos) + { + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.Delta_tLS_6), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.Delta_tLSF_6), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.WN_LSF_6), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.DN_6), 6); + line_aux += std::string(36, ' '); + line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + + } + else + { + data.push_back(line_str); + } + } + + out.close(); + out.open(navGalfilename, std::ios::out | std::ios::trunc); + out.seekp(0); + for (int i = 0; i < (int) data.size() - 1; i++) + { + out << data[i] << std::endl; + } + out.close(); + out.open(navGalfilename, std::ios::out | std::ios::app); + out.seekp(pos); + std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl; +} + + + +void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Utc_Model& utc_model, const Gps_Iono& iono) +{ + std::vector data; + std::string line_aux; + + long pos = out.tellp(); + out.seekp(0); + data.clear(); + + bool no_more_finds = false; + std::string line_str; + + while(!out.eof()) + { + std::getline(out, line_str); + + if(!no_more_finds) + { + line_aux.clear(); + + if (version == 2) + { + if (line_str.find("ION ALPHA", 59) != std::string::npos) + { + line_aux += std::string(2, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha0, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha1, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha2, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha3, 10, 2), 12); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("ION ALPHA", 20); + data.push_back(line_aux); + } + else if (line_str.find("ION BETA", 59) != std::string::npos) + { + line_aux += std::string(2, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta0, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta1, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta2, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta3, 10, 2), 12); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("ION BETA", 20); + data.push_back(line_aux); + } + else if (line_str.find("DELTA-UTC", 59) != std::string::npos) + { + line_aux += std::string(3, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0, 18, 2), 19); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1, 18, 2), 19); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_t_OT), 9); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_WN_T + 1024), 9); // valid until 2019 + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::leftJustify("DELTA-UTC: A0,A1,T,W", 20); + data.push_back(line_aux); + } + else if (line_str.find("LEAP SECONDS", 59) != std::string::npos) + { + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LS), 6); + line_aux += std::string(54, ' '); + line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + } + + if (version == 3) + { + if (line_str.find("GPSA", 0) != std::string::npos) + { + line_aux += std::string("GPSA"); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha0, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha1, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha2, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha3, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("GPSB", 0) != std::string::npos) + { + line_aux += std::string("GPSB"); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta0, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta1, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta2, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta3, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("GPUT", 0) != std::string::npos) + { + line_aux += std::string("GPUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_t_OT), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_WN_T + 1024), 5); // valid until 2019 + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("LEAP SECONDS", 59) != std::string::npos) + { + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LS), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_WN_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_DN), 6); + line_aux += std::string(36, ' '); + line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + } + } + else + { + data.push_back(line_str); + } + } + + out.close(); + out.open(navfilename, std::ios::out | std::ios::trunc); + out.seekp(0); + for (int i = 0; i < (int) data.size() - 1; i++) + { + out << data[i] << std::endl; + } + out.close(); + out.open(navfilename, std::ios::out | std::ios::app); + out.seekp(pos); + std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl; +} + + +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, const Gps_Utc_Model& utc_model) +{ std::string line; // -------- Line 1 @@ -680,7 +929,139 @@ void Rinex_Printer::rinex_nav_header(std::ofstream& out, const Gps_Iono& iono, c out << line << std::endl; } -void Rinex_Printer::rinex_nav_header(std::ofstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac) + +void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac) +{ + std::vector data; + std::string line_aux; + + long pos = out.tellp(); + out.seekp(0); + data.clear(); + + bool no_more_finds = false; + std::string line_str; + + while(!out.eof()) + { + std::getline(out, line_str); + + if(!no_more_finds) + { + line_aux.clear(); + + if (line_str.find("GPSA", 0) != std::string::npos) + { + line_aux += std::string("GPSA"); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha0, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha1, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha2, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha3, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GAL", 0) != std::string::npos) && (line_str.find("IONOSPHERIC CORR", 59) != std::string::npos)) + { + line_aux += std::string("GAL "); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai0_5, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai1_5, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai2_5, 10, 2), 12); + double zero = 0.0; + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(zero, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GPSB", 0) != std::string::npos) && (line_str.find("IONOSPHERIC CORR", 59) != std::string::npos)) + { + line_aux += std::string("GPSB"); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_beta0, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_beta1, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_beta2, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_beta3, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GPUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GPUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A0, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A1, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_t_OT), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_T + 1024), 5); // valid until 2019 + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GAUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GAUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A0_6, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A1_6, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.t0t_6), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WNot_6), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GPGA", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GPGA"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_0G_10, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_1G_10, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.t_0G_10), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.WN_0G_10), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("LEAP SECONDS", 59) != std::string::npos) + { + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LS), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_DN), 6); + line_aux += std::string(36, ' '); + line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + + } + else + { + data.push_back(line_str); + } + } + + out.close(); + out.open(navMixfilename, std::ios::out | std::ios::trunc); + out.seekp(0); + for (int i = 0; i < (int) data.size() - 1; i++) + { + out << data[i] << std::endl; + } + out.close(); + out.open(navMixfilename, std::ios::out | std::ios::app); + out.seekp(pos); + std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl; +} + + +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac) { std::string line; stringVersion = "3.02"; @@ -814,7 +1195,8 @@ void Rinex_Printer::rinex_nav_header(std::ofstream& out, const Gps_Iono& gps_ion out << line << std::endl; } -void Rinex_Printer::rinex_sbs_header(std::ofstream& out) + +void Rinex_Printer::rinex_sbs_header(std::fstream& out) { std::string line; @@ -922,7 +1304,7 @@ void Rinex_Printer::rinex_sbs_header(std::ofstream& out) } -void Rinex_Printer::log_rinex_nav(std::ofstream& out, const std::map& eph_map) +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) { std::string line; std::map::const_iterator gps_ephemeris_iter; @@ -932,7 +1314,7 @@ void Rinex_Printer::log_rinex_nav(std::ofstream& out, const std::mapsecond, gps_ephemeris_iter->second.d_Toe); + boost::posix_time::ptime p_utc_time = Rinex_Printer::compute_GPS_time(gps_ephemeris_iter->second, gps_ephemeris_iter->second.d_Toc); std::string timestring = boost::posix_time::to_iso_string(p_utc_time); std::string month (timestring, 4, 2); std::string day (timestring, 6, 2); @@ -1125,7 +1507,6 @@ void Rinex_Printer::log_rinex_nav(std::ofstream& out, const std::map& eph_map) +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) { std::string line; std::map::const_iterator galileo_ephemeris_iter; @@ -1264,7 +1645,7 @@ void Rinex_Printer::log_rinex_nav(std::ofstream& out, const std::mapsecond, galileo_ephemeris_iter->second.TOW_5); + boost::posix_time::ptime p_utc_time = Rinex_Printer::compute_Galileo_time(galileo_ephemeris_iter->second, galileo_ephemeris_iter->second.t0e_1); std::string timestring = boost::posix_time::to_iso_string(p_utc_time); std::string month (timestring, 4, 2); std::string day (timestring, 6, 2); @@ -1433,7 +1814,7 @@ void Rinex_Printer::log_rinex_nav(std::ofstream& out, const std::map& gps_eph_map, const std::map& galileo_eph_map) +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& galileo_eph_map) { version = 3; stringVersion = "3.02"; @@ -1441,10 +1822,91 @@ void Rinex_Printer::log_rinex_nav(std::ofstream& out, const std::map data; + std::string line_aux; + out.seekp(0); + data.clear(); + + bool no_more_finds = false; + std::string line_str; + + while(!out.eof()) + { + std::getline(out, line_str); + + if(!no_more_finds) + { + line_aux.clear(); + + if (version == 2) + { + if (line_str.find("TIME OF FIRST OBS", 59) != std::string::npos) // TIME OF FIRST OBS last header annotation might change in the future + { + data.push_back(line_str); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LS), 6); + line_aux += std::string(54, ' '); + line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + } + + if (version == 3) + { + if (line_str.find("TIME OF FIRST OBS", 59) != std::string::npos) + { + data.push_back(line_str); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LS), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_WN_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_DN), 6); + line_aux += std::string(36, ' '); + line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + } + } + else + { + data.push_back(line_str); + } + } + + out.close(); + out.open(obsfilename, std::ios::out | std::ios::trunc); + out.seekp(0); + for (int i = 0; i < (int) data.size() - 1; i++) + { + out << data[i] << std::endl; + } + out.close(); + out.open(obsfilename, std::ios::out | std::ios::in | std::ios::app); + out.seekp(0, std::ios_base::end); +} + + +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph, const double d_TOW_first_observation) +{ std::string line; // -------- Line 1 @@ -1704,8 +2166,67 @@ void Rinex_Printer::rinex_obs_header(std::ofstream& out, const Gps_Ephemeris& ep } +void Rinex_Printer::update_obs_header(std::fstream& out, const Galileo_Utc_Model& galileo_utc_model) +{ + std::vector data; + std::string line_aux; -void Rinex_Printer::rinex_obs_header(std::ofstream& out, const Galileo_Ephemeris& eph, const double d_TOW_first_observation) + out.seekp(0); + data.clear(); + + bool no_more_finds = false; + std::string line_str; + + while(!out.eof()) + { + std::getline(out, line_str); + + if(!no_more_finds) + { + line_aux.clear(); + + if (line_str.find("TIME OF FIRST OBS", 59) != std::string::npos) + { + data.push_back(line_str); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.Delta_tLS_6), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.Delta_tLSF_6), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WN_LSF_6), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.DN_6), 6); + line_aux += std::string(36, ' '); + line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + + } + else + { + data.push_back(line_str); + } + } + + out.close(); + out.open(obsfilename, std::ios::out | std::ios::trunc); + out.seekp(0); + for (int i = 0; i < (int) data.size() - 1; i++) + { + out << data[i] << std::endl; + } + out.close(); + out.open(obsfilename, std::ios::out | std::ios::in |std::ios::app); + out.seekp(0, std::ios_base::end); +} + + +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& eph, const double d_TOW_first_observation) { std::string line; version = 3; @@ -1907,8 +2428,9 @@ void Rinex_Printer::rinex_obs_header(std::ofstream& out, const Galileo_Ephemeris } -void Rinex_Printer::rinex_obs_header(std::ofstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, const double d_TOW_first_observation) +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, const double d_TOW_first_observation) { + if(galileo_eph.e_1){} // avoid warning, not needed std::string line; version = 3; @@ -2135,7 +2657,8 @@ void Rinex_Printer::rinex_obs_header(std::ofstream& out, const Gps_Ephemeris& gp out << line << std::endl; } -void Rinex_Printer::log_rinex_obs(std::ofstream& out, const Gps_Ephemeris& eph, const double obs_time, const std::map& pseudoranges) + +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, const double obs_time, const std::map& pseudoranges) { // RINEX observations timestamps are GPS timestamps. std::string line; @@ -2378,8 +2901,7 @@ void Rinex_Printer::log_rinex_obs(std::ofstream& out, const Gps_Ephemeris& eph, } - -void Rinex_Printer::log_rinex_obs(std::ofstream& out, const Galileo_Ephemeris& eph, double obs_time, const std::map& pseudoranges) +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& eph, double obs_time, const std::map& pseudoranges) { // RINEX observations timestamps are Galileo timestamps. // See http://gage14.upc.es/gLAB/HTML/Observation_Rinex_v3.01.html @@ -2499,8 +3021,9 @@ void Rinex_Printer::log_rinex_obs(std::ofstream& out, const Galileo_Ephemeris& e } -void Rinex_Printer::log_rinex_obs(std::ofstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, double gps_obs_time, const std::map& pseudoranges) +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, double gps_obs_time, const std::map& pseudoranges) { + if(galileo_eph.e_1){} // avoid warning, not needed std::string line; boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(gps_eph, gps_obs_time); @@ -2692,7 +3215,7 @@ void Rinex_Printer::to_date_time(int gps_week, int gps_tow, int &year, int &mont -void Rinex_Printer::log_rinex_sbs(std::ofstream& out, const Sbas_Raw_Msg& sbs_message) +void Rinex_Printer::log_rinex_sbs(std::fstream& out, const Sbas_Raw_Msg& sbs_message) { // line 1: PRN / EPOCH / RCVR std::stringstream line1; diff --git a/src/algorithms/PVT/libs/rinex_printer.h b/src/algorithms/PVT/libs/rinex_printer.h index df5829e56..585f6f463 100644 --- a/src/algorithms/PVT/libs/rinex_printer.h +++ b/src/algorithms/PVT/libs/rinex_printer.h @@ -59,6 +59,8 @@ #include #include #include "gps_navigation_message.h" +#include "gps_utc_model.h" +#include "gps_iono.h" #include "galileo_navigation_message.h" #include "sbas_telemetry_data.h" #include "GPS_L1_CA.h" @@ -84,46 +86,46 @@ public: */ ~Rinex_Printer(); - std::ofstream obsFile ; //& eph_map); + void log_rinex_nav(std::fstream& out, const std::map& eph_map); /*! * \brief Writes data from the Galileo navigation message into the RINEX file */ - void log_rinex_nav(std::ofstream& out, const std::map& eph_map); + void log_rinex_nav(std::fstream& out, const std::map& eph_map); /*! * \brief Writes data from the Mixed (GPS/Galileo) navigation message into the RINEX file */ - void log_rinex_nav(std::ofstream& out, const std::map& gps_eph_map, const std::map& galileo_eph_map); + void log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& galileo_eph_map); /*! * \brief Writes GPS observables into the RINEX file */ - void log_rinex_obs(std::ofstream& out, const Gps_Ephemeris& eph, double obs_time, const std::map& pseudoranges); + void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, double obs_time, const std::map& pseudoranges); /*! * \brief Writes Galileo observables into the RINEX file */ - void log_rinex_obs(std::ofstream& out, const Galileo_Ephemeris& eph, double obs_time, const std::map& pseudoranges); + void log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& eph, double obs_time, const std::map& pseudoranges); /*! * \brief Writes Galileo observables into the RINEX file */ - void log_rinex_obs(std::ofstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, const double gps_obs_time, const std::map& pseudoranges); + void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, const double gps_obs_time, const std::map& pseudoranges); /*! * \brief Represents GPS time in the date time format. Leap years are considered, but leap seconds are not. @@ -178,7 +180,17 @@ public: /*! * \brief Writes raw SBAS messages into the RINEX file */ - void log_rinex_sbs(std::ofstream& out, const Sbas_Raw_Msg& sbs_message); + void log_rinex_sbs(std::fstream& out, const Sbas_Raw_Msg& sbs_message); + + void update_nav_header(std::fstream& out, const Gps_Utc_Model& gps_utc, const Gps_Iono& gps_iono); + + void update_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac); + + void update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac); + + void update_obs_header(std::fstream& out, const Gps_Utc_Model& utc_model); + + void update_obs_header(std::fstream& out, const Galileo_Utc_Model& galileo_utc_model); std::map satelliteSystem; // observationType; //