1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-15 12:40:35 +00:00

bds_b1i: Fixing bugs with utc model

This commit is contained in:
Damian Miralles 2019-01-01 13:46:57 -06:00
parent 2865e97b84
commit b6b98bea69
9 changed files with 146 additions and 265 deletions

View File

@ -1972,7 +1972,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
{
rp->log_rinex_obs(rp->obsFile, beidou_dnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "B1");
}
if (!b_rinex_header_updated and (d_pvt_solver->beidou_dnav_utc_model.d_A0 != 0))
if (!b_rinex_header_updated and (d_pvt_solver->beidou_dnav_utc_model.d_A0_UTC != 0))
{
rp->update_obs_header(rp->obsFile, d_pvt_solver->beidou_dnav_utc_model);
rp->update_nav_header(rp->navFile, d_pvt_solver->beidou_dnav_utc_model, d_pvt_solver->beidou_dnav_iono);

View File

@ -1640,11 +1640,9 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Beidou_Dnav_Iono&
// -------- Line 5 system time correction
line.clear();
line += std::string("BDUT");
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0, 16, 2), 18);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1, 15, 2), 16);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.d_t_OT), 7);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.i_WN_T + 1024), 5); // valid until 2019
line += std::string(10, ' ');
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0_UTC, 16, 2), 18);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1_UTC, 15, 2), 16);
line += std::string(23, ' ');
line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20);
Rinex_Printer::lengthCheck(line);
@ -2819,11 +2817,9 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Beidou_Dnav_Utc_M
else if (line_str.find("BDUT", 0) != std::string::npos)
{
line_aux += std::string("GPUT");
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0, 16, 2), 18);
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1, 15, 2), 16);
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.d_t_OT), 7);
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.i_WN_T + 1024), 5); // valid until 2019
line_aux += std::string(10, ' ');
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0_UTC, 16, 2), 18);
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1_UTC, 15, 2), 16);
line_aux += std::string(23, ' ');
line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20);
data.push_back(line_aux);
}

View File

@ -331,7 +331,6 @@ void beidou_b1i_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satell
int32_t n = 0;
for (int32_t i = 0; i < d_symbols_per_preamble; i++)
{
int32_t m = 0;
if (BEIDOU_DNAV_PREAMBLE.at(i) == '1')
{
for (uint32_t j = 0; j < d_samples_per_symbol; j++)

View File

@ -154,12 +154,12 @@ const double D1_TOA_LSB = TWO_P12;
const double D1_OMEGA_DOT_ALMANAC_LSB = PI_TWO_N38;
const double D1_OMEGA_ALMANAC_LSB = PI_TWO_N23;
const double D1_M0_ALMANAC_LSB = PI_TWO_N23;
const double D1_A0GPS_LSB = 0.1;
const double D1_A1GPS_LSB = 0.1;
const double D1_A0GAL_LSB = 0.1;
const double D1_A1GAL_LSB = 0.1;
const double D1_A0GLO_LSB = 0.1;
const double D1_A1GLO_LSB = 0.1;
const double D1_A0GPS_LSB = 0.1e-9;
const double D1_A1GPS_LSB = 0.1e-9;
const double D1_A0GAL_LSB = 0.1e-9;
const double D1_A1GAL_LSB = 0.1e-9;
const double D1_A0GLO_LSB = 0.1e-9;
const double D1_A1GLO_LSB = 0.1e-9;
const double D1_A0UTC_LSB = TWO_N30;
const double D1_A1UTC_LSB = TWO_N50;

View File

@ -2,7 +2,6 @@
* \file beidou_dnav_almanac.h
* \brief Interface of a Beidou DNAV Almanac storage
*
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
*
* -------------------------------------------------------------------------
@ -39,16 +38,14 @@
/*!
* \brief This class is a storage for the GPS SV ALMANAC data as described in IS-GPS-200E
*
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
* \brief This class is a storage for the BeiDou D1 almanac
*/
class Beidou_Dnav_Almanac
{
public:
unsigned int i_satellite_PRN; //!< SV PRN NUMBER
double d_Delta_i;
double d_Toa; //!< Almanac data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s]
double d_Toa; //!< Almanac data reference time of week [s]
double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles]
double d_e_eccentricity; //!< Eccentricity [dimensionless]
double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)]

