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 ClockSatStore.hpp Store a tabular list of clock data (bias, 40 * drift, accel) for several satellites, and compute values at any 41 * timetag from this table. Inherits TabularSatStore. This class is 42 * not virtual and could be used as is, however note there is no 43 * FileStore, and no data file input (loadFile()), but there are 44 * addData() routines. */ 45 46 #ifndef GPSTK_CLOCK_SAT_STORE_INCLUDE 47 #define GPSTK_CLOCK_SAT_STORE_INCLUDE 48 49 #include <map> 50 #include <iostream> 51 52 #include "Exception.hpp" 53 #include "SatID.hpp" 54 #include "CommonTime.hpp" 55 #include "TabularSatStore.hpp" 56 #include "FileStore.hpp" 57 58 namespace gpstk 59 { 60 /// @ingroup GNSSEph 61 //@{ 62 63 /** Data record for storing clock data. See note on units in 64 * class ClockSatStore. */ 65 typedef struct ClockDataRecord 66 { 67 double bias, sig_bias; ///< clock bias and sigma 68 double drift, sig_drift; ///< clock drift and sigma 69 double accel, sig_accel; ///< clock acceleration and sigma 70 } ClockRecord; 71 72 /// Output stream operator is used by dump() in TabularSatStore 73 std::ostream& operator<<(std::ostream& os, const ClockRecord& rec) throw(); 74 75 // This is a helper for SWIG processing - it needs a template 76 // instation of the base type of ClockSatStore before it is 77 // used, so this statement must be between the ClockDataRecord 78 // and ClockSatStore declarations. 79 #ifdef SWIG 80 %template(TabularSatStore_ClockRecord) gpstk::TabularSatStore<gpstk::ClockRecord>; 81 #endif 82 83 /** Store a table of data vs time for each of several 84 * satellites. The data are stored as ClockRecords, one for 85 * each (satellite,time) pair. The getValue(sat, t) routine 86 * interpolates the table for sat at time t and returns the 87 * result as a DataRecord object. 88 * @note this class (dump()) requires that 89 * operator<<(DataRecord) be defined, unless dump() is 90 * declared and defined in this class. 91 * @note It is assumed that the units of the quanitities are 92 * 'coordinated' meaning that units(drift) == units(bias)/sec, 93 * units(acc) == units(drift)/s/s and units(sigX) == 94 * units(X). This assumption is critical only when 95 * interpolation is used to estimate X/sec from X data. No 96 * other assumptions are made about units. 97 * @note SP3 data (in the file and in SP3Data) are NOT 98 * coordinated; users and derived classes must deal with units 99 * consistently. */ 100 class ClockSatStore : public TabularSatStore<ClockRecord> 101 { 102 103 // member data 104 protected: 105 106 /// flag indicating whether acceleration data is present 107 bool haveClockAccel; 108 109 /** Type of interpolation: 1=linear, 2=Lagrange, 3=numerical 110 * derivative? */ 111 int interpType; 112 113 /** Order of Lagrange interpolation; should be even, is 114 * forced to be even in setInterpolationOrder (for linear 115 * interpolation it is 2). */ 116 unsigned int interpOrder; 117 118 /// Store half the interpolation order, for convenience 119 unsigned int Nhalf; 120 121 /// Flag to reject bad clock data; default true 122 bool rejectBadClockFlag; 123 124 // member functions 125 public: 126 127 /// Default constructor ClockSatStore()128 ClockSatStore() throw() : haveClockAccel(false), 129 interpType(2), Nhalf(5), 130 rejectBadClockFlag(true) 131 { 132 // @note if interpType = 1, interpOrder = 2 (linear) 133 interpOrder = 2*Nhalf; 134 haveClockBias = true; 135 haveClockDrift = havePosition = haveVelocity = false; 136 } 137 138 /// Destructor ~ClockSatStore()139 virtual ~ClockSatStore() {}; 140 hasClockAccel() const141 bool hasClockAccel() const throw() { return haveClockAccel; } 142 143 /** Return value for the given satellite at the given time 144 * (usually via interpolation of the data table). This 145 * interface from TabularSatStore. 146 * @param[in] sat the SatID of the satellite of interest 147 * @param[in] ttag the time (CommonTime) of interest 148 * @return object of type ClockRecord containing the data value(s). 149 * @throw InvalidRequest if data value cannot be computed, 150 * for example because 151 * a) the time t does not lie within the time limits of the 152 * data table 153 * b) checkDataGap is true and there is a data gap 154 * c) checkInterval is true and the interval is larger than 155 * maxInterval */ 156 virtual ClockRecord getValue(const SatID& sat, const CommonTime& ttag) 157 const; 158 159 /** Return the clock bias for the given satellite at the given time 160 * @param[in] sat the SatID of the satellite of interest 161 * @param[in] ttag the time (CommonTime) of interest 162 * @return double the clock bias 163 * @throw InvalidRequest if bias cannot be computed, for 164 * example because 165 * a) the time t does not lie within the time limits of the 166 * data table 167 * b) checkDataGap is true and there is a data gap 168 * c) checkInterval is true and the interval is larger than 169 * maxInterval */ 170 double getClockBias(const SatID& sat, const CommonTime& ttag) 171 const; 172 173 /** Return the clock drift for the given satellite at the given time 174 * @param[in] sat the SatID of the satellite of interest 175 * @param[in] ttag the time (CommonTime) of interest 176 * @return double the clock drift 177 * @throw InvalidRequest if drift cannot be computed, for 178 * example because 179 * a) the time t does not lie within the time limits of the 180 * data table 181 * b) checkDataGap is true and there is a data gap 182 * c) checkInterval is true and the interval is larger than 183 * maxInterval 184 * d) there is no drift data in the store */ 185 double getClockDrift(const SatID& sat, const CommonTime& ttag) 186 const; 187 188 /** Dump information about the object to an ostream. 189 * @param[in] os ostream to receive the output; defaults to std::cout 190 * @param[in] detail integer level of detail to provide; 191 * allowed values are: 192 * 0: number of satellites, time step and time limits, flags, 193 * gap and interval flags and values, and file information 194 * 1: number of data/sat 195 * 2: above plus all the data tables */ dump(std::ostream & os=std::cout,int detail=0) const196 virtual void dump(std::ostream& os = std::cout, int detail = 0) const throw() 197 { 198 os << "Dump of ClockSatStore(" << detail << "):\n"; 199 os << " This store " 200 << (haveClockAccel ? "contains":" does not contain") 201 << " clock acceleration data." << std::endl; 202 os << " Interpolation is "; 203 if(interpType == 2) 204 os << "Lagrange, of order " << interpOrder 205 << " (" << Nhalf << " points on each side)" << std::endl; 206 else 207 os << "Linear." << std::endl; 208 TabularSatStore<ClockRecord>::dump(os,detail); 209 os << "End dump of ClockSatStore.\n"; 210 } 211 212 /** Add a complete ClockRecord to the store; this is the 213 * preferred method of adding data to the tables. 214 * @note If these addXXX() routines are used more than once 215 * for the same record (sat,ttag), be aware that since ttag 216 * is used as they key in a std::map, the value used must 217 * be EXACTLY the same in all calls; (numerical noise could 218 * cause the std::map to consider two "equal" ttags as 219 * different). 220 * @throw InvalidRequest 221 */ 222 void addClockRecord(const SatID& sat, const CommonTime& ttag, 223 const ClockRecord& rec); 224 225 /** Add clock bias data (only) to the store 226 * @throw InvalidRequest 227 */ 228 void addClockBias(const SatID& sat, const CommonTime& ttag, 229 const double& bias, const double& sig=0.0); 230 231 /** Add clock drift data (only) to the store 232 * @throw InvalidRequest 233 */ 234 void addClockDrift(const SatID& sat, const CommonTime& ttag, 235 const double& drift, const double& sig=0.0); 236 237 /** Add clock acceleration data (only) to the store 238 * @throw InvalidRequest 239 */ 240 void addClockAcceleration(const SatID& sat, const CommonTime& ttag, 241 const double& accel, const double& sig=0.0); 242 243 /// Get current interpolation order. getInterpolationOrder(void)244 unsigned int getInterpolationOrder(void) throw() 245 { return interpOrder; } 246 247 /** Set the interpolation order; this routine forces the 248 * order to be even. */ setInterpolationOrder(unsigned int order)249 void setInterpolationOrder(unsigned int order) throw() 250 { 251 if(interpType == 2) Nhalf = (order+1)/2; 252 else Nhalf = 1; 253 interpOrder = 2*Nhalf; 254 } 255 256 /** Set the flag; if true then bad position values are rejected when 257 * adding data to the store. */ rejectBadClocks(const bool flag)258 void rejectBadClocks(const bool flag) 259 { rejectBadClockFlag = flag; } 260 261 /// Set the type of interpolation to Lagrange (default) setLagrangeInterp(void)262 void setLagrangeInterp(void) throw() 263 { interpType = 2; setInterpolationOrder(10); } 264 265 /// Set the type of interpolation to linear. Note that setLinearInterp(void)266 void setLinearInterp(void) throw() 267 { interpType = 1; setInterpolationOrder(2); } 268 269 }; // end class ClockSatStore 270 271 //@} 272 273 } // End of namespace gpstk 274 275 #endif // GPSTK_CLOCK_SAT_STORE_INCLUDE 276