Introducing RINEX Galileo navigation data file.

This commit is contained in:
Carles Fernandez 2014-08-31 15:58:09 +02:00
parent b770a5137e
commit f6a55955ae
3 changed files with 318 additions and 37 deletions

View File

@ -177,35 +177,35 @@ int galileo_e1_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_it
{
d_kml_dump->print_position_galileo(d_ls_pvt, d_flag_averaging);
//ToDo: Implement Galileo RINEX and Galileo NMEA outputs
// d_nmea_printer->Print_Nmea_Line(d_ls_pvt, d_flag_averaging);
// d_nmea_printer->Print_Nmea_Line(d_ls_pvt, d_flag_averaging);
//
// if (!b_rinex_header_writen) // & we have utc data in nav message!
// {
// std::map<int,Galileo_Ephemeris>::iterator galileo_ephemeris_iter;
// galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.begin();
// if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end())
// {
// rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time);
// rp->rinex_nav_header(rp->navFile, d_ls_pvt->galielo_iono, d_ls_pvt->galileo_utc_model);
// b_rinex_header_writen = true; // do not write header anymore
// }
// }
// if(b_rinex_header_writen) // Put here another condition to separate annotations (e.g 30 s)
// {
// // Limit the RINEX navigation output rate to 1/6 seg
// // Notice that d_sample_counter period is 1ms (for GPS correlators)
// if ((d_sample_counter-d_last_sample_nav_output)>=6000)
// {
// rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map);
// d_last_sample_nav_output=d_sample_counter;
// }
// std::map<int,Gps_Ephemeris>::iterator gps_ephemeris_iter;
// gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin();
// if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end())
// {
// rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map);
// }
// }
if (!b_rinex_header_writen) // & we have utc data in nav message!
{
std::map<int,Galileo_Ephemeris>::iterator galileo_ephemeris_iter;
galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.begin();
if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end())
{
//rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time);
rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model);
b_rinex_header_writen = true; // do not write header anymore
}
}
if(b_rinex_header_writen) // Put here another condition to separate annotations (e.g 30 s)
{
// Limit the RINEX navigation output rate to 1/6 seg
// Notice that d_sample_counter period is 4ms (for Galileo correlators)
if ((d_sample_counter - d_last_sample_nav_output) >= 6000)
{
rp->log_rinex_nav(rp->navGalFile, d_ls_pvt->galileo_ephemeris_map);
d_last_sample_nav_output = d_sample_counter;
}
// std::map<int, Galileo_Ephemeris>::iterator galileo_ephemeris_iter;
// galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.begin();
// if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end())
// {
// rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map);
// }
}
}
}

View File

