1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-09-29 15:30:52 +00:00

Merge branch 'glonass' of https://github.com/gnss-sdr/gnss-sdr into glonass

This commit is contained in:
Carles Fernandez 2017-10-31 11:35:26 +01:00
commit d6ea3dac53
23 changed files with 463 additions and 263 deletions

View File

@ -67,7 +67,16 @@ Observables.dump_filename=/archive/glo_observables.dat
;######### PVT CONFIG ############
PVT.implementation=RTKLIB_PVT
PVT.averaging_depth=100
PVT.flag_averaging=true
PVT.output_rate_ms=10
PVT.positioning_mode=PPP_Static
PVT.output_rate_ms=100
PVT.display_rate_ms=500
PVT.trop_model=Saastamoinen
PVT.flag_rtcm_server=true
PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1
PVT.rtcm_tcp_port=2101
PVT.rtcm_MT1019_rate_ms=5000
PVT.rtcm_MT1045_rate_ms=5000
PVT.rtcm_MT1097_rate_ms=1000
PVT.rtcm_MT1077_rate_ms=1000
PVT.rinex_version=2

View File

@ -13,7 +13,7 @@ ControlThread.wait_for_flowgraph=false
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=File_Signal_Source
SignalSource.filename=/Users/carlesfernandez/Documents/workspace/code2/trunk/data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ;/datalogger/signals/CTTC/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ; <- PUT YOUR FILE HERE
SignalSource.filename=/archive/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ;/datalogger/signals/CTTC/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ; <- PUT YOUR FILE HERE
SignalSource.item_type=ishort
SignalSource.sampling_frequency=4000000
SignalSource.freq=1575420000

View File

@ -190,8 +190,8 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg)
// TODO Add GLONASS with gps week number and tow,
// insert new ephemeris record
DLOG(INFO) << "GLONASS GNAV New Ephemeris record inserted in global map with TOW =" << glonass_gnav_eph->d_TOW
<< ", GLONASS GNAV Week Number =" << glonass_gnav_eph->d_WN
<< " and Ephemeris IOD = " << glonass_gnav_eph->compute_GLONASS_time(glonass_gnav_eph->d_t_b)
<< ", Week Number =" << glonass_gnav_eph->d_WN
<< " and Ephemeris IOD in UTC = " << glonass_gnav_eph->compute_GLONASS_time(glonass_gnav_eph->d_t_b)
<< " from SV = " << glonass_gnav_eph->i_satellite_slot_number;
// update/insert new ephemeris record to the global ephemeris map
d_ls_pvt->glonass_gnav_ephemeris_map[glonass_gnav_eph->i_satellite_PRN] = *glonass_gnav_eph;
@ -542,13 +542,13 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite
std::map<int,Gps_Ephemeris>::const_iterator tmp_eph_iter_gps = d_ls_pvt->gps_ephemeris_map.find(in[i][epoch].PRN);
std::map<int,Galileo_Ephemeris>::const_iterator tmp_eph_iter_gal = d_ls_pvt->galileo_ephemeris_map.find(in[i][epoch].PRN);
std::map<int,Gps_CNAV_Ephemeris>::const_iterator tmp_eph_iter_cnav = d_ls_pvt->gps_cnav_ephemeris_map.find(in[i][epoch].PRN);
std::map<int,Glonass_Gnav_Ephemeris>::const_iterator tmp_eph_iter_glo_gnav = d_ls_pvt->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN);
std::map<int,Glonass_Gnav_Ephemeris>::const_iterator tmp_eph_iter_glo_gnav = d_ls_pvt->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN);
if(((tmp_eph_iter_gps->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("1C") == 0))
|| ((tmp_eph_iter_cnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("2S") == 0))
|| ((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("1B") == 0))
|| ((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("5X") == 0))
|| ((tmp_eph_iter_glo_gnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("1C") == 0))
|| ((tmp_eph_iter_glo_gnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("2C") == 0)))
|| ((tmp_eph_iter_glo_gnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("1G") == 0))
|| ((tmp_eph_iter_glo_gnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("2G") == 0)))
{
// store valid observables in a map.
gnss_observables_map.insert(std::pair<int,Gnss_Synchro>(i, in[i][epoch]));
@ -579,7 +579,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite
{
if(tmp_eph_iter_glo_gnav != d_ls_pvt->glonass_gnav_ephemeris_map.end())
{
//d_rtcm_printer->lock_time(d_ls_pvt->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time
d_rtcm_printer->lock_time(d_ls_pvt->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time
}
}
@ -839,7 +839,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite
}
if(type_of_rx == 23) // GLONASS L1 C/A only
{
std::string signal("1C");
std::string signal("1G");
if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend())
{
rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal);
@ -849,7 +849,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite
}
if(type_of_rx == 24) // GLONASS L2 C/A only
{
std::string signal("2C");
std::string signal("2G");
if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend())
{
rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, signal);
@ -859,7 +859,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite
}
if(type_of_rx == 25) // GLONASS L1 C/A + GLONASS L2 C/A
{
std::string signal("1C 2C");
std::string signal("1G 2G");
if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend())
{
rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal);
@ -872,7 +872,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite
{
if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) && (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) )
{
std::string glo_signal("1C");
std::string glo_signal("1G");
rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal);
rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac);
b_rinex_header_written = true; // do not write header anymore
@ -882,7 +882,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite
{
if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) && (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) )
{
std::string glo_signal("1C");
std::string glo_signal("1G");
std::string gal_signal("1B");
rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal, gal_signal);
rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac);
@ -1112,7 +1112,6 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite
{
if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) && (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) )
{
std::string glo_signal("1C");
rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map);
}

View File

