1 //==============================================================================
2 //
3 //  This file is part of GPSTk, the GPS Toolkit.
4 //
5 //  The GPSTk 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 GPSTk 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 GPSTk; 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-2020, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 //  This software was developed by Applied Research Laboratories at the
28 //  University of Texas at Austin, under contract to an agency or agencies
29 //  within the U.S. Department of Defense. The U.S. Government retains all
30 //  rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 //  Pursuant to DoD Directive 523024
33 //
34 //  DISTRIBUTION STATEMENT A: This software has been approved for public
35 //                            release, distribution is unlimited.
36 //
37 //==============================================================================
38 
39 /// @file QZSEphemeris.cpp Encapsulates the QZSS broadcast ephemeris and clock.
40 /// Inherits OrbitEph, which does most of the work; this class adds health and
41 /// accuracy information, fit interval, ionospheric correction terms and data
42 /// flags.
43 
44 #include <string>
45 #include "Exception.hpp"
46 #include "QZSWeekSecond.hpp"
47 #include "TimeString.hpp"
48 
49 #include "QZSEphemeris.hpp"
50 
51 using namespace std;
52 
53 namespace gpstk
54 {
55    // Returns true if the time, ct, is within the period of validity of
56    // this OrbitEph object.
57    // @throw Invalid Request if the required data has not been stored.
isValid(const CommonTime & ct) const58    bool QZSEphemeris::isValid(const CommonTime& ct) const
59    {
60       try {
61          if(ct >= beginValid && ct <= endValid) return true;
62          return false;
63       }
64       catch(Exception& e) { GPSTK_RETHROW(e); }
65    }
66 
67    // This function returns the health status of the SV.
isHealthy(void) const68    bool QZSEphemeris::isHealthy(void) const
69    {
70       try {
71          OrbitEph::isHealthy();     // ignore the return value; for dataLoaded check
72 
73          // health is a bit map (0==good), 5 bits (MSB to LSB) applying to signals:
74          //  (L1C/A)(L2C)(L5)(L1C)(LEX). Cf IS-QZSS 5.2.2.2.3 and Table 5.1.2-1 pg 50
75          // Thus health == 1 means all are healthy except LEX
76          //if((health & 0x1)==0) return true;    // LEX is healthy
77          //if((health & 0x2)==0) return true;    // L1C is healthy
78          //if((health & 0x4)==0) return true;    // L5 is healthy
79          //if((health & 0x8)==0) return true;    // L2C is healthy
80          //if((health & 0x10)==0) return true;   // L1C/A is healthy
81 
82          if((health & 0x1E)==0) return true;   // all but LEX
83          return false;
84       }
85       catch(Exception& e) { GPSTK_RETHROW(e); }
86    }
87 
88    // Determine the health by signal, where
89    //    which = 5 4 3 2 1 as signal = L1C/A L2C L5 L1C LEX.
90    // Cf IS-QZSS 5.2.2.2.3 and Table 5.1.2-1 pg 50
isHealthy(const int which) const91    bool QZSEphemeris::isHealthy(const int which) const
92    {
93       try {
94          OrbitEph::isHealthy();     // ignore the return value; for dataLoaded check
95 
96          // health is a bit map (0==good), 5 bits (MSB to LSB) applying to signals:
97          //  (L1C/A)(L2C)(L5)(L1C)(LEX). Cf IS-QZSS 5.2.2.2.3 and Table 5.1.2-1 pg 50
98          // Thus health == 1 means all are healthy except LEX
99          switch(which) {
100             case 5:     // L1C/A
101                if((health & 0x10)==0) return true;
102                break;
103             case 4:     // L2C
104                if((health & 0x08)==0) return true;
105                break;
106             case 3:     // L5
107                if((health & 0x04)==0) return true;
108                break;
109             case 2:     // L1C
110                if((health & 0x02)==0) return true;
111                break;
112             case 1:     // LEX
113                if((health & 0x01)==0) return true;
114                break;
115             default:
116                break;
117          }
118          return false;
119       }
120       catch(Exception& e) { GPSTK_RETHROW(e); }
121    }
122 
123    // adjustBeginningValidity determines the beginValid and endValid times.
124    // @throw Invalid Request if the required data has not been stored.
125    //
126    // NOTE: The QZSS ICD does not make the same sort of promises about
127    // the relationship of t-sub-oe and beginning time of transmission as
128    // GPS.  Therefore, we should NOT adjust the beginValid time to be
129    // anything other than the earliest tranmit time we recorded.
adjustValidity(void)130    void QZSEphemeris::adjustValidity(void)
131    {
132       try {
133          OrbitEph::adjustValidity();   // for dataLoaded check
134          beginValid = transmitTime;
135          endValid = ctToe + fitDuration*1800.0;     // hours*3600/2
136       }
137       catch(Exception& e) { GPSTK_RETHROW(e); }
138    }
139 
140    // Dump the orbit, etc information to the given output stream.
141    // @throw Invalid Request if the required data has not been stored.
dumpBody(std::ostream & os) const142    void QZSEphemeris::dumpBody(std::ostream& os) const
143    {
144       try {
145          OrbitEph::dumpBody(os);
146 
147          os << "           QZSS-SPECIFIC PARAMETERS\n"
148             << scientific << setprecision(8)
149             << "Tgd (L1/L2) : " << setw(16) << Tgd << " meters" << endl
150             << "HOW time    : " << setw(6) << HOWtime << " (sec of QZS week "
151                << setw(4) << static_cast<QZSWeekSecond>(ctToe).getWeek() << ")"
152             << "   fitDuration: " << setw(2) << fitDuration << " hours" << endl
153             << "TransmitTime: " << OrbitEph::timeDisplay(transmitTime) << endl
154             << "Accuracy    : " << fixed << setprecision(2)
155             << getAccuracy() << " meters" << endl
156             << "IODC: " << IODC << "   IODE: " << IODE << "   health: " << health
157             << "   codeflags: " << codeflags << "   L2Pdata: " << L2Pdata
158             << endl;
159       }
160       catch(Exception& e) { GPSTK_RETHROW(e); }
161    }
162 
163 } // end namespace
164