@ -42,10 +42,7 @@
#include <gflags/gflags.h>
#include <glog/logging.h>
#include "sbas_telemetry_data.h"
#include "gps_navigation_message.h"
#include "gps_ephemeris.h"
#include "gps_iono.h"
#include "gps_utc_model.h"
using google::LogMessage;
@ -58,10 +55,13 @@ Rinex_Printer::Rinex_Printer()
navfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_GPS_NAV");
obsfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_OBS");
sbsfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_SBAS");
navGalfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_GAL_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::sbsFile.open(sbsfilename, std::ios::out | std::ios::app);
Rinex_Printer::navGalFile.open(navGalfilename, std::ios::out | std::ios::app);
// RINEX v3.00 codes
satelliteSystem["GPS"] = "G";
@ -167,13 +167,15 @@ Rinex_Printer::Rinex_Printer()
Rinex_Printer::~Rinex_Printer()
{
// close RINEX files
long posn, poso, poss;
long posn, poso, poss, posng;
posn = navFile.tellp();
poso = obsFile.tellp();
poss = obsFile.tellp();
posng = navGalFile.tellp();
Rinex_Printer::navFile.close();
Rinex_Printer::obsFile.close();
Rinex_Printer::sbsFile.close();
Rinex_Printer::navGalFile.close();
// If nothing written, erase the files.
if (posn == 0)
{
@ -187,6 +189,10 @@ Rinex_Printer::~Rinex_Printer()
{
remove(sbsfilename.c_str());
}
if (posng == 0)
{
remove(navGalfilename.c_str());
}
}
@ -353,6 +359,108 @@ std::string Rinex_Printer::getLocalTime()
}
void Rinex_Printer::rinex_nav_header(std::ofstream& out, Galileo_Iono iono, Galileo_Utc_Model utc_model)
{
std::string line;
stringVersion = "3.01";
version = 3;
// -------- Line 1
line = std::string(5, ' ');
line += stringVersion;
line += std::string(11, ' ');
line += std::string("N: GNSS NAV DATA");
line += std::string(4, ' ');
line += std::string("E: GALILEO");
line += std::string(10, ' ');
line += std::string("RINEX VERSION / TYPE");
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- Line 2
line.clear();
line += Rinex_Printer::getLocalTime();
line += std::string("PGM / RUN BY / DATE");
line += std::string(1, ' ');
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- Line COMMENT
line.clear();
line += Rinex_Printer::leftJustify("GALILEO NAVIGATION MESSAGE FILE GENERATED BY GNSS-SDR", 60);
line += Rinex_Printer::leftJustify("COMMENT", 20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- Line COMMENT
line.clear();
line += Rinex_Printer::leftJustify("See http://gnss-sdr.org", 60);
line += Rinex_Printer::leftJustify("COMMENT", 20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- Line ionospheric info 1
line.clear();
line += std::string("GAL ");
line += std::string(1, ' ');
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.ai0_5, 10, 2), 12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.ai1_5, 10, 2), 12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.ai2_5, 10, 2), 12);
double zero = 0.0;
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(zero, 10, 2), 12);
line += std::string(7, ' ');
line += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- Line system time correction
line.clear();
line += std::string("GAUT");
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A0_6, 16, 2), 18);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A1_6, 15, 2), 16);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.t0t_6), 7);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.WNot_6), 5);
line += std::string(10, ' ');
line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- Line system time correction 2
/* line.clear();
line += std::string("GPGA");
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.XXX, 16, 2), 18);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.XXX, 15, 2), 16);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.XXX), 7);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.XXX), 5);
line += std::string(10, ' ');
line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;*/
// -------- Line 6 leap seconds
// For leap second information, see http://www.endruntechnologies.com/leap.htm
line.clear();
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.Delta_tLS_6), 6);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.Delta_tLSF_6), 6);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.WN_LSF_6), 6);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.DN_6), 6);
line += std::string(36, ' ');
line += Rinex_Printer::leftJustify("LEAP SECONDS", 20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- End of Header
line.clear();
line += std::string(60, ' ');
line += Rinex_Printer::leftJustify("END OF HEADER", 20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
}
void Rinex_Printer::rinex_nav_header(std::ofstream& out, Gps_Iono iono, Gps_Utc_Model utc_model)
{
@ -524,7 +632,6 @@ void Rinex_Printer::rinex_nav_header(std::ofstream& out, Gps_Iono iono, Gps_Utc_
}
void Rinex_Printer::rinex_sbs_header(std::ofstream& out)
{
std::string line;
@ -911,6 +1018,158 @@ void Rinex_Printer::log_rinex_nav(std::ofstream& out, std::map<int,Gps_Ephemeris
void Rinex_Printer::log_rinex_nav(std::ofstream& out, std::map<int, Galileo_Ephemeris> eph_map)
{
std::string line;
std::map<int,Galileo_Ephemeris>::iterator galileo_ephemeris_iter;
line.clear();
for(galileo_ephemeris_iter = eph_map.begin();
galileo_ephemeris_iter != eph_map.end();
galileo_ephemeris_iter++)
{
// -------- SV / EPOCH / SV CLK
boost::posix_time::ptime p_utc_time = Rinex_Printer::compute_Galileo_time(galileo_ephemeris_iter->second, galileo_ephemeris_iter->second.TOW_5);
std::string timestring = boost::posix_time::to_iso_string(p_utc_time);
std::string month (timestring, 4, 2);
std::string day (timestring, 6, 2);
std::string hour (timestring, 9, 2);
std::string minutes (timestring, 11, 2);
std::string seconds (timestring, 13, 2);
line += satelliteSystem["Galileo"];
if (galileo_ephemeris_iter->second.i_satellite_PRN < 10) line += std::string("0");
line += boost::lexical_cast<std::string>(galileo_ephemeris_iter->second.i_satellite_PRN);
std::string year (timestring, 0, 4);
line += std::string(1, ' ');
line += year;
line += std::string(1, ' ');
line += month;
line += std::string(1, ' ');
line += day;
line += std::string(1, ' ');
line += hour;
line += std::string(1, ' ');
line += minutes;
line += std::string(1, ' ');
line += seconds;
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.af0_4, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.af1_4, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.af2_4, 18, 2);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 1
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.IOD_ephemeris, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.C_rs_3, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.delta_n_3, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.M0_1, 18, 2);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 2
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.C_uc_3, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.e_1, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.C_us_3, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.A_1, 18, 2);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 3
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.t0e_1, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.C_ic_4, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.OMEGA_0_2, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.C_is_4, 18, 2);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 4
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.i_0_2, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.C_rc_3, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.omega_2, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.OMEGA_dot_3, 18, 2);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 5
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.iDot_2, 18, 2);
line += std::string(1, ' ');
double zero = 0.0;
line += Rinex_Printer::doub2for(zero, 18, 2);
line += std::string(1, ' ');
double Galileo_week_continuous_number = (double)(galileo_ephemeris_iter->second.WN_5);
line += Rinex_Printer::doub2for(Galileo_week_continuous_number, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(zero, 18, 2);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 6
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(zero, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(zero, 18, 2); //
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(zero, 18, 2); //
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(zero, 18, 2); //
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 7
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.TOW_5, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(zero, 18, 2);
line += std::string(1, ' ');
line += std::string(18, ' '); // spare
line += std::string(1, ' ');
line += std::string(18, ' '); // spare
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
line.clear();
}
}
void Rinex_Printer::rinex_obs_header(std::ofstream& out, Gps_Ephemeris eph, double d_TOW_first_observation)
{
@ -1529,6 +1788,20 @@ boost::posix_time::ptime Rinex_Printer::compute_GPS_time(Gps_Ephemeris eph, doub
return p_time;
}
boost::posix_time::ptime Rinex_Printer::compute_Galileo_time(Galileo_Ephemeris eph, double obs_time)
{
// The RINEX v2.11 v3.00 format uses GPS time for the observations epoch, not UTC time, thus, no leap seconds needed here.
// (see Section 3 in http://igscb.jpl.nasa.gov/igscb/data/format/rinex211.txt)
// (see Pag. 17 in http://igscb.jpl.nasa.gov/igscb/data/format/rinex300.pdf)
// --??? No time correction here, since it will be done in the RINEX processor
double galileo_t = obs_time;
boost::posix_time::time_duration t = boost::posix_time::millisec((galileo_t + 604800*(double)(eph.WN_5))*1000);
boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t);
return p_time;
}
/*
enum RINEX_enumMarkerType {

View File

@ -57,9 +57,11 @@
#include <sstream> // for stringstream
#include <iomanip> // for setprecision
#include <map>
#include <boost/date_time/posix_time/posix_time.hpp>
#include "gps_navigation_message.h"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "galileo_navigation_message.h"
#include "GPS_L1_CA.h"
#include "Galileo_E1.h"
#include "gnss_synchro.h"
class Sbas_Raw_Msg;
@ -84,12 +86,15 @@ public:
std::ofstream obsFile ; //<! Output file stream for RINEX observation file
std::ofstream navFile ; //<! Output file stream for RINEX navigation data file
std::ofstream sbsFile ; //<! Output file stream for RINEX SBAS raw data file
std::ofstream navGalFile ; //<! Output file stream for RINEX Galileo navigation data file
/*!
* \brief Generates the Navigation Data header
*/
void rinex_nav_header(std::ofstream& out, Gps_Iono iono, Gps_Utc_Model utc_model);
void rinex_nav_header(std::ofstream& out, Galileo_Iono iono, Galileo_Utc_Model utc_model);
/*!
* \brief Generates the Observation data header
*/
@ -110,11 +115,13 @@ public:
*/
boost::posix_time::ptime compute_GPS_time(Gps_Ephemeris eph, double obs_time);
boost::posix_time::ptime compute_Galileo_time(Galileo_Ephemeris eph, double obs_time);
/*!
* \brief Writes data from the navigation message into the RINEX file
*/
void log_rinex_nav(std::ofstream& out, std::map<int,Gps_Ephemeris> eph_map);
void log_rinex_nav(std::ofstream& out, std::map<int,Gps_Ephemeris> eph_map);
void log_rinex_nav(std::ofstream& out, std::map<int, Galileo_Ephemeris> eph_map);
/*!
* \brief Writes observables into the RINEX file
@ -165,6 +172,7 @@ private:
std::string navfilename;
std::string obsfilename;
std::string sbsfilename;
std::string navGalfilename;
/*
* Generates the data for the PGM / RUN BY / DATE line