@ -3208,9 +3208,9 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Glonass_Gnav_Ephem
strm << numberTypesObservations;
line += Rinex_Printer::rightJustify(strm.str(), 3);
std::string signal_ = "1C";
std::string signal_ = "1G";
std::size_t found_1C = glonass_bands.find(signal_);
signal_ = "2C";
signal_ = "2G";
std::size_t found_2C = glonass_bands.find(signal_);
if(found_1C != std::string::npos)
@ -3535,13 +3535,13 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps
// Find GLONASS Signal in Mixed file
unsigned int number_of_observations_glo = 0;
std::string signal_("1C");
std::string signal_("1G");
std::size_t found_1C = glonass_bands.find(signal_);
if(found_1C != std::string::npos)
{
number_of_observations_glo = number_of_observations_glo + 4;
}
signal_ = "2C";
signal_ = "2G";
std::size_t found_2C = glonass_bands.find(signal_);
if(found_2C != std::string::npos)
{
@ -3851,13 +3851,13 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris&
line.clear();
unsigned int number_of_observations_glo = 0;
signal_ = "1C";
signal_ = "1G";
std::size_t found_1C = glonass_bands.find(signal_);
if(found_1C != std::string::npos)
{
number_of_observations_glo = number_of_observations_glo + 4;
}
signal_ = "2C";
signal_ = "2G";
std::size_t found_2C = glonass_bands.find(signal_);
if(found_2C != std::string::npos)
{

View File

@ -115,7 +115,8 @@ bool rtklib_solver::get_PVT(const std::map<int,Gnss_Synchro> & gnss_observables_
std::map<int,Galileo_Ephemeris>::const_iterator galileo_ephemeris_iter;
std::map<int,Gps_Ephemeris>::const_iterator gps_ephemeris_iter;
std::map<int,Gps_CNAV_Ephemeris>::const_iterator gps_cnav_ephemeris_iter;
std::map<int,Glonass_Gnav_Ephemeris>::const_iterator glonass_gnav_ephemeris_iter;
std::map<int,Glonass_Gnav_Ephemeris>::const_iterator glonass_gnav_ephemeris_iter;
const Glonass_Gnav_Utc_Model gnav_utc = this->glonass_gnav_utc_model;
this->set_averaging_flag(flag_averaging);
@ -123,6 +124,7 @@ bool rtklib_solver::get_PVT(const std::map<int,Gnss_Synchro> & gnss_observables_
// ****** PREPARE THE DATA (SV EPHEMERIS AND OBSERVATIONS) ************************
// ********************************************************************************
int valid_obs = 0; //valid observations counter
int glo_valid_obs = 0; //GLONASS L1/L2 valid observations counter
obsd_t obs_data[MAXOBS];
eph_t eph_data[MAXOBS];
@ -279,75 +281,74 @@ bool rtklib_solver::get_PVT(const std::map<int,Gnss_Synchro> & gnss_observables_
break;
}
case 'R': //TODO This should be using rtk lib nomenclature
{
std::string sig_(gnss_observables_iter->second.Signal);
// GLONASS GNAV L1
if(sig_.compare("1C") == 0)
{
// 1 Glo - find the ephemeris for the current GLONASS SV observation. The SV Slot Number (PRN ID) is the map key
glonass_gnav_ephemeris_iter = glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (glonass_gnav_ephemeris_iter != glonass_gnav_ephemeris_map.end())
{
//convert ephemeris from GNSS-SDR class to RTKLIB structure
geph_data[valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second);
//convert observation from GNSS-SDR class to RTKLIB structure
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
obs_data[valid_obs] = insert_obs_to_rtklib(newobs,
gnss_observables_iter->second,
glonass_gnav_ephemeris_iter->second.d_WN,
0);//TODO are THESE VALUES OK
valid_obs++;
}
else // the ephemeris are not available for this SV
{
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN;
}
{
std::string sig_(gnss_observables_iter->second.Signal);
// GLONASS GNAV L1
if(sig_.compare("1G") == 0)
{
// 1 Glo - find the ephemeris for the current GLONASS SV observation. The SV Slot Number (PRN ID) is the map key
glonass_gnav_ephemeris_iter = glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (glonass_gnav_ephemeris_iter != glonass_gnav_ephemeris_map.cend())
{
//convert ephemeris from GNSS-SDR class to RTKLIB structure
geph_data[glo_valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second, gnav_utc);
//convert observation from GNSS-SDR class to RTKLIB structure
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
obs_data[glo_valid_obs] = insert_obs_to_rtklib(newobs,
gnss_observables_iter->second,
glonass_gnav_ephemeris_iter->second.d_WN,
0);//Band 0 (L1)
glo_valid_obs++;
}
else // the ephemeris are not available for this SV
{
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN;
}
}
// GLONASS GNAV L2
if(sig_.compare("2C") == 0)
{
// 1 Gal - find the ephemeris for the current GALILEO SV observation. The SV PRN ID is the map key
glonass_gnav_ephemeris_iter = glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (glonass_gnav_ephemeris_iter != glonass_gnav_ephemeris_map.end())
{
bool found_L1_obs=false;
for (int i = 0; i < valid_obs; i++)
{
// TODO what is this?
if (geph_data[i].sat == (static_cast<int>(gnss_observables_iter->second.PRN+NSATGPS+NSATGLO)))
{
obs_data[i] = insert_obs_to_rtklib(obs_data[i],
gnss_observables_iter->second,
glonass_gnav_ephemeris_iter->second.d_WN,
2);//Band 3 (L5/E5)
found_L1_obs=true;
break;
}
}
if (!found_L1_obs)
{
//insert GLONASS GNAV L2 obs as new obs and also insert its ephemeris
//convert ephemeris from GNSS-SDR class to RTKLIB structure
geph_data[valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second);
//convert observation from GNSS-SDR class to RTKLIB structure
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
obs_data[valid_obs] = insert_obs_to_rtklib(newobs,
gnss_observables_iter->second,
galileo_ephemeris_iter->second.WN_5,
2); //Band 3 (L5/E5)
valid_obs++;
}
}
else // the ephemeris are not available for this SV
{
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN;
}
}
// GLONASS GNAV L2
if(sig_.compare("2G") == 0)
{
// 1 GLONASS - find the ephemeris for the current GLONASS SV observation. The SV PRN ID is the map key
glonass_gnav_ephemeris_iter = glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN);
if (glonass_gnav_ephemeris_iter != glonass_gnav_ephemeris_map.cend())
{
bool found_L1_obs=false;
for (int i = 0; i < glo_valid_obs; i++)
{
if (geph_data[i].sat == (static_cast<int>(gnss_observables_iter->second.PRN+NSATGPS)))
{
obs_data[i] = insert_obs_to_rtklib(obs_data[i],
gnss_observables_iter->second,
glonass_gnav_ephemeris_iter->second.d_WN,
1);//Band 1 (L2)
found_L1_obs=true;
break;
}
}
if (!found_L1_obs)
{
//insert GLONASS GNAV L2 obs as new obs and also insert its ephemeris
//convert ephemeris from GNSS-SDR class to RTKLIB structure
geph_data[glo_valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second, gnav_utc);
//convert observation from GNSS-SDR class to RTKLIB structure
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
obs_data[glo_valid_obs] = insert_obs_to_rtklib(newobs,
gnss_observables_iter->second,
glonass_gnav_ephemeris_iter->second.d_WN,
1); //Band 1 (L2)
glo_valid_obs++;
}
}
else // the ephemeris are not available for this SV
{
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN;
}
}
break;
}
}
break;
}
default :
DLOG(INFO) << "Hybrid observables: Unknown GNSS";
break;
@ -359,12 +360,15 @@ bool rtklib_solver::get_PVT(const std::map<int,Gnss_Synchro> & gnss_observables_
// **********************************************************************
this->set_valid_position(false);
if (valid_obs > 0)
if (valid_obs > 0 || glo_valid_obs > 0)
{
int result = 0;
nav_t nav_data;
nav_data.eph = eph_data;
nav_data.geph = geph_data;
nav_data.n = valid_obs;
nav_data.ng = glo_valid_obs;
for (int i = 0; i < MAXSAT; i++)
{
nav_data.lam[i][0] = SPEED_OF_LIGHT / FREQ1; /* L1/E1 */
@ -372,7 +376,7 @@ bool rtklib_solver::get_PVT(const std::map<int,Gnss_Synchro> & gnss_observables_
nav_data.lam[i][2] = SPEED_OF_LIGHT / FREQ5; /* L5/E5 */
}
result = rtkpos(&rtk_, obs_data, valid_obs, &nav_data);
result = rtkpos(&rtk_, obs_data, valid_obs + glo_valid_obs, &nav_data);
if(result == 0)
{
LOG(INFO) << "RTKLIB rtkpos error message: " << rtk_.errbuf;

View File

@ -87,7 +87,7 @@ public:
std::map<int,Galileo_Ephemeris> galileo_ephemeris_map; //!< Map storing new Galileo_Ephemeris
std::map<int,Gps_Ephemeris> gps_ephemeris_map; //!< Map storing new GPS_Ephemeris
std::map<int,Gps_CNAV_Ephemeris> gps_cnav_ephemeris_map; //!< Map storing new GPS_CNAV_Ephemeris
std::map<int,Glonass_Gnav_Ephemeris> glonass_gnav_ephemeris_map; //!< Map storing new GLONASS GNAV Ephmeris
std::map<int,Glonass_Gnav_Ephemeris> glonass_gnav_ephemeris_map; //!< Map storing new GLONASS GNAV Ephmeris
Galileo_Utc_Model galileo_utc_model;
Galileo_Iono galileo_iono;

View File

@ -182,6 +182,7 @@ const int SYS_ALL = 0xFF; //!< navigation system: all
#define ENAGLO
#ifdef ENAGLO
const int MINPRNGLO = 1; //!< min satellite slot number of GLONASS
const int MAXPRNGLO = 27; //!< max satellite slot number of GLONASS
@ -194,6 +195,12 @@ const int NSATGLO = 0;
const int NSYSGLO = 0;
#endif
/*
const int MINPRNGLO = 1; //!< min satellite slot number of GLONASS
const int MAXPRNGLO = 27; //!< max satellite slot number of GLONASS
const int NSATGLO = (MAXPRNGLO - MINPRNGLO + 1); //!< number of GLONASS satellites
const int NSYSGLO = 1;
*/
const int MINPRNGAL = 1; //!< min satellite PRN number of Galileo
const int MAXPRNGAL = 30; //!< max satellite PRN number of Galileo
const int NSATGAL = (MAXPRNGAL - MINPRNGAL + 1); //!< number of Galileo satellites

View File

@ -52,7 +52,7 @@ obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synch
rtklib_obs.sat = gnss_synchro.PRN+NSATGPS+NSATGLO;
break;
case 'R':
rtklib_obs.sat = gnss_synchro.PRN;
rtklib_obs.sat = gnss_synchro.PRN+NSATGPS;
break;
default:
@ -64,56 +64,46 @@ obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synch
return rtklib_obs;
}
geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph)
geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const Glonass_Gnav_Utc_Model & gnav_clock_model)
{
double week, sec;
int adj_week;
geph_t rtklib_sat = {0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0.0, 0.0, 0.0}, {0.0, 0.0,
0.0}, {0.0, 0.0, 0.0}, 0.0, 0.0, 0.0};
gtime_t t_utc;
struct tm utcinfo;
rtklib_sat.sat = glonass_gnav_eph.i_satellite_slot_number; /* satellite number */
rtklib_sat.iode = glonass_gnav_eph.d_iode; /* IODE (0-6 bit of tb field) */
rtklib_sat.frq = glonass_gnav_eph.i_satellite_freq_channel; /* satellite frequency number */
rtklib_sat.svh = glonass_gnav_eph.d_l3rd_n; /* satellite health*/
rtklib_sat.sva = glonass_gnav_eph.d_F_T; /* satellite accuracy*/
rtklib_sat.age = glonass_gnav_eph.d_E_n; /* satellite age*/
rtklib_sat.pos[0] = glonass_gnav_eph.d_Xn*1000; /* satellite position (ecef) (m) */
rtklib_sat.pos[1] = glonass_gnav_eph.d_Yn*1000; /* satellite position (ecef) (m) */
rtklib_sat.pos[2] = glonass_gnav_eph.d_Zn*1000; /* satellite position (ecef) (m) */
rtklib_sat.vel[0] = glonass_gnav_eph.d_VXn*1000; /* satellite velocity (ecef) (m/s) */
rtklib_sat.vel[1] = glonass_gnav_eph.d_VYn*1000; /* satellite velocity (ecef) (m/s) */
rtklib_sat.vel[2] = glonass_gnav_eph.d_VZn*1000; /* satellite velocity (ecef) (m/s) */
rtklib_sat.acc[0] = glonass_gnav_eph.d_AXn*1000; /* satellite acceleration (ecef) (m/s^2) */
rtklib_sat.acc[1] = glonass_gnav_eph.d_AYn*1000; /* satellite acceleration (ecef) (m/s^2) */
rtklib_sat.acc[2] = glonass_gnav_eph.d_AZn*1000; /* satellite acceleration (ecef) (m/s^2) */
rtklib_sat.taun = glonass_gnav_eph.d_tau_n; /* SV clock bias (s) */
rtklib_sat.gamn = glonass_gnav_eph.d_gamma_n; /* SV relative freq bias */
rtklib_sat.age = glonass_gnav_eph.d_Delta_tau_n; /* delay between L1 and L2 (s) */
rtklib_sat.sat = glonass_gnav_eph.i_satellite_slot_number + NSATGPS; /* satellite number */
rtklib_sat.iode = static_cast<int>(glonass_gnav_eph.d_t_b); /* IODE (0-6 bit of tb field) */
rtklib_sat.frq = glonass_gnav_eph.i_satellite_freq_channel; /* satellite frequency number */
rtklib_sat.svh = glonass_gnav_eph.d_l3rd_n; /* satellite health*/
rtklib_sat.sva = static_cast<int>(glonass_gnav_eph.d_F_T); /* satellite accuracy*/
rtklib_sat.age = static_cast<int>(glonass_gnav_eph.d_E_n); /* satellite age*/
rtklib_sat.pos[0] = glonass_gnav_eph.d_Xn*1000; /* satellite position (ecef) (m) */
rtklib_sat.pos[1] = glonass_gnav_eph.d_Yn*1000; /* satellite position (ecef) (m) */
rtklib_sat.pos[2] = glonass_gnav_eph.d_Zn*1000; /* satellite position (ecef) (m) */
rtklib_sat.vel[0] = glonass_gnav_eph.d_VXn*1000; /* satellite velocity (ecef) (m/s) */
rtklib_sat.vel[1] = glonass_gnav_eph.d_VYn*1000; /* satellite velocity (ecef) (m/s) */
rtklib_sat.vel[2] = glonass_gnav_eph.d_VZn*1000; /* satellite velocity (ecef) (m/s) */
rtklib_sat.acc[0] = glonass_gnav_eph.d_AXn*1000; /* satellite acceleration (ecef) (m/s^2) */
rtklib_sat.acc[1] = glonass_gnav_eph.d_AYn*1000; /* satellite acceleration (ecef) (m/s^2) */
rtklib_sat.acc[2] = glonass_gnav_eph.d_AZn*1000; /* satellite acceleration (ecef) (m/s^2) */
rtklib_sat.taun = glonass_gnav_eph.d_tau_n; /* SV clock bias (s) */
rtklib_sat.gamn = glonass_gnav_eph.d_gamma_n; /* SV relative freq bias */
rtklib_sat.age = static_cast<int>(glonass_gnav_eph.d_Delta_tau_n); /* delay between L1 and L2 (s) */
utcinfo.tm_mon = 0;
utcinfo.tm_mday = glonass_gnav_eph.d_N_T;
utcinfo.tm_year = glonass_gnav_eph.d_yr - 1900;
utcinfo.tm_hour = 6; // Diff between utc and (utc(su) + 3.00h)
utcinfo.tm_min = 0;
utcinfo.tm_sec = glonass_gnav_eph.d_t_b;
t_utc.time = mktime(&utcinfo);
t_utc.sec = glonass_gnav_eph.d_tau_c;
rtklib_sat.toe = utc2gpst(t_utc); /* epoch of epherides (gpst) */
utcinfo.tm_mon = 0;
utcinfo.tm_mday = glonass_gnav_eph.d_N_T;
utcinfo.tm_year = glonass_gnav_eph.d_yr - 1900;
utcinfo.tm_hour = 6;
utcinfo.tm_min = 0;
utcinfo.tm_sec = glonass_gnav_eph.d_t_k;
t_utc.time = mktime(&utcinfo);
t_utc.sec = glonass_gnav_eph.d_tau_c;
rtklib_sat.tof = utc2gpst(t_utc); /* message frame time (gpst) */
// Time expressed in GPS Time but using RTKLib format
glonass_gnav_eph.glot_to_gpst(glonass_gnav_eph.d_tod, gnav_clock_model.d_tau_c, gnav_clock_model.d_tau_gps, &week, &sec);
adj_week = adjgpsweek(static_cast<int>(week));
rtklib_sat.toe = gpst2time(adj_week, sec);
// Time expressed in GPS Time but using RTKLib format
glonass_gnav_eph.glot_to_gpst(glonass_gnav_eph.d_t_k, gnav_clock_model.d_tau_c, gnav_clock_model.d_tau_gps, &week, &sec);
adj_week = adjgpsweek(static_cast<int>(week));
rtklib_sat.tof = gpst2time(adj_week, sec);
return rtklib_sat;
}
eph_t eph_to_rtklib(const Galileo_Ephemeris & gal_eph)
{
eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0,

View File

@ -37,6 +37,7 @@
#include "gps_ephemeris.h"
#include "gps_cnav_ephemeris.h"
#include "glonass_gnav_ephemeris.h"
#include "glonass_gnav_utc_model.h"
eph_t eph_to_rtklib(const Galileo_Ephemeris & gal_eph);
eph_t eph_to_rtklib(const Gps_Ephemeris & gps_eph);
@ -46,7 +47,7 @@ eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris & gps_cnav_eph);
* \param glonass_gnav_eph GLONASS GNAV Ephemeris structure
* \return Ephemeris structure for RTKLIB parsing
*/
geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph);
geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const Glonass_Gnav_Utc_Model & gnav_clock_model);
obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synchro, int week, int band);

