diff --git a/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf b/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf index 3b08957b4..4f5abda49 100644 --- a/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf +++ b/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf @@ -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 diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc index 85e6bba5e..3e6758e58 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc @@ -547,8 +547,8 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite || ((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(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); } diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 06508ee75..52863abe2 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -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) { diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index c19dd7f4b..de34231d7 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -115,7 +115,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ std::map::const_iterator galileo_ephemeris_iter; std::map::const_iterator gps_ephemeris_iter; std::map::const_iterator gps_cnav_ephemeris_iter; - std::map::const_iterator glonass_gnav_ephemeris_iter; + std::map::const_iterator glonass_gnav_ephemeris_iter; this->set_averaging_flag(flag_averaging); @@ -123,6 +123,7 @@ bool rtklib_solver::get_PVT(const std::map & 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]; @@ -278,76 +279,75 @@ bool rtklib_solver::get_PVT(const std::map & 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; - } + case 'R': //TODO This should be using rtk lib nomenclature + { + 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); + //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(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(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); + //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 +359,15 @@ bool rtklib_solver::get_PVT(const std::map & 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 +375,7 @@ bool rtklib_solver::get_PVT(const std::map & 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; diff --git a/src/algorithms/libs/rtklib/rtklib.h b/src/algorithms/libs/rtklib/rtklib.h index ec0274b71..7aa7ddf5f 100644 --- a/src/algorithms/libs/rtklib/rtklib.h +++ b/src/algorithms/libs/rtklib/rtklib.h @@ -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 diff --git a/src/algorithms/libs/rtklib/rtklib_conversions.cc b/src/algorithms/libs/rtklib/rtklib_conversions.cc index c495fc210..bf30141d2 100644 --- a/src/algorithms/libs/rtklib/rtklib_conversions.cc +++ b/src/algorithms/libs/rtklib/rtklib_conversions.cc @@ -45,18 +45,18 @@ obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synch //Galileo is the third satellite system for RTKLIB, so, add the required offset to discriminate Galileo ephemeris switch(gnss_synchro.System) { - case 'G': - rtklib_obs.sat = gnss_synchro.PRN; - break; - case 'E': - rtklib_obs.sat = gnss_synchro.PRN+NSATGPS+NSATGLO; - break; - case 'R': - rtklib_obs.sat = gnss_synchro.PRN; - break; + case 'G': + rtklib_obs.sat = gnss_synchro.PRN; + break; + case 'E': + rtklib_obs.sat = gnss_synchro.PRN+NSATGPS+NSATGLO; + break; + case 'R': + rtklib_obs.sat = gnss_synchro.PRN+NSATGPS; + break; - default: - rtklib_obs.sat = gnss_synchro.PRN; + default: + rtklib_obs.sat = gnss_synchro.PRN; } rtklib_obs.time = gpst2time(adjgpsweek(week), gnss_synchro.RX_time); rtklib_obs.rcv = 1; @@ -64,60 +64,62 @@ 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) { + int 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}; + 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(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(glonass_gnav_eph.d_F_T); /* satellite accuracy*/ + rtklib_sat.age = static_cast(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(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_hour = -6; utcinfo.tm_min = 0; - utcinfo.tm_sec = glonass_gnav_eph.d_t_b; + utcinfo.tm_sec = glonass_gnav_eph.d_tod; t_utc.time = mktime(&utcinfo); t_utc.sec = glonass_gnav_eph.d_tau_c; - rtklib_sat.toe = utc2gpst(t_utc); /* epoch of epherides (gpst) */ + rtklib_sat.toe = utc2gpst(t_utc); /* message frame time (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_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) */ - + rtklib_sat.tof = utc2gpst(t_utc); /* message frame time (gpst) */ 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, - 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.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, 0.0, 0.0 }; //Galileo is the third satellite system for RTKLIB, so, add the required offset to discriminate Galileo ephemeris rtklib_sat.sat = gal_eph.i_satellite_PRN+NSATGPS+NSATGLO; rtklib_sat.A = gal_eph.A_1 * gal_eph.A_1; @@ -167,7 +169,7 @@ eph_t eph_to_rtklib(const Galileo_Ephemeris & gal_eph) eph_t eph_to_rtklib(const Gps_Ephemeris & gps_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, - 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.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, 0.0, 0.0 }; rtklib_sat.sat = gps_eph.i_satellite_PRN; rtklib_sat.A = gps_eph.d_sqrt_A * gps_eph.d_sqrt_A; rtklib_sat.M0 = gps_eph.d_M_0; @@ -218,7 +220,7 @@ eph_t eph_to_rtklib(const Gps_Ephemeris & gps_eph) eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris & gps_cnav_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, - 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.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, 0.0, 0.0 }; rtklib_sat.sat = gps_cnav_eph.i_satellite_PRN; const double A_REF = 26559710.0; // See IS-GPS-200H, pp. 170 rtklib_sat.A = A_REF + gps_cnav_eph.d_DELTA_A; diff --git a/src/algorithms/libs/rtklib/rtklib_rtksvr.cc b/src/algorithms/libs/rtklib/rtklib_rtksvr.cc index 0c2aabedf..b8c0288db 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtksvr.cc +++ b/src/algorithms/libs/rtklib/rtklib_rtksvr.cc @@ -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}; @@ -366,7 +372,7 @@ 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}, {*glo_fcn}, {*pcvt0}, sbssat0, {*sbsion0}, {*dgps0}, {*ssr0}, {*lexeph0}, {{0,0.0}, 0.0, {0.0}, {{0.0},{0.0}} }, pppcorr0} ; char file[1024]; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc index 1e3f86622..5a61f5b5a 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc @@ -379,6 +379,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib current_symbol.Flag_valid_word = false; } + current_symbol.PRN = this->d_satellite.get_PRN(); current_symbol.TOW_at_current_symbol_s = floor(d_TOW_at_current_symbol*1000.0)/1000.0; current_symbol.TOW_at_current_symbol_s -=delta_t; //Galileo to GPS TOW diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.h b/src/core/system_parameters/glonass_gnav_ephemeris.h index 281237b48..46ece9f95 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.h +++ b/src/core/system_parameters/glonass_gnav_ephemeris.h @@ -102,6 +102,7 @@ public: 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_tod; template diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.cc b/src/core/system_parameters/glonass_gnav_navigation_message.cc index 1f3b5291d..adb35c141 100644 --- a/src/core/system_parameters/glonass_gnav_navigation_message.cc +++ b/src/core/system_parameters/glonass_gnav_navigation_message.cc @@ -492,38 +492,39 @@ 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; // 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(); - flag_TOW_set = true; - flag_TOW_new = true; - } + { + d_TOW = get_TOW(); + gnav_ephemeris.d_TOW = d_TOW; + gnav_ephemeris.d_WN = get_WN(); + 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; } - break; case 6: @@ -572,8 +573,8 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) flag_almanac_str_7 = true; } - break; + case 8: // --- It is string 8 ---------------------------------------------- i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); @@ -593,6 +594,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) flag_almanac_str_8 = true; break; + case 9: // --- It is string 9 ---------------------------------------------- if (flag_almanac_str_8 == true) @@ -615,6 +617,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) flag_almanac_str_9 = true; } break; + case 10: // --- It is string 10 --------------------------------------------- i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); @@ -657,6 +660,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) flag_almanac_str_11 = true; } break; + case 12: // --- It is string 12 --------------------------------------------- i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); @@ -698,6 +702,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) flag_almanac_str_13 = true; } break; + case 14: // --- It is string 14 --------------------------------------------- if (d_frame_ID == 5) @@ -745,15 +750,14 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) flag_almanac_str_15 = true; } break; + default: LOG(INFO) << "GLONASS GNAV: Invalid String ID of received. Received " << d_string_ID << ", but acceptable range is from 1-15"; - break; } // switch string ID ... - return d_string_ID; } @@ -805,10 +809,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; }