1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-02-22 14:00:13 +00:00

Debugging GLONASS code to obtain position solution

This commit is contained in:
Damian Miralles 2017-10-19 13:22:55 -06:00
parent 93640ffd46
commit a1b9b092f5
16 changed files with 242 additions and 115 deletions

View File

@ -271,7 +271,7 @@ endif(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
# Append -O2 optimization flag for Debug builds # Append -O2 optimization flag for Debug builds
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
# allow 'large' files in 32 bit builds # allow 'large' files in 32 bit builds
if(UNIX) if(UNIX)

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, // TODO Add GLONASS with gps week number and tow,
// insert new ephemeris record // insert new ephemeris record
DLOG(INFO) << "GLONASS GNAV New Ephemeris record inserted in global map with TOW =" << glonass_gnav_eph->d_TOW 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 << ", Week Number =" << glonass_gnav_eph->d_WN
<< " and Ephemeris IOD = " << glonass_gnav_eph->compute_GLONASS_time(glonass_gnav_eph->d_t_b) << " 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; << " from SV = " << glonass_gnav_eph->i_satellite_slot_number;
// update/insert new ephemeris record to the global ephemeris map // 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; d_ls_pvt->glonass_gnav_ephemeris_map[glonass_gnav_eph->i_satellite_PRN] = *glonass_gnav_eph;
@ -542,7 +542,7 @@ 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,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,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,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)) 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_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("1B") == 0))

View File

@ -116,6 +116,7 @@ bool rtklib_solver::get_PVT(const std::map<int,Gnss_Synchro> & gnss_observables_
std::map<int,Gps_Ephemeris>::const_iterator gps_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,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); this->set_averaging_flag(flag_averaging);
@ -290,7 +291,7 @@ bool rtklib_solver::get_PVT(const std::map<int,Gnss_Synchro> & gnss_observables_
if (glonass_gnav_ephemeris_iter != glonass_gnav_ephemeris_map.cend()) if (glonass_gnav_ephemeris_iter != glonass_gnav_ephemeris_map.cend())
{ {
//convert ephemeris from GNSS-SDR class to RTKLIB structure //convert ephemeris from GNSS-SDR class to RTKLIB structure
geph_data[glo_valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second); geph_data[glo_valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second, gnav_utc);
//convert observation from GNSS-SDR class to RTKLIB structure //convert observation from GNSS-SDR class to RTKLIB structure
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}}; obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
obs_data[glo_valid_obs] = insert_obs_to_rtklib(newobs, obs_data[glo_valid_obs] = insert_obs_to_rtklib(newobs,
@ -329,7 +330,7 @@ bool rtklib_solver::get_PVT(const std::map<int,Gnss_Synchro> & gnss_observables_
{ {
//insert GLONASS GNAV L2 obs as new obs and also insert its ephemeris //insert GLONASS GNAV L2 obs as new obs and also insert its ephemeris
//convert ephemeris from GNSS-SDR class to RTKLIB structure //convert ephemeris from GNSS-SDR class to RTKLIB structure
geph_data[glo_valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second); geph_data[glo_valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second, gnav_utc);
//convert observation from GNSS-SDR class to RTKLIB structure //convert observation from GNSS-SDR class to RTKLIB structure
obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}}; obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}};
obs_data[glo_valid_obs] = insert_obs_to_rtklib(newobs, obs_data[glo_valid_obs] = insert_obs_to_rtklib(newobs,

View File

@ -87,7 +87,7 @@ public:
std::map<int,Galileo_Ephemeris> galileo_ephemeris_map; //!< Map storing new Galileo_Ephemeris 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_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,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_Utc_Model galileo_utc_model;
Galileo_Iono galileo_iono; Galileo_Iono galileo_iono;

View File

@ -30,10 +30,11 @@
#include "rtklib_conversions.h" #include "rtklib_conversions.h"
#include "rtklib_rtkcmn.h" #include "rtklib_rtkcmn.h"
#include <boost/date_time/posix_time/posix_time.hpp>
obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synchro, int week, int band) obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synchro, int week, int band)
{ {
rtklib_obs.D[band] = gnss_synchro.Carrier_Doppler_hz; rtklib_obs.D[band] = gnss_synchro.Carrier_Doppler_hz;
rtklib_obs.P[band] = gnss_synchro.Pseudorange_m; rtklib_obs.P[band] = gnss_synchro.Pseudorange_m;
rtklib_obs.L[band] = gnss_synchro.Carrier_phase_rads / (2.0 * PI); rtklib_obs.L[band] = gnss_synchro.Carrier_phase_rads / (2.0 * PI);
@ -64,13 +65,12 @@ obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synch
return rtklib_obs; 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)
{ {
int week; 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, 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 + NSATGPS; /* satellite number */ 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.iode = static_cast<int>(glonass_gnav_eph.d_t_b); /* IODE (0-6 bit of tb field) */
@ -91,26 +91,15 @@ geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph)
rtklib_sat.gamn = glonass_gnav_eph.d_gamma_n; /* SV relative freq bias */ 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) */ rtklib_sat.age = static_cast<int>(glonass_gnav_eph.d_Delta_tau_n); /* delay between L1 and L2 (s) */
utcinfo.tm_mon = 0; // Time expressed in GPS Time but using RTKLib format
utcinfo.tm_mday = glonass_gnav_eph.d_N_T; 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);
utcinfo.tm_year = glonass_gnav_eph.d_yr - 1900; adj_week = adjgpsweek(static_cast<int>(week));
utcinfo.tm_hour = -6; rtklib_sat.toe = gpst2time(adj_week, sec);
utcinfo.tm_min = 0;
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); /* 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_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_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; return rtklib_sat;
} }

View File

@ -37,6 +37,7 @@
#include "gps_ephemeris.h" #include "gps_ephemeris.h"
#include "gps_cnav_ephemeris.h" #include "gps_cnav_ephemeris.h"
#include "glonass_gnav_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 Galileo_Ephemeris & gal_eph);
eph_t eph_to_rtklib(const Gps_Ephemeris & gps_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 * \param glonass_gnav_eph GLONASS GNAV Ephemeris structure
* \return Ephemeris structure for RTKLIB parsing * \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); obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synchro, int week, int band);

View File

@ -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) if(d_nav.flag_update_slot_number == true)
{ {
LOG(INFO) << "GLONASS GNAV Slot Number Identified on channel " << d_channel; 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; d_nav.flag_update_slot_number = false;
} }
} }

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 //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) */ 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}, {2017, 1, 1, 0, 0, 0, -18},
{2015, 7, 1, 0, 0, 0, -17}, {2015, 7, 1, 0, 0, 0, -17},
{2012, 7, 1, 0, 0, 0, -16}, {2012, 7, 1, 0, 0, 0, -16},