View File

@ -350,6 +350,12 @@ int decoderaw(rtksvr_t *svr, int index)
/* decode download file ------------------------------------------------------*/
void decodefile(rtksvr_t *svr, int index)
{
int i = 0;
char glo_fcn[MAXPRNGLO+1];
// Allocate space for GLONASS frequency channels depending on availability
for(i=0; i < MAXPRNGLO+1; i++)
glo_fcn[i]='0';
pcv_t pcvt0[MAXSAT] = { {0, {'0'}, {'0'}, {0, 0.0}, {0, 0.0}, {{0.0},{0.0}}, {{0.0},{0.0}} } };
sbsfcorr_t sbsfcorr0 = {{0, 0.0}, 0.0, 0.0, 0.0, 0, 0, 0};
sbslcorr_t sbslcorr0 = { {0, 0.0}, 0, {0.0}, {0.0}, 0.0, 0.0};
@ -365,8 +371,8 @@ void decodefile(rtksvr_t *svr, int index)
nav_t nav = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
{0, 0, (erpd_t *){0}}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0},
{0.0}, {0.0}, {0.0}, {0.0}, 0, {{0.0},{0.0}}, {{0.0},{0.0}}, {{0.0}, {0.0}, {0.0}},
{0.0}, {0.0}, {'0'}, {*pcvt0}, sbssat0, {*sbsion0}, {*dgps0}, {*ssr0}, {*lexeph0},
{0.0}, {0.0}, {0.0}, {0.0}, 0, {{0.0},{0.0}}, {{0.0},{0.0}}, {{0.0},{0.0},{0.0}},
{0.0}, {0.0}, {*glo_fcn}, {*pcvt0}, sbssat0, {*sbsion0}, {*dgps0}, {*ssr0}, {*lexeph0},
{{0,0.0}, 0.0, {0.0}, {{0.0},{0.0}} }, pppcorr0} ;
char file[1024];

