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 OrbitEph.hpp Encapsulates the "least common denominator"
40  * orbit parameters that determine a satellite ephemeris, that is,
41  * clock model, Kepler orbit elements plus harmonic perturbations with
42  * time of ephemeris, satellite ID, and begin and end times of
43  * validity.  Although it can also be used alone, this class is most
44  * often to be used as a base class for a fuller implementation of the
45  * ephemeris and clock, by adding health and accuracy information, fit
46  * interval, ionospheric correction terms and data flags. It serves as
47  * the base class for broadcast ephemerides for GPS, QZSS, Galileo,
48  * and BeiDou, with RINEX Navigation input, among others. */
49 
50 #ifndef GPSTK_ORBITEPH_HPP
51 #define GPSTK_ORBITEPH_HPP
52 
53 #include <string>
54 #include "Exception.hpp"
55 #include "CommonTime.hpp"
56 #include "ObsID.hpp"
57 #include "SatID.hpp"
58 #include "Xvt.hpp"
59 //#include "Rinex3NavData.hpp"
60 
61 namespace gpstk
62 {
63       /** @defgroup GNSSEph GNSS Ephemeris Processing
64        * Tools for processing and computing GNSS SV positions */
65 
66       /// @ingroup GNSSEph
67       //@{
68 
69    class OrbitEph
70    {
71    public:
72          /// Default constuctor
73       OrbitEph();
74 
75          /// Destructor
~OrbitEph(void)76       virtual ~OrbitEph(void) {}
77 
78          /** Create a copy of this object and return a pointer to
79           * it. This function MUST be overridden in any derived class
80           * using the derived class name. */
clone(void) const81       virtual OrbitEph* clone(void) const
82       { return new OrbitEph(*this); }
83 
84          /** Returns true if the time, ct, is within the period of
85           * validity of this OrbitEph object.
86           * @throw Invalid Request if the required data has not been stored. */
87       virtual bool isValid(const CommonTime& ct) const;
88 
89          /** Return true if orbit data have been loaded.
90           * Returns false if no data have been loaded. */
dataLoaded(void) const91       virtual bool dataLoaded(void) const
92       { return dataLoadedFlag; }
93 
94          /// Return a string that will identify the derived class
getName(void) const95       virtual std::string getName(void) const
96       { return std::string("OrbitEph"); }
97 
98          /** This function returns the health status of the
99           * SV. OrbitEph has no health information, so it returns
100           * true; however the derived class should override this
101           * function, computing a meaningful health. */
isHealthy(void) const102       virtual bool isHealthy(void) const
103       {
104          if(!dataLoadedFlag)
105             GPSTK_THROW(InvalidRequest("Data not loaded"));
106          return true;
107       }
108 
109          /** Compute the satellite clock bias (seconds) at the given time
110           * @throw Invalid Request if the required data has not been stored. */
111       double svClockBias(const CommonTime& t) const;
112 
113          /** Compute the satellite clock drift (sec/sec) at the given time
114           * @throw Invalid Request if the required data has not been stored. */
115       double svClockDrift(const CommonTime& t) const;
116 
117          /** Compute satellite position at the given time.
118           * This implements equations of motion as defined in IS-GPS-200.
119           * (This code has its origins in 1980's FORTRAN code that has
120           * been ported to C, then C++, then became part of the gpstk.
121           * The original code was based on IS-GPS-200 Table 20-IV.
122           * In July 2013, the code was modified to conform to Table 30-II
123           * which includes additional time-dependent terms (A(dot)
124           * and delta n(dot)) that are in CNAV but not in LNAV.  These
125           * changes should be backward compatible with LNAV as long as the
126           * Adot and dndot variables are appropriately set to 0.0 by the
127           * LNAV loaders.)
128           * @throw Invalid Request if the required data has not been stored. */
129       Xvt svXvt(const CommonTime& t) const;
130 
131          /** Compute satellite relativity correction (sec) at the given time
132           * @throw Invalid Request if the required data has not been stored. */
133       double svRelativity(const CommonTime& t) const;
134 
135          /** adjustBeginningValidity determines the beginValid and
136           * endValid times.  In OrbitEph it simply assumes a 4-hour
137           * fit interval; however the derived class should override
138           * this function, using an appropriate fit interval.
139           * @throw Invalid Request if the required data has not been stored. */
adjustValidity(void)140       virtual void adjustValidity(void)
141       {
142          if(!dataLoadedFlag) GPSTK_THROW(InvalidRequest("Data not loaded"));
143          if (satID.system == SatelliteSystem::GPS)
144             beginValid = ctToe - 7200.0;
145          endValid = ctToe + 7200.0;
146       }
147 
148          /** Dump the overhead information as a string containing a
149           * single line.
150           * @throw Invalid Request if the required data has not been stored. */
151       virtual std::string asString(void) const;
152 
153          /** Utility routine for dumpBody(); return the time in the
154           * appropriate time system as a string.  Override for other
155           * than GPS time systems.
156           * @param t time to display
157           * @param showHead if true, print only a header (default
158           *   false) */
159       virtual std::string timeDisplay(const CommonTime& t, bool showHead=false)
160          const;
161 
162          /** Dump the overhead information to the given output stream.
163           * @throw Invalid Request if the required data has not been stored. */
164       virtual void dumpHeader(std::ostream& os = std::cout) const;
165 
166          /** Dump the orbit, etc information to the given output stream.
167           * @throw Invalid Request if the required data has not been stored. */
168       virtual void dumpBody(std::ostream& os = std::cout) const;
169 
170          /** Dump the object to the given output stream.
171           * @throw Invalid Request if the required data has not been stored. */
dump(std::ostream & os=std::cout) const172       virtual void dump(std::ostream& os = std::cout) const
173       {
174          dumpHeader(os);
175          dumpBody(os);
176       }
177 
178          /** Define this OrbitEph by converting the given RINEX
179           * navigation data.
180           * @note this will be both overridden and called by the
181           *   derived classes
182           * @note currently has fixes for MGEX data.
183           * @param rnd Rinex3NavData
184           * @return true if OrbitEph was defined, false otherwise */
185          //virtual bool load(const Rinex3NavData& rnd);
186 
187          // member data
188 
189          // overhead
190       bool dataLoadedFlag; ///< True if data is present
191       SatID satID;         ///< Define satellite system and specific SV
192       ObsID obsID;         ///< Defines carrier and tracking code
193       CommonTime ctToe;    ///< Ephemeris epoch
194 
195          // Clock information
196       CommonTime ctToc;    ///< Clock Epoch
197       double af0;          ///< SV clock error (sec)
198       double af1;          ///< SV clock drift (sec/sec)
199       double af2;          ///< SV clock drift rate (sec/sec**2)
200 
201          // Major orbit parameters
202       double M0;           ///< Mean anomaly (rad)
203       double dn;           ///< Correction to mean motion (rad/sec)
204       double ecc;          ///< Eccentricity
205       double A;            ///< Semi-major axis (m)
206       double OMEGA0;       ///< Rt ascension of ascending node (rad)
207       double i0;           ///< Inclination (rad)
208       double w;            ///< Argument of perigee (rad)
209       double OMEGAdot;     ///< Rate of Rt ascension (rad/sec)
210       double idot;         ///< Rate of inclination angle (rad/sec)
211          // Orbit parameters for modernized message
212       double dndot;        ///< Rate of correction to mean motion (rad/sec/sec)
213       double Adot;         ///< Rate of semi-major axis (m/sec)
214 
215          // Harmonic perturbations
216       double Cuc;          ///< Cosine latitude (rad)
217       double Cus;          ///< Sine latitude (rad)
218       double Crc;          ///< Cosine radius (m)
219       double Crs;          ///< Sine radius (m)
220       double Cic;          ///< Cosine inclination (rad)
221       double Cis;          ///< Sine inclination (rad)
222 
223       CommonTime beginValid;  ///< Time at beginning of validity
224       CommonTime endValid;    ///< Time at end of fit validity
225 
226    }; // end class OrbitEph
227 
228       //@}
229 
230       /// Write OrbitEph to output stream
231    std::ostream& operator<<(std::ostream& os, const OrbitEph& eph);
232 
233 } // end namespace
234 
235 #endif // GPSTK_ORBITEPH_HPP
236