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 ClockModel.cpp
41  * Implement clock modeling for program DDBase.
42  */
43 
44 //------------------------------------------------------------------------------------
45 // includes
46 // system
47 
48 // GPSTk
49 
50 // DDBase
51 #include "DDBase.hpp"
52 #include "index.hpp"
53 
54 //------------------------------------------------------------------------------------
55 using namespace std;
56 using namespace gpstk;
57 
58 //------------------------------------------------------------------------------------
59 // prototypes -- for this module only
60 /**
61  * @throw Exception
62  */
63 int RemoveClockJumps(void);             // here
64 /**
65  * @throw Exception
66  */
67 int OutputClockData(void);              // DataOutput.cpp
68 
69 //------------------------------------------------------------------------------------
ClockModel(void)70 int ClockModel(void)
71 {
72 try {
73    int iret=0;
74 
75    if(CI.Verbose) oflog << "BEGIN ClockModel()"
76       << " at total time " << fixed << setprecision(3)
77       << double(clock()-totaltime)/double(CLOCKS_PER_SEC) << " seconds."
78       ; //<< endl;
79    oflog << " -- ClockModel() is not yet implemented." << endl;
80 
81    // TD remove discontinuitites in the clock model by looking at second differences
82    // of the Station.ClockBuffer data. These are caused when the number of satellites
83    // in the PR solution changes. Also remove an average by summing up the weighted
84    // average jump removed.
85    //iret = RemoveClockJumps();
86    //if(iret) return iret;
87 
88    // output the clock data - Station.ClockBuffer and RxTimeOffset
89    // this may be called just before abort in ReadAndProcessRawData, if PRS is far off
90    OutputClockData();
91 
92    return iret;
93 }
94 catch(Exception& e) { GPSTK_RETHROW(e); }
95 catch(std::exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
96 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
97 }   // end ClockModel()
98 
99 //------------------------------------------------------------------------------------
RemoveClockJumps(void)100 int RemoveClockJumps(void)
101 {
102 try {
103    if(CI.Verbose) oflog << "BEGIN RemoveClockJumps()" << endl;
104 
105    bool jump;
106    int n,iprev;
107    size_t i;
108    double curr,prev = 0,prevprev,sdiff,prevsdiff,frac,offset;
109    CommonTime tt;
110    map<int,double> jumps;
111    map<string,Station>::iterator it;
112 
113    for(it=Stations.begin(); it != Stations.end(); it++) {
114          // loop over epochs
115       //offset = 0.0;
116       jumps.clear();
117       for(n=0,i=0; i<it->second.ClockBuffer.size(); i++) {
118          curr = it->second.ClockBuffer[i];
119          // when PRS fails, 0.0 is pushed into ClockBuffer
120          if(curr == 0.0) continue;
121          tt = FirstEpoch + it->second.CountBuffer[i]*CI.DataInterval;
122 
123          // second difference at (i) is (i)-2(i-1)+(i-2) ; ignore gaps in time
124          if(n > 1) {
125             jump = false;
126             //const double fdiff = curr-prev;
127             sdiff = curr-2*prev+prevprev;
128             frac = 2*fabs(fabs(sdiff)-fabs(prevsdiff))/(fabs(sdiff)+fabs(prevsdiff));
129             if(n>2 && fabs(sdiff)>0.3 && fabs(prevsdiff)>0.3
130                    && sdiff*prevsdiff<0. && frac < 0.15) {
131                jump = true;
132                jumps[iprev] = prev-prevprev;
133                oflog << "Define jump at " << iprev << endl;
134                //offset += prev-prevprev;
135             }
136             //curr = it->second.ClockBuffer[i] += offset;
137 
138             //oflog << "C2D " << it->first << " " << tt.printf("%4F %10.3g")
139             //   << fixed << setprecision(6)
140             //   << " " << setw(10) << curr
141             //   << " " << setw(10) << fdiff
142             //   << " " << setw(10) << sdiff;
143             //if(jump) oflog << " jump " << frac;
144             //oflog << endl;
145 
146             prevsdiff = sdiff;
147          }
148 
149          iprev = i;
150          prevprev = prev;
151          prev = curr;
152          n++;
153 
154       }
155 
156       jump = false;
157       offset = 0.0;
158       map<int,double>::const_iterator kt = jumps.begin();
159       for(n=0,i=0; i<it->second.ClockBuffer.size(); i++) {
160          curr = it->second.ClockBuffer[i];
161          if(curr == 0.0) continue;
162          tt = FirstEpoch + it->second.CountBuffer[i]*CI.DataInterval;
163          if(kt != jumps.end() && kt->first == (int)i) {
164             oflog << "Found jump at " << i << endl;
165             jump = true;
166             offset += kt->second;
167             kt++;
168          }
169          it->second.ClockBuffer[i] -= offset;
170 
171          //oflog << "C2DF " << it->first << " " << tt.printf("%4F %10.3g")
172          //   << fixed << setprecision(6)
173          //   << " " << setw(10) << curr
174          //   << " " << setw(10) << curr-offset;
175          //if(jump) { oflog << " jump " << setw(10) << offset; jump=false; }
176          //oflog << endl;
177       }
178    }
179 
180    return 0;
181 }
182 catch(Exception& e) { GPSTK_RETHROW(e); }
183 catch(std::exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
184 catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
185 }   // end RemoveClockJumps()
186 
187 //------------------------------------------------------------------------------------
188 //------------------------------------------------------------------------------------
189