View File

@ -1,5 +1,5 @@
/*!
m * \file beidou_navigation_message.cc
* \file beidou_navigation_message.cc
* \brief Implementation of a BeiDou D1 NAV Data message decoder as described in BeiDou ICD Version 2.1
*
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
@ -47,6 +47,18 @@ void Beidou_Dnav_Navigation_Message::reset()
flag_utc_model_valid = false;
flag_crc_test = false;
flag_d1_sf1 = false;
flag_d1_sf2 = false;
flag_d1_sf3 = false;
flag_d1_sf4 = false;
flag_d1_sf5 = false;
flag_d1_sf5_p7 = false;
flag_d1_sf5_p8 = false;
flag_d1_sf5_p9 = false;
flag_d1_sf5_p10 = false;
flag_new_SOW_available = false;
d_previous_aode = 0;
flag_sf1_p1 = false;
flag_sf1_p2 = false;
flag_sf1_p3 = false;
@ -150,8 +162,6 @@ void Beidou_Dnav_Navigation_Message::reset()
d_beta3 = 0;
d_A1UTC = 0;
d_A0UTC = 0;
d_t_OT = 0;
i_WN_T = 0;
d_DeltaT_LS = 0;
i_WN_LSF = 0;
i_DN = 0;
@ -435,23 +445,7 @@ int Beidou_Dnav_Navigation_Message::d1_subframe_decoder(std::string const &subfr
// Decode all 5 sub-frames
switch (subframe_ID)
{
//--- Decode the sub-frame id ------------------------------------------
case 1:
//--- It is subframe 1 -------------------------------------
// Compute the time of week (SOW) of the first sub-frames in the array ====
// The transmitted SOW is actual SOW of the next subframe
// (the variable subframe at this point contains bits of the last subframe).
//SOW = bin2dec(subframe(31:47)) * 6;
//we are in the first subframe (the transmitted SOW is the start time of the next subframe) !
//d_SOW_SF1 = d_SOW_SF1 * 6;
//b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG);
//b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG);
//b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG);
//i_SV_accuracy = static_cast<int>(read_navigation_unsigned(subframe_bits, SV_ACCURACY)); // (20.3.3.3.1.3)
// b_L2_P_data_flag = read_navigation_bool(subframe_bits, L2_P_DATA_FLAG); //
//i_code_on_L2 = static_cast<int>(read_navigation_unsigned(subframe_bits, CA_OR_P_ON_L2));
case 1: // --- It is subframe 1 ---
d_SOW_SF1 = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SOW));
d_SOW = d_SOW_SF1; // Set transmission time
@ -501,12 +495,11 @@ int Beidou_Dnav_Navigation_Message::d1_subframe_decoder(std::string const &subfr
// Set system flags for message reception
flag_d1_sf1 = true;
flag_iono_valid = true;
flag_utc_model_valid = true;
flag_new_SOW_available = true;
break;
case 2: //--- It is subframe 2 -------------------
case 2: // --- It is subframe 2 ---
d_SOW_SF2 = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SOW));
@ -542,7 +535,7 @@ int Beidou_Dnav_Navigation_Message::d1_subframe_decoder(std::string const &subfr
break;
case 3: // --- It is subframe 3 -------------------------------------
case 3: // --- It is subframe 3 ---
d_SOW_SF3 = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SOW));
d_SOW = d_SOW_SF3; // Set transmission time
@ -576,7 +569,7 @@ int Beidou_Dnav_Navigation_Message::d1_subframe_decoder(std::string const &subfr
break;
case 4: // --- It is subframe 4 ---------- Almanac, ionospheric model, UTC parameters, SV health (PRN: 25-32)
case 4: // --- It is subframe 4 ---
d_SOW_SF4 = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SOW));
d_SOW = d_SOW_SF4; // Set transmission time
@ -615,56 +608,8 @@ int Beidou_Dnav_Navigation_Message::d1_subframe_decoder(std::string const &subfr
flag_new_SOW_available = true;
break;
/* b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG);
b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG);
b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG);
SV_data_ID = static_cast<int>(read_navigation_unsigned(subframe_bits, SV_DATA_ID));
SV_page = static_cast<int>(read_navigation_unsigned(subframe_bits, SV_PAGE));
if (SV_page > 24 && SV_page < 33) // Page 4 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110)
{
//! \TODO read almanac
if(SV_data_ID){}
}
if (SV_page == 52) // Page 13 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110)
{
//! \TODO read Estimated Range Deviation (ERD) values
}
if (SV_page == 56) // Page 18 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110)
{
// Page 18 - Ionospheric and UTC data
d_t_OT = static_cast<double>(read_navigation_unsigned(subframe_bits, T_OT));
d_t_OT = d_t_OT * T_OT_LSB;
i_WN_T = static_cast<int>(read_navigation_unsigned(subframe_bits, WN_T));
d_DeltaT_LS = static_cast<double>(read_navigation_signed(subframe_bits, DELTAT_LS));
i_WN_LSF = static_cast<int>(read_navigation_unsigned(subframe_bits, WN_LSF));
i_DN = static_cast<int>(read_navigation_unsigned(subframe_bits, DN)); // Right-justified ?
d_DeltaT_LSF = static_cast<double>(read_navigation_signed(subframe_bits, DELTAT_LSF));
flag_iono_valid = true;
}
if (SV_page == 57)
{
// Reserved
}
if (SV_page == 63) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110)
{
// Page 25 Anti-Spoofing, SV config and almanac health (PRN: 25-32)
//! \TODO Read Anti-Spoofing, SV config
almanacHealth[25] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA25));
almanacHealth[26] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA26));
almanacHealth[27] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA27));
almanacHealth[28] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA28));
almanacHealth[29] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA29));
almanacHealth[30] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA30));
almanacHealth[31] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA31));
almanacHealth[32] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA32));
}
break;
*/
case 5://--- It is subframe 5 -----------------almanac health (PRN: 1-24) and Almanac reference week number and time.
case 5: // --- It is subframe 5 ---
int SV_page_5;
d_SOW_SF5 = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SOW));
d_SOW = d_SOW_SF5; // Set transmission time
@ -708,7 +653,6 @@ int Beidou_Dnav_Navigation_Message::d1_subframe_decoder(std::string const &subfr
if (SV_page_5 == 7)
{
//! \TODO read almanac
almanacHealth[1] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA1));
almanacHealth[2] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA2));
almanacHealth[3] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA3));
@ -729,7 +673,7 @@ int Beidou_Dnav_Navigation_Message::d1_subframe_decoder(std::string const &subfr
almanacHealth[18] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA18));
almanacHealth[19] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA19));
}
if (SV_page_5 == 8) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110)
if (SV_page_5 == 8)
{
almanacHealth[20] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA20));
almanacHealth[21] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA21));
@ -747,25 +691,16 @@ int Beidou_Dnav_Navigation_Message::d1_subframe_decoder(std::string const &subfr
}
if (SV_page_5 == 9) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110)
if (SV_page_5 == 9)
{
d_A0GPS = static_cast<double>(read_navigation_signed(subframe_bits, D1_A0GPS));
d_A0GPS = d_A0GPS * D1_A0GPS_LSB;
d_A0GPS = static_cast<double>(read_navigation_signed(subframe_bits, D1_A0GPS)) * D1_A0GPS_LSB;
d_A1GPS = static_cast<double>(read_navigation_signed(subframe_bits, D1_A1GPS)) * D1_A1GPS_LSB;
d_A0GAL = static_cast<double>(read_navigation_signed(subframe_bits, D1_A0GAL)) * D1_A0GAL_LSB;
d_A1GAL = static_cast<double>(read_navigation_signed(subframe_bits, D1_A1GAL)) * D1_A1GAL_LSB;
d_A0GLO = static_cast<double>(read_navigation_signed(subframe_bits, D1_A0GLO)) * D1_A0GLO_LSB;
d_A1GLO = static_cast<double>(read_navigation_signed(subframe_bits, D1_A1GLO)) * D1_A1GLO_LSB;
d_A1GPS = static_cast<double>(read_navigation_signed(subframe_bits, D1_A1GPS));
d_A1GPS = d_A1GPS * D1_A1GPS_LSB;
d_A0GAL = static_cast<double>(read_navigation_signed(subframe_bits, D1_A0GAL));
d_A0GAL = d_A0GAL * D1_A0GAL_LSB;
d_A1GAL = static_cast<double>(read_navigation_signed(subframe_bits, D1_A1GAL));
d_A1GAL = d_A1GAL* D1_A1GAL_LSB;
d_A0GLO = static_cast<double>(read_navigation_signed(subframe_bits, D1_A0GLO));
d_A0GLO = d_A0GLO * D1_A0GLO_LSB;
d_A1GLO = static_cast<double>(read_navigation_signed(subframe_bits, D1_A1GLO));
d_A1GLO = d_A1GLO* D1_A1GLO_LSB;
flag_d1_sf5_p9 = true;
}
if (SV_page_5 == 10)
{
@ -776,6 +711,8 @@ int Beidou_Dnav_Navigation_Message::d1_subframe_decoder(std::string const &subfr
d_A0UTC = d_A0GPS * D1_A0GPS_LSB;
d_A1UTC = static_cast<double>(read_navigation_signed(subframe_bits, D1_A1UTC));
d_A1UTC = d_A1UTC * D1_A1UTC_LSB;
flag_d1_sf5_p10 = true;
}
// Set system flags for message reception
@ -1135,20 +1072,25 @@ Beidou_Dnav_Utc_Model Beidou_Dnav_Navigation_Message::get_utc_model()
Beidou_Dnav_Utc_Model utc_model;
utc_model.valid = flag_utc_model_valid;
// UTC parameters
utc_model.d_A1 = d_A1UTC;
utc_model.d_A0 = d_A0UTC;
utc_model.d_t_OT = d_t_OT;
utc_model.i_WN_T = i_WN_T;
utc_model.d_A1_UTC = d_A1UTC;
utc_model.d_A0_UTC = d_A0UTC;
utc_model.d_DeltaT_LS = d_DeltaT_LS;
utc_model.i_WN_LSF = i_WN_LSF;
utc_model.i_DN = i_DN;
utc_model.d_DeltaT_LSF = d_DeltaT_LSF;
utc_model.d_A0_GPS = d_A0GPS;
utc_model.d_A1_GPS = d_A1GPS;
utc_model.d_A0_GAL = d_A0GAL;
utc_model.d_A1_GAL = d_A1GAL;
utc_model.d_A0_GLO = d_A0GLO;
utc_model.d_A1_GLO = d_A1GLO;
// warning: We clear flag_utc_model_valid in order to not re-send the same information to the ionospheric parameters queue
flag_utc_model_valid = false;
return utc_model;
}
bool Beidou_Dnav_Navigation_Message::have_new_ephemeris() // Check if we have a new ephemeris stored in the galileo navigation class
{
if(i_satellite_PRN > 0 and i_satellite_PRN < 6)
@ -1170,9 +1112,8 @@ bool Beidou_Dnav_Navigation_Message::have_new_ephemeris() // Check if we have a
flag_eph_valid = true;
// Update the time of ephemeris information
d_previous_aode = d_AODE;
DLOG(INFO) << "Beidou D2 NAV Ephemeris have been received and belong to the same batch" << std::endl;
return true;
return true;
}
}
}
@ -1189,41 +1130,39 @@ bool Beidou_Dnav_Navigation_Message::have_new_ephemeris() // Check if we have a
flag_eph_valid = true;
// Update the time of ephemeris information
d_previous_aode = d_AODE;
DLOG(INFO) << "Beidou D1 NAV Ephemeris have been received and belong to the same batch" << std::endl;
return true;
return true;
}
}
}
return false;
}
bool Beidou_Dnav_Navigation_Message::have_new_iono()
{
// the condition on flag_utc_model is added to have a time stamp for iono
if (flag_iono_valid == true)
{
flag_iono_valid = false; // clear the flag
return true;
}
return false;
}
bool Beidou_Dnav_Navigation_Message::have_new_utc_model()
{
if (flag_utc_model_valid == true)
if (flag_d1_sf5_p9 == true and flag_d1_sf5_p10 == true)
{
flag_utc_model_valid = false; // clear the flag
flag_d1_sf5_p9 = false;
flag_d1_sf5_p10 = false;
flag_utc_model_valid = true;
return true;
}
return false;
}
bool Beidou_Dnav_Navigation_Message::have_new_almanac()
{
if ((flag_d1_sf4 == true) and (flag_d1_sf5 == true))
@ -1238,7 +1177,6 @@ bool Beidou_Dnav_Navigation_Message::have_new_almanac()
return false;
}
bool Beidou_Dnav_Navigation_Message::satellite_validation()
{
bool flag_data_valid = false;

View File

@ -82,16 +82,22 @@ public:
bool flag_crc_test;
double d_previous_aode;
bool flag_sf1_p1; //!< D2 NAV Message, Subframe 1, Pagge 1 decoded indicator
bool flag_sf1_p2; //!< D2 NAV Message, Subframe 1, Pagge 2 decoded indicator
bool flag_sf1_p3; //!< D2 NAV Message, Subframe 1, Pagge 3 decoded indicator
bool flag_sf1_p4; //!< D2 NAV Message, Subframe 1, Pagge 4 decoded indicator
bool flag_sf1_p5; //!< D2 NAV Message, Subframe 1, Pagge 5 decoded indicator
bool flag_sf1_p6; //!< D2 NAV Message, Subframe 1, Pagge 6 decoded indicator
bool flag_sf1_p7; //!< D2 NAV Message, Subframe 1, Pagge 7 decoded indicator
bool flag_sf1_p8; //!< D2 NAV Message, Subframe 1, Pagge 8 decoded indicator
bool flag_sf1_p9; //!< D2 NAV Message, Subframe 1, Pagge 9 decoded indicator
bool flag_sf1_p10; //!< D2 NAV Message, Subframe 1, Pagge 10 decoded indicator
bool flag_d1_sf5_p7; //!< D1 NAV Message, Subframe 5, Page 09 decoded indicator
bool flag_d1_sf5_p8; //!< D1 NAV Message, Subframe 5, Page 09 decoded indicator
bool flag_d1_sf5_p9; //!< D1 NAV Message, Subframe 5, Page 09 decoded indicator
bool flag_d1_sf5_p10; //!< D1 NAV Message, Subframe 5, Page 10 decoded indicator
bool flag_sf1_p1; //!< D2 NAV Message, Subframe 1, Page 1 decoded indicator
bool flag_sf1_p2; //!< D2 NAV Message, Subframe 1, Page 2 decoded indicator
bool flag_sf1_p3; //!< D2 NAV Message, Subframe 1, Page 3 decoded indicator
bool flag_sf1_p4; //!< D2 NAV Message, Subframe 1, Page 4 decoded indicator
bool flag_sf1_p5; //!< D2 NAV Message, Subframe 1, Page 5 decoded indicator
bool flag_sf1_p6; //!< D2 NAV Message, Subframe 1, Page 6 decoded indicator
bool flag_sf1_p7; //!< D2 NAV Message, Subframe 1, Page 7 decoded indicator
bool flag_sf1_p8; //!< D2 NAV Message, Subframe 1, Page 8 decoded indicator
bool flag_sf1_p9; //!< D2 NAV Message, Subframe 1, Page 9 decoded indicator
bool flag_sf1_p10; //!< D2 NAV Message, Subframe 1, Page 10 decoded indicator
//broadcast orbit 1
double d_SOW; //!< Time of BeiDou Week of the ephemeris set (taken from subframes SOW) [s]
@ -211,11 +217,8 @@ public:
double d_beta3; //!< Coefficient 3 of a cubic equation representing the period of the model [s(semi-circle)^3]
// UTC parameters
double d_A2UTC;
double d_A1UTC; //!< 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s/s]
double d_A0UTC; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s]
double d_t_OT; //!< Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200E) [s]
int i_WN_T; //!< UTC reference week number [weeks]
double d_DeltaT_LS; //!< delta time due to leap seconds [s]. Number of leap seconds since 6-Jan-1980 as transmitted by the GPS almanac.
int i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks]
int i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days]

