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 "GPSEphemerisStore.hpp"
40 #include "CivilTime.hpp"
41 #include "TimeString.hpp"
42 #include "TestUtil.hpp"
43 
44 using namespace std;
45 
46 class GPSEphemerisStore_T
47 {
48 public:
doGetPrnXvtTests()49    unsigned doGetPrnXvtTests()
50    {
51       TUDEF("GPSEphemerisStore","getPrnXvt");
52       try
53       {
54             // make sure that getPrnXvt is getting the correct
55             // ephemeris.  Implicitly checks the findUserEphemeris
56             // method
57          gpstk::GPSEphemerisStore store;
58          gpstk::GPSEphemeris eph1, eph2, eph3;
59 /* GPSEphemeris has no bit conversion.  Fantastic.
60          uint32_t eph1A[] =
61             {
62                0x22C37D35, 0x2E4A29A4, 0x37D48009, 0x04F4E198, 0x1D41EC15,
63                0x320E27A1, 0x002579BA, 0x1523280D, 0x003FFDA6, 0x2A29ABD4,
64                0x22C37D35, 0x2E4A4A34, 0x153DCC28, 0x102DD458, 0x16E3D199,
65                0x3E06421D, 0x2712797D, 0x0449A87B, 0x035D9E95, 0x23281F08,
66                0x22C37D35, 0x2E4A6BBC, 0x00210DF1, 0x0B2D283A, 0x3FE1892B,
67                0x2541587B, 0x05C7D01B, 0x234D0E14, 0x3FE8D0D5, 0x15019354
68             };
69          uint32_t eph2A[] =
70             {
71                0x22C37D35, 0x2E7049A4, 0x37D40016, 0x00F4E1BB, 0x1D41EC2A,
72                0x320E279E, 0x00257985, 0x04A327F5, 0x003FFDF5, 0x2A29BA24,
73                0x22C37D35, 0x2E6FCADC, 0x04BDCC31, 0x102DD44E, 0x10CDEE29,
74                0x3E06421D, 0x271281C4, 0x0449687C, 0x035D9EF9, 0x2327C738,
75                0x22C37D35, 0x2E6FEB54, 0x00210DF1, 0x0B2D4100, 0x3FE18902,
76                0x25415966, 0x05C7D00D, 0x234CFF0D, 0x3FE8D090, 0x04819308
77             };
78          uint32_t eph3A[] =
79             {
80                0x22C37D35, 0x2EE02910, 0x37D40016, 0x06E83CBF, 0x1D41EC2A,
81                0x320E279E, 0x00257985, 0x0523985E, 0x003FFDCA, 0x2A29ABD4,
82                0x22C37D35, 0x2EE04A80, 0x053E3CEC, 0x0FE91F3A, 0x03128E40,
83                0x3E64C223, 0x2704E56A, 0x045DA85F, 0x035F8430, 0x23984F1C,
84                0x22C37D35, 0x2EE06B08, 0x00264DC4, 0x0B04B772, 0x3FFA492B,
85                0x25420F75, 0x05A0501C, 0x237C7C98, 0x3FE8EF4C, 0x0501DC50
86             };
87 
88          eph1.addSubframe(&eph1A[ 0], 1919, 11, 1);
89          eph1.addSubframe(&eph1A[10], 1919, 11, 1);
90          eph1.addSubframe(&eph1A[20], 1919, 11, 1);
91 
92          eph2.addSubframe(&eph2A[ 0], 1919, 11, 1);
93          eph2.addSubframe(&eph2A[10], 1919, 11, 1);
94          eph2.addSubframe(&eph2A[20], 1919, 11, 1);
95 
96          eph3.addSubframe(&eph3A[ 0], 1919, 11, 1);
97          eph3.addSubframe(&eph3A[10], 1919, 11, 1);
98          eph3.addSubframe(&eph3A[20], 1919, 11, 1);
99 */
100 
101          gpstk::SatID sat(11, gpstk::SatelliteSystem::GPS);
102          gpstk::ObsID obsID(gpstk::ObservationType::NavMsg,
103                             gpstk::CarrierBand::L1,
104                             gpstk::TrackingCode::CA);
105 
106          eph1.transmitTime = gpstk::GPSWeekSecond(1917, 568800);
107          eph1.HOWtime = 568806;
108          eph1.IODE = eph1.IODC = 84;
109          eph1.health = 0;
110          eph1.accuracyFlag = 2;
111          eph1.accuracy = 4.85;
112          eph1.Tgd = -1.21071935E-08;
113          eph1.codeflags = 1;
114          eph1.L2Pdata = 1;
115             // what units? What significance? Who knows, poorly documented.
116          eph1.fitDuration = 4;
117          eph1.fitint = 0;
118          eph1.dataLoadedFlag = true;
119          eph1.satID = sat;
120          eph1.obsID = obsID;
121          eph1.ctToe = gpstk::GPSWeekSecond(1917, 576000);
122          eph1.ctToc = gpstk::GPSWeekSecond(1917, 576000);
123          eph1.af0 = -6.66419510E-04;
124          eph1.af1 = -1.13686838E-12;
125          eph1.af2 = 0.00000000E+00;
126          eph1.M0 = 1.99681727E+00;
127          eph1.dn = 5.91703218E-09;
128          eph1.ecc = 1.68173878E-02;
129          eph1.A = 5.15368285E+03 * 5.15368285E+03;
130          eph1.OMEGA0 = 1.35418919E+00;
131          eph1.i0 = 8.97860144E-01;
132          eph1.w = 1.58433409E+00;
133          eph1.OMEGAdot = -8.47928177E-09;
134          eph1.idot = 1.43934567E-10;
135          eph1.dndot = 0;
136          eph1.Adot = 0;
137          eph1.Cuc = -3.76813114E-06;
138          eph1.Cus = 8.17701221E-06;
139          eph1.Crc = 1.84968750E+02;
140          eph1.Crs = -7.05000000E+01;
141          eph1.Cic = 2.45869160E-07;
142          eph1.Cis = -2.27242708E-07;
143          eph1.adjustValidity();
144 
145          eph2.IODE = eph2.IODC = 18;
146          eph2.transmitTime   = gpstk::GPSWeekSecond(1917, 570630);
147          eph2.HOWtime        = 570606; //570636;
148          eph2.health         = 0;
149          eph2.accuracyFlag   = 0;
150          eph2.accuracy       = 2.4;
151          eph2.Tgd            = -1.21071935E-08;
152          eph2.codeflags      = 1;
153          eph2.L2Pdata        = 1;
154             // what units? What significance? Who knows, poorly documented.
155          eph2.fitDuration    = 4;
156          eph2.fitint         = 0;
157          eph2.dataLoadedFlag = true;
158          eph2.satID          = sat;
159          eph2.obsID          = obsID;
160          eph2.ctToe          = gpstk::GPSWeekSecond(1917, 575984);
161          eph2.ctToc          = gpstk::GPSWeekSecond(1917, 575984);
162          eph2.af0            = -6.66412525E-04;
163          eph2.af1            = -1.02318154E-12;
164          eph2.af2            = 0.00000000E+00;
165          eph2.M0             = 1.99448351E+00;
166          eph2.dn             = 5.91703218E-09;
167          eph2.ecc            = 1.68173917E-02;
168          eph2.A              = 5.15368285E+03 * 5.15368285E+03;
169          eph2.OMEGA0         = 1.35418933E+00;
170          eph2.i0             = 8.97860150E-01;
171          eph2.w              = 1.58433400E+00;
172          eph2.OMEGAdot       = -8.47963893E-09;
173          eph2.idot           = 1.43934567E-10;
174          eph2.dndot          = 0;
175          eph2.Adot           = 0;
176          eph2.Cuc            = -3.76813114E-06;
177          eph2.Cus            = 8.17514956E-06;
178          eph2.Crc            = 1.84968750E+02;
179          eph2.Crs            = -7.05000000E+01;
180          eph2.Cic            = 2.45869160E-07;
181          eph2.Cis            = -2.27242708E-07;
182          eph2.adjustValidity();
183 
184          eph3.IODE = eph3.IODC = 20;
185          eph3.transmitTime   = gpstk::GPSWeekSecond(1917, 576000);
186          eph3.HOWtime        = 576006;
187          eph3.health         = 0;
188          eph3.accuracyFlag   = 0;
189          eph3.accuracy       = 2.4;
190          eph3.Tgd            = -1.21071935E-08;
191          eph3.codeflags      = 1;
192          eph3.L2Pdata        = 1;
193             // what units? What significance? Who knows, poorly documented.
194          eph3.fitDuration    = 4;
195          eph3.fitint         = 0;
196          eph3.dataLoadedFlag = true;
197          eph3.satID          = sat;
198          eph3.obsID          = obsID;
199          eph3.ctToe          = gpstk::GPSWeekSecond(1917, 583184);
200          eph3.ctToc          = gpstk::GPSWeekSecond(1917, 583184);
201          eph3.af0            = -6.66419510E-04;
202          eph3.af1            = -1.02318154E-12;
203          eph3.af2            = 0.00000000E+00;
204          eph3.M0             = 3.04459617E+00;
205          eph3.dn             = 5.81881381E-09;
206          eph3.ecc            = 1.68157691E-02;
207          eph3.A              = 5.15368655E+03 * 5.15368655E+03;
208          eph3.OMEGA0         = 1.35412860E+00;
209          eph3.i0             = 8.97861215E-01;
210          eph3.w              = 1.58440514E+00;
211          eph3.OMEGAdot       = -8.43570852E-09;
212          eph3.idot           = 1.70007081E-10;
213          eph3.dndot          = 0;
214          eph3.Adot           = 0;
215          eph3.Cuc            = -3.06405127E-06;
216          eph3.Cus            = 8.32602382E-06;
217          eph3.Crc            = 1.80031250E+02;
218          eph3.Crs            = -5.64062500E+01;
219          eph3.Cic            = 2.84984708E-07;
220          eph3.Cis            = -4.28408384E-08;
221          eph3.adjustValidity();
222 
223          store.addEphemeris(eph1);
224          store.addEphemeris(eph2);
225          store.addEphemeris(eph3);
226 
227          gpstk::CommonTime start = gpstk::CivilTime(2016, 10, 8, 13, 50, 0);
228          start.setTimeSystem(gpstk::TimeSystem::Any);
229             // test from 13:50:00 to 18:10:00 at 5min increments
230             // 2 + 1400H + 1500H + 1600H + 1700H + 3
231             // 5 + 4xH = 5 + 4*12 = 53
232          for (unsigned long epCount = 0; epCount < 53; epCount++)
233          {
234             gpstk::CommonTime what(start + (epCount * 300));
235             short iodc, expected;
236                // this will change if "start" changes
237             if (epCount < 2)
238                expected = -666;
239             else if (epCount < 8)
240                expected = 84;
241             else if (epCount < 26)
242                expected = 18;
243             else
244                expected = 20;
245             try
246             {
247                   //gpstk::Xvt meh = store.getXvt(11, what, iodc);
248                gpstk::GPSEphemeris eph = store.findEphemeris(sat, what);
249                iodc = eph.IODC;
250             }
251             catch (gpstk::InvalidRequest &exc)
252             {
253                iodc = -666;
254             }
255             TUASSERTE(short, expected, iodc);
256                /*
257             cout << setw(2) << epCount << " "
258                  << gpstk::printTime(what, "%Y/%02m/%02d %02H:%02M:%02S")
259                  << " " << iodc << " expect " << expected << endl;
260                */
261          }
262       }
263       catch (gpstk::Exception &exc)
264       {
265          cerr << exc << endl;
266          TUFAIL("Unexpected exception");
267       }
268       catch (...)
269       {
270          TUFAIL("Unexpected exception");
271       }
272 
273       TURETURN();
274    }
275 };
276 
277 
main(int argc,char * argv[])278 int main(int argc, char *argv[])
279 {
280    unsigned total = 0;
281    GPSEphemerisStore_T testClass;
282    total += testClass.doGetPrnXvtTests();
283 
284    cout << "Total Failures for " << __FILE__ << ": " << total << endl;
285    return total;
286 }
287