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 #include <iostream>
40 #include "TestUtil.hpp"
41 #include "OrbElem.hpp"
42
43 using namespace std;
44
45 /** Threshold for how much different our velocities can be between
46 * being computed directly via svXvt and computed via differencing
47 * svXvt positions over time. */
48 double velDiffThresh = 0.0008;
49
50 // we have to make a class that isn't abstract to test with.
51 class OrbElemNonAbstract : public gpstk::OrbElem
52 {
53 public:
54 OrbElemNonAbstract() = default;
clone() const55 gpstk::OrbElem* clone() const override
56 { return nullptr; }
getName() const57 std::string getName() const override
58 { return "foo"; }
getNameLong() const59 std::string getNameLong() const override
60 { return "bar"; }
adjustBeginningValidity()61 void adjustBeginningValidity() override
62 { GPSTK_ASSERT(false); } // don't call this.
dumpTerse(std::ostream & s=std::cout) const63 void dumpTerse(std::ostream& s = std::cout) const
64 override
65 { s << "terse" << endl; }
66 };
67
68
69 class OrbElem_T
70 {
71 public:
72 unsigned testSvXvt();
73 };
74
75
76 unsigned OrbElem_T ::
testSvXvt()77 testSvXvt()
78 {
79 TUDEF("OrbElem", "svXvt");
80 // Hard code orbital parameters mostly so we can copy and paste
81 // the data into other similar tests with minimal changes.
82 OrbElemNonAbstract oe;
83 oe.Cuc = -.324845314026e-05;
84 oe.Cus = .101532787085e-04;
85 oe.Crc = .168968750000e+03;
86 oe.Crs = -.646250000000e+02;
87 oe.Cic = .320374965668e-06;
88 oe.Cis = .117346644402e-06;
89 oe.M0 = -.136404614938e+01;
90 oe.dn = .489591822036e-08;
91 oe.dndot = 0;
92 oe.ecc = .146582192974e-01;
93 oe.A = .515359719276e+04 * .515359719276e+04;
94 oe.Adot = 0;
95 oe.OMEGA0 = -.296605403382e+01;
96 oe.i0 = .941587707856e+00;
97 oe.w = -.224753761329e+01;
98 oe.OMEGAdot = -.804390648956e-08;
99 oe.idot = .789318592573e-10;
100 oe.ctToc = gpstk::CivilTime(2015,7,19,1,59,28.0,gpstk::TimeSystem::GPS);
101 oe.af0 = .579084269702e-03;
102 oe.af1 = .227373675443e-11;
103 oe.af2 = .000000000000e+00;
104 oe.dataLoadedFlag = true;
105 oe.satID = gpstk::SatID(2, gpstk::SatelliteSystem::GPS);
106 oe.ctToe = gpstk::GPSWeekSecond(1854,.716800000000e+04);
107 oe.setHealthy(true);
108 // iode .700000000000e+01
109 // codes on L2 .100000000000e+01
110 // L2 P data .000000000000e+00
111 // sv accuracy .240000000000e+01
112 // sv health .000000000000e+00
113 // tgd -.204890966415e-07
114 // iodc .700000000000e+01
115 // xmit time .360000000000e+04
116 // fit int .400000000000e+01
117 bool testFailed = false;
118 try
119 {
120 // first compute Xvt
121 static const unsigned SECONDS = 7200;
122 gpstk::Xvt zeroth_array[SECONDS];
123 for (unsigned ii = 0; ii < SECONDS; ii++)
124 {
125 zeroth_array[ii] = oe.svXvt(oe.ctToc + ii);
126 }
127 // then compute first derivative of position, i.e. velocity
128 gpstk::Triple deriv[SECONDS];
129 double h = 1; // time step size in seconds
130 for (unsigned ii = 0; ii < SECONDS; ii++)
131 {
132 if (ii == 0)
133 {
134 deriv[ii] = (1/h)*(-1.5*zeroth_array[ii].getPos() +
135 2.0*zeroth_array[ii+1].getPos() -
136 0.5*zeroth_array[ii+2].getPos());
137 }
138 else if ((ii == 1) || (ii == (SECONDS-2)))
139 {
140 deriv[ii] = (1/h)*(-0.5*zeroth_array[ii-1].getPos() +
141 0.5*zeroth_array[ii+1].getPos());
142 }
143 else if (ii == (SECONDS-1))
144 {
145 deriv[ii] = (1/h)*(0.5*zeroth_array[ii-2].getPos() -
146 2.0*zeroth_array[ii-1].getPos() +
147 1.5*zeroth_array[ii].getPos());
148 }
149 else
150 {
151 deriv[ii] = (1/h)*((1.0/12.0)*zeroth_array[ii-2].getPos() -
152 (2.0/3.0)*zeroth_array[ii-1].getPos() +
153 (2.0/3.0)*zeroth_array[ii+1].getPos() -
154 (1.0/12.0)*zeroth_array[ii+2].getPos());
155 }
156 }
157 // then check the difference between derived and computed velocity
158 for (unsigned ii = 0; ii < SECONDS; ii++)
159 {
160 double derivedMag = deriv[ii].mag();
161 double computedMag = zeroth_array[ii].getVel().mag();
162 // If you want to print the data e.g. to plot, uncomment
163 // this stream output statement and comment out tbe break
164 // statement below.
165 // Just don't check it in that way, please.
166 // cerr << ii << " " << (computedMag - derivedMag) << endl;
167 if (fabs(computedMag - derivedMag) > velDiffThresh)
168 {
169 // no sense in printing 7200 success/fail messages.
170 testFailed = true;
171 break;
172 }
173 }
174 if (testFailed)
175 {
176 TUFAIL("computed velocity is significantly different from derived"
177 " velocity");
178 }
179 else
180 {
181 TUPASS("velocity check");
182 }
183 }
184 catch (gpstk::Exception& exc)
185 {
186 cerr << exc;
187 TUFAIL("Exception");
188 }
189 catch (...)
190 {
191 TUFAIL("Exception");
192 }
193 TURETURN();
194 }
195
196
main()197 int main()
198 {
199 unsigned total = 0;
200 OrbElem_T testClass;
201 total += testClass.testSvXvt();
202
203 cout << "Total Failures for " << __FILE__ << ": " << total << endl;
204 return total;
205 }
206