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 /**
40  * @file OrbElemStore.hpp
41  * Base class for storing and/or computing position, velocity,
42  * and clock data.  This class is typically extended in order
43  * to implement SV-system specific behavior.  Theoretically,
44  * it could be used to store OrbElemBase objects across multiple
45  * systems, but that would entail moving all the time tags to a
46  * common system.
47  */
48 
49 #ifndef GPSTK_ORBELEMSTORE_HPP
50 #define GPSTK_ORBELEMSTORE_HPP
51 
52 #include <iostream>
53 #include <list>
54 #include <map>
55 
56 #include "CommonTime.hpp"
57 #include "Exception.hpp"
58 #include "OrbElemBase.hpp"
59 #include "SatID.hpp"
60 #include "TimeSystem.hpp"
61 #include "XvtStore.hpp"
62 
63 namespace gpstk
64 {
65       /// @ingroup ephemstore
66       //@{
67 
68       /// Base class for storing and accessing an objects position,
69       /// velocity, and clock data. Also defines a simple interface to remove
70       /// data that has been added.
71    class OrbElemStore : public XvtStore<SatID>
72    {
73    public:
74 
OrbElemStore()75       OrbElemStore()
76       throw()
77       :initialTime(CommonTime::END_OF_TIME),
78          finalTime(CommonTime::BEGINNING_OF_TIME),
79          timeSysForStore(TimeSystem::Any)
80       {
81          initialTime.setTimeSystem(timeSysForStore);
82          finalTime.setTimeSystem(timeSysForStore);
83          setOnlyHealthyFlag(true);
84       }
85 
86          ///
87          /// Notes regarding the rationalize( ) function.
88          /// The timing relationships defined in IS-GPS-200 20.3.4.5 mean
89          /// (1.) The end of validity of a given set of orbital elements
90          /// may be determined by the beginning of transmission of a new
91          /// upload.
92          /// (2.) The beginning of validity of the SECOND set of elements
93          /// following and upload should be Toe-(0.5 fit interval) but
94          /// it is not practical to differentiate between the first and
95          ///
96          /// second set following an upload when only looking at a
97          /// single set of elements.
98          ///
99          /// The rationalize( ) function is a means of addressing these
100          /// shortcomings.   The intention is to load all the navigation
101          /// message data in the store, then call rationalize( ).  The
102          /// function will sweep through the ordered set of elements and
103          /// make appropriate adjustments to beginning and end of
104          /// validity values.  In general, the only changes will
105          /// occur in set of elements immediately before an upload,
106          /// the first set following the upload, and (perhaps) the
107          /// second set following the upload.
108          ///
109       void rationalize( );
110 
111       virtual ~OrbElemStore();
112 
113          /// Returns the position, velocity, and clock offset of the indicated
114          /// object in ECEF coordinates (meters) at the indicated time.
115          /// @param[in] id the object's identifier
116          /// @param[in] t the time to look up
117          /// @return the Xvt of the object at the indicated time
118          /// @throw InvalidRequest If the request can not be completed for any
119          ///    reason, this is thrown. The text may have additional
120          ///    information as to why the request failed.
121       virtual Xvt getXvt(const SatID& id, const CommonTime& t) const;
122 
123          /** Compute the position, velocity and clock offset of the
124           * indicated object in ECEF coordinates (meters) at the
125           * indicated time.
126           * This method functions similarly to getXvt() except that it
127           * does not throw an exception for any reason.  Instead, the
128           * caller is expected to check the value of the "health"
129           * field of the returned Xvt and decide what to do with the
130           * data.
131           * @note This function ignores the onlyHealthy flag.  It is
132           *   up to the caller to examine the state of the health flag
133           *   and decide what to do.
134           * @param[in] id the object's identifier
135           * @param[in] t the time to look up
136           * @return the Xvt of the object at the indicated time */
137       virtual Xvt computeXvt(const SatID& id, const CommonTime& t) const
138          throw();
139 
140          /** Get the satellite health at a specific time.
141           * @param[in] id the object's identifier
142           * @param[in] t the time to look up
143           * @return the health status of the object at the indicated time. */
144       virtual Xvt::HealthStatus getSVHealth(const SatID& id,
145                                             const CommonTime& t) const throw();
146 
147          /// A debugging function that outputs in human readable form,
148          /// all data stored in this object.
149          /// @param[in] s the stream to receive the output; defaults to cout
150          /// @param[in] detail the level of detail to provide
151       virtual void dump(std::ostream& s = std::cout, short detail = 0)
152          const throw();
153 
154          /**
155           * @throw InvalidParameter
156           * @throw Exception
157           */
158       virtual bool addOrbElem(const OrbElemBase* eph);
159 
160          /// Edit the dataset, removing data outside the indicated time interval
161          /// @param[in] tmin defines the beginning of the time interval
162          /// @param[in] tmax defines the end of the time interval
163       virtual void edit(const CommonTime& tmin,
164                         const CommonTime& tmax = CommonTime::END_OF_TIME)
165          throw();
166 
167          /// Clear the dataset, meaning remove all data
168       virtual void clear(void) throw();
169 
170          /// Determine the earliest time for which this object can successfully
171          /// determine the Xvt for any object.
172          /// @return The initial time
173          /// @throw InvalidRequest This is thrown if the object has no data.
getInitialTime() const174       virtual CommonTime getInitialTime() const
175          throw()
176       { return initialTime; }
177 
178 
179          /// Determine the latest time for which this object can successfully
180          /// determine the Xvt for any object.
181          /// @return The final time
182          /// @throw InvalidRequest This is thrown if the object has no data.
getFinalTime() const183       virtual CommonTime getFinalTime() const
184          throw()
185       { return finalTime; }
186 
187          /// Return the number of orbit/clock elements stored in this store.
188       virtual unsigned size() const
189          throw();
190 
velocityIsPresent() const191       virtual bool velocityIsPresent()
192          const throw()
193       { return true; }
194 
195          /// Return true if velocity data is present in the store
hasVelocity() const196       virtual bool hasVelocity() const throw()
197       { return true; }
198 
199          /// Return true if the given SatID is present in the store
200       virtual bool isPresent(const SatID& id) const throw();
201 
202          /// Classes to set/access the store TimeSystem information.
getTimeSystem() const203       TimeSystem getTimeSystem() const { return timeSysForStore; }
setTimeSystem(const TimeSystem ts)204       void setTimeSystem(const TimeSystem ts) { timeSysForStore = ts; }
205 
206          /// Classes to set/test the satellite system list.
207       bool isSatSysPresent(const SatelliteSystem ss) const;
208       void addSatSys(const SatelliteSystem ss);
209       void validSatSystem(const SatID& sat) const;
210       std::list<SatelliteSystem> getValidSystemList() const;
211       void dumpValidSystemList(std::ostream& out) const;
212 
213       /*
214        *  Explanation of find( ) function for OrbElemStore
215        *
216        *  The findOrbElem( ) funtion
217        *  does the best possible job of emulating the choice
218        *  that would be made by a real-time user
219        *
220        *  It is strongly suggested that the user load ALL
221        *  available set of orbital elements into the store,
222        *  regardless of health status.
223        */
224       /// @param sat SatID of satellite of interest
225       /// @param t time with which to search for OrbElemBase
226       /// @return a reference to the desired OrbElemBase
227       /// @throw InvalidRequest object thrown when no OrbElemBase is found
228       const OrbElemBase* findOrbElem( const SatID& sat, const CommonTime& t )
229          const;
230 
231          /// Find an OrbElemBase for the indicated satellite at time
232          /// t. The OrbElemBase chosen is the one with HOW time
233          /// closest to the time t, (i.e. with smallest fabs(t-HOW),
234          /// but still within the fit interval.
235          /// @param sat the SV of interest
236          /// @param t the time of interest
237          /// @return a reference to desired OrbElemBase
238          /// @throw InvalidRequest object thrown when no OrbElemBase is found
239       const OrbElemBase* findNearOrbElem(const SatID& sat, const CommonTime& t)
240          const;
241 
242          /// Find an OrbElemBase for the indicated satellite that has
243          /// a Toe corresponding to time t.  If no such OrbElemBase
244          /// exists in the store, throw an InvalidRequest exception
245          /// @param sat the SV of interest
246          /// @param t the time of interest
247          /// @return a reference to desired OrbElemBase
248          /// @throw InvalidRequest object thrown when no OrbElemBase is found
249       const OrbElemBase* findToe(const SatID& sat, const CommonTime& t)
250          const;
251 
252          /// Return a list of SatID object representing the satellites that
253          /// are contained in the store.
254          /// @return list of SatID objects
255       std::list<gpstk::SatID> getSatIDList() const;
256 
257       virtual std::set<SatID> getIndexSet() const;
258 
259          /// Add all ephemerides to an existing list<OrbElemBase>.
260          /// @return the number of ephemerides added.
261       int addToList( std::list<OrbElemBase*>& v ) const
262          throw();
263 
264          /// This is intended to store sets of unique orbital elements
265          /// for a single SV.  The key is the beginning of the period
266          /// of validity for each set of elements.
267       typedef std::map<CommonTime, OrbElemBase*> OrbElemMap;
268 
269          /** Returns a map of the ephemerides available for the specified
270           * satellite.  Note that the return is specifically chosen as a
271           * const reference.  The intent is to provide "read only" access
272           * for analysis.  If the map needs to be modified, see other methods.
273           * @throw InvalidRequest
274           */
275       const OrbElemMap& getOrbElemMap( const SatID& sat ) const;
276 
277    protected:
278 
279          /// This is intended to hold all unique OrbElemBase objects for each SV
280          /// The key is the prn of the SV.
281       typedef std::map<SatID, OrbElemMap> UBEMap;
282 
283          /// The map where all EngEphemerides are stored.
284       UBEMap ube;
285 
286       CommonTime initialTime; //< Time of the first OrbElemBase in the store
287       CommonTime finalTime;   //< Time of the last OrbElemBase in the store
288 
289          // List of the satellite systems stored in this store.  Typically
290          // only one and set by descendents.
291       std::list<SatelliteSystem> sysList;
292 
293          // TimeSystem used in this store.  Set by default to "Any", but
294          // typically overridden by descendents.
295       TimeSystem timeSysForStore;
296 
297          // Here is a method to simplify the .cpp
updateInitialFinal(const OrbElemBase * eph)298       void updateInitialFinal(const OrbElemBase* eph)
299       {
300          if (eph->beginValid<initialTime)
301             initialTime = eph->beginValid;
302 
303          if (eph->endValid>finalTime)
304             finalTime = eph->endValid;
305       }
306 
307    }; // end class
308 
309       //@}
310 
311 } // namespace
312 
313 #endif
314