View File

@ -1,7 +1,8 @@
/*
* \file gps_utc_model.h
* \brief Interface of a GPS UTC MODEL storage
* \author Javier Arribas, 2013. jarribas(at)cttc.es
/*!
* \file beidou_dnav_utc_model.c
* \brief Interface of a BeiDou UTC Model storage
* \author Damian Miralles, 2018. dmiralles2009(at)gmail.com
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
*
* -------------------------------------------------------------------------
*
@ -30,83 +31,22 @@
#include "beidou_dnav_utc_model.h"
#include <cmath>
Beidou_Dnav_Utc_Model::Beidou_Dnav_Utc_Model()
{
valid = false;
d_A1 = 0;
d_A0 = 0;
d_t_OT = 0;
i_WN_T = 0;
d_A1_UTC = 0;
d_A0_UTC = 0;
d_DeltaT_LS = 0;
i_WN_LSF = 0;
i_DN = 0;
d_DeltaT_LSF = 0;
d_A0_GPS = 0;
d_A1_GPS = 0;
d_A0_GAL = 0;
d_A1_GAL = 0;
d_A0_GLO = 0;
d_A1_GLO = 0;
}
double Beidou_Dnav_Utc_Model::utc_time(double beidoutime_corrected, int i_BEIDOU_week)
{
double t_utc;
double t_utc_daytime;
double Delta_t_UTC = d_DeltaT_LS + d_A0 + d_A1 * (beidoutime_corrected - d_t_OT + 604800 * static_cast<double>(i_BEIDOU_week - i_WN_T));
// Determine if the effectivity time of the leap second event is in the past
int weeksToLeapSecondEvent = i_WN_LSF - i_BEIDOU_week;
if (weeksToLeapSecondEvent >= 0) // is not in the past
{
//Detect if the effectivity time and user's time is within six hours = 6 * 60 *60 = 21600 s
int secondOfLeapSecondEvent = i_DN * 24 * 60 * 60;
if (weeksToLeapSecondEvent > 0)
{
t_utc_daytime = fmod(beidoutime_corrected - Delta_t_UTC, 86400);
}
else //we are in the same week than the leap second event
{
if (std::abs(beidoutime_corrected - secondOfLeapSecondEvent) > 21600)
{
/* 20.3.3.5.2.4a
* Whenever the effectivity time indicated by the WN_LSF and the DN values
* is not in the past (relative to the user's present time), and the user's
* present time does not fall in the time span which starts at six hours prior
* to the effectivity time and ends at six hours after the effectivity time,
* the UTC/GPS-time relationship is given by
*/
t_utc_daytime = fmod(beidoutime_corrected - Delta_t_UTC, 86400);
}
else
{
/* 20.3.3.5.2.4b
* Whenever the user's current time falls within the time span of six hours
* prior to the effectivity time to six hours after the effectivity time,
* proper accommodation of the leap second event with a possible week number
* transition is provided by the following expression for UTC:
*/
int W = fmod(beidoutime_corrected - Delta_t_UTC - 43200, 86400) + 43200;
t_utc_daytime = fmod(W, 86400 + d_DeltaT_LSF - d_DeltaT_LS);
//implement something to handle a leap second event!
}
if ((beidoutime_corrected - secondOfLeapSecondEvent) > 21600)
{
Delta_t_UTC = d_DeltaT_LSF + d_A0 + d_A1 * (beidoutime_corrected - d_t_OT + 604800 * static_cast<double>(i_BEIDOU_week - i_WN_T));
t_utc_daytime = fmod(beidoutime_corrected - Delta_t_UTC, 86400);
}
}
}
else // the effectivity time is in the past
{
/* 20.3.3.5.2.4c
* Whenever the effectivity time of the leap second event, as indicated by the
* WNLSF and DN values, is in the "past" (relative to the user's current time),
* and the user's current time does not fall in the time span as given above
* in 20.3.3.5.2.4b,*/
Delta_t_UTC = d_DeltaT_LSF + d_A0 + d_A1 * (beidoutime_corrected - d_t_OT + 604800 * static_cast<double>(i_BEIDOU_week - i_WN_T));
t_utc_daytime = fmod(beidoutime_corrected - Delta_t_UTC, 86400);
}
double secondsOfWeekBeforeToday = 86400 * floor(beidoutime_corrected / 86400);
t_utc = secondsOfWeekBeforeToday + t_utc_daytime;
return t_utc;
}

View File

@ -1,7 +1,8 @@
/*!
* \file gps_utc_model.h
* \brief Interface of a GPS UTC MODEL storage
* \author Javier Arribas, 2013. jarribas(at)cttc.es
* \file beidou_dnav_utc_model.h
* \brief Interface of a BeiDou UTC MODEL storage
* \author Damian Miralles, 2018. dmiralles2009@gmail.com
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
*
* -------------------------------------------------------------------------
*
@ -37,27 +38,35 @@
/*!
* \brief This class is a storage for the GPS UTC MODEL data as described in IS-GPS-200E
* \brief This class is a storage for the BeiDou DNAV UTC Model.
* \details Implementation follows the interface described in the Open Service Signal (Version 2.1)
*
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
*/
class Beidou_Dnav_Utc_Model
{
public:
bool valid;
// UTC parameters
double d_A1; //!< 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s/s]
double d_A0; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s]
double d_t_OT; //!< Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200E) [s]
int i_WN_T; //!< UTC reference week number [weeks]
double d_DeltaT_LS; //!< delta time due to leap seconds [s]. Number of leap seconds since 6-Jan-1980 as transmitted by the GPS almanac.
int i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks]
int i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days]
double d_DeltaT_LSF; //!< Scheduled future or recent past (relative to NAV message upload) value of the delta time due to leap seconds [s]
/*!
* Default constructor
*/
// BeiDou UTC parameters
double d_A0_UTC; //!< BDT clock bias relative to UTC [s]
double d_A1_UTC; //!< BDT clock rate relative to UTC [s/s]
double d_DeltaT_LS; //!< Delta time due to leap seconds before the new leap second effective
int i_WN_LSF; //!< Week number of the new leap second
int i_DN; //!< Day number of week of the new leap second
double d_DeltaT_LSF; //!< Delta time due to leap seconds after the new leap second effective [s]
// BeiDou to GPS time corrections
double d_A0_GPS; //!< BDT clock bias relative to GPS time [s]
double d_A1_GPS; //!< BDT clock rate relative to GPS time [s/s]
// BeiDou to Galileo time corrections
double d_A0_GAL; //!< BDT clock bias relative to GAL time [s]
double d_A1_GAL; //!< BDT clock rate relative to GAL time [s/s]
// BeiDou to GLONASS time corrections
double d_A0_GLO; //!< BDT clock bias relative to GLO time [s]
double d_A1_GLO; //!< BDT clock rate relative to GLO time [s/s]
Beidou_Dnav_Utc_Model();
template <class Archive>
@ -71,21 +80,20 @@ public:
{
};
archive& make_nvp("valid", valid);
archive& make_nvp("d_A1", d_A1);
archive& make_nvp("d_A0", d_A0);
archive& make_nvp("d_t_OT", d_t_OT);
archive& make_nvp("i_WN_T", i_WN_T);
archive& make_nvp("d_A1", d_A1_UTC);
archive& make_nvp("d_A0", d_A0_UTC);
archive& make_nvp("d_DeltaT_LS", d_DeltaT_LS);
archive& make_nvp("i_WN_LSF", i_WN_LSF);
archive& make_nvp("i_DN", i_DN);
archive& make_nvp("d_DeltaT_LSF", d_DeltaT_LSF);
archive& make_nvp("d_A0_GPS", d_A0_GPS);
archive& make_nvp("d_A0_GPS", d_A1_GPS);
archive& make_nvp("d_A0_GPS", d_A0_GAL);
archive& make_nvp("d_A0_GPS", d_A1_GAL);
archive& make_nvp("d_A0_GPS", d_A0_GLO);
archive& make_nvp("d_A0_GPS", d_A1_GLO);
}
/*!
* \brief Computes the Coordinated Universal Time (UTC) and
* returns it in [s] (IS-GPS-200E, 20.3.3.5.2.4)
*/
double utc_time(double beidoutime_corrected, int i_BEIDOU_week);
};
#endif