1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-10-31 23:26:22 +00:00

bugreport: Time managment with boost posix time

Need to fix bug in time duration with posix time and deal with day
offsets in the code. Something seems off with day duration for long
periods of time.
This commit is contained in:
Damian Miralles 2017-10-24 08:51:38 -06:00
commit c9fba22307
17 changed files with 324 additions and 207 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

@ -13,7 +13,7 @@ ControlThread.wait_for_flowgraph=false
;######### SIGNAL_SOURCE CONFIG ############ ;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=File_Signal_Source 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.item_type=ishort
SignalSource.sampling_frequency=4000000 SignalSource.sampling_frequency=4000000
SignalSource.freq=1575420000 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, // 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;

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

@ -64,14 +64,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, const Glonass_Gnav_Utc_Model & gnav_clock_model)
geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph)
{ {
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) */
@ -92,25 +90,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; // 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_t_k, 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.tof = gpst2time(adj_week, sec);
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) */
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;
} }
} }
@ -354,7 +355,8 @@ 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) if (this->d_flag_preamble == true and d_nav.flag_TOW_new == true)
//update TOW at the preamble instant //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; double dummy_dtow = d_nav.get_TOW() - GLONASS_GNAV_PREAMBLE_DURATION_S;
d_TOW_at_current_symbol = d_nav.gnav_ephemeris.d_TOW - GLONASS_GNAV_PREAMBLE_DURATION_S;
d_nav.flag_TOW_new = false; d_nav.flag_TOW_new = 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},
@ -149,7 +147,7 @@ const int GLONASS_L1_CA_HISTORY_DEEP = 100;
// NAVIGATION MESSAGE DEMODULATION AND DECODING // 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} #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_BITS = 30;
const int GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS = 300; const int GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS = 300;
const int GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS = 2000; const int GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS = 2000;

View File

@ -79,20 +79,94 @@ 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::days d3(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);
if(tod < 0)
{
d3 = boost::gregorian::days(-1);
}
boost::posix_time::ptime glonass_time(d1+d2+d3, 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 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;
@ -74,7 +75,6 @@ void Glonass_Gnav_Navigation_Message::reset()
//broadcast orbit 1 //broadcast orbit 1
flag_TOW_set = false; flag_TOW_set = false;
flag_TOW_new = 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; flag_CRC_test = false;
d_frame_ID = 0; d_frame_ID = 0;
@ -325,7 +325,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;
@ -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 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 // 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); 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++) 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 // 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 // Compute the arithmetic modules to wrap around range
@ -514,17 +514,17 @@ 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(); 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_TOW = d_TOW;
gnav_ephemeris.d_WN = get_WN();
flag_TOW_set = true; flag_TOW_set = true;
flag_TOW_new = true; flag_TOW_new = true;
} }
// 4) Set time of day (tod) when ephemeris data is complety decoded // 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; gnav_ephemeris.d_tod = gnav_ephemeris.d_t_k + 2*d_string_ID;
} }
break; break;
case 6: case 6:
@ -573,8 +573,8 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string)
flag_almanac_str_7 = true; flag_almanac_str_7 = true;
} }
break;
break;
case 8: case 8:
// --- It is string 8 ---------------------------------------------- // --- It is string 8 ----------------------------------------------
i_alm_satellite_slot_number = static_cast<unsigned int>(read_navigation_unsigned(string_bits, n_A)); i_alm_satellite_slot_number = static_cast<unsigned int>(read_navigation_unsigned(string_bits, n_A));
@ -594,7 +594,6 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string)
flag_almanac_str_8 = true; flag_almanac_str_8 = true;
break; break;
case 9: case 9:
// --- It is string 9 ---------------------------------------------- // --- It is string 9 ----------------------------------------------
if (flag_almanac_str_8 == true) if (flag_almanac_str_8 == true)
@ -617,7 +616,6 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string)
flag_almanac_str_9 = true; flag_almanac_str_9 = true;
} }
break; break;
case 10: case 10:
// --- It is string 10 --------------------------------------------- // --- It is string 10 ---------------------------------------------
i_alm_satellite_slot_number = static_cast<unsigned int>(read_navigation_unsigned(string_bits, n_A)); i_alm_satellite_slot_number = static_cast<unsigned int>(read_navigation_unsigned(string_bits, n_A));
@ -660,7 +658,6 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string)
flag_almanac_str_11 = true; flag_almanac_str_11 = true;
} }
break; break;
case 12: case 12:
// --- It is string 12 --------------------------------------------- // --- It is string 12 ---------------------------------------------
i_alm_satellite_slot_number = static_cast<unsigned int>(read_navigation_unsigned(string_bits, n_A)); i_alm_satellite_slot_number = static_cast<unsigned int>(read_navigation_unsigned(string_bits, n_A));
@ -702,7 +699,6 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string)
flag_almanac_str_13 = true; flag_almanac_str_13 = true;
} }
break; break;
case 14: case 14:
// --- It is string 14 --------------------------------------------- // --- It is string 14 ---------------------------------------------
if (d_frame_ID == 5) if (d_frame_ID == 5)
@ -750,14 +746,15 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string)
flag_almanac_str_15 = true; flag_almanac_str_15 = true;
} }
break; break;
default: default:
LOG(INFO) << "GLONASS GNAV: Invalid String ID of received. Received " << d_string_ID LOG(INFO) << "GLONASS GNAV: Invalid String ID of received. Received " << d_string_ID
<< ", but acceptable range is from 1-15"; << ", but acceptable range is from 1-15";
break; break;
} // switch string ID ... } // switch string ID ...
return d_string_ID; return d_string_ID;
} }

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
@ -97,7 +101,6 @@ public:
bool flag_TOW_set; //!< Flag indicating when the TOW has been set 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 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 // Clock terms
double d_satClkCorr; // Satellite clock error 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_) 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

@ -63,3 +63,23 @@ TEST(GlonassGnavEphemerisTest, ComputeGlonassTime)
ASSERT_TRUE(expected_gtime.minutes() - t.minutes() < FLT_EPSILON ); ASSERT_TRUE(expected_gtime.minutes() - t.minutes() < FLT_EPSILON );
ASSERT_TRUE(expected_gtime.seconds() - t.seconds() < FLT_EPSILON ); ASSERT_TRUE(expected_gtime.seconds() - t.seconds() < FLT_EPSILON );
} }
TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT)
{
Glonass_Gnav_Ephemeris gnav_eph;
gnav_eph.d_yr = 2005;
gnav_eph.d_N_T = 32;
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 );
}

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]');
%
%
%
%