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 <list>
40 #include <string>
41 #include <iostream>
42 #include <fstream>
43 #include <iomanip>
44 #include <sstream>
45
46 #include "SatID.hpp"
47 #include "Exception.hpp"
48 #include "CivilTime.hpp"
49 #include "CommonTime.hpp"
50 #include "SP3EphemerisStore.hpp"
51 #include "TestUtil.hpp"
52
53 using namespace gpstk;
54 using namespace std;
55
56 class SP3EphemerisStore_T
57 {
58 public:
SP3EphemerisStore_T()59 SP3EphemerisStore_T()
60 {
61 epsilon = 1E-12;
62 }
63
64 //=============================================================================
65 // Initialize Test Data Filenames
66 //=============================================================================
init()67 void init()
68 {
69 std::string dataFilePath = gpstk::getPathData();
70 std::string tempFilePath = gpstk::getPathTestTemp();
71 std::string fileSep = gpstk::getFileSep();
72
73 inputSP3Data = dataFilePath + fileSep +
74 "test_input_sp3_nav_ephemerisData.sp3";
75 inputSP3cData = dataFilePath + fileSep +
76 "test_input_SP3c.sp3";
77 inputAPCData = dataFilePath + fileSep +
78 "test_input_sp3_nav_apcData.sp3";
79 inputSixNinesData = dataFilePath + fileSep +
80 "inputs" + fileSep + "igs" + fileSep + "igr20354.sp3";
81 inputNotaFile = dataFilePath + fileSep + "NotaFILE";
82 outputDataDump = tempFilePath + fileSep + "SP3_DataDump.txt";
83
84 inputComparisonOutput1 =
85 "x:(-1.51906e+07, -2.15539e+07, 3.31227e+06),"
86 " v:(488.793, 118.124, 3125.01), clk bias:1.68268e-05,"
87 " clk drift:1.93783e-11, relcorr:-8.45152e-09,"
88 " health:Unused";
89 inputComparisonOutput15 =
90 "x:(-1.57075e+07, 1.72951e+07, 1.24252e+07),"
91 " v:(408.54, -1568.11, 2651.16), clk bias:0.000411558,"
92 " clk drift:3.22901e-12, relcorr:1.32734e-08,"
93 " health:Unused";
94 inputComparisonOutput31 =
95 "x:(-1.69885e+07, 2.21265e+06, 2.02132e+07),"
96 " v:(-1670.69, -1985.6, -1151.13), clk bias:0.000294455,"
97 " clk drift:-5.8669e-11, relcorr:-1.60472e-08,"
98 " health:Unused";
99 }
100
101
102 //=============================================================================
103 // General test for the SP3EphemerisStore
104 // Makes sure SP3EphemerisStore can be instantiated and can load
105 // a file; also ensures that nonexistent files throw an exception
106 //=============================================================================
SP3ESTest()107 unsigned SP3ESTest()
108 {
109 TUDEF("SP3EphemerisStore", "Constructor");
110
111 // Verify the consturctor builds the SP3EphemerisStore object
112 try
113 {
114 SP3EphemerisStore store;
115 TUPASS("SP3EphemerisStore object successfully created");
116 }
117 catch (...)
118 {
119 TUFAIL("SP3EphemerisStore object could not be created");
120 }
121
122 SP3EphemerisStore store;
123
124 // Verify opening an empty file throws an error
125 try
126 {
127 store.loadFile(inputNotaFile);
128 TUFAIL("Opening an empty file did not throw an exception");
129 }
130 catch (Exception& e)
131 {
132 TUPASS("Opening an empty file threw the correct exception");
133 }
134 catch (...)
135 {
136 TUFAIL("Opening an empty file caused an unexpected exception");
137 }
138
139 // Verify opening a file works with no errors
140 try
141 {
142 store.loadFile(inputSP3Data);
143 TUPASS("Opening a valid file works with no exceptions");
144 }
145 catch (...)
146 {
147 TUFAIL("Exception thrown when opening a valid file");
148 }
149
150 // Write the dump of the loaded file
151 ofstream dumpData;
152 dumpData.open (outputDataDump.c_str());
153 store.dump(dumpData,1);
154 dumpData.close();
155
156 TURETURN();
157 }
158
159
160 /// test loading of SP3c data
sp3cTest()161 unsigned sp3cTest()
162 {
163 TUDEF("SP3EphemerisStore", "whatever");
164 SP3EphemerisStore store;
165 TUCATCH(store.loadFile(inputSP3cData));
166 TUASSERTE(size_t, 750, store.size());
167 TURETURN();
168 }
169
170
171 //=============================================================================
172 // Test for getXvt.
173 // Tests the getXvt method in SP3EphemerisStore by comparing known
174 // results with the method's output for various time stamps in an
175 // SP3 file; also ensures nonexistent SatIDs throw an exception
176 //=============================================================================
getXvtTest()177 unsigned getXvtTest()
178 {
179 TUDEF("SP3EphemerisStore", "getXvt");
180
181 try
182 {
183 SP3EphemerisStore store;
184 store.loadFile(inputSP3Data);
185
186 stringstream outputStream1;
187 stringstream outputStream15;
188 stringstream outputStream31;
189
190 const short PRN0 = 0; // Nonexistent in SP3 file
191 const short PRN1 = 1;
192 const short PRN15 = 15;
193 const short PRN31 = 31;
194 const short PRN32 = 32; // Nonexistent in SP3 file
195
196 SatID sid0(PRN0,SatelliteSystem::GPS);
197 SatID sid1(PRN1,SatelliteSystem::GPS);
198 SatID sid15(PRN15,SatelliteSystem::GPS);
199 SatID sid31(PRN31,SatelliteSystem::GPS);
200 SatID sid32(PRN32,SatelliteSystem::GPS);
201
202 CivilTime eTimeCiv(1997,4,6,6,15,0); // Time stamp of one epoch
203 CommonTime eTime = eTimeCiv.convertToCommonTime();
204 CivilTime bTimeCiv(1997,4,6,0,0,0); // Time stamp of first epoch
205 CommonTime bTime = bTimeCiv.convertToCommonTime();
206
207 try
208 {
209 // Verify that an InvalidRequest exception is thrown
210 // when SatID is not in the data
211 try
212 {
213 store.getXvt(sid0,bTime);
214 TUFAIL("No exception thrown when getXvt looks for an invalid"
215 " SatID");
216 }
217 catch (InvalidRequest& e)
218 {
219 TUPASS("Expected exception thrown when getXvt looks for an"
220 " invalid SatID");
221 }
222 catch (...)
223 {
224 TUFAIL("Unexpected exception thrown when getXvt looks for an"
225 " invalid SatID");
226 }
227
228 // Verify that an InvalidRequest exception is thrown
229 // when SatID is not in the data
230 try
231 {
232 store.getXvt(sid32,bTime);
233 TUFAIL("No exception thrown when getXvt looks for an invalid"
234 " SatID");
235 }
236 catch (InvalidRequest& e)
237 {
238 TUPASS("Expected exception thrown when getXvt looks for an"
239 " invalid SatID");
240 }
241 catch (...)
242 {
243 TUFAIL("Unexpected exception thrown when getXvt looks for an"
244 " invalid SatID");
245 }
246
247 // Verify that no exception is thrown for SatID in the data set
248 try
249 {
250 store.getXvt(sid1,eTime);
251 TUPASS("No exception thrown when getXvt looks for a valid"
252 " SatID");
253 }
254 catch (...)
255 {
256 TUFAIL("Exception thrown when getXvt looks for a valid SatID");
257 }
258
259 outputStream1 << store.getXvt(sid1,eTime);
260 outputStream15 << store.getXvt(sid15,eTime);
261 outputStream31 << store.getXvt(sid31,eTime);
262 }
263
264 catch (Exception& e)
265 {
266 cout << e;
267 }
268
269 // Were the values set to expectation using the explicit
270 //constructor?
271 TUASSERTE(std::string, inputComparisonOutput1, outputStream1.str());
272 TUASSERTE(std::string, inputComparisonOutput15, outputStream15.str());
273 TUASSERTE(std::string, inputComparisonOutput31, outputStream31.str());
274 }
275 catch (...)
276 {
277 TUFAIL("Unexpected exception");
278 }
279
280 TURETURN();
281 }
282
283
284 //=============================================================================
285 // Test for computeXvt.
286 // Tests the computeXvt method in SP3EphemerisStore by comparing known
287 // results with the method's output for various time stamps in an
288 // SP3 file; also ensures nonexistent SatIDs throw an exception
289 //=============================================================================
computeXvtTest()290 unsigned computeXvtTest()
291 {
292 TUDEF("SP3EphemerisStore", "computeXvt");
293
294 try
295 {
296 SP3EphemerisStore store;
297 stringstream outputStream1;
298 stringstream outputStream15;
299 stringstream outputStream31;
300 Xvt rv;
301 SatID sid0(0, SatelliteSystem::GPS);
302 SatID sid1(1, SatelliteSystem::GPS);
303 SatID sid15(15, SatelliteSystem::GPS);
304 SatID sid31(31, SatelliteSystem::GPS);
305 SatID sid32(32, SatelliteSystem::GPS);
306 CommonTime eTime = CivilTime(1997,4,6,6,15,0,gpstk::TimeSystem::GPS);
307 CommonTime bTime = CivilTime(1997,4,6,0,0,0,gpstk::TimeSystem::GPS);
308
309 store.rejectBadPositions(false);
310 store.rejectBadClocks(false);
311 store.rejectPredPositions(false);
312 store.rejectPredClocks(false);
313 store.loadFile(inputSP3Data);
314
315 TUCATCH(rv = store.computeXvt(sid0,bTime));
316 TUASSERTE(Xvt::HealthStatus, Xvt::HealthStatus::Unavailable,rv.health);
317 TUCATCH(rv = store.computeXvt(sid32,bTime));
318 TUASSERTE(Xvt::HealthStatus, Xvt::HealthStatus::Unavailable,rv.health);
319 TUCATCH(rv = store.computeXvt(sid1,eTime));
320 TUASSERTE(Xvt::HealthStatus, Xvt::HealthStatus::Unused, rv.health);
321 outputStream1 << store.computeXvt(sid1,eTime);
322 outputStream15 << store.computeXvt(sid15,eTime);
323 outputStream31 << store.computeXvt(sid31,eTime);
324
325 // Were the values set to expectation using the explicit
326 //constructor?
327 TUASSERTE(std::string, inputComparisonOutput1, outputStream1.str());
328 TUASSERTE(std::string, inputComparisonOutput15, outputStream15.str());
329 TUASSERTE(std::string, inputComparisonOutput31, outputStream31.str());
330 }
331 catch (...)
332 {
333 TUFAIL("Unexpected exception");
334 }
335
336 TURETURN();
337 }
338
339
340 //=============================================================================
341 // Test for getSVHealth.
342 // Tests the getSVHealth method in SP3EphemerisStore by comparing known
343 // results with the method's output for various time stamps in an
344 // SP3 file; also ensures nonexistent SatIDs throw an exception
345 //=============================================================================
getSVHealthTest()346 unsigned getSVHealthTest()
347 {
348 TUDEF("SP3EphemerisStore", "getSVHealth");
349
350 try
351 {
352 // These are the same test queries used in computeXvt but
353 // the health results expected are different given that
354 // SP3 can provide Xvt data but not health data.
355 SP3EphemerisStore store;
356 Xvt::HealthStatus rv;
357 SatID sid0(0, SatelliteSystem::GPS);
358 SatID sid1(1, SatelliteSystem::GPS);
359 SatID sid15(15, SatelliteSystem::GPS);
360 SatID sid27(27, SatelliteSystem::GPS);
361 SatID sid31(31, SatelliteSystem::GPS);
362 SatID sid32(32, SatelliteSystem::GPS);
363 CommonTime eTime = CivilTime(1997,4,6,6,15,0,gpstk::TimeSystem::GPS);
364 CommonTime bTime = CivilTime(1997,4,6,0,0,0,gpstk::TimeSystem::GPS);
365
366 store.rejectBadPositions(false);
367 store.rejectBadClocks(false);
368 store.rejectPredPositions(false);
369 store.rejectPredClocks(false);
370 store.loadFile(inputSP3Data);
371
372 TUCATCH(rv = store.getSVHealth(sid0,bTime));
373 TUASSERTE(Xvt::HealthStatus, Xvt::HealthStatus::Unused, rv);
374 TUCATCH(rv = store.getSVHealth(sid32,bTime));
375 TUASSERTE(Xvt::HealthStatus, Xvt::HealthStatus::Unused, rv);
376 TUCATCH(rv = store.getSVHealth(sid1,eTime));
377 TUASSERTE(Xvt::HealthStatus, Xvt::HealthStatus::Unused, rv);
378
379 store.clear();
380 TUASSERTE(int, 0, store.size());
381 store.loadFile(inputSixNinesData);
382 SatID sid4(4, SatelliteSystem::GPS);
383 CommonTime cTime = CivilTime(2019,1,10,1,5,0,gpstk::TimeSystem::GPS);
384 // PRN 4 has clock bias of 999999.999999 but a valid position
385 TUCATCH(rv = store.getSVHealth(sid4, cTime));
386 TUASSERTE(Xvt::HealthStatus, Xvt::HealthStatus::Unused, rv);
387 // PRN 27 has an invalid position and clock bias
388 TUCATCH(rv = store.getSVHealth(sid27, cTime));
389 TUASSERTE(Xvt::HealthStatus, Xvt::HealthStatus::Unused, rv);
390 // PRN 1 should be fine
391 TUCATCH(rv = store.getSVHealth(sid1, cTime));
392 TUASSERTE(Xvt::HealthStatus, Xvt::HealthStatus::Unused, rv);
393 }
394 catch (...)
395 {
396 TUFAIL("Unexpected exception");
397 }
398 TURETURN();
399 }
400
401
402 //=============================================================================
403 // Test for getInitialTime
404 // Tests getInitialTime method in SP3EphemerisStore by ensuring that
405 // the method outputs the initial time stamp in an SP3 file
406 //=============================================================================
getInitialTimeTest()407 unsigned getInitialTimeTest()
408 {
409 TUDEF("SP3EphemerisStore", "getInitialTime");
410
411 try
412 {
413 SP3EphemerisStore store;
414 store.loadFile(inputSP3Data);
415
416 CommonTime computedInitialTime = store.getInitialTime();
417
418 CivilTime knownInitialTimeCiv(1997,4,6,0,0,0);
419 CommonTime knownInitialTime =
420 knownInitialTimeCiv.convertToCommonTime();
421
422 // Check that the function returns the initial time from the file
423 TUASSERTE(CommonTime, knownInitialTime, computedInitialTime);
424 }
425 catch (...)
426 {
427 TUFAIL("Unexpected exception");
428 }
429
430 TURETURN();
431 }
432
433
434 //=============================================================================
435 // Test for getFinalTime
436 // Tests getFinalTime method in SP3EphemerisStore by ensuring that
437 // the method outputs the final time stamp in an SP3 file
438 //=============================================================================
getFinalTimeTest()439 unsigned getFinalTimeTest()
440 {
441 TUDEF("SP3EphemerisStore", "getFinalTime");
442
443 try
444 {
445 SP3EphemerisStore store;
446 store.loadFile(inputSP3Data);
447
448 CommonTime computedFinalTime = store.getFinalTime();
449
450 CivilTime knownFinalTimeCiv(1997,4,6,23,45,0);
451 CommonTime knownFinalTime = knownFinalTimeCiv.convertToCommonTime();
452
453 // Check that the function returns the initial time from the file
454 TUASSERTE(CommonTime, knownFinalTime, computedFinalTime);
455 }
456 catch (...)
457 {
458 TUFAIL("Unexpected exception");
459 }
460
461 TURETURN();
462 }
463 //=============================================================================
464 // Test for getPosition
465 // Tests getPosition method in SP3EphemerisStore by comparing the outputs
466 // of the method to known values in two SP3 files--one with position and
467 // velocity values and one with only position values
468 //=============================================================================
getPositionTest()469 unsigned getPositionTest()
470 {
471 TUDEF("SP3EphemerisStore", "getPosition");
472
473 try
474 {
475 SP3EphemerisStore igsStore;
476 igsStore.loadFile(inputSP3Data);
477
478 const short PRN1 = 1;
479 const short PRN31 = 31;
480
481 CivilTime igsTimeCiv(1997,4,6,2,0,0);
482 CommonTime igsTime = igsTimeCiv.convertToCommonTime();
483
484 SatID sid1(PRN1,SatelliteSystem::GPS);
485 SatID sid31(PRN31,SatelliteSystem::GPS);
486
487 Triple computedPosition_igs1 = igsStore.getPosition(sid1,igsTime);
488 Triple computedPosition_igs31 = igsStore.getPosition(sid31,igsTime);
489
490 Triple knownPosition_igs1(-17432922.132,6688018.407,-18768291.053);
491 Triple knownPosition_igs31(-5075919.490,25101160.691,-6633797.696);
492
493 double relativeError;
494 std::stringstream testMessageStream;
495 std::string testMessageP1 =
496 "getPosition obtained the wrong position in the ";
497 std::string testMessageP2 = " direction for SatID 1";
498 // Check that the computed position matches the known
499 // value for SatID 1
500 for (unsigned i = 0; i < 3; i++)
501 {
502 testMessageStream << testMessageP1 << i << testMessageP2;
503 relativeError =
504 fabs(knownPosition_igs1[i] - computedPosition_igs1[i]) /
505 fabs(knownPosition_igs1[i]);
506 testFramework.assert(relativeError < epsilon,
507 testMessageStream.str(),
508 __LINE__);
509 testMessageStream.str(std::string());
510 }
511
512 //------------------------------------------------------------------
513 // Check that the computed position matches the known
514 // value for SatID 31
515 //------------------------------------------------------------------
516 testMessageP2 = " direction for SatID 31";
517 for (unsigned i = 0; i < 3; i++)
518 {
519 testMessageStream << testMessageP1 << i << testMessageP2;
520 relativeError = fabs(knownPosition_igs31[i] -
521 computedPosition_igs31[i]) /
522 fabs(knownPosition_igs31[i]);
523 testFramework.assert(relativeError < epsilon ,
524 testMessageStream.str() ,
525 __LINE__);
526 testMessageStream.str(std::string());
527 }
528
529 SP3EphemerisStore apcStore;
530 apcStore.loadFile(inputAPCData);
531
532 CivilTime apcTimeCiv(2001,7,22,2,0,0);
533 CommonTime apcTime = apcTimeCiv.convertToCommonTime();
534
535 Triple computedPosition_apc1 = apcStore.getPosition(sid1,apcTime);
536 Triple computedPosition_apc31 = apcStore.getPosition(sid31,apcTime);
537
538 Triple knownPosition_apc1(-5327654.053,-16633919.811,20164748.602);
539 Triple knownPosition_apc31(2170451.938,-22428932.839,-14059088.503);
540
541 //------------------------------------------------------------------
542 // Check that the computed position matches the known
543 // value for SatID 1
544 //------------------------------------------------------------------
545 testMessageP2 = " direction for SatID 1";
546 for (unsigned i = 0; i < 3; i++)
547 {
548 testMessageStream << testMessageP1 << i << testMessageP2;
549 relativeError = fabs(knownPosition_apc1[i] -
550 computedPosition_apc1[i]) /
551 fabs(knownPosition_apc1[i]);
552 testFramework.assert(relativeError < epsilon ,
553 testMessageStream.str() ,
554 __LINE__);
555 testMessageStream.str(std::string());
556 }
557
558 //------------------------------------------------------------------
559 // Check that the computed position matches the known
560 // value for SatID 31
561 //------------------------------------------------------------------
562 testMessageP2 = " direction for SatID 31";
563 for (unsigned i = 0; i < 3; i++)
564 {
565 testMessageStream << testMessageP1 << i << testMessageP2;
566 relativeError = fabs(knownPosition_apc31[i] -
567 computedPosition_apc31[i]) /
568 fabs(knownPosition_apc31[i]);
569 testFramework.assert(relativeError < epsilon ,
570 testMessageStream.str() ,
571 __LINE__);
572 testMessageStream.str(std::string());
573 }
574
575
576 //------------------------------------------------------------------
577 // Check that getSatList() and getIndexSet() return expected values
578 // The data set has data for 29 SVs with PRN 12, PRN 16,
579 // and PRN 32 missing
580 //------------------------------------------------------------------
581 set<SatID> expectedSet;
582 for (unsigned i=1;i<=31;i++)
583 {
584 if (i!=12 && i!=16 && i!=32)
585 {
586 SatID sid(i,SatelliteSystem::GPS);
587 expectedSet.insert(sid);
588 }
589 }
590
591 vector<SatID> loadedList = apcStore.getSatList();
592 set<SatID> loadedSet = apcStore.getIndexSet();
593 TUASSERTE(unsigned,expectedSet.size(),loadedSet.size());
594 TUASSERTE(unsigned,expectedSet.size(),loadedList.size());
595
596 set<SatID>::const_iterator cit;
597 for (cit=expectedSet.begin();cit!=expectedSet.end();cit++)
598 {
599 bool found = false;
600 const SatID& sidr = *cit;
601 if (loadedSet.find(sidr)!=loadedSet.end())
602 found = true;
603 TUASSERTE(bool,true,found);
604 }
605
606 vector<SatID>::const_iterator citl;
607 for (citl=loadedList.begin();citl!=loadedList.end();citl++)
608 {
609 bool found = false;
610 const SatID& sidr = *citl;
611 if (expectedSet.find(sidr)!=expectedSet.end())
612 found = true;
613 TUASSERTE(bool,true,found);
614 }
615
616 }
617 catch (...)
618 {
619 TUFAIL("Unexpected exception");
620 }
621
622 TURETURN();
623 }
624
625 //=============================================================================
626 // Test for getVelocity
627 // Tests getPosition method in SP3EphemerisStore by comparing the outputs
628 // of the method to known values in an SP3 files with position and
629 // velocity values
630 //=============================================================================
getVelocityTest()631 unsigned getVelocityTest()
632 {
633 TUDEF("SP3EphemerisStore", "getVelocity");
634
635 try
636 {
637 SP3EphemerisStore Store;
638 Store.loadFile(inputAPCData);
639
640 const short PRN1 = 1;
641 const short PRN31 = 31;
642
643 CivilTime testTimeCiv(2001,7,22,2,0,0);
644 CommonTime testTime = testTimeCiv.convertToCommonTime();
645
646 SatID sid1(PRN1,SatelliteSystem::GPS);
647 SatID sid31(PRN31,SatelliteSystem::GPS);
648
649 Triple computedVelocity_1 = Store.getVelocity(sid1,testTime);
650 Triple computedVelocity_31 = Store.getVelocity(sid31,testTime);
651
652 Triple knownVelocity_1(1541.6040306,-2000.8516260,-1256.4479944);
653 Triple knownVelocity_31(1165.3672035,-1344.4254143,2399.1497704);
654
655 double relativeError;
656 std::stringstream testMessageStream;
657 std::string testMessageP2,
658 testMessageP1 = "getVelocity obtained the wrong velocity in the ";
659 //------------------------------------------------------------------
660 // Check that the computed position matches the known
661 // value for SatID 1
662 //------------------------------------------------------------------
663 testMessageP2 = " direction for SatID 1";
664 for (unsigned i = 0; i < 3; i++)
665 {
666 testMessageStream << testMessageP1 << i << testMessageP2;
667 relativeError = fabs(knownVelocity_1[i] - computedVelocity_1[i]) /
668 fabs(computedVelocity_1[i]);
669 testFramework.assert(relativeError < epsilon ,
670 testMessageStream.str() ,
671 __LINE__);
672 testMessageStream.str(std::string());
673 }
674
675 //------------------------------------------------------------------
676 // Check that the computed position matches the known
677 // value for SatID 1
678 //------------------------------------------------------------------
679 testMessageP2 = " direction for SatID 31";
680 for (unsigned i = 0; i < 3; i++)
681 {
682 testMessageStream << testMessageP1 << i << testMessageP2;
683 relativeError = fabs(knownVelocity_31[i] - computedVelocity_31[i])/
684 fabs(computedVelocity_31[i]);
685 testFramework.assert(relativeError < epsilon ,
686 testMessageStream.str() ,
687 __LINE__);
688 testMessageStream.str(std::string());
689 }
690 }
691 catch (...)
692 {
693 TUFAIL("Unexpected exception");
694 }
695
696 TURETURN();
697 }
698
699 private:
700 double epsilon; // Floating point error threshold
701 std::string dataFilePath;
702
703 std::string inputSP3Data;
704 std::string inputSP3cData;
705 std::string inputAPCData;
706 std::string inputSixNinesData;
707
708 std::string outputDataDump;
709
710 std::string inputNotaFile;
711
712 std::string inputComparisonOutput1;
713 std::string inputComparisonOutput15;
714 std::string inputComparisonOutput31;
715 };
716
717
main()718 int main() // Main function to initialize and run all tests above
719 {
720 unsigned errorTotal = 0;
721 SP3EphemerisStore_T testClass;
722 testClass.init();
723
724 errorTotal += testClass.SP3ESTest();
725 errorTotal += testClass.sp3cTest();
726 errorTotal += testClass.getXvtTest();
727 errorTotal += testClass.computeXvtTest();
728 errorTotal += testClass.getSVHealthTest();
729 errorTotal += testClass.getInitialTimeTest();
730 errorTotal += testClass.getFinalTimeTest();
731 errorTotal += testClass.getPositionTest();
732 errorTotal += testClass.getVelocityTest();
733
734 cout << "Total Failures for " << __FILE__ << ": " << errorTotal << endl;
735
736 return errorTotal; // Return the total number of errors
737 }
738