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 GNSSconstants.hpp
41  * Constants as defined in the GPS-ICD-200D and by all RINEX GNSSs
42  */
43 
44 #ifndef GPSTK_GPS_URA_HPP
45 #define GPSTK_GPS_URA_HPP
46 
47 #include "Exception.hpp"
48 #include "RinexSatID.hpp"
49 #include <cmath>
50 
51 namespace gpstk
52 {
53       /// @ingroup GNSSEph
54       //@{
55 
56       /// constant for the max array index in sv accuracy table
57    const int SV_ACCURACY_GPS_MAX_INDEX_VALUE = 15;
58       /// map from SV accuracy/URA flag to minimum accuracy values in m
59    const double SV_ACCURACY_GPS_MIN_INDEX[] = {0.0, 2.4, 3.4, 4.85, 6.85, 9.65,
60                                                13.65, 24.0, 48.0, 96.0, 192.0,
61                                                384.0, 768.0, 1536.0, 3072.0,
62                                                6144.0};
63       /// Map from SV accuracy/URA flag to NOMINAL accuracy values in m
64       /// Further details in ICD-GPS-200C, section 20.3.3.3.1.3
65    const double SV_ACCURACY_GPS_NOMINAL_INDEX[] = {2.0, 2.8, 4.0, 5.7, 8.0,
66                                                    11.3, 16.0, 32.0, 64.0, 128.0,
67                                                    256.0, 512.0, 1024.0, 2048.0,
68                                                    4096.0, 9.999999999999e99};
69       /// map from SV accuracy/URA flag to maximum accuracy values in m
70    const double SV_ACCURACY_GPS_MAX_INDEX[] = {2.4, 3.4, 4.85, 6.85, 9.65,
71                                                13.65, 24.0, 48.0, 96.0, 192.0,
72                                                384.0, 768.0, 1536.0, 3072.0,
73                                                6144.0, 9.999999999999e99};
74       /// constant for the max array index in sv accuracy table
75    const int SV_CNAV_ACCURACY_GPS_MAX_INDEX_VALUE = 15;
76 
77       /// map from SV accuracy/URA flag to minimum accuracy values in m
78    const double SV_CNAV_ACCURACY_GPS_MIN_INDEX[] = {0.0, 0.01, 0.02, 0.03, 0.04, 0.06,
79                                                     0.08, 0.11, 0.15, 0.21, 0.30,
80                                                     0.43, 0.60, 0.85, 1.2, 1.7,
81                                                     2.4, 3.4, 4.85, 6.85, 9.65,
82                                                     13.65, 24.0, 48.0, 96.0, 192.0,
83                                                     384.0, 768.0, 1536.0, 3072.0,
84                                                     6144.0};
85       /// map for SV accuracy/Nominal URA indices
86       /// Further details in
87       /// IS-GPS-200 30.3.3.1.1.4
88       /// IS-GPS-705 20.3.3.1.1.4
89       /// IS_GPS-800 3.5.3.5
90    const double SV_CNAV_ACCURACY_GPS_NOM_INDEX[] = {0.011049, 0.015625, 0.022097, 0.03125,
91                                                     0.044194, 0.0625, 0.088388, 0.125, 0.176777,
92                                                     0.25, 0.353553, 0.5, 0.707107, 1, 1.414214, 2,
93                                                     2.8, 4, 5.7, 8, 11.3, 16, 32, 64, 128, 256, 512,
94                                                     1024, 2048, 4096};
95       /// constant for max array index in gps nom index table
96    const int SV_CNAV_NOMINAL_MAX_INDEX = 30;
97 
98       /// constant for gps nom index table offset
99    const int SV_CNAV_INDEX_OFFSET = 15;
100 
101       /// map from SV accuracy/URA flag to maximum accuracy values in m
102    const double SV_CNAV_ACCURACY_GPS_MAX_INDEX[] = {0.01, 0.02, 0.03, 0.04, 0.06,
103                                                     0.08, 0.11, 0.15, 0.21, 0.30,
104                                                     0.43, 0.60, 0.85, 1.20, 1.7,
105                                                     2.4, 3.4, 4.85, 6.85, 9.65,
106                                                     13.65, 24.0, 48.0, 96.0, 192.0,
107                                                     384.0, 768.0, 1536.0, 3072.0,
108                                                     6144.0, 9.999999999999e99};
109 
110 
111    inline
accuracy2ura(double acc)112    short accuracy2ura(double acc) throw()
113    {
114       short ura = 0;
115       while ( (ura <= SV_ACCURACY_GPS_MAX_INDEX_VALUE) &&
116               (acc > SV_ACCURACY_GPS_MAX_INDEX[ura]))
117          ura++;
118       if (ura > SV_ACCURACY_GPS_MAX_INDEX_VALUE)
119          ura = SV_ACCURACY_GPS_MAX_INDEX_VALUE;
120       return ura;
121    }
122 
123    inline
ura2accuracy(short ura)124    double ura2accuracy(short ura) throw()
125    {
126       if(ura < 0)
127          return SV_ACCURACY_GPS_MAX_INDEX[0];
128       if(ura > SV_ACCURACY_GPS_MAX_INDEX_VALUE)
129          return SV_ACCURACY_GPS_MAX_INDEX[SV_ACCURACY_GPS_MAX_INDEX_VALUE];
130       return SV_ACCURACY_GPS_MAX_INDEX[ura];
131    }
132 
133    inline
nominalAccuracy2ura(double acc)134    short nominalAccuracy2ura(double acc) throw()
135    {
136       short ura = 0;
137       while ( (ura <= SV_ACCURACY_GPS_MAX_INDEX_VALUE) &&
138               (acc > SV_ACCURACY_GPS_NOMINAL_INDEX[ura]))
139          ura++;
140       if (ura > SV_ACCURACY_GPS_MAX_INDEX_VALUE)
141          ura = SV_ACCURACY_GPS_MAX_INDEX_VALUE;
142       return ura;
143    }
144 
145    inline
ura2nominalAccuracy(short ura)146    double ura2nominalAccuracy(short ura) throw()
147    {
148       if(ura < 0)
149          return SV_ACCURACY_GPS_NOMINAL_INDEX[0];
150       if(ura > SV_ACCURACY_GPS_MAX_INDEX_VALUE)
151          return SV_ACCURACY_GPS_NOMINAL_INDEX[SV_ACCURACY_GPS_MAX_INDEX_VALUE];
152       return SV_ACCURACY_GPS_NOMINAL_INDEX[ura];
153    }
154 
155    inline
accuracy2CNAVura(double acc)156    short accuracy2CNAVura(double acc) throw()
157    {
158       short ura = -15;
159       while ( (ura <= SV_CNAV_ACCURACY_GPS_MAX_INDEX_VALUE) &&
160               (acc > SV_CNAV_ACCURACY_GPS_MAX_INDEX[ura+15]))
161          ura++;
162       if (ura > SV_CNAV_ACCURACY_GPS_MAX_INDEX_VALUE)
163          ura = SV_CNAV_ACCURACY_GPS_MAX_INDEX_VALUE;
164       return ura;
165    }
166 
167    inline
ura2CNAVaccuracy(short ura)168    double ura2CNAVaccuracy(short ura)
169    {
170       short ndx = ura+SV_CNAV_INDEX_OFFSET;
171       if(ndx < 0 || ndx > SV_CNAV_NOMINAL_MAX_INDEX)
172       {
173          InvalidRequest exc("URA index out of range");
174          GPSTK_THROW(exc);
175       }
176       return SV_CNAV_ACCURACY_GPS_MAX_INDEX[ndx];
177    }
178 
179    inline
ura2CNAVNominalaccuracy(short ura)180    double ura2CNAVNominalaccuracy(short ura)
181    {
182       short ndx = ura+SV_CNAV_INDEX_OFFSET;
183       if(ndx < 0 || ndx > SV_CNAV_NOMINAL_MAX_INDEX)
184       {
185          InvalidRequest exc("URA index out of range");
186          GPSTK_THROW(exc);
187       }
188       return SV_CNAV_ACCURACY_GPS_NOM_INDEX[ndx];
189    }
190 
191       //@}
192 
193 } // namespace
194 
195 #endif //GPSTK_GPS_URA_HPP
196