View File

@ -67,7 +67,7 @@ GlonassL1CaTelemetryDecoder::~GlonassL1CaTelemetryDecoder()
{}
void GlonassL1CaTelemetryDecoder::set_satellite(Gnss_Satellite satellite)
void GlonassL1CaTelemetryDecoder::set_satellite(const Gnss_Satellite & satellite)
{
satellite_ = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
telemetry_decoder_->set_satellite(satellite_);

View File

@ -53,27 +53,27 @@ public:
unsigned int out_streams);
virtual ~GlonassL1CaTelemetryDecoder();
std::string role()
std::string role() override
{
return role_;
}
//! Returns "GLONASS_L1_CA_Telemetry_Decoder"
std::string implementation()
std::string implementation() override
{
return "GLONASS_L1_CA_Telemetry_Decoder";
}
void connect(gr::top_block_sptr top_block);
void disconnect(gr::top_block_sptr top_block);
gr::basic_block_sptr get_left_block();
gr::basic_block_sptr get_right_block();
void set_satellite(Gnss_Satellite satellite);
void set_channel(int channel){telemetry_decoder_->set_channel(channel);}
void reset()
void connect(gr::top_block_sptr top_block) override;
void disconnect(gr::top_block_sptr top_block) override;
gr::basic_block_sptr get_left_block() override;
gr::basic_block_sptr get_right_block() override;
void set_satellite(const Gnss_Satellite & satellite) override;
void set_channel(int channel) override {telemetry_decoder_->set_channel(channel);}
void reset() override
{
return;
}
size_t item_size()
size_t item_size() override
{
return 0;
}

View File