View File

@ -79,20 +79,87 @@ Glonass_Gnav_Ephemeris::Glonass_Gnav_Ephemeris()
d_tau_c = 0.0; d_tau_c = 0.0;
d_TOW = 0.0; // tow of the start of frame d_TOW = 0.0; // tow of the start of frame
d_WN = 0.0; // week number 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::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::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); boost::posix_time::ptime glonass_time(d1+d2, t);
return glonass_time; 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
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 (GLONASS_LEAP_SECONDS[i][0] == d_yr)
{
// We add the leap second when going from utc to gpst
total_sec += abs(GLONASS_LEAP_SECONDS[i][6]);
}
}
// Compute Week number
*wn = floor(total_sec/604800);
// Compute day of week
dayofweek = modf (total_sec/604800 , wn);
dayofweek = round(7*dayofweek);
// Compute the arithmetic modules to wrap around range
*tow = total_sec - 604800*floor(total_sec/604800);
*tow = dayofweek*86400 + tod_offset + glot2utc_corr + glot2gpst_corr + d_tau_n;
}
double Glonass_Gnav_Ephemeris::check_t(double time) double Glonass_Gnav_Ephemeris::check_t(double time)
{ {
double corrTime; double corrTime;

View File

@ -159,6 +159,17 @@ public:
*/ */
boost::posix_time::ptime compute_GLONASS_time(const double offset_time) const; boost::posix_time::ptime compute_GLONASS_time(const double offset_time) const;
/*!
* \brief Converts from GLONASST to UTC
* \ param [I]
* \ param offset_time Is the start of day offset to compute the time
* \ 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;
void glot_to_gpst(double tod_offset, double glot2utc_corr, double glot2gpst_corr, double * WN, double * TOW) const;
/*! /*!
* Default constructor * Default constructor
*/ */

View File

@ -43,6 +43,7 @@
void Glonass_Gnav_Navigation_Message::reset() void Glonass_Gnav_Navigation_Message::reset()
{ {
//!< Satellite Identification //!< Satellite Identification
i_satellite_PRN = 0;
i_alm_satellite_slot_number = 0; //!< SV Orbit Slot Number i_alm_satellite_slot_number = 0; //!< SV Orbit Slot Number
flag_update_slot_number = false; flag_update_slot_number = false;
@ -325,7 +326,7 @@ double Glonass_Gnav_Navigation_Message::get_WN()
boost::gregorian::date gps_epoch { 1980, 1, 6 }; boost::gregorian::date gps_epoch { 1980, 1, 6 };
// Map to UTC // Map to UTC
boost::gregorian::date glo_date(gnav_ephemeris.d_yr, 1, 1); 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; glo_date = glo_date + d2;
@ -367,7 +368,7 @@ double Glonass_Gnav_Navigation_Message::get_TOW()
boost::gregorian::date glo_date(gnav_ephemeris.d_yr, 1, 1); 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; glo_date = glo_date + d2;
dayofweek = static_cast<double>(glo_date.day_of_week()); dayofweek = static_cast<double>(glo_date.day_of_week());
@ -514,9 +515,10 @@ 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 // 3). Set TOW once the year has been defined, it helps with leap second determination
if (flag_ephemeris_str_1 == true) if (flag_ephemeris_str_1 == true)
{ {
d_TOW = get_TOW(); //d_TOW = get_TOW();
gnav_ephemeris.d_TOW = d_TOW; 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);
gnav_ephemeris.d_WN = get_WN(); d_TOW = gnav_ephemeris.d_TOW;
//gnav_ephemeris.d_WN = d_WN();
flag_TOW_set = true; flag_TOW_set = true;
flag_TOW_new = true; flag_TOW_new = true;
} }

View File

@ -65,6 +65,10 @@ public:
unsigned int d_string_ID; unsigned int d_string_ID;
bool flag_update_slot_number; 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_Ephemeris gnav_ephemeris; //!< Ephemeris information decoded
Glonass_Gnav_Utc_Model gnav_utc_model; //!< UTC model information 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 Glonass_Gnav_Almanac gnav_almanac[GLONASS_L1_CA_NBR_SATS]; //!< Almanac information for all 24 satellites

View File

@ -135,6 +135,26 @@ 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";
PRN = 0;
}
else
{
PRN = PRN_;
}
}
}
void Gnss_Satellite::set_PRN(unsigned int PRN_) void Gnss_Satellite::set_PRN(unsigned int PRN_)

View File

@ -50,6 +50,7 @@ public:
Gnss_Satellite(); //!< Default Constructor. Gnss_Satellite(); //!< Default Constructor.
Gnss_Satellite(const std::string& system_, unsigned int PRN_); //!< Concrete GNSS satellite Constructor. Gnss_Satellite(const std::string& system_, unsigned int PRN_); //!< Concrete GNSS satellite Constructor.
~Gnss_Satellite(); //!< Default Destructor. ~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 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() 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"} std::string get_system_short() const; //!< Gets the satellite system {"G", "R", "SBAS", "E", "C"}

View File

@ -80,6 +80,38 @@ TEST(GlonassGnavNavigationMessageTest, CRCTestFailure)
ASSERT_FALSE(test_result); ASSERT_FALSE(test_result);
} }
/*!
* \brief Testing string decoding for GLONASS GNAV messages
* \test The provided string (str1.....str15) was generated with a version of
* MATLAB GNSS-SDR that the author coded to perform proper decoding of GLONASS
* GNAV signals. The same assumption is to be applied for ephemeris and almanac
* data provided.
*/
TEST(GlonassGnavNavigationMessageTest, ComputeTOWandWN1)
{
// Variable declarations
double tow, wn;
Glonass_Gnav_Navigation_Message gnav_nav_message;
Glonass_Gnav_Ephemeris gnav_ephemeris;
// Fill out ephemeris values for truth
gnav_nav_message.gnav_ephemeris.d_t_k = 70200;
gnav_nav_message.gnav_ephemeris.d_tau_c = 9.6391886472702e-08;
gnav_nav_message.gnav_ephemeris.d_yr = 2005;
gnav_nav_message.gnav_ephemeris.d_N_T = 28;
// Call target test method
tow = gnav_nav_message.get_TOW();
wn = gnav_nav_message.get_WN();
// Perform assertions of decoded fields
ASSERT_TRUE(gnav_ephemeris.d_P_1 - gnav_nav_message.gnav_ephemeris.d_P_1 < FLT_EPSILON );
ASSERT_TRUE(gnav_ephemeris.d_t_k - gnav_nav_message.gnav_ephemeris.d_t_k < FLT_EPSILON );
ASSERT_TRUE(gnav_ephemeris.d_VXn - gnav_nav_message.gnav_ephemeris.d_VXn < FLT_EPSILON );
ASSERT_TRUE(gnav_ephemeris.d_AXn - gnav_nav_message.gnav_ephemeris.d_AXn < FLT_EPSILON );
ASSERT_TRUE(gnav_ephemeris.d_Xn - gnav_nav_message.gnav_ephemeris.d_Xn < FLT_EPSILON );
}
/*! /*!
* \brief Testing string decoding for GLONASS GNAV messages * \brief Testing string decoding for GLONASS GNAV messages
* \test The provided string (str1.....str15) was generated with a version of * \test The provided string (str1.....str15) was generated with a version of

View File

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