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 "AlmOrbit.hpp"
40 #include "Xvt.hpp"
41 #include "GPSWeekSecond.hpp"
42 #include "CommonTime.hpp"
43 #include "TestUtil.hpp"
44 #include <iostream>
45 #include <sstream>
46
47 using namespace std;
48 using namespace gpstk;
49
50 /** Threshold for how much different our velocities can be between
51 * being computed directly via svXvt and computed via differencing
52 * svXvt positions over time. */
53 double velDiffThresh = 0.0008;
54
55 class AlmOrbit_T: public AlmOrbit
56 {
57 public:
AlmOrbit_T()58 AlmOrbit_T()
59 {
60 eps = 1E-12; // Default Constructor, set the precision value
61 }
~AlmOrbit_T()62 ~AlmOrbit_T() {} // Default Desructor
63
64 //=============================================================================
65 // Test will check the initialization of AlmOrbit objects
66 //=============================================================================
initializationTest(void)67 int initializationTest(void)
68 {
69 TUDEF("AlmOrbit", "Default Constructor");
70 std::string testMesg;
71
72 gpstk::AlmOrbit empty;
73
74 //--------------------------------------------------------------------
75 //Does the default constructor function correctly?
76 //--------------------------------------------------------------------
77 testMesg = "PRN not initialized to 0";
78 TUASSERTE(short, 0, empty.getPRN());
79 testMesg = "Ecc not initialized to 0";
80 TUASSERTFEPS(0, empty.getecc(), eps);
81 testMesg = "Offset not initialized to 0";
82 TUASSERTFEPS(0, empty.geti_offset(), eps);
83 testMesg = "OMEGAdot not initialized to 0";
84 TUASSERTFEPS(0, empty.getOMEGAdot(), eps);
85 testMesg = "Ahalf not initialized to 0";
86 TUASSERTFEPS(0, empty.getAhalf(), eps);
87 testMesg = "OMEGA0 not initialized to 0";
88 TUASSERTFEPS(0, empty.getOMEGA0(), eps);
89 testMesg = "W not initialized to 0";
90 TUASSERTFEPS(0, empty.getw(), eps);
91 testMesg = "M0 not initialized to 0";
92 TUASSERTFEPS(0, empty.getM0(), eps);
93 testMesg = "AF0 not initialized to 0";
94 TUASSERTFEPS(0, empty.getAF0(), eps);
95 testMesg = "AF1 not initialized to 0";
96 TUASSERTFEPS(0, empty.getAF1(), eps);
97 testMesg = "Toa not initialized to 0";
98 TUASSERTE(long, 0, empty.getToaSOW());
99 testMesg = "Xmit_time not initialized to 0";
100 TUASSERTE(long, 0, empty.getxmit_time());
101 testMesg = "Week not initialized to 0";
102 TUASSERTE(short, 0, empty.getToaWeek());
103 // No SV health get method
104 // testMesg = "SV_health not initialized to 0";
105 // TUASSERTE(short, 0, empty.getSV_health());
106
107 //============================================================================
108
109 // Should be tested by testing the inhereted members as comparison points
110 // instead of using the get methods, but compare.PRN doesn't work due to
111 // inheritance issues
112
113 //============================================================================
114
115 gpstk::AlmOrbit compare(1, 0.00346661, 0.00388718, -8.01176E-09, 5153.58,
116 -0.296182, -1.31888, 2.79387, 0.000148773,
117 7.63976E-11, 466944, 250560, 797, 0);
118
119 TUCSM("Explicit Constructor");
120 //----------------------------------------------------------------
121 //Does the explicit constructor function correctly?
122 //----------------------------------------------------------------
123 testMesg = "PRN value was not initialized correctly";
124 TUASSERTE(short, 1, compare.getPRN());
125 testMesg = "Ecc value was not initialized correctly";
126 TUASSERTFEPS(0.00346661, compare.getecc(), eps);
127 testMesg = "Offset value was not initialized correctly";
128 TUASSERTFEPS(0.00388718, compare.geti_offset(), eps);
129 testMesg = "OMEGAdot value was not initialized correctly";
130 TUASSERTFEPS(-8.01176E-09, compare.getOMEGAdot(), eps);
131 testMesg = "Ahalf value was not initialized correctly";
132 TUASSERTFEPS(5153.58, compare.getAhalf(), eps);
133 testMesg = "OMEGA0 value was not initialized correctly";
134 TUASSERTFEPS(-0.296182, compare.getOMEGA0(), eps);
135 testMesg = "W value was not initialized correctly";
136 TUASSERTFEPS(-1.31888, compare.getw(), eps);
137 testMesg = "M0 value was not initialized correctly";
138 TUASSERTFEPS(2.79387, compare.getM0(), eps);
139 testMesg = "AF0 value was not initialized correctly";
140 TUASSERTFEPS(0.000148773, compare.getAF0(), eps);
141 testMesg = "AF1 value was not initialized correctly";
142 TUASSERTFEPS(7.63976E-11, compare.getAF1(), eps);
143 testMesg = "Toa value was not initialized correctly";
144 TUASSERTE(long, 466944, compare.getToaSOW());
145 testMesg = "Xmit_time value was not initialized correctly";
146 TUASSERTE(long, 250560, compare.getxmit_time());
147 testMesg = "Week value was not initialized correctly";
148 TUASSERTE(short, 797, compare.getToaWeek());
149 // No SV health get method
150 // testMesg = "SV_health value was not initialized correctly";
151 // TUASSERTE(short, 0, AlmOrbit::SV_health);
152
153 TURETURN();
154 }
155 //=============================================================================
156 // Test will check the dump method for various verbosities
157 //=============================================================================
dumpTest(void)158 int dumpTest(void)
159 {
160 TUDEF("AlmOrbit", "Dump");
161 std::string testMesg;
162
163 gpstk::AlmOrbit compare(1, 0.00346661, 0.00388718, -8.01176E-09, 5153.58,
164 -0.296182, -1.31888, 2.79387, 0.000148773,
165 7.63976E-11, 466944, 250560, 797, 0);
166
167
168 std::stringstream outputStream1, outputStream2, outputStream3;
169 std::string outputString1, referenceString1, outputString2,
170 referenceString2, outputString3, referenceString3;
171
172 referenceString1 = "1, 466944, 797, 0, 1.4877e-04, 7.6398e-11,"
173 " 3.4666e-03, -1.3189e+00, 5.1536e+03, 2.7939e+00, -2.9618e-01, "
174 "-8.0118e-09, 3.8872e-03\n";
175 compare.dump(outputStream1, 0);
176 outputString1 = outputStream1.str();
177
178 //-----------------------------------------------------------------
179 //Did the least verbose dump method function correctly?
180 //-----------------------------------------------------------------
181 testMesg = "Least-verbose dump method did not function correctly";
182 TUASSERTE(std::string, referenceString1, outputString1);
183
184 referenceString2 = "PRN:1 Toa:466944 H:0 AFO:1.4877e-04 AF1:7.6398e-11 "
185 "Ecc:3.4666e-03\n w:-1.3189e+00 Ahalf:5.1536e+03 "
186 "M0:2.7939e+00\n OMEGA0:-2.9618e-01 "
187 "OMEGAdot:-8.0118e-09 Ioff:3.8872e-03\n";
188 compare.dump(outputStream2, 1);
189 outputString2 = outputStream2.str();
190
191 //-----------------------------------------------------------------
192 //Did the mid-level verbose dump method function correctly?
193 //-----------------------------------------------------------------
194 testMesg = "Medium-verbose dump method did not function correctly";
195 TUASSERTE(std::string, referenceString2, outputString2);
196
197
198 referenceString3 = "PRN: 1\n"
199 "Toa: 466944\n"
200 "xmit_time: 250560\n"
201 "week: 797\n"
202 "SV_health: 0\n"
203 "AFO: 1.4877e-04 sec\n"
204 "AF1: 7.6398e-11 sec/sec\n"
205 "Sqrt A: 5.1536e+03 sqrt meters\n"
206 "Eccentricity: 3.4666e-03\n"
207 "Arg of perigee: -1.3189e+00 rad\n"
208 "Mean anomaly at epoch: 2.7939e+00 rad\n"
209 "Right ascension: -2.9618e-01 rad"
210 " -8.0118e-09 rad/sec\n"
211 "Inclination offset: 3.8872e-03 rad \n";
212 compare.dump(outputStream3, 2);
213 outputString3 = outputStream3.str();
214
215 //-----------------------------------------------------------------
216 //Did the most verbose dump method function correctly?
217 //-----------------------------------------------------------------
218 testMesg = "High-verbose dump method did not function correctly";
219 TUASSERTE(std::string, referenceString3, outputString3);
220
221 TURETURN();
222
223 }
224 //=============================================================================
225 // Test will check the various operators
226 //=============================================================================
operatorTest(void)227 int operatorTest(void)
228 {
229 TUDEF("AlmOrbit", "operator<<");
230 std::string testMesg;
231
232 std::stringstream outputStream;
233 std::string outputString, referenceString;
234
235 gpstk::AlmOrbit compare(1, 0.00346661, 0.00388718, -8.01176E-09, 5153.58,
236 -0.296182, -1.31888, 2.79387, 0.000148773,
237 7.63976E-11, 466944, 250560, 797, 0);
238
239 referenceString = "PRN:1 Toa:466944 H:0 AFO:1.4877e-04 AF1:7.6398e-11 "
240 "Ecc:3.4666e-03\n w:-1.3189e+00 Ahalf:5.1536e+03 "
241 "M0:2.7939e+00\n OMEGA0:-2.9618e-01 "
242 "OMEGAdot:-8.0118e-09 Ioff:3.8872e-03\n";
243
244 outputStream << compare;
245 outputString = outputStream.str();
246
247
248 //-----------------------------------------------------------------
249 //Did the << operator function correctly?
250 //-----------------------------------------------------------------
251 testMesg = "The redirection operator << did not function correctly";
252 TUASSERTE(std::string, referenceString, outputString);
253
254 TURETURN();
255
256 }
257 //=============================================================================
258 // Test will check the various get methods
259 //=============================================================================
getTest(void)260 int getTest(void)
261 {
262 TUDEF("AlmOrbit", "get Methods");
263 std::string testMesg;
264
265 gpstk::AlmOrbit compare(1, 0.00346661, 0.00388718, -8.01176E-09, 5153.58,
266 -0.296182, -1.31888, 2.79387, 0.000148773,
267 7.63976E-11, 466944, 250560, 797, 0);
268
269 gpstk::GPSWeekSecond reference1(797,466944);
270 gpstk::CommonTime cRef1 (reference1);
271
272 //------------------------------------------------------------------
273 //Did the getToaTime method function correctly?
274 //------------------------------------------------------------------
275 testMesg = "getToaTime method did not function correctly";
276 TUASSERTE(gpstk::CommonTime, cRef1, compare.getToaTime());
277
278 gpstk::GPSWeekSecond reference2(797, 250560);
279 gpstk::CommonTime cRef2 (reference2);
280 //------------------------------------------------------------------
281 //Did the getTransmitTime method function correctly?
282 //------------------------------------------------------------------
283 testMesg = "getTransmitTime method did not function correctly";
284 TUASSERTE(gpstk::CommonTime, cRef2, compare.getTransmitTime());
285
286 //------------------------------------------------------------------
287 //Did the getFullWeek method function correctly?
288 //------------------------------------------------------------------
289 testMesg = "getFullWeek method did not function correctly";
290 TUASSERTE(short, 797, compare.getFullWeek());
291
292 //setting Toa to < -302400 & xmit_time to 0
293 gpstk::AlmOrbit compare1(1, 0.00346661, 0.00388718, -8.01176E-09,
294 5153.58, -0.296182, -1.31888, 2.79387,
295 0.000148773, 7.63976E-11, -302401, 0, 797, 0);
296
297 //------------------------------------------------------------------
298 //Did the getFullWeek method round the week down?
299 //------------------------------------------------------------------
300 testMesg = "getFullWeek method did not round the week down";
301 TUASSERTE(short, 796, compare1.getFullWeek());
302
303 //setting Toa to > 302400 & xmit_time to 0
304 gpstk::AlmOrbit compare2(1, 0.00346661, 0.00388718, -8.01176E-09,
305 5153.58, -0.296182, -1.31888, 2.79387,
306 0.000148773, 7.63976E-11, 302401, 0, 797, 0);
307
308 //------------------------------------------------------------------
309 //Did the getFullWeek method round the week up?
310 //------------------------------------------------------------------
311 testMesg = "getFullWeek method did not round the week up";
312 TUASSERTE(short, 798, compare2.getFullWeek());
313
314 TURETURN();
315 }
316 //=============================================================================
317 // Test will check the svXvt method
318 //=============================================================================
svXvtTest(void)319 int svXvtTest(void)
320 {
321 TUDEF("AlmOrbit", "svXvt");
322 gpstk::AlmOrbit oe(2, .146582192974e-01,
323 .941587707856e+00 - (0.3*gpstk::PI),
324 -.804390648956e-08, .515359719276e+04,
325 -.296605403382e+01, -.224753761329e+01,
326 -.136404614938e+01, .579084269702e-03,
327 .227373675443e-11, 7168, 3600, 1854, 0);
328 bool testFailed = false;
329 try
330 {
331 // first compute Xvt
332 static const unsigned SECONDS = 7200;
333 gpstk::Xvt zeroth_array[SECONDS];
334 for (unsigned ii = 0; ii < SECONDS; ii++)
335 {
336 zeroth_array[ii] = oe.svXvt(oe.getToaTime() + ii);
337 }
338 // then compute first derivative of position, i.e. velocity
339 gpstk::Triple deriv[SECONDS];
340 double h = 1; // time step size in seconds
341 for (unsigned ii = 0; ii < SECONDS; ii++)
342 {
343 if (ii == 0)
344 {
345 deriv[ii] = (1/h)*(-1.5*zeroth_array[ii].getPos() +
346 2.0*zeroth_array[ii+1].getPos() -
347 0.5*zeroth_array[ii+2].getPos());
348 }
349 else if ((ii == 1) || (ii == (SECONDS-2)))
350 {
351 deriv[ii] = (1/h)*(-0.5*zeroth_array[ii-1].getPos() +
352 0.5*zeroth_array[ii+1].getPos());
353 }
354 else if (ii == (SECONDS-1))
355 {
356 deriv[ii] = (1/h)*(0.5*zeroth_array[ii-2].getPos() -
357 2.0*zeroth_array[ii-1].getPos() +
358 1.5*zeroth_array[ii].getPos());
359 }
360 else
361 {
362 deriv[ii] = (1/h)*((1.0/12.0)*zeroth_array[ii-2].getPos() -
363 (2.0/3.0)*zeroth_array[ii-1].getPos() +
364 (2.0/3.0)*zeroth_array[ii+1].getPos() -
365 (1.0/12.0)*zeroth_array[ii+2].getPos());
366 }
367 }
368 // then check the difference between derived and computed velocity
369 for (unsigned ii = 0; ii < SECONDS; ii++)
370 {
371 double derivedMag = deriv[ii].mag();
372 double computedMag = zeroth_array[ii].getVel().mag();
373 // If you want to print the data e.g. to plot, uncomment
374 // this stream output statement and comment out tbe break
375 // statement below.
376 // Just don't check it in that way, please.
377 // cerr << ii << " " << (computedMag - derivedMag) << endl;
378 if (fabs(computedMag - derivedMag) > velDiffThresh)
379 {
380 // no sense in printing 7200 success/fail messages.
381 testFailed = true;
382 break;
383 }
384 }
385 if (testFailed)
386 {
387 TUFAIL("computed velocity is significantly different from derived"
388 " velocity");
389 }
390 else
391 {
392 TUPASS("velocity check");
393 }
394 }
395 catch (gpstk::Exception& exc)
396 {
397 cerr << exc;
398 TUFAIL("Exception");
399 }
400 catch (...)
401 {
402 TUFAIL("Exception");
403 }
404 TURETURN();
405 }
406
407
408 private:
409 double eps;
410 };
411
412
main()413 int main() //Main function to initialize and run all tests above
414 {
415 int errorTotal = 0;
416 AlmOrbit_T testClass;
417
418 errorTotal += testClass.initializationTest();
419 errorTotal += testClass.dumpTest();
420 errorTotal += testClass.operatorTest();
421 errorTotal += testClass.getTest();
422 errorTotal += testClass.svXvtTest();
423
424 std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal
425 << std::endl;
426
427 return errorTotal; //Return the total number of errors
428 }
429