GPSLNavEph.cpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation; either version 3.0 of the License, or
8 // any later version.
9 //
10 // The GNSSTk is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with GNSSTk; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 // This software was developed by Applied Research Laboratories at the
20 // University of Texas at Austin.
21 // Copyright 2004-2022, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 
26 //==============================================================================
27 //
28 // This software was developed by Applied Research Laboratories at the
29 // University of Texas at Austin, under contract to an agency or agencies
30 // within the U.S. Department of Defense. The U.S. Government retains all
31 // rights to use, duplicate, distribute, disclose, or release this software.
32 //
33 // Pursuant to DoD Directive 523024
34 //
35 // DISTRIBUTION STATEMENT A: This software has been approved for public
36 // release, distribution is unlimited.
37 //
38 //==============================================================================
39 #include "GPSLNavEph.hpp"
40 #include "GPSWeekSecond.hpp"
41 #include "TimeString.hpp"
42 #include "GPS_URA.hpp"
43 
44 using namespace std;
45 
46 namespace gnsstk
47 {
48  GPSLNavEph ::
49  GPSLNavEph()
50  : pre2(0),
51  pre3(0),
52  tlm2(0),
53  tlm3(0),
54  isf2(false),
55  isf3(false),
56  iodc(0),
57  iode(0),
58  fitIntFlag(0),
59  healthBits(0xff),
60  uraIndex(0),
61  tgd(0.0),
62  asFlag2(false),
63  asFlag3(false),
64  alert2(false),
65  alert3(false),
66  codesL2(GPSLNavL2Codes::Invalid1),
67  aodo(-1),
68  L2Pdata(false)
69  {
71  msgLenSec = 18.0;
72  }
73 
74 
75  bool GPSLNavEph ::
76  validate() const
77  {
78  return GPSLNavData::validate() && ((pre2 == 0) || (pre2 == 0x8b)) &&
79  ((pre3 == 0) || (pre3 == 0x8b));
80  }
81 
82 
84  getUserTime() const
85  {
87  return mr + 6.0;
88  }
89 
90 
91  void GPSLNavEph ::
93  {
94  GPSWeekSecond xws(xmitTime), toeWS(Toe);
95  int xmitWeek = xws.week;
96  long xmitSOW = (long) xws.sow;
97  bool isNominalToe = (long)toeWS.sow % 7200 == 0;
98  double fitSeconds = 3600.0 * getLegacyFitInterval(iodc, fitIntFlag);
99  endFit = Toe + (fitSeconds/2.0);
100 
101  // If the toe is NOT offset, then the begin valid time can be set
102  // to the beginning of the two hour interval.
103  // NOTE: This is only true for GPS. We can't do this
104  // for QZSS, even though it also broadcasts the LNAV message format.
105  if (signal.system==SatelliteSystem::GPS && isNominalToe)
106  {
107  xmitSOW = xmitSOW - (xmitSOW % 7200);
108  }
109 
110  // If there IS an offset, all we can assume is that we (hopefully)
111  // captured the earliest transmission and set the begin valid time
112  // to that value.
113  //
114  // @note Prior to GPS III, the offset was typically applied
115  // to BOTH the first and second data sets following a
116  // cutover. So this means the SECOND data set will NOT be
117  // coerced to the top of the even hour start time if it
118  // wasn't collected at the top of the hour.
119  beginFit = GPSWeekSecond(xmitWeek, xmitSOW, xws.getTimeSystem());
120  // If an upload cutover, need some adjustment.
121  // Calculate the SOW aligned with the mid point and then
122  // calculate the number of seconds the toe is SHORT
123  // of that value. That's how far the endValid needs
124  // to be adjusted.
125  if (!isNominalToe)
126  {
127  long sow = (long) toeWS.sow;
128  long num900secIntervals = sow / 900;
129  long midPointSOW = (num900secIntervals+1) * 900;
130  double adjustUp = (double) (midPointSOW - sow);
131  endFit += adjustUp;
132  }
133  }
134 
135 
136  void GPSLNavEph ::
137  dump(std::ostream& s, DumpDetail dl) const
138  {
139  if (dl != DumpDetail::Terse)
140  {
141  // standard dump routine is fine for anything other than Terse
142  GPSLNavData::dump(s,dl);
143  return;
144  }
145  ios::fmtflags oldFlags = s.flags();
146 
147  s.setf(ios::fixed, ios::floatfield);
148  s.setf(ios::right, ios::adjustfield);
149  s.setf(ios::uppercase);
150  s.precision(0);
151  s.fill(' ');
152 
153  std::string svn("0");
154  if (getSVN(signal.sat, Toe, svn))
155  {
156  s << setw(2) << " " << svn << " ";
157  }
158  else
159  {
160  s << " XX ";
161  }
162 
163  s << setw(2) << signal.sat.id << " ! ";
164 
165  string tform = "%3j %02H:%02M:%02S";
166 
167  s << printTime( beginFit, tform ) << " ! ";
168  s << printTime( Toe, tform ) << " ! ";
169  s << printTime( endFit, tform ) << " ! ";
170 
172  {
173  s << setw(4) << setprecision(1) << ura2accuracy(uraIndex) << " ! ";
174  }
175  else
176  {
177  s << setw(4) << "N/A" << " ! ";
178  }
179  s << "0x" << setfill('0') << hex << setw(3) << iodc << " ! ";
180  s << "0x" << setfill('0') << setw(2) << (unsigned)healthBits;
181  s << setfill(' ') << dec;
182  s << " " << setw(2) << (unsigned)healthBits << " ! ";
183 
184  s << endl;
185  s.flags(oldFlags);
186  }
187 
188 
189  void GPSLNavEph ::
190  dumpSVStatus(std::ostream& s) const
191  {
192  const ios::fmtflags oldFlags = s.flags();
196  unsigned health = healthBits;
197  s << " SUBFRAME OVERHEAD" << endl << endl
198  << " SOW DOW:HH:MM:SS IOD ALERT A-S ISF"
199  << endl
200  << "SF1 HOW: "
201  << gnsstk::printTime(xmitTime+6, "%7.0g %3a-%1w:%02H:%02M:%02S")
202  << " 0x" << hex << setw(3) << internal << setfill('0')
203  << nouppercase << iodc << dec << setfill(' ') << " "
204  << noboolalpha << alert << " " << (asFlag ? " on " : "off ")
205  << (isf ? "enhanced" : "legacy") << endl
206  << "SF2 HOW: "
207  << gnsstk::printTime(xmit2+6, "%7.0g %3a-%1w:%02H:%02M:%02S")
208  << " 0x" << hex << setw(2) << internal << setfill('0')
209  << nouppercase << iode << dec << setfill(' ') << " "
210  << alert2 << " " << (asFlag2 ? " on " : "off ")
211  << (isf2 ? "enhanced" : "legacy") << endl
212  << "SF3 HOW: "
213  << gnsstk::printTime(xmit3+6, "%7.0g %3a-%1w:%02H:%02M:%02S")
214  << " 0x" << hex << setw(2) << internal << setfill('0')
215  << nouppercase << iode << dec << setfill(' ') << " "
216  << alert3 << " " << (asFlag3 ? " on " : "off ")
217  << (isf3 ? "enhanced" : "legacy") << endl
218  << endl
219  << " SV STATUS" << endl << endl
220  << "Health bits : 0x" << setw(2)
221  << internal << setfill('0') << hex << health << dec
222  << ", " << setfill(' ') << health << endl
223  << "Fit interval flag :" << setw(10) << (unsigned)fitIntFlag << endl
224  << "URA index :" << setw(10) << (unsigned)uraIndex << endl
225  << "Code on L2 :" << setw(10) << StringUtils::asString(codesL2)
226  << endl
227  << "L2 P Nav data :" << " " << (L2Pdata ? "off" : " on")
228  << endl << right
229  << "Tgd :" << setw(14) << setprecision(6) << scientific
230  << uppercase << tgd << " sec" << endl;
231  if (aodo != -1)
232  {
233  s << "AODO :" << setw(10) << aodo << " sec" << endl;
234  }
235  s << endl;
236  s.flags(oldFlags);
237  }
238 
239 
241  operator()(const std::shared_ptr<GPSLNavEph> lhs,
242  const std::shared_ptr<GPSLNavEph> rhs) const
243  {
244  if (lhs->signal < rhs->signal) return true;
245  if (rhs->signal < lhs->signal) return false;
246  GPSWeekSecond lws(lhs->Toe), rws(rhs->Toe);
247  if (lws.week < rws.week) return true;
248  if (rws.week < lws.week) return false;
249  if (lhs->iodc < rhs->iodc) return true;
250  return false;
251  }
252 
253 
255  operator()(const std::shared_ptr<GPSLNavEph> lhs,
256  const std::shared_ptr<GPSLNavEph> rhs) const
257  {
258  // We still need to do signal and Toe, so do those first,
259  // since they're the most likely to change.
260  if (lhs->signal < rhs->signal) return true;
261  if (rhs->signal < lhs->signal) return false;
262  GPSWeekSecond lws(lhs->Toe), rws(rhs->Toe);
263  if (lws.week < rws.week) return true;
264  if (rws.week < lws.week) return false;
265  if (lhs->iodc < rhs->iodc) return true;
266  if (rhs->iodc < lhs->iodc) return false;
267  // Everything else is in the order it appears in Table 6-I-1,
268  // for convenience (i.e. if there's a compelling reason to
269  // change it, this order has no specific meaning)
270  if (lhs->healthBits < rhs->healthBits) return true;
271  if (rhs->healthBits < lhs->healthBits) return false;
272  if (lhs->uraIndex < rhs->uraIndex) return true;
273  if (rhs->uraIndex < lhs->uraIndex) return false;
274  if (lhs->tgd < rhs->tgd) return true;
275  if (rhs->tgd < lhs->tgd) return false;
276  if (lhs->af0 < rhs->af0) return true;
277  if (rhs->af0 < lhs->af0) return false;
278  if (lhs->af1 < rhs->af1) return true;
279  if (rhs->af1 < lhs->af1) return false;
280  if (lhs->af2 < rhs->af2) return true;
281  if (rhs->af2 < lhs->af2) return false;
282  if (lhs->Toc < rhs->Toc) return true;
283  if (rhs->Toc < lhs->Toc) return false;
284  if (lhs->Ahalf < rhs->Ahalf) return true;
285  if (rhs->Ahalf < lhs->Ahalf) return false;
286  if (lhs->dn < rhs->dn) return true;
287  if (rhs->dn < lhs->dn) return false;
288  if (lhs->fitIntFlag < rhs->fitIntFlag) return true;
289  if (rhs->fitIntFlag < lhs->fitIntFlag) return false;
290  if (lhs->ecc < rhs->ecc) return true;
291  if (rhs->ecc < lhs->ecc) return false;
292  if (lhs->M0 < rhs->M0) return true;
293  if (rhs->M0 < lhs->M0) return false;
294  if (lhs->Toe < rhs->Toe) return true;
295  if (rhs->Toe < lhs->Toe) return false;
296  if (lhs->Crs < rhs->Crs) return true;
297  if (rhs->Crs < lhs->Crs) return false;
298  if (lhs->Cuc < rhs->Cuc) return true;
299  if (rhs->Cuc < lhs->Cuc) return false;
300  if (lhs->Cus < rhs->Cus) return true;
301  if (rhs->Cus < lhs->Cus) return false;
302  if (lhs->iode < rhs->iode) return true;
303  if (rhs->iode < lhs->iode) return false;
304  if (lhs->isf < rhs->isf) return true;
305  if (rhs->isf < lhs->isf) return false;
306  if (lhs->isf2 < rhs->isf2) return true;
307  if (rhs->isf2 < lhs->isf2) return false;
308  if (lhs->isf3 < rhs->isf3) return true;
309  if (rhs->isf3 < lhs->isf3) return false;
310  if (lhs->w < rhs->w) return true;
311  if (rhs->w < lhs->w) return false;
312  if (lhs->OMEGAdot < rhs->OMEGAdot) return true;
313  if (rhs->OMEGAdot < lhs->OMEGAdot) return false;
314  if (lhs->OMEGA0 < rhs->OMEGA0) return true;
315  if (rhs->OMEGA0 < lhs->OMEGA0) return false;
316  if (lhs->i0 < rhs->i0) return true;
317  if (rhs->i0 < lhs->i0) return false;
318  if (lhs->idot < rhs->idot) return true;
319  if (rhs->idot < lhs->idot) return false;
320  if (lhs->Cic < rhs->Cic) return true;
321  if (rhs->Cic < lhs->Cic) return false;
322  if (lhs->Cis < rhs->Cis) return true;
323  if (rhs->Cis < lhs->Cis) return false;
324  if (lhs->Crc < rhs->Crc) return true;
325  if (rhs->Crc < lhs->Crc) return false;
326  if (lhs->alert < rhs->alert) return true;
327  if (rhs->alert < lhs->alert) return false;
328  if (lhs->alert2 < rhs->alert2) return true;
329  if (rhs->alert2 < lhs->alert2) return false;
330  if (lhs->alert3 < rhs->alert3) return true;
331  if (rhs->alert3 < lhs->alert3) return false;
332  return false;
333  }
334 }
gnsstk::GPSLNavEph::codesL2
GPSLNavL2Codes codesL2
Code on L2 in-phase component.
Definition: GPSLNavEph.hpp:108
gnsstk::GPSLNavEph::alert2
bool alert2
Alert flag from SF2 HOW.
Definition: GPSLNavEph.hpp:104
gnsstk::GPSLNavEph::isf2
bool isf2
Integrity status flag from subframe 2.
Definition: GPSLNavEph.hpp:96
gnsstk::NavData::msgLenSec
double msgLenSec
Definition: NavData.hpp:199
gnsstk::GPSLNavEph::xmit3
CommonTime xmit3
Transmit time for subframe 3.
Definition: GPSLNavEph.hpp:91
gnsstk::SatID::id
int id
Satellite identifier, e.g. PRN.
Definition: SatID.hpp:154
gnsstk::GPSLNavData::asFlag
bool asFlag
Anti-spoof flag from HOW.
Definition: GPSLNavData.hpp:84
gnsstk::NavMessageID::messageType
NavMessageType messageType
Definition: NavMessageID.hpp:97
GPS_URA.hpp
gnsstk::max
T max(const SparseMatrix< T > &SM)
Maximum element - return 0 if empty.
Definition: SparseMatrix.hpp:881
gnsstk::GPSLNavEphCEIComp::operator()
bool operator()(const std::shared_ptr< GPSLNavEph > lhs, const std::shared_ptr< GPSLNavEph > rhs) const
Definition: GPSLNavEph.cpp:255
gnsstk::GPSLNavEph::fitIntFlag
uint8_t fitIntFlag
Fit interval flag from subframe 2.
Definition: GPSLNavEph.hpp:100
gnsstk::GPSLNavData::isf
bool isf
Integrity status flag.
Definition: GPSLNavData.hpp:82
gnsstk::GPSLNavEph::dump
void dump(std::ostream &s, DumpDetail dl) const override
Definition: GPSLNavEph.cpp:137
gnsstk::NavFit::endFit
CommonTime endFit
Time at end of fit interval.
Definition: NavFit.hpp:55
gnsstk::StringUtils::asString
std::string asString(IonexStoreStrategy e)
Convert a IonexStoreStrategy to a whitespace-free string name.
Definition: IonexStoreStrategy.cpp:46
gnsstk::GPSLNavEph::L2Pdata
bool L2Pdata
Definition: GPSLNavEph.hpp:114
gnsstk::GPSLNavEph::asFlag2
bool asFlag2
Anti-spoof flag from SF2 HOW.
Definition: GPSLNavEph.hpp:106
gnsstk::OrbitDataKepler::Toe
CommonTime Toe
Orbit epoch.
Definition: OrbitDataKepler.hpp:171
gnsstk::NavData::signal
NavMessageID signal
Source signal identification for this navigation message data.
Definition: NavData.hpp:175
gnsstk::GPSLNavEph::aodo
long aodo
Age of Data Offset in seconds (-1=uninitialized).
Definition: GPSLNavEph.hpp:115
gnsstk::GPSLNavEph::uraIndex
uint8_t uraIndex
4-bit URA index from subframe 1, word 3.
Definition: GPSLNavEph.hpp:102
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::GPSLNavEph::validate
bool validate() const override
Definition: GPSLNavEph.cpp:76
gnsstk::GPSWeekSecond
Definition: GPSWeekSecond.hpp:56
gnsstk::GPSLNavL2Codes::Invalid1
@ Invalid1
Not a valid broadcast value.
gnsstk::OrbitDataKepler::xmitTime
CommonTime xmitTime
Time of transmission of the start of the data.
Definition: OrbitDataKepler.hpp:170
gnsstk::GPSLNavL2Codes
GPSLNavL2Codes
Codes on L2 channel, per IS-GPS-200 20.3.3.3.1.2.
Definition: GPSLNavL2Codes.hpp:51
gnsstk::SatelliteSystem::GPS
@ GPS
gnsstk::GPSLNavEph::isf3
bool isf3
Integrity status flag from subframe 3.
Definition: GPSLNavEph.hpp:97
gnsstk::NavSignalID::system
SatelliteSystem system
GNSS for this signal.
Definition: NavSignalID.hpp:94
gnsstk::GPSLNavData::alert
bool alert
Alert flag from HOW.
Definition: GPSLNavData.hpp:83
gnsstk::GPSLNavData::validate
bool validate() const override
Definition: GPSLNavData.cpp:58
gnsstk::GPSLNavEph::healthBits
uint8_t healthBits
6 SV health bits from subframe 1, word 3.
Definition: GPSLNavEph.hpp:101
gnsstk::GPSLNavEph::pre3
uint32_t pre3
The TLM preamble from word 1 of subframe 3.
Definition: GPSLNavEph.hpp:93
gnsstk::NavSatelliteID::sat
SatID sat
ID of satellite to which the nav data applies.
Definition: NavSatelliteID.hpp:169
gnsstk::GPSLNavEph::xmit2
CommonTime xmit2
Transmit time for subframe 2.
Definition: GPSLNavEph.hpp:90
gnsstk::CommonTime
Definition: CommonTime.hpp:84
gnsstk::WeekSecond::sow
double sow
Definition: WeekSecond.hpp:155
gnsstk::GPSLNavEph::iode
uint16_t iode
Issue Of Data-Ephemeris.
Definition: GPSLNavEph.hpp:99
gnsstk::GPSLNavEph::fixFit
void fixFit()
Definition: GPSLNavEph.cpp:92
gnsstk::getLegacyFitInterval
short getLegacyFitInterval(const short iodc, const short fiti)
Definition: GNSSconstants.hpp:111
gnsstk::NavFit::beginFit
CommonTime beginFit
Time at beginning of fit interval.
Definition: NavFit.hpp:54
gnsstk::Week::week
int week
Full week number.
Definition: Week.hpp:267
gnsstk::GPSLNavEph::dumpSVStatus
void dumpSVStatus(std::ostream &s) const override
Definition: GPSLNavEph.cpp:190
gnsstk::DumpDetail::Terse
@ Terse
Aptly named, multiple lines of output with no labels.
GPSWeekSecond.hpp
gnsstk::DumpDetail
DumpDetail
Specify level of detail for dump output.
Definition: DumpDetail.hpp:51
gnsstk::printTime
std::string printTime(const CommonTime &t, const std::string &fmt)
Definition: TimeString.cpp:64
gnsstk::GPSLNavEph::asFlag3
bool asFlag3
Anti-spoof flag from SF3 HOW.
Definition: GPSLNavEph.hpp:107
gnsstk::SV_ACCURACY_GPS_MAX_INDEX_VALUE
const int SV_ACCURACY_GPS_MAX_INDEX_VALUE
constant for the max array index in sv accuracy table
Definition: GPS_URA.hpp:57
std
Definition: Angle.hpp:142
gnsstk::NavMessageType::Ephemeris
@ Ephemeris
Precision orbits for the transmitting SV.
gnsstk::GPSLNavEph::iodc
uint16_t iodc
Issue Of Data-Clock for the ephemeris.
Definition: GPSLNavEph.hpp:98
gnsstk::NavData::getSVN
bool getSVN(const SatID &sat, const gnsstk::CommonTime &when, std::string &svn) const
Definition: NavData.hpp:150
GPSLNavEph.hpp
gnsstk::OrbitDataKepler::health
SVHealth health
SV health status.
Definition: OrbitDataKepler.hpp:173
gnsstk::ura2accuracy
double ura2accuracy(short ura) noexcept
Definition: GPS_URA.hpp:124
gnsstk::GPSLNavEph::pre2
uint32_t pre2
The TLM preamble from word 1 of subframe 2.
Definition: GPSLNavEph.hpp:92
TimeString.hpp
gnsstk::GPSLNavEphIODCComp::operator()
bool operator()(const std::shared_ptr< GPSLNavEph > lhs, const std::shared_ptr< GPSLNavEph > rhs) const
Definition: GPSLNavEph.cpp:241
gnsstk::OrbitDataKepler::dump
void dump(std::ostream &s, DumpDetail dl) const override
Definition: OrbitDataKepler.cpp:61
gnsstk::GPSLNavEph::tgd
double tgd
Ionospheric group delay in seconds.
Definition: GPSLNavEph.hpp:103
gnsstk::GPSLNavEph::getUserTime
CommonTime getUserTime() const override
Definition: GPSLNavEph.cpp:84
gnsstk::GPSLNavEph::alert3
bool alert3
Alert flag from SF3 HOW.
Definition: GPSLNavEph.hpp:105


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:39