52 #define CHECK_SV_HERE(itty, prn) \
53 if (itty == almPRN.end()) \
55 SVNotPresentException \
56 exc("Attempt to get data from EngAlmanac from a SV that is not" \
63 EngAlmanac :: EngAlmanac()
66 for (
int n = 0; n < 4; n++)
68 alpha[n] =
beta[n] = 0.0;
71 A0 =
A1 = dt_ls = dt_lsf = 0.0;
84 bool EngAlmanac::addSubframe(
const long subframe[10],
88 for (
int n=0;n<10;++n)
89 tinput[n] =
static_cast<uint32_t
>( subframe[n] );
90 return( addSubframe( tinput,
static_cast<const short>( gpsWeek )));
93 bool EngAlmanac::addSubframe(
const uint32_t subframe[10],
98 if (!subframeConvert(subframe, gpsWeek, ficked))
101 short pat = getSubframePattern(subframe);
104 if ((ficked[0] != 0x8b) || ((ficked[4] != 4) && (ficked [4] != 5))
105 || (pat < 4) || (pat > 10))
108 exc(
"EngAlmanac::addSubframe: Not a valid almanac page.");
121 if ((ficked[19] < 0) || (ficked[19] >
MAX_PRN_GPS))
123 InvalidParameter exc(
"EngAlmanac::addSubframe, PRN out of range "
128 int prn =
static_cast<short>( ficked[19] );
130 SatID sat(prn,SatelliteSystem::GPS);
131 almPRN[sat] =
AlmOrbit(prn, ficked[7], ficked[9], ficked[10],
132 ficked[12], ficked[13], ficked[14],
133 ficked[15], ficked[16], ficked[17],
134 static_cast<long>( ficked[8] ),
135 static_cast<long>( ficked[2] ),
137 static_cast<short>( ficked[11] ));
143 for (
int i=1; i <=24; i++)
144 health[i] =
static_cast<char>( ficked[7 + i] );
146 t_oa = ((subframe[2] >> 14) & 0xFF) * 4096;
147 wn_a =
static_cast<int>(ficked[7]);
148 convert8bit(gpsWeek, &ficked[7]);
149 alm_wk =
static_cast<int>(ficked[7]);
158 alpha[0] = ficked[7];
159 alpha[1] = ficked[8];
160 alpha[2] = ficked[9];
161 alpha[3] = ficked[10];
162 beta[0] = ficked[11];
163 beta[1] = ficked[12];
164 beta[2] = ficked[13];
165 beta[3] = ficked[14];
169 t_ot =
static_cast<long>( ficked[17] );
170 wn_t =
static_cast<int>( ficked[18] );
171 wn_lsf =
static_cast<int>( ficked[20] );
172 dn =
static_cast<char>( ficked[21] );
179 SV_config[i] =
static_cast<char>( ficked[6 + i] );
182 health[i] =
static_cast<char>( ficked[14 + i] );
187 for (
int i=0; i<22; i++)
188 special_msg +=
static_cast<char>( ficked[7 + i] );
198 double EngAlmanac::getEcc(
SatID sat)
const
200 AlmOrbits::const_iterator i = almPRN.find(sat);
204 return (*i).second.ecc;
207 double EngAlmanac::getIOffset(
SatID sat)
const
209 AlmOrbits::const_iterator i = almPRN.find(sat);
213 return (*i).second.i_offset;
216 double EngAlmanac::getOmegadot(
SatID sat)
const
219 AlmOrbits::const_iterator i = almPRN.find(sat);
223 return (*i).second.OMEGAdot;
226 short EngAlmanac::get6bitHealth(
SatID sat)
const
228 SVBitsMap::const_iterator i = health.find(sat.
id);
229 if (i == health.end())
231 SVNotPresentException svnpe(
"SV health not present for PRN " +
239 short EngAlmanac::getSVHealth(
SatID sat)
const
241 AlmOrbits::const_iterator i = almPRN.find(sat);
245 return (*i).second.SV_health;
248 short EngAlmanac::getSVConfig(
SatID sat)
const
250 SVBitsMap::const_iterator i = SV_config.find(sat.
id);
251 if (i == SV_config.end())
253 SVNotPresentException svnpe(
"SV Configuration not present for PRN " +
261 double EngAlmanac::getAhalf(
SatID sat)
const
263 AlmOrbits::const_iterator i = almPRN.find(sat);
267 return (*i).second.Ahalf;
270 double EngAlmanac::getA(
SatID sat)
const
272 AlmOrbits::const_iterator i = almPRN.find(sat);
276 return (*i).second.Ahalf * (*i).second.Ahalf;
279 double EngAlmanac::getOmega0(
SatID sat)
const
282 AlmOrbits::const_iterator i = almPRN.find(sat);
286 return (*i).second.OMEGA0;
289 double EngAlmanac::getW(
SatID sat)
const
291 AlmOrbits::const_iterator i = almPRN.find(sat);
295 return (*i).second.w;
298 double EngAlmanac::getM0(
SatID sat)
const
300 AlmOrbits::const_iterator i = almPRN.find(sat);
304 return (*i).second.M0;
307 double EngAlmanac::getAf0(
SatID sat)
const
309 AlmOrbits::const_iterator i = almPRN.find(sat);
313 return (*i).second.AF0;
317 double EngAlmanac::getAf1(
SatID sat)
const
319 AlmOrbits::const_iterator i = almPRN.find(sat);
323 return (*i).second.AF1;
327 double EngAlmanac::getToa()
const noexcept
329 return static_cast<double>( t_oa );
332 double EngAlmanac::getToa(
SatID sat)
const
334 AlmOrbits::const_iterator i = almPRN.find(sat);
338 return static_cast<double>( (*i).second.Toa );
342 double EngAlmanac::getXmitTime(
SatID sat)
const
344 AlmOrbits::const_iterator i = almPRN.find(sat);
348 return static_cast<double>( (*i).second.xmit_time );
352 short EngAlmanac::getFullWeek(
SatID sat)
const
354 AlmOrbits::const_iterator i = almPRN.find(sat);
357 return (*i).second.getFullWeek();
360 void EngAlmanac::getIon(
double a[4],
double b[4])
const
365 exc(
"UTC offset (subframe 4, page 18) is not present.");
368 for (
int n = 0; n < 4; n++)
375 void EngAlmanac::getUTC(
double& a0,
double& a1,
double& deltaTLS,
376 long& tot,
int& WNt,
int& WNLSF,
377 int& DN,
double& deltaTLSF)
const
382 exc(
"UTC offset (subframe 4, page 18) is not present.");
391 DN =
static_cast<int>( dn );
395 short EngAlmanac::getAlmWeek()
const noexcept
402 AlmOrbits::const_iterator i = almPRN.find(sat);
411 AlmOrbits::const_iterator i = almPRN.find(sat);
415 return (*i).second.svXvt(t);
418 bool EngAlmanac::isData(
SatID sat)
const noexcept
420 return (almPRN.find(sat) != almPRN.end());
426 for (
int i = 0; i < len; i++)
438 bool EngAlmanac::check(ostream& s)
const
443 s <<
"UTC offset (subframe 4, page 18) is not present." << endl;
445 double p51Toa=getToa();
446 for (
int prn=1; prn<=32; prn++)
450 double svToa = getToa(
gnsstk::SatID(prn, SatelliteSystem::GPS));
453 s <<
"Toa mis-match on prn " << prn
454 <<
" page 51 Toa=" << p51Toa
455 <<
", SV Toa=" << svToa << endl;
459 catch (SVNotPresentException& e)
461 cout <<
"No page for prn " << prn << endl;
470 ios::fmtflags oldFlags = s.flags();
474 s <<
"****************************************************************"
475 <<
"***************" << endl
476 <<
"Broadcast Almanac (Engineering Units)" << endl
479 s << endl <<
" Iono Parameters" << endl << endl;
480 s <<
"Alpha: " << scientific << setprecision(6);
481 for (
int i=0; i<4; i++)
482 s << setw(13) << alpha[i] <<
" ";
483 s <<
" various" << endl;
484 s <<
" Beta: " << fixed << setprecision(1);
485 for (
int i=0; i<4; i++)
486 s << setw(13) <<
beta[i] <<
" ";
487 s <<
" various" << endl;
489 s << endl <<
" UTC Paramters" << endl << endl;
490 s << scientific << setprecision(8)
491 <<
"A0: " << setw(15) << A0 <<
" sec" << endl
492 <<
"A1: " << setw(15) <<
A1 <<
" sec/sec" << endl
493 << fixed << setprecision(1)
494 <<
"dt_ls: " << setw(15) << dt_ls <<
" sec" << endl
495 <<
"t_ot: " << setw(15) << t_ot <<
" sec" << endl
496 <<
"wn_t: " << setw(15) << wn_t <<
" week" << endl
497 <<
"wn_lsf " << setw(15) << wn_lsf <<
" week" << endl
498 <<
"dn: " << setw(15) << (int)dn <<
" days" << endl
499 <<
"dt_lsf: " << setw(15) << dt_lsf <<
" sec" << endl;
501 s << endl <<
" Orbit Parameters" << endl << endl;
502 for (AlmOrbits::const_iterator i = almPRN.begin(); i != almPRN.end(); i++)
503 s<< scientific << (*i).second;
505 s << endl <<
" Special Message" << endl << endl;
509 s << endl <<
" Page 25 Health, AS, & SV config" << endl << endl;
511 s <<
"Toa: " << setfill(
' ') << setw(8) << t_oa
512 <<
", week: " << setw(5) << wn_a <<
" (" << alm_wk <<
")" << endl
514 <<
"PRN health AS cfg PRN health AS cfg" << endl;
517 for (SVBitsMap::const_iterator i = health.begin(); i != health.end(); i++)
520 if (prn >= 1 && prn <= 32)
521 bits[prn] =
int2bin(i->second, 6);
524 for (SVBitsMap::const_iterator i = SV_config.begin(); i != SV_config.end(); i++)
527 if (prn >= 1 && prn <= 32)
529 bits[prn] +=
" " +
int2bin(i->second, 4);
530 bits[prn].insert(9,
" ");
534 for (
int i=1; i<=16; i++)
535 s << setw(2) << i <<
" " << bits[i] <<
" "
536 << setw(2) << i+16 <<
" " << bits[i+16] << endl;