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 ObsClockModel.hpp
41  * Yet another abstract class used to define an interface to a model that
42  * accepts GPS observation datat and determines a clock model from it. It
43  * mainly adds the ability to specify the characteristcs of the observations
44  * that are to be accpeted into the model. It also defines a function that
45  * accepts Observed Range Deviations and computes the mean of these (that
46  * meet the selection criteria) as an estimate of the receiver clock.
47  */
48 
49 #ifndef OBSCLOCKMODEL_HPP
50 #define OBSCLOCKMODEL_HPP
51 
52 #include <map>
53 #include "Exception.hpp"
54 #include "gps_constants.hpp"
55 
56 #include "Stats.hpp"
57 #include "ClockModel.hpp"
58 #include "ORDEpoch.hpp"
59 
60 
61 namespace gpstk
62 {
63       /// @ingroup ClockModel
64       //@{
65 
66    class ObsClockModel : public ClockModel
67    {
68    public:
69       enum SvMode
70       {
71          IGNORE,   ///< do not include ORDs from this SV
72          HEALTHY,  ///< include ORDs from this SV if it is healthy
73          ALWAYS    ///< always include ORDs from this SV
74       };
75 
76       enum SvStatus
77       {
78          USED,      ///< ORD used in the clock bias computation
79          MANUAL,    ///< ORD removed from computation by user request
80          SVHEALTH,  ///< ORD removed from computation because SV unhealthy
81          ELEVATION, ///< ORD removed from computation because SV elevation < mask
82          WONKY,     ///< ORD removed due to being flagged wonky
83          SIGMA      ///< ORD removed from computation because it was outlier
84       };
85 
86          /// defines a store for each SV's #SvMode
87       typedef std::map<SatID, SvMode> SvModeMap;
88 
89          /// defines a store for each SV's #SvStatus
90       typedef std::map<SatID, SvStatus> SvStatusMap;
91 
ObsClockModel(double sigma=2,double elmask=0,SvMode mode=ALWAYS)92       ObsClockModel(double sigma = 2, double elmask = 0, SvMode mode = ALWAYS)
93             : sigmam(sigma), elvmask(elmask), useWonkyData(false)
94       {
95          status.clear();
96          setSvMode(mode);
97       }
98 
99          /**
100           * @throw InvalidValue
101           */
102       virtual void addEpoch(const ORDEpoch& re) = 0;
103 
104          // set accessor methods ----------------------------------------------
105 
106          /**
107           * set a SvMode for all SVs.
108           * @param right #SvModeMap
109           * @return a reference to this object
110           */
111       ObsClockModel& setSvModeMap(const SvModeMap& right) throw();
112 
113          /**
114           * set the SvMode for a particular SV.
115           * @param prn Sv number of the SV
116           * @param mode #SvMode for the SV
117           * @return a reference to this object
118           */
setSvMode(const SatID & svid,const SvMode & mode)119       ObsClockModel& setSvMode(const SatID& svid, const SvMode& mode) throw()
120       { modes[svid] = mode; return *this; }
121 
122          /**
123           * set the SvMode for all SVs
124           * @param mode #SvMode for the SVs
125           * @return a reference to this object
126           */
setSvMode(const SvMode & mode)127       ObsClockModel& setSvMode(const SvMode& mode) throw()
128       {
129          for(int prn = 1; prn <= gpstk::MAX_PRN; prn++)
130          {
131             SatID svid(prn, SatelliteSystem::GPS);
132             modes[svid] = mode;
133          }
134          return *this;
135       }
136 
137          /**
138           * set the sigma multiple for ORD stripping.
139           * @param right sigma multiple value
140           * @return a reference to this object
141           */
setSigmaMultiplier(double right)142       ObsClockModel& setSigmaMultiplier(double right) throw()
143       { sigmam = right; return *this; }
144 
145          /**
146           * set the elevation mask angle for ORD stripping.
147           * @param right elevation mask angle value
148           * @return a reference to this object
149           */
setElevationMask(double right)150       ObsClockModel& setElevationMask(double right) throw()
151       { elvmask = right; return *this; }
152 
153          /** Set useWonkyData true and ords that are flagged as wonky
154              will be included in any clock estimation calculations.
155          **/
setUseWonkyData(bool right)156       ObsClockModel& setUseWonkyData(bool right) throw()
157       { useWonkyData = right; return *this; }
158 
159          // get accessor methods ----------------------------------------------
160 
161          /**
162           * get the map indicating how each ORD was used in the bias
163           * computation.
164           * @return a const reference to the #SvStatusMap
165           */
getSvStatusMap() const166       const SvStatusMap& getSvStatusMap() const throw()
167       { return status; };
168 
169          /**
170           * get the status of a particular ORD in the bias computation.
171           * @param prn the PRN number indicating the ORD of interest
172           * @return #SvStatus
173           * @throw ObjectNotFound an ORD for that SV is not in the map
174           */
175       SvStatus getSvStatus(const SatID& svid) const;
176 
177          /**
178           * get the map indicating how to use each ORD in the bias computation.
179           * @return a const reference to the #SvModeMap
180           */
getSvModeMap() const181       const SvModeMap& getSvModeMap() const throw() { return modes; }
182 
183          /**
184           * get how a particular ORD is to be used in the bias computation.
185           * @param prn the Sv number indicating the mode of interest
186           * @return #SvMode
187           * @throw ObjectNotFound a mode for that SV is not in the map
188           */
189       SvMode getSvMode(const SatID& svid) const;
190 
191          /**
192           * returns the sigma multiple value used for ORD stripping.
193           * @return sigma multiple
194           */
getSigmaMultiplier() const195       double getSigmaMultiplier() const throw() { return sigmam; }
196 
197          /**
198           * returns the elevation mask angle used for ORD stripping.
199           * @return elevation mask angle
200           */
getElevationMask() const201       double getElevationMask() const throw() { return elvmask; }
202 
203 
204          /**
205           * return the current value of the userWonkyData flag.
206           */
getUseWonkyData() const207       bool getUseWonkyData() const throw()
208       { return useWonkyData; }
209 
210          /** Computes an average of all ORD in the epoch that pass the
211           * elevation mask, and SvModeMap tests, removes those ORDS
212           * that exceede the sigmam value and returns the resulting
213           * statistics. This is effectivly a simple single epoch clock
214           * model.
215           * @throw InvalidValue */
216       Stats<double> simpleOrdClock(const ORDEpoch& oe);
217 
218       virtual void dump(std::ostream& s, short detail=1) const throw();
219 
operator <<(std::ostream & s,const ObsClockModel & r)220       friend std::ostream& operator<<(std::ostream& s, const ObsClockModel& r)
221       { r.dump(s, 0); return s; };
222 
223    protected:
224 
225       double sigmam;        ///< sigma multiple value for ORD stripping
226       double elvmask;       ///< elevation mask angle for ORD stripping
227       SvStatusMap status;   ///< map of ORD usage in bias computation
228       SvModeMap modes;      ///< map of modes to use ORDs in bias computation
229       bool useWonkyData;    ///< set to use ords that are flagged wonky
230    };
231 
232       //@}
233 
234 }
235 #endif
236