ord.cpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk 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 GNSSTk 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 GNSSTk; 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-2022, 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 <tuple>
40 #include <typeinfo>
41 #include <vector>
42 #include "ord.hpp"
43 #include "GPSEllipsoid.hpp"
44 #include "GNSSconstants.hpp"
45 #include "RawRange.hpp"
46 #include "Position.hpp"
47 #include "SatID.hpp"
48 #include "CommonTime.hpp"
49 #include "NavLibrary.hpp"
50 #include "Xvt.hpp"
51 #include "NavSatelliteID.hpp"
52 #include "GPSEllipsoid.hpp"
53 
54 using std::vector;
55 using std::cout;
56 
57 namespace gnsstk {
58 namespace ord {
59 
60 double IonosphereFreeRange(const std::vector<double>& frequencies,
61  const std::vector<double>& pseudoranges) {
62  // Check vectors are same length
63  if (frequencies.size() != pseudoranges.size()) {
65  "Mismatch between frequency and pseudorange array size");
66  GNSSTK_THROW(exc)
67  }
68 
69  // Check vectors are at least two
70  if (frequencies.size() < 2) {
72  "Multiple frequency and range values are required.");
73  GNSSTK_THROW(exc)
74  }
75 
76  // Check vectors aren't greater than two
77  if (frequencies.size() > 2) {
79  "Only dual-frequency ionosphere correction is supported.");
80  GNSSTK_THROW(exc)
81  }
82 
83  // TODO(someone): Add proper gamma calculation for arbitrary
84  // number of frequencies.
85  const double gamma = (frequencies[0]/frequencies[1]) *
86  (frequencies[0]/frequencies[1]);
87 
88  // for dual-frequency see IS-GPS-200, section 20.3.3.3.3.3
89  double icpr = (pseudoranges[1] - gamma * pseudoranges[0])/(1-gamma);
90 
91  return icpr;
92 }
93 
95  const gnsstk::CommonTime& time, CarrierBand band,
96  const gnsstk::Position& rxLoc, const gnsstk::Xvt& svXvt) {
97  Position trx(rxLoc);
98  Position svPos(svXvt);
99 
100  double elevation = trx.elevation(svPos);
101  double azimuth = trx.azimuth(svPos);
102 
103  double iono = ionoModel.getCorrection(time, trx, elevation, azimuth, band);
104  return -iono;
105 }
106 
108  NavLibrary& ephemeris) {
109  Xvt rv;
113  GNSSTK_ASSERT(ephemeris.getXvt(NavSatelliteID(satId), time, rv));
114  return rv;
115 }
116 
117 double RawRange1(
118  const Position& rxLoc,
119  const SatID& satId,
120  const CommonTime& timeReceived,
121  NavLibrary& ephemeris,
122  Xvt& svXvt
123 )
124 {
125  bool success;
126  double range;
127  GPSEllipsoid ellipsoid;
128  std::tie(success, range, svXvt) =
129  RawRange::fromReceive(rxLoc, timeReceived, ephemeris,
130  NavSatelliteID(satId), ellipsoid);
131  GNSSTK_ASSERT(success);
132  return range;
133 }
134 
135 
136 double RawRange2(double pseudorange, const Position& rxLoc,
137  const SatID& satId, const CommonTime& time,
138  NavLibrary& ephemeris, Xvt& svXvt) {
139 
140  bool success;
141  double range;
142  GPSEllipsoid ellipsoid;
143  std::tie(success, range, svXvt) =
144  RawRange::fromNominalReceiveWithObs(rxLoc, time, pseudorange, ephemeris,
145  NavSatelliteID(satId), ellipsoid);
146  GNSSTK_ASSERT(success);
147  return range;
148 }
149 
150 
151 double RawRange3(double pseudorange, const gnsstk::Position& rxLoc,
152  const gnsstk::SatID& satId, const gnsstk::CommonTime& time,
153  NavLibrary& ephemeris, gnsstk::Xvt& svXvt) {
154  bool success;
155  double range;
156  GPSEllipsoid ellipsoid;
157  std::tie(success, range, svXvt) =
158  RawRange::fromSvTransmitWithObs(rxLoc, pseudorange, ephemeris,
159  NavSatelliteID(satId), time, ellipsoid,
160  true);
161  GNSSTK_ASSERT(success);
162  return range;
163 }
164 
165 double RawRange4(const gnsstk::Position& rxLoc, const gnsstk::SatID& satId,
166  const gnsstk::CommonTime& time,
167  NavLibrary& ephemeris, gnsstk::Xvt& svXvt) {
168 
169  GNSSTK_ASSERT(ephemeris.getXvt(NavSatelliteID(satId), time, svXvt));
170 
171  // Compute initial time of flight estimate using the
172  // geometric range at transmit time. This fails to account
173  // for the rotation of the earth, but should be good to
174  // within about 40 m
175  GPSEllipsoid ellipsoid;
176  double tofEstimate = rxLoc.slantRange(svXvt.x) / ellipsoid.c();
177 
178  bool success;
179  double range;
180  Xvt rotatedSvXvt;
181 
182  // First estimate the range by using the receiveNominal as the
183  // transmit time.
184  std::tie(success, range, rotatedSvXvt) =
185  RawRange::fromSvTransmit(rxLoc, ephemeris, NavSatelliteID(satId), time,
186  ellipsoid, true, SVHealth::Any,
188  tofEstimate, 0, 2);
189  GNSSTK_ASSERT(success);
190 
191  // Create a mock pseudorange using the estimated range and SV clock offsets
192  double fakePsuedorange = range -
193  (rotatedSvXvt.clkbias + rotatedSvXvt.relcorr) * ellipsoid.c();
194 
195  std::tie(success, range, rotatedSvXvt) =
196  RawRange::fromNominalReceiveWithObs(rxLoc, time, fakePsuedorange,
197  ephemeris, NavSatelliteID(satId),
198  ellipsoid, false);
199  GNSSTK_ASSERT(success);
200  svXvt = rotatedSvXvt;
201  return range;
202 }
203 
204 double SvClockBiasCorrection(const gnsstk::Xvt& svXvt) {
205  double svclkbias = svXvt.clkbias * C_MPS;
206  double svclkdrift = svXvt.clkdrift * C_MPS;
207  return -svclkbias;
208 }
209 
211  double relativity = svXvt.computeRelativityCorrection() * C_MPS;
212  return -relativity;
213 }
214 
216  const gnsstk::Position& rxLoc, const gnsstk::Xvt& svXvt) {
217  Position trx(rxLoc);
218  Position svPos(svXvt);
219 
220  double elevation = trx.elevation(svPos);
221 
222  double trop = tropModel.correction(elevation);
223 
224  return trop;
225 }
226 
227 /*
228  * Example not fully fleshed-out. If dual-band data given, for example,
229  * then the last IonosphereModelCorrection call must not be made.
230  * Users should construct an ORD algorithm based on their data and use case.
231  *
232 double calculate_ord(const std::vector<CarrierBand>& bands,
233  const std::vector<double>& pseudoranges,
234  const gnsstk::Position& rx_loc,
235  const gnsstk::SatID& sat_id,
236  const gnsstk::CommonTime& transmit_time,
237  const gnsstk::CommonTime& receive_time,
238  const gnsstk::IonoModelStore& iono_model,
239  const gnsstk::TropModel& trop_model,
240  NavLibrary& ephemeris,
241  int range_method) {
242  double ps_range = IonosphereFreeRange(bands, pseudoranges);
243 
244  gnsstk::Xvt sv_xvt;
245  // find raw_range
246  double range = 0;
247  switch (range_method) {
248  case 1:
249  range = RawRange1(rx_loc, sat_id, receive_time, ephemeris, sv_xvt);
250  break;
251  case 2:
252  range = RawRange2(ps_range, rx_loc, sat_id, receive_time, ephemeris,
253  sv_xvt);
254  break;
255  case 3:
256  range = RawRange3(ps_range, rx_loc, sat_id, transmit_time, ephemeris,
257  sv_xvt);
258  break;
259  case 4:
260  range = RawRange4(rx_loc, sat_id, receive_time, ephemeris, sv_xvt);
261  break;
262  }
263 
264  // apply sv relativity correction
265  range += SvRelativityCorrection(sv_xvt);
266 
267  // apply sv clock bias correction
268  range += SvClockBiasCorrection(sv_xvt);
269 
270  // apply troposphere model correction
271  range += TroposphereCorrection(trop_model, rx_loc, sv_xvt);
272 
273  // apply ionosphere model correction -- GPS only (this is Klobuchar)
274  range += IonosphereModelCorrection(iono_model,
275  receive_time, bands[0],
276  rx_loc, sv_xvt);
277 
278  return ps_range - range;
279 }
280  */
281 
282 } // namespace ord
283 } // namespace gnsstk
Xvt.hpp
gnsstk::ord::SvClockBiasCorrection
double SvClockBiasCorrection(const gnsstk::Xvt &svXvt)
Definition: ord.cpp:204
gnsstk::RawRange::fromNominalReceiveWithObs
static std::tuple< bool, double, Xvt > fromNominalReceiveWithObs(const Position &rxPos, const CommonTime &receiveNominal, double pseudorange, NavLibrary &navLib, const NavSatelliteID &sat, const EllipsoidModel &ellipsoid, bool smallAngleApprox=false, SVHealth xmitHealth=SVHealth::Any, NavValidityType valid=NavValidityType::ValidOnly, NavSearchOrder order=NavSearchOrder::User)
Definition: RawRange.cpp:242
gnsstk::ord::RawRange1
double RawRange1(const Position &rxLoc, const SatID &satId, const CommonTime &timeReceived, NavLibrary &ephemeris, Xvt &svXvt)
Definition: ord.cpp:117
ord.hpp
gnsstk::CarrierBand
CarrierBand
Definition: CarrierBand.hpp:54
gnsstk::RawRange::fromSvTransmit
static std::tuple< bool, double, Xvt > fromSvTransmit(const Position &rxPos, NavLibrary &navLib, const NavSatelliteID &sat, const CommonTime &transmit, const EllipsoidModel &ellipsoid, bool smallAngleApprox=false, SVHealth xmitHealth=SVHealth::Any, NavValidityType valid=NavValidityType::ValidOnly, NavSearchOrder order=NavSearchOrder::User, double seed=0.07, double threshold=1.e-13, int maxIter=5)
Definition: RawRange.cpp:90
gnsstk::NavSatelliteID
Definition: NavSatelliteID.hpp:57
gnsstk::NavLibrary::getXvt
bool getXvt(const NavSatelliteID &sat, const CommonTime &when, Xvt &xvt, bool useAlm, SVHealth xmitHealth=SVHealth::Any, NavValidityType valid=NavValidityType::ValidOnly, NavSearchOrder order=NavSearchOrder::User)
Definition: NavLibrary.cpp:52
NavSatelliteID.hpp
gnsstk::SatID
Definition: SatID.hpp:89
SatID.hpp
gnsstk::TropModel
Definition: TropModel.hpp:105
Position.hpp
gnsstk::GPSEllipsoid
Definition: GPSEllipsoid.hpp:67
GNSSconstants.hpp
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::RawRange::fromReceive
static std::tuple< bool, double, Xvt > fromReceive(const Position &rxPos, const CommonTime &receive, NavLibrary &navLib, const NavSatelliteID &sat, const EllipsoidModel &ellipsoid, bool smallAngleApprox=false, SVHealth xmitHealth=SVHealth::Any, NavValidityType valid=NavValidityType::ValidOnly, NavSearchOrder order=NavSearchOrder::User, double seed=0.07, double threshold=1.e-13, int maxIter=5)
Definition: RawRange.cpp:150
gnsstk::ord::RawRange4
double RawRange4(const gnsstk::Position &rxLoc, const gnsstk::SatID &satId, const gnsstk::CommonTime &time, NavLibrary &ephemeris, gnsstk::Xvt &svXvt)
Definition: ord.cpp:165
gnsstk::Position::azimuth
double azimuth(const Position &Target) const
Definition: Position.cpp:1365
gnsstk::Xvt::relcorr
double relcorr
relativity correction (standard 2R.V/c^2 term), seconds
Definition: Xvt.hpp:155
example4.tropModel
tropModel
Definition: example4.py:20
gnsstk::RawRange::fromSvTransmitWithObs
static std::tuple< bool, double, Xvt > fromSvTransmitWithObs(const Position &rxPos, double pseudorange, NavLibrary &navLib, const NavSatelliteID &sat, const CommonTime &transmit, const EllipsoidModel &ellipsoid, bool smallAngleApprox=false, SVHealth xmitHealth=SVHealth::Any, NavValidityType valid=NavValidityType::ValidOnly, NavSearchOrder order=NavSearchOrder::User)
Definition: RawRange.cpp:118
gnsstk::Exception
Definition: Exception.hpp:151
gnsstk::SVHealth::Any
@ Any
Use in searches when you don't care about the SV health.
gnsstk::Xvt::x
Triple x
Sat position ECEF Cartesian (X,Y,Z) meters.
Definition: Xvt.hpp:151
gnsstk::ord::IonosphereModelCorrection
double IonosphereModelCorrection(const gnsstk::IonoModelStore &ionoModel, const gnsstk::CommonTime &time, CarrierBand band, const gnsstk::Position &rxLoc, const gnsstk::Xvt &svXvt)
Definition: ord.cpp:94
gnsstk::IonoModelStore
Definition: IonoModelStore.hpp:62
NavLibrary.hpp
gnsstk::GPSEllipsoid::c
virtual double c() const noexcept
Definition: GPSEllipsoid.hpp:87
gnsstk::NavLibrary
Definition: NavLibrary.hpp:944
gnsstk::C_MPS
const double C_MPS
m/s, speed of light; this value defined by GPS but applies to GAL and GLO.
Definition: GNSSconstants.hpp:74
gnsstk::NavValidityType::ValidOnly
@ ValidOnly
Only load/find nav messages that pass validity checks.
example4.time
time
Definition: example4.py:103
gnsstk::ord::SvRelativityCorrection
double SvRelativityCorrection(gnsstk::Xvt &svXvt)
Definition: ord.cpp:210
gnsstk::CommonTime
Definition: CommonTime.hpp:84
gnsstk::Xvt::clkdrift
double clkdrift
satellite clock drift in seconds/second
Definition: Xvt.hpp:154
RawRange.hpp
gnsstk::Xvt
Definition: Xvt.hpp:60
gnsstk::ord::getSvXvt
gnsstk::Xvt getSvXvt(const gnsstk::SatID &satId, const gnsstk::CommonTime &time, NavLibrary &ephemeris)
Definition: ord.cpp:107
gnsstk::ord::RawRange3
double RawRange3(double pseudorange, const gnsstk::Position &rxLoc, const gnsstk::SatID &satId, const gnsstk::CommonTime &time, NavLibrary &ephemeris, gnsstk::Xvt &svXvt)
Definition: ord.cpp:151
GPSEllipsoid.hpp
GNSSTK_ASSERT
#define GNSSTK_ASSERT(CONDITION)
Provide an "ASSERT" type macro.
Definition: Exception.hpp:373
CommonTime.hpp
gnsstk::ord::TroposphereCorrection
double TroposphereCorrection(const gnsstk::TropModel &tropModel, const gnsstk::Position &rxLoc, const gnsstk::Xvt &svXvt)
Definition: ord.cpp:215
gnsstk::ord::RawRange2
double RawRange2(double pseudorange, const Position &rxLoc, const SatID &satId, const CommonTime &time, NavLibrary &ephemeris, Xvt &svXvt)
Definition: ord.cpp:136
gnsstk::range
double range(const Position &A, const Position &B)
Definition: Position.cpp:1273
gnsstk::Triple::slantRange
double slantRange(const Triple &right) const noexcept
Definition: Triple.cpp:173
gnsstk::Position
Definition: Position.hpp:136
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
gnsstk::Xvt::clkbias
double clkbias
Sat clock correction in seconds.
Definition: Xvt.hpp:153
gnsstk::NavSearchOrder::User
@ User
Return the latest message before the search time.
gnsstk::IonoModelStore::getCorrection
virtual double getCorrection(const CommonTime &time, const Position &rxgeo, double svel, double svaz, CarrierBand band=CarrierBand::L1) const
Definition: IonoModelStore.cpp:61
gnsstk::Xvt::computeRelativityCorrection
virtual double computeRelativityCorrection(void)
Definition: Xvt.cpp:98
gnsstk::Position::elevation
double elevation(const Position &Target) const
Definition: Position.cpp:1308
gnsstk::ord::IonosphereFreeRange
double IonosphereFreeRange(const std::vector< double > &frequencies, const std::vector< double > &pseudoranges)
Definition: ord.cpp:60


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:40