@ -49,14 +49,14 @@ using google::LogMessage;
glonass_l1_ca_telemetry_decoder_cc_sptr
glonass_l1_ca_make_telemetry_decoder_cc(Gnss_Satellite satellite, bool dump)
glonass_l1_ca_make_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump)
{
return glonass_l1_ca_telemetry_decoder_cc_sptr(new glonass_l1_ca_telemetry_decoder_cc(satellite, dump));
}
glonass_l1_ca_telemetry_decoder_cc::glonass_l1_ca_telemetry_decoder_cc(
Gnss_Satellite satellite,
const Gnss_Satellite & satellite,
bool dump) :
gr::block("glonass_l1_ca_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
@ -221,7 +221,8 @@ void glonass_l1_ca_telemetry_decoder_cc::decode_string(double *frame_symbols,int
if(d_nav.flag_update_slot_number == true)
{
LOG(INFO) << "GLONASS GNAV Slot Number Identified on channel " << d_channel;
d_satellite.what_block(d_satellite.get_system(), d_nav.get_ephemeris().d_n);
d_satellite.update_PRN(d_nav.gnav_ephemeris.d_n);
d_satellite.what_block(d_satellite.get_system(), d_nav.gnav_ephemeris.d_n);
d_nav.flag_update_slot_number = false;
}
}
@ -354,7 +355,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib
if (this->d_flag_preamble == true and d_nav.flag_TOW_new == true)
//update TOW at the preamble instant
{
d_TOW_at_current_symbol = floor((d_nav.d_TOW - GLONASS_GNAV_PREAMBLE_DURATION_S)*1000.0)/1000.0;
d_TOW_at_current_symbol = floor((d_nav.gnav_ephemeris.d_TOW - GLONASS_GNAV_PREAMBLE_DURATION_S)*1000)/1000;
d_nav.flag_TOW_new = false;
}
@ -379,7 +380,8 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib
current_symbol.Flag_valid_word = false;
}
current_symbol.TOW_at_current_symbol_s = floor(d_TOW_at_current_symbol*1000.0)/1000.0;
current_symbol.PRN = this->d_satellite.get_PRN();
current_symbol.TOW_at_current_symbol_s = d_TOW_at_current_symbol;
current_symbol.TOW_at_current_symbol_s -=delta_t; //Galileo to GPS TOW
if(d_dump == true)
@ -414,7 +416,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib
}
void glonass_l1_ca_telemetry_decoder_cc::set_satellite(Gnss_Satellite satellite)
void glonass_l1_ca_telemetry_decoder_cc::set_satellite(const Gnss_Satellite & satellite)
{
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
DLOG(INFO) << "Setting decoder Finite State Machine to satellite "<< d_satellite;

View File

@ -51,7 +51,7 @@ class glonass_l1_ca_telemetry_decoder_cc;
typedef boost::shared_ptr<glonass_l1_ca_telemetry_decoder_cc> glonass_l1_ca_telemetry_decoder_cc_sptr;
glonass_l1_ca_telemetry_decoder_cc_sptr glonass_l1_ca_make_telemetry_decoder_cc(Gnss_Satellite satellite, bool dump);
glonass_l1_ca_telemetry_decoder_cc_sptr glonass_l1_ca_make_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump);
/*!
* \brief This class implements a block that decodes the GNAV data defined in GLONASS ICD v5.1
@ -62,9 +62,9 @@ glonass_l1_ca_telemetry_decoder_cc_sptr glonass_l1_ca_make_telemetry_decoder_cc(
class glonass_l1_ca_telemetry_decoder_cc : public gr::block
{
public:
~glonass_l1_ca_telemetry_decoder_cc(); //!< Class destructor
void set_satellite(Gnss_Satellite satellite); //!< Set satellite PRN
void set_channel(int channel); //!< Set receiver's channel
~glonass_l1_ca_telemetry_decoder_cc(); //!< Class destructor
void set_satellite(const Gnss_Satellite & satellite); //!< Set satellite PRN
void set_channel(int channel); //!< Set receiver's channel
/*!
* \brief This is where all signal processing takes place
@ -74,8 +74,8 @@ public:
private:
friend glonass_l1_ca_telemetry_decoder_cc_sptr
glonass_l1_ca_make_telemetry_decoder_cc(Gnss_Satellite satellite, bool dump);
glonass_l1_ca_telemetry_decoder_cc(Gnss_Satellite satellite, bool dump);
glonass_l1_ca_make_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump);
glonass_l1_ca_telemetry_decoder_cc(const Gnss_Satellite & satellite, bool dump);
void decode_string(double *symbols, int frame_length);

View File

@ -91,8 +91,6 @@ const int GLONASS_L1_CA_NBR_SATS = 24; // STRING DATA WITHOUT PREAMB
//FIXME Probably should use leap seconds definitions of rtklib
const double GLONASS_LEAP_SECONDS[21][7] = { /* leap seconds (y,m,d,h,m,s,utc-gpst) */
{2019, 1, 1, 0, 0, 0, -20},
{2018, 1, 1, 0, 0, 0, -19},
{2017, 1, 1, 0, 0, 0, -18},
{2015, 7, 1, 0, 0, 0, -17},
{2012, 7, 1, 0, 0, 0, -16},
@ -149,7 +147,7 @@ const int GLONASS_L1_CA_HISTORY_DEEP = 100;
// NAVIGATION MESSAGE DEMODULATION AND DECODING
#define GLONASS_GNAV_PREAMBLE {1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0}
const double GLONASS_GNAV_PREAMBLE_DURATION_S = 0.3;
const double GLONASS_GNAV_PREAMBLE_DURATION_S = 0.300;
const int GLONASS_GNAV_PREAMBLE_LENGTH_BITS = 30;
const int GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS = 300;
const int GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS = 2000;

View File

@ -79,20 +79,87 @@ Glonass_Gnav_Ephemeris::Glonass_Gnav_Ephemeris()
d_tau_c = 0.0;
d_TOW = 0.0; // tow of the start of frame
d_WN = 0.0; // week number of the start of frame
d_tod = 0.0;
}
boost::posix_time::ptime Glonass_Gnav_Ephemeris::compute_GLONASS_time(const double offset_time) const
{
boost::posix_time::time_duration t(0, 0, offset_time + d_tau_c);
boost::posix_time::time_duration t(0, 0, offset_time + d_tau_c + d_tau_n);
boost::gregorian::date d1(d_yr, 1, 1);
boost::gregorian::days d2(d_N_T);
boost::gregorian::days d2(d_N_T - 1);
boost::posix_time::ptime glonass_time(d1+d2, t);
return glonass_time;
}
boost::posix_time::ptime Glonass_Gnav_Ephemeris::glot_to_utc(const double offset_time, const double glot2utc_corr) const
{
double tod = 0.0;
double utcsu2utc = 3*3600;
double glot2utcsu = 3*3600;
tod = offset_time - glot2utcsu - utcsu2utc + glot2utc_corr + d_tau_n;
boost::posix_time::time_duration t(0, 0, tod);
boost::gregorian::date d1(d_yr, 1, 1);
boost::gregorian::days d2(d_N_T - 1);
boost::posix_time::ptime utc_time(d1+d2, t);
return utc_time;
}
void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_corr, double glot2gpst_corr, double * wn, double * tow) const
{
double tod = 0.0;
double dayofweek = 0.0;
double utcsu2utc = 3*3600;
double glot2utcsu = 3*3600;
double days = 0.0;
double total_sec = 0.0, sec_of_day = 0.0;
int i = 0;
boost::gregorian::date gps_epoch { 1980, 1, 6 };
// tk is relative to UTC(SU) + 3.00 hrs, so we need to convert to utc and add corrections
// tk plus 10 sec is the true tod since get_TOW is called when in str5
tod = tod_offset - glot2utcsu - utcsu2utc;
boost::posix_time::time_duration t(0, 0, tod);
boost::gregorian::date d1(d_yr, 1, 1);
boost::gregorian::days d2(d_N_T-1);
boost::posix_time::ptime glonass_time(d1+d2, t);
boost::gregorian::date utc_date = glonass_time.date();
// Total number of days
std::string fdat = boost::posix_time::to_simple_string(glonass_time);
days = static_cast<double>((utc_date - gps_epoch).days());
// Total number of seconds
sec_of_day = static_cast<double>((glonass_time.time_of_day()).total_seconds());
total_sec = days*86400 + sec_of_day;
for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++)
{
if (d_yr >= GLONASS_LEAP_SECONDS[i][0])
{
// We add the leap second when going from utc to gpst
total_sec += fabs(GLONASS_LEAP_SECONDS[i][6]);
break;
}
}
// Compute Week number
*wn = floor(total_sec/604800);
// Compute the arithmetic modules to wrap around range
*tow = total_sec - 604800*floor(total_sec/604800);
// Perform corrections from fractional seconds
*tow += glot2utc_corr + glot2gpst_corr;
}
double Glonass_Gnav_Ephemeris::check_t(double time)
{
double corrTime;

View File

@ -99,9 +99,10 @@ public:
double d_satClkDrift; //!< GLONASS clock error
double d_dtr; //!< relativistic clock correction term
double d_iode; //!< Issue of data, ephemeris (Bit 0-6 of tb)
double d_tau_c;
double d_TOW; // tow of the start of frame
double d_WN; // week number of the start of frame
double d_tau_c; //!< GLONASST 2 UTC correction (todo) may be eliminated
double d_TOW; //!< GLONASST IN GPST seconds of week
double d_WN; //!< GLONASST IN GPST week number of the start of frame
double d_tod; //!< Time of Day since ephemeris where decoded
template<class Archive>
@ -158,6 +159,26 @@ public:
*/
boost::posix_time::ptime compute_GLONASS_time(const double offset_time) const;
/*!
* \brief Converts from GLONASST to UTC
* \details The function simply adjust for the 6 hrs offset between GLONASST and UTC
* \param[in] offset_time Is the start of day offset
* \param[in] glot2utc_corr Correction from GLONASST to UTC
* \returns UTC time as a boost::posix_time::ptime object
*/
boost::posix_time::ptime glot_to_utc(const double offset_time, const double glot2utc_corr) const;
/*!
* \brief Converts from GLONASST to GPST
* \details Converts from GLONASST to GPST in time of week (TOW) and week number (WN) format
* \param[in] tod_offset Is the start of day offset
* \param[in] glot2utc_corr Correction from GLONASST to UTC
* \param[in] glot2gpst_corr Correction from GLONASST to GPST
* \param[out] WN Week Number, not in mod(1024) format
* \param[out] TOW Time of Week in seconds of week
*/
void glot_to_gpst(double tod_offset, double glot2utc_corr, double glot2gpst_corr, double * WN, double * TOW) const;
/*!
* Default constructor
*/

View File

@ -43,6 +43,7 @@
void Glonass_Gnav_Navigation_Message::reset()
{
//!< Satellite Identification
i_satellite_PRN = 0;
i_alm_satellite_slot_number = 0; //!< SV Orbit Slot Number
flag_update_slot_number = false;
@ -74,7 +75,6 @@ void Glonass_Gnav_Navigation_Message::reset()
//broadcast orbit 1
flag_TOW_set = false;
flag_TOW_new = false;
d_TOW = 0.0; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s]
flag_CRC_test = false;
d_frame_ID = 0;
@ -325,7 +325,7 @@ double Glonass_Gnav_Navigation_Message::get_WN()
boost::gregorian::date gps_epoch { 1980, 1, 6 };
// Map to UTC
boost::gregorian::date glo_date(gnav_ephemeris.d_yr, 1, 1);
boost::gregorian::days d2(gnav_ephemeris.d_N_T);
boost::gregorian::days d2(gnav_ephemeris.d_N_T-1);
glo_date = glo_date + d2;
@ -363,7 +363,7 @@ double Glonass_Gnav_Navigation_Message::get_TOW()
// tk is relative to UTC(SU) + 3.00 hrs, so we need to convert to utc and add corrections
// tk plus 10 sec is the true tod since get_TOW is called when in str5
TOD = (gnav_ephemeris.d_t_k + 10) - glot2utcsu - utcsu2utc + gnav_utc_model.d_tau_c + gnav_utc_model.d_tau_gps;
TOD = (gnav_ephemeris.d_t_k + 10) - glot2utcsu - utcsu2utc;// + gnav_utc_model.d_tau_c + gnav_utc_model.d_tau_gps;
boost::gregorian::date glo_date(gnav_ephemeris.d_yr, 1, 1);
@ -375,10 +375,10 @@ double Glonass_Gnav_Navigation_Message::get_TOW()
for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++)
{
if (GLONASS_LEAP_SECONDS[i][0] == gnav_ephemeris.d_yr)
if (gnav_ephemeris.d_yr >= GLONASS_LEAP_SECONDS[i][0])
{
// We add the leap second when going from utc to gpst
TOW += GLONASS_LEAP_SECONDS[i][6];
TOW += fabs(GLONASS_LEAP_SECONDS[i][6]);
}
}
// Compute the arithmetic modules to wrap around range
@ -492,21 +492,21 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string)
// Compute Year and DoY based on Algorithm A3.11 of GLONASS ICD
// 1). Current year number J in the four-year interval is calculated
if (gnav_ephemeris.d_N_T >= 1 && gnav_ephemeris.d_N_T <= 366)
{
J = 1;
}
{
J = 1;
}
else if (gnav_ephemeris.d_N_T >= 367 && gnav_ephemeris.d_N_T <= 731)
{
J = 2;
}
{
J = 2;
}
else if (gnav_ephemeris.d_N_T >= 732 && gnav_ephemeris.d_N_T <= 1096)
{
J = 3;
}
{
J = 3;
}
else if (gnav_ephemeris.d_N_T >= 1097 && gnav_ephemeris.d_N_T <= 1461)
{
J = 4;
}
{
J = 4;
}
// 2). Current year in common form is calculated by the following formula:
gnav_ephemeris.d_yr = 1996 + 4.0 * (gnav_utc_model.d_N_4 - 1.0) + (J - 1.0);
gnav_ephemeris.d_tau_c = gnav_utc_model.d_tau_c;
@ -514,13 +514,14 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string)
// 3). Set TOW once the year has been defined, it helps with leap second determination
if (flag_ephemeris_str_1 == true)
{
d_TOW = get_TOW();
gnav_ephemeris.d_TOW = d_TOW;
gnav_ephemeris.d_WN = get_WN();
gnav_ephemeris.glot_to_gpst(gnav_ephemeris.d_t_k+10, gnav_utc_model.d_tau_c, gnav_utc_model.d_tau_gps, &gnav_ephemeris.d_WN, &gnav_ephemeris.d_TOW);
flag_TOW_set = true;
flag_TOW_new = true;
}
// 4) Set time of day (tod) when ephemeris data is complety decoded
gnav_ephemeris.d_tod = gnav_ephemeris.d_t_k + 2*d_string_ID;
}
@ -805,10 +806,8 @@ bool Glonass_Gnav_Navigation_Message::have_new_ephemeris() //Check if we have a
DLOG(INFO) << "GLONASS GNAV Ephemeris (1, 2, 3, 4) have been received and belong to the same batch" << std::endl;
new_eph = true;
}
}
return new_eph;
}

View File

@ -65,6 +65,10 @@ public:
unsigned int d_string_ID;
bool flag_update_slot_number;
// satellite identification info
int i_channel_ID;
unsigned int i_satellite_PRN;
Glonass_Gnav_Ephemeris gnav_ephemeris; //!< Ephemeris information decoded
Glonass_Gnav_Utc_Model gnav_utc_model; //!< UTC model information
Glonass_Gnav_Almanac gnav_almanac[GLONASS_L1_CA_NBR_SATS]; //!< Almanac information for all 24 satellites
@ -97,7 +101,6 @@ public:
bool flag_TOW_set; //!< Flag indicating when the TOW has been set
bool flag_TOW_new; //!< Flag indicating when a new TOW has been computed
double d_TOW; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s]
// Clock terms
double d_satClkCorr; // Satellite clock error

View File

@ -135,6 +135,27 @@ void Gnss_Satellite::set_system(const std::string& system_)
}
void Gnss_Satellite::update_PRN(unsigned int PRN_)
{
if (system.compare("Glonass") != 0)
{
DLOG(INFO) << "Trying to update PRN for not GLONASS system";
PRN = 0;
}
else
{
if (PRN_ < 1 or PRN_ > 24)
{
DLOG(INFO) << "This PRN is not defined";
// Adjusting for PRN 26, now used in
PRN = PRN_;
}
else
{
PRN = PRN_;
}
}
}
void Gnss_Satellite::set_PRN(unsigned int PRN_)

View File

@ -50,6 +50,7 @@ public:
Gnss_Satellite(); //!< Default Constructor.
Gnss_Satellite(const std::string& system_, unsigned int PRN_); //!< Concrete GNSS satellite Constructor.
~Gnss_Satellite(); //!< Default Destructor.
void update_PRN(unsigned int PRN); //!< Updates the PRN Number when information is decoded, only applies to GLONASS GNAV messages
unsigned int get_PRN() const; //!< Gets satellite's PRN
std::string get_system() const; //!< Gets the satellite system {"GPS", "GLONASS", "SBAS", "Galileo", "Beidou"}
std::string get_system_short() const; //!< Gets the satellite system {"G", "R", "SBAS", "E", "C"}

View File

@ -63,3 +63,75 @@ TEST(GlonassGnavEphemerisTest, ComputeGlonassTime)
ASSERT_TRUE(expected_gtime.minutes() - t.minutes() < FLT_EPSILON );
ASSERT_TRUE(expected_gtime.seconds() - t.seconds() < FLT_EPSILON );
}
/*!
* \brief Testing conversion from GLONASST to GPST
* \test Tests scenario for N_T when greater than 365 days. Possible values here from 1 to 365*4
*/
TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT1)
{
Glonass_Gnav_Ephemeris gnav_eph;
gnav_eph.d_yr = 2004;
gnav_eph.d_N_T = 366+28;
double tod = 70200;
double week = 0.0;
double tow = 0.0;
double true_leap_sec = 13;
double true_week = 1307;
double true_tow = 480600+true_leap_sec;
gnav_eph.glot_to_gpst(tod, 0.0, 0.0, &week, &tow);
// Perform assertions of decoded fields
ASSERT_TRUE(week - true_week < FLT_EPSILON );
ASSERT_TRUE(tow - true_week < FLT_EPSILON );
}
/*!
* \brief Testing conversion from GLONASST to GPST
* \test This version tests the conversion for offsets greater than 30 in a leap year
*/
TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT2)
{
Glonass_Gnav_Ephemeris gnav_eph;
gnav_eph.d_yr = 2016;
gnav_eph.d_N_T = 268;
double tod = 7560;
double week = 0.0;
double tow = 0.0;
double true_leap_sec = 13;
double true_week = 1915;
double true_tow = 480600+true_leap_sec;
gnav_eph.glot_to_gpst(tod, 0.0, 0.0, &week, &tow);
// Perform assertions of decoded fields
ASSERT_TRUE(week - true_week < FLT_EPSILON );
ASSERT_TRUE(tow - true_week < FLT_EPSILON );
}
/*!
* \brief Testing conversion from GLONASST to GPST
* \test This version tests the conversion around the vicinity of February 29 days when in leap year
*/
TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT3)
{
Glonass_Gnav_Ephemeris gnav_eph;
gnav_eph.d_yr = 2016;
gnav_eph.d_N_T = 62;
double tod = 7560 + 6*3600;
double week = 0.0;
double tow = 0.0;
double true_leap_sec = 13;
double true_week = 1307;
double true_tow = 480600+true_leap_sec;
gnav_eph.glot_to_gpst(tod, 0.0, 0.0, &week, &tow);
// Perform assertions of decoded fields
ASSERT_TRUE(week - true_week < FLT_EPSILON );
ASSERT_TRUE(tow - true_week < FLT_EPSILON );
}

View File

@ -41,76 +41,76 @@ title('Doppler frequency')
xlabel('TOW [s]')
ylabel('[Hz]');
%read true obs from simulator (optional)
GPS_STARTOFFSET_s = 68.802e-3;
true_observables_log_path='/home/javier/git/gnss-sdr/build/obs_out.bin';
GNSS_true_observables= read_true_sim_observables_dump(true_observables_log_path);
%correct the clock error using true values (it is not possible for a receiver to correct
%the receiver clock offset error at the observables level because it is required the
%decoding of the ephemeris data and solve the PVT equations)
SPEED_OF_LIGHT_M_S = 299792458.0;
%find the reference satellite
[~,ref_sat_ch]=min(GNSS_observables.Pseudorange_m(:,min_idx+1));
shift_time_s=GNSS_true_observables.Pseudorange_m(ref_sat_ch,:)/SPEED_OF_LIGHT_M_S-GPS_STARTOFFSET_s;
%Compute deltas if required and interpolate to measurement time
delta_true_psudorange_m=GNSS_true_observables.Pseudorange_m(1,:)-GNSS_true_observables.Pseudorange_m(2,:);
delta_true_interp_psudorange_m=interp1(GNSS_true_observables.RX_time(1,:)-shift_time_s, ...
delta_true_psudorange_m,GNSS_observables.RX_time(1,min_idx+1:end),'lineal','extrap');
true_interp_acc_carrier_phase_ch1_hz=interp1(GNSS_true_observables.RX_time(1,:)-shift_time_s, ...
GNSS_true_observables.Carrier_phase_hz(1,:),GNSS_observables.RX_time(1,min_idx+1:end),'lineal','extrap');
true_interp_acc_carrier_phase_ch2_hz=interp1(GNSS_true_observables.RX_time(1,:)-shift_time_s, ...
GNSS_true_observables.Carrier_phase_hz(2,:),GNSS_observables.RX_time(2,min_idx+1:end),'lineal','extrap');
%Compute measurement errors
delta_measured_psudorange_m=GNSS_observables.Pseudorange_m(1,min_idx+1:end)-GNSS_observables.Pseudorange_m(2,min_idx+1:end);
psudorange_error_m=delta_measured_psudorange_m-delta_true_interp_psudorange_m;
psudorange_rms_m=sqrt(sum(psudorange_error_m.^2)/length(psudorange_error_m))
acc_carrier_error_ch1_hz=GNSS_observables.Carrier_phase_hz(1,min_idx+1:end)-true_interp_acc_carrier_phase_ch1_hz...
-GNSS_observables.Carrier_phase_hz(1,min_idx+1)+true_interp_acc_carrier_phase_ch1_hz(1);
acc_phase_rms_ch1_hz=sqrt(sum(acc_carrier_error_ch1_hz.^2)/length(acc_carrier_error_ch1_hz))
acc_carrier_error_ch2_hz=GNSS_observables.Carrier_phase_hz(2,min_idx+1:end)-true_interp_acc_carrier_phase_ch2_hz...
-GNSS_observables.Carrier_phase_hz(2,min_idx+1)+true_interp_acc_carrier_phase_ch2_hz(1);
acc_phase_rms_ch2_hz=sqrt(sum(acc_carrier_error_ch2_hz.^2)/length(acc_carrier_error_ch2_hz))
%plot results
figure;
plot(GNSS_true_observables.RX_time(1,:),delta_true_psudorange_m,'g');
hold on;
plot(GNSS_observables.RX_time(1,min_idx+1:end),delta_measured_psudorange_m,'b');
title('TRUE vs. measured Pseudoranges [m]')
xlabel('TOW [s]')
ylabel('[m]');
figure;
plot(GNSS_observables.RX_time(1,min_idx+1:end),psudorange_error_m)
title('Pseudoranges error [m]')
xlabel('TOW [s]')
ylabel('[m]');
figure;
plot(GNSS_observables.RX_time(1,min_idx+1:end),acc_carrier_error_ch1_hz)
title('Accumulated carrier phase error CH1 [hz]')
xlabel('TOW [s]')
ylabel('[hz]');
figure;
plot(GNSS_observables.RX_time(1,min_idx+1:end),acc_carrier_error_ch2_hz)
title('Accumulated carrier phase error CH2 [hz]')
xlabel('TOW [s]')
ylabel('[hz]');
%
% %read true obs from simulator (optional)
% GPS_STARTOFFSET_s = 68.802e-3;
%
% true_observables_log_path='/home/javier/git/gnss-sdr/build/obs_out.bin';
% GNSS_true_observables= read_true_sim_observables_dump(true_observables_log_path);
%
% %correct the clock error using true values (it is not possible for a receiver to correct
% %the receiver clock offset error at the observables level because it is required the
% %decoding of the ephemeris data and solve the PVT equations)
%
% SPEED_OF_LIGHT_M_S = 299792458.0;
%
% %find the reference satellite
% [~,ref_sat_ch]=min(GNSS_observables.Pseudorange_m(:,min_idx+1));
% shift_time_s=GNSS_true_observables.Pseudorange_m(ref_sat_ch,:)/SPEED_OF_LIGHT_M_S-GPS_STARTOFFSET_s;
%
%
% %Compute deltas if required and interpolate to measurement time
% delta_true_psudorange_m=GNSS_true_observables.Pseudorange_m(1,:)-GNSS_true_observables.Pseudorange_m(2,:);
% delta_true_interp_psudorange_m=interp1(GNSS_true_observables.RX_time(1,:)-shift_time_s, ...
% delta_true_psudorange_m,GNSS_observables.RX_time(1,min_idx+1:end),'lineal','extrap');
% true_interp_acc_carrier_phase_ch1_hz=interp1(GNSS_true_observables.RX_time(1,:)-shift_time_s, ...
% GNSS_true_observables.Carrier_phase_hz(1,:),GNSS_observables.RX_time(1,min_idx+1:end),'lineal','extrap');
% true_interp_acc_carrier_phase_ch2_hz=interp1(GNSS_true_observables.RX_time(1,:)-shift_time_s, ...
% GNSS_true_observables.Carrier_phase_hz(2,:),GNSS_observables.RX_time(2,min_idx+1:end),'lineal','extrap');
%
% %Compute measurement errors
%
% delta_measured_psudorange_m=GNSS_observables.Pseudorange_m(1,min_idx+1:end)-GNSS_observables.Pseudorange_m(2,min_idx+1:end);
% psudorange_error_m=delta_measured_psudorange_m-delta_true_interp_psudorange_m;
% psudorange_rms_m=sqrt(sum(psudorange_error_m.^2)/length(psudorange_error_m))
%
% acc_carrier_error_ch1_hz=GNSS_observables.Carrier_phase_hz(1,min_idx+1:end)-true_interp_acc_carrier_phase_ch1_hz...
% -GNSS_observables.Carrier_phase_hz(1,min_idx+1)+true_interp_acc_carrier_phase_ch1_hz(1);
%
% acc_phase_rms_ch1_hz=sqrt(sum(acc_carrier_error_ch1_hz.^2)/length(acc_carrier_error_ch1_hz))
%
% acc_carrier_error_ch2_hz=GNSS_observables.Carrier_phase_hz(2,min_idx+1:end)-true_interp_acc_carrier_phase_ch2_hz...
% -GNSS_observables.Carrier_phase_hz(2,min_idx+1)+true_interp_acc_carrier_phase_ch2_hz(1);
% acc_phase_rms_ch2_hz=sqrt(sum(acc_carrier_error_ch2_hz.^2)/length(acc_carrier_error_ch2_hz))
%
%
% %plot results
% figure;
% plot(GNSS_true_observables.RX_time(1,:),delta_true_psudorange_m,'g');
% hold on;
% plot(GNSS_observables.RX_time(1,min_idx+1:end),delta_measured_psudorange_m,'b');
% title('TRUE vs. measured Pseudoranges [m]')
% xlabel('TOW [s]')
% ylabel('[m]');
%
% figure;
% plot(GNSS_observables.RX_time(1,min_idx+1:end),psudorange_error_m)
% title('Pseudoranges error [m]')
% xlabel('TOW [s]')
% ylabel('[m]');
%
% figure;
% plot(GNSS_observables.RX_time(1,min_idx+1:end),acc_carrier_error_ch1_hz)
% title('Accumulated carrier phase error CH1 [hz]')
% xlabel('TOW [s]')
% ylabel('[hz]');
%
% figure;
% plot(GNSS_observables.RX_time(1,min_idx+1:end),acc_carrier_error_ch2_hz)
% title('Accumulated carrier phase error CH2 [hz]')
% xlabel('TOW [s]')
% ylabel('[hz]');
%
%
%
%