RawRange.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 <limits>
41 #include "GNSSconstants.hpp"
42 #include "RawRange.hpp"
43 #include "Triple.hpp"
44 #include "CommonTime.hpp"
45 #include "EllipsoidModel.hpp"
46 #include "NavLibrary.hpp"
47 #include "NavSatelliteID.hpp"
48 #include "EllipsoidModel.hpp"
49 #include "SVHealth.hpp"
50 #include "NavValidityType.hpp"
51 #include "NavSearchOrder.hpp"
52 #include "Xvt.hpp"
53 #include "Position.hpp"
54 
55 namespace gnsstk
56 {
57  std::tuple<bool, double, Xvt> RawRange::fromSvPos(
58  const Position& rxPos,
59  const Xvt& svXvt,
60  const EllipsoidModel& ellipsoid,
61  bool smallAngleApprox,
62  double seed,
63  double threshold,
64  int maxIter
65  )
66  {
67  int iter = 0;
68  double tof = seed;
69  double tof_prev;
70  double range;
71  Xvt rotatedSvXvt;
72 
73  // Optimize `tau = range(tau) / c`
74  do {
75  tof_prev = tof;
76 
77  std::tie(range, rotatedSvXvt) =
78  computeRange(rxPos, svXvt, tof, ellipsoid, smallAngleApprox);
79 
80  tof = range / ellipsoid.c();
81 
82  } while(ABS(tof - tof_prev) > threshold && ++iter < maxIter);
83 
84  std::tie(range, rotatedSvXvt) =
85  computeRange(rxPos, svXvt, tof, ellipsoid, smallAngleApprox);
86 
87  return std::make_tuple(true, range, rotatedSvXvt);
88  }
89 
90  std::tuple<bool, double, Xvt> RawRange::fromSvTransmit(
91  const Position& rxPos,
92  NavLibrary& navLib,
93  const NavSatelliteID& sat,
94  const CommonTime& transmit,
95  const EllipsoidModel& ellipsoid,
96  bool smallAngleApprox,
97  SVHealth xmitHealth,
99  NavSearchOrder order,
100  double seed,
101  double threshold,
102  int maxIter
103  )
104  {
105  Xvt svXvt;
106  // false = always use ephemeris
107  if(!navLib.getXvt(sat, transmit, svXvt, false, xmitHealth, valid, order))
108  {
109  return std::make_tuple(false,
110  std::numeric_limits<double>::quiet_NaN(),
111  svXvt);
112  }
113 
114  return fromSvPos(rxPos, svXvt, ellipsoid, smallAngleApprox,
115  seed, threshold, maxIter);
116  }
117 
118  std::tuple<bool, double, Xvt> RawRange::fromSvTransmitWithObs(
119  const Position& rxPos,
120  double pseudorange,
121  NavLibrary& navLib,
122  const NavSatelliteID& sat,
123  const CommonTime& transmit,
124  const EllipsoidModel& ellipsoid,
125  bool smallAngleApprox,
126  SVHealth xmitHealth,
128  NavSearchOrder order
129  )
130  {
131  Xvt svXvt;
132  if(!navLib.getXvt(sat, transmit, svXvt, false, xmitHealth, valid, order))
133  {
134  return std::make_tuple(false,
135  std::numeric_limits<double>::quiet_NaN(),
136  svXvt);
137  }
138 
139  double tof = (pseudorange / ellipsoid.c()) - svXvt.clkbias - svXvt.relcorr;
140 
141  double range;
142  Xvt rotatedSvXvt;
143  std::tie(range, rotatedSvXvt) =
144  computeRange(rxPos, svXvt, tof, ellipsoid, smallAngleApprox);
145 
146  return std::make_tuple(true, range, rotatedSvXvt);
147  }
148 
149 
150  std::tuple<bool, double, Xvt> RawRange::fromReceive(
151  const Position& rxPos,
152  const CommonTime& receive,
153  NavLibrary& navLib,
154  const NavSatelliteID& sat,
155  const EllipsoidModel& ellipsoid,
156  bool smallAngleApprox,
157  SVHealth xmitHealth,
159  NavSearchOrder order,
160  double seed,
161  double threshold,
162  int maxIter)
163  {
164  bool success;
165  CommonTime transmitEst;
166  Xvt svXvt;
167 
168  // Estimate transmit time by iterative optimization
169  std::tie(success, transmitEst) =
170  estTransmitFromReceive(rxPos, receive, navLib, sat, ellipsoid,
171  xmitHealth, valid, order, seed,
172  threshold, maxIter);
173  if(!success)
174  {
175  return std::make_tuple(false,
176  std::numeric_limits<double>::quiet_NaN(),
177  svXvt);
178  }
179 
180  // Get SV position at estimated transmit time
181  success = navLib.getXvt(sat, transmitEst, svXvt, false,
182  xmitHealth, valid, order);
183  if(!success)
184  {
185  return std::make_tuple(false,
186  std::numeric_limits<double>::quiet_NaN(),
187  svXvt);
188  }
189 
190  // Compute range between SV and RX
191  double range;
192  Xvt rotatedSvXvt;
193  std::tie(range, rotatedSvXvt) = computeRange(rxPos, receive, svXvt,
194  transmitEst, ellipsoid,
195  smallAngleApprox);
196  return std::make_tuple(true, range, rotatedSvXvt);
197  }
198 
199  std::tuple<bool, double, Xvt> RawRange::fromNominalReceive(
200  const Position& rxPos,
201  const CommonTime& receiveNominal,
202  NavLibrary& navLib,
203  const NavSatelliteID& sat,
204  const EllipsoidModel& ellipsoid,
205  bool smallAngleApprox,
206  SVHealth xmitHealth,
208  NavSearchOrder order,
209  double seed,
210  double threshold,
211  int maxIter)
212  {
213  bool success;
214  double range;
215  Xvt rotatedSvXvt;
216 
217  // First estimate the range by using the receiveNominal as the
218  // transmit time.
219  std::tie(success, range, rotatedSvXvt) =
220  fromSvTransmit(rxPos, navLib, sat, receiveNominal, ellipsoid,
221  smallAngleApprox, xmitHealth, valid, order,
222  seed, threshold, maxIter);
223  if(!success)
224  {
225  return std::make_tuple(false,
226  std::numeric_limits<double>::quiet_NaN(),
227  rotatedSvXvt);
228  }
229 
230  // Create mock pseudorange using the estimated range and clock offsets
231  double fakePsuedorange =
232  range - (rotatedSvXvt.clkbias + rotatedSvXvt.relcorr) * ellipsoid.c();
233 
234  // Compute range by using mock pseudorange
235  std::tie(success, range, rotatedSvXvt) =
236  fromNominalReceiveWithObs(rxPos, receiveNominal, fakePsuedorange,
237  navLib, sat, ellipsoid, smallAngleApprox,
238  xmitHealth, valid, order);
239  return std::make_tuple(success, range, rotatedSvXvt);
240  }
241 
242  std::tuple<bool, double, Xvt> RawRange::fromNominalReceiveWithObs(
243  const Position& rxPos,
244  const CommonTime& receiveNominal,
245  double pseudorange,
246  NavLibrary& navLib,
247  const NavSatelliteID& sat,
248  const EllipsoidModel& ellipsoid,
249  bool smallAngleApprox,
250  SVHealth xmitHealth,
252  NavSearchOrder order)
253  {
254  bool success;
255  CommonTime transmitEst;
256  Xvt svXvt;
257 
258  // Estimate transmit time
259  std::tie(success, transmitEst) =
260  estTransmitFromObs(receiveNominal, pseudorange, navLib, sat,
261  xmitHealth, valid, order);
262  if(!success)
263  {
264  return std::make_tuple(false,
265  std::numeric_limits<double>::quiet_NaN(),
266  svXvt);
267  }
268 
269  // Get SV position at transmit time
270  success = navLib.getXvt(sat, transmitEst, svXvt, false,
271  xmitHealth, valid, order);
272  if(!success)
273  {
274  return std::make_tuple(false,
275  std::numeric_limits<double>::quiet_NaN(),
276  svXvt);
277  }
278 
279  // Estimate time of flight (tof)
280  // Can't use receiveNominal to estimate the time of flight
281  // since receiveNominal might contain a large receiver clock offset.
282  // A more consistent approach is to derive tof from the "instantaneous"
283  // range from the now known SV pos at transmit time
284  double range;
285  std::tie(range, std::ignore) =
286  computeRange(rxPos, svXvt, 0, ellipsoid, smallAngleApprox);
287  double tof = range / ellipsoid.c();
288 
289  // Compute range using the estimated tof
290  Xvt rotatedSvXvt;
291  std::tie(range, rotatedSvXvt) =
292  computeRange(rxPos, svXvt, tof, ellipsoid, smallAngleApprox);
293 
294  return std::make_tuple(true, range, rotatedSvXvt);
295  }
296 
297 
298  std::tuple<bool, CommonTime> RawRange::estTransmitFromReceive(
299  const Position& rxPos,
300  const CommonTime& receive,
301  NavLibrary& navLib,
302  const NavSatelliteID& sat,
303  const EllipsoidModel& ellipsoid,
304  SVHealth xmitHealth,
306  NavSearchOrder order,
307  double seed,
308  double threshold,
309  int maxIter)
310  {
311  Xvt svXvt;
312  CommonTime estTransmit;
313  int iter = 0;
314  double tof = seed;
315  double prevTof;
316 
317  // Optimize this pair of functions:
318  // `transmit = receive - tof`
319  // `tof = range(transmit, tof) / c`
320  do {
321  estTransmit = receive - tof;
322 
323  if(!navLib.getXvt(sat, estTransmit, svXvt,
324  false, xmitHealth, valid, order))
325  {
326  return std::make_tuple(false, CommonTime::BEGINNING_OF_TIME);
327  }
328 
329  double range;
330  std::tie(range, std::ignore) =
331  computeRange(rxPos, receive, svXvt, estTransmit, ellipsoid);
332  // std::tie(range, std::ignore) =
333  // computeRange(rxPos, svXvt, 0, ellipsoid);
334  // std::tie(range, std::ignore) =
335  // computeRange(rxPos, svXvt, range / ellipsoid.c(), ellipsoid);
336 
337 
338  prevTof = tof;
339  tof = range / ellipsoid.c();
340 
341  } while(ABS(tof - prevTof) > threshold && ++iter < maxIter);
342 
343  return std::make_tuple(true, estTransmit);
344  }
345 
346 
347  std::tuple<bool, CommonTime> RawRange::estTransmitFromObs(
348  const CommonTime& nominalReceive,
349  double pseudorange,
350  NavLibrary& navLib,
351  const NavSatelliteID& sat,
352  SVHealth xmitHealth,
354  NavSearchOrder order
355  )
356  {
357  CommonTime nominalTransmit = nominalReceive - (pseudorange / C_MPS);
358 
359  Xvt svXvt;
360  if(!navLib.getXvt(sat, nominalTransmit, svXvt, false,
361  xmitHealth, valid, order))
362  {
363  return std::make_tuple(false, CommonTime::BEGINNING_OF_TIME);
364  }
365 
366  CommonTime transmit = nominalTransmit - (svXvt.clkbias + svXvt.relcorr);
367  return std::make_tuple(true, transmit);
368  }
369 
370 
371  std::tuple<double, Xvt> RawRange::computeRange(
372  const Position& rxPos,
373  const CommonTime& receive,
374  const Xvt& svXvt,
375  const CommonTime& transmit,
376  const EllipsoidModel& ellipsoid,
377  bool smallAngleApprox)
378  {
379  double tof = receive - transmit;
380  return computeRange(rxPos, svXvt, tof, ellipsoid, smallAngleApprox);
381  }
382 
383  std::tuple<double, Xvt> RawRange::computeRange(
384  const Position& rxPos,
385  const Xvt& svXvt,
386  double tof,
387  const EllipsoidModel& ellipsoid,
388  bool smallAngleApprox)
389  {
390  Xvt svXvtRotated = rotateECEF(svXvt, tof, ellipsoid, smallAngleApprox);
391  double dist = range(rxPos, svXvtRotated.x);
392  return std::make_tuple(dist, svXvtRotated);
393  }
394 
395  std::tuple<double, Position> RawRange::computeRange(
396  const Position& rxPos,
397  const CommonTime& receive,
398  const Position& svPos,
399  const CommonTime& transmit,
400  const EllipsoidModel& ellipsoid,
401  bool smallAngleApprox)
402  {
403  double tof = receive - transmit;
404  return computeRange(rxPos, svPos, tof, ellipsoid, smallAngleApprox);
405  }
406 
407  std::tuple<double, Position> RawRange::computeRange(
408  const Position& rxPos,
409  const Position& svPos,
410  double tof,
411  const EllipsoidModel& ellipsoid,
412  bool smallAngleApprox
413  )
414  {
415  Position svPosRotated = rotateECEF(svPos, tof, ellipsoid, smallAngleApprox);
416  double dist = range(rxPos, svPosRotated);
417  return std::make_tuple(dist, svPosRotated);
418  }
419 
421  const Triple& vec,
422  double dt,
423  const EllipsoidModel& ellipsoid,
424  bool smallAngleApprox)
425  {
426  double rotate = dt * ellipsoid.angVelocity();
427 
428  Triple vecRotated(vec);
429 
430  if(smallAngleApprox)
431  {
432  vecRotated[0] = vec[0] + vec[1] * rotate;
433  vecRotated[1] = vec[1] - vec[0] * rotate;
434  vecRotated[2] = vec[2];
435  }
436  else
437  {
438  vecRotated = vec.R3(rotate * RAD_TO_DEG);
439  }
440 
441  return vecRotated;
442  }
443 
445  const Position& vec,
446  double dt,
447  const EllipsoidModel& ellipsoid,
448  bool smallAngleApprox)
449  {
450  Position pos(vec);
451  Position::CoordinateSystem sys = pos.getCoordinateSystem();
452  pos.asECEF();
453 
454  Triple rotatedVec = rotateECEF(static_cast<Triple>(pos), dt,
455  ellipsoid, smallAngleApprox);
456  pos.setECEF(rotatedVec);
457  pos.transformTo(sys);
458 
459  return pos;
460  }
461 
463  const Xvt& xvt,
464  double dt,
465  const EllipsoidModel& ellipsoid,
466  bool smallAngleApprox)
467  {
468  Xvt returnXvt(xvt);
469  returnXvt.x = rotateECEF(xvt.x, dt, ellipsoid, smallAngleApprox);
470  returnXvt.v = rotateECEF(xvt.v, dt, ellipsoid, smallAngleApprox);
471  return returnXvt;
472  }
473 
474 
475 } // namespace gnsstk
gnsstk::RawRange::fromSvPos
static std::tuple< bool, double, Xvt > fromSvPos(const Position &rxPos, const Xvt &svXvt, const EllipsoidModel &ellipsoid, bool smallAngleApprox=false, double seed=0.07, double threshold=1.e-13, int maxIter=5)
Definition: RawRange.cpp:57
gnsstk::RawRange::fromNominalReceive
static std::tuple< bool, double, Xvt > fromNominalReceive(const Position &rxPos, const CommonTime &receiveNominal, 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.7, double threshold=1.e-13, int maxIter=5)
Definition: RawRange.cpp:199
Xvt.hpp
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
SVHealth.hpp
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
Position.hpp
gnsstk::EllipsoidModel::angVelocity
virtual double angVelocity() const noexcept=0
gnsstk::CommonTime::BEGINNING_OF_TIME
static const GNSSTK_EXPORT CommonTime BEGINNING_OF_TIME
earliest representable CommonTime
Definition: CommonTime.hpp:102
gnsstk::Xvt::v
Triple v
satellite velocity in ECEF Cartesian, meters/second
Definition: Xvt.hpp:152
gnsstk::SVHealth
SVHealth
Identify different types of SV health states.
Definition: SVHealth.hpp:52
gnsstk::NavValidityType
NavValidityType
Definition: NavValidityType.hpp:53
GNSSconstants.hpp
gnsstk::NavSearchOrder
NavSearchOrder
Specify the behavior of nav data searches in NavLibrary/NavDataFactory.
Definition: NavSearchOrder.hpp:51
gnsstk::Triple
Definition: Triple.hpp:68
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::Xvt::relcorr
double relcorr
relativity correction (standard 2R.V/c^2 term), seconds
Definition: Xvt.hpp:155
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::RawRange::estTransmitFromReceive
static std::tuple< bool, CommonTime > estTransmitFromReceive(const Position &rxPos, const CommonTime &receive, NavLibrary &navLib, const NavSatelliteID &sat, const EllipsoidModel &ellipsoid, 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:298
gnsstk::Xvt::x
Triple x
Sat position ECEF Cartesian (X,Y,Z) meters.
Definition: Xvt.hpp:151
gnsstk::RAD_TO_DEG
static const double RAD_TO_DEG
Conversion Factor from radians to degrees (units: degrees)
Definition: GNSSconstants.hpp:78
NavLibrary.hpp
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::Triple::R3
Triple R3(const double &angle) const noexcept
Definition: Triple.cpp:285
gnsstk::CommonTime
Definition: CommonTime.hpp:84
NavValidityType.hpp
RawRange.hpp
example6.valid
valid
Definition: example6.py:20
gnsstk::Xvt
Definition: Xvt.hpp:60
gnsstk::Position::CoordinateSystem
CoordinateSystem
The coordinate systems supported by Position.
Definition: Position.hpp:142
example4.pos
pos
Definition: example4.py:125
ABS
#define ABS(x)
Definition: MathBase.hpp:73
CommonTime.hpp
gnsstk::range
double range(const Position &A, const Position &B)
Definition: Position.cpp:1273
Triple.hpp
gnsstk::Position
Definition: Position.hpp:136
NavSearchOrder.hpp
gnsstk::Xvt::clkbias
double clkbias
Sat clock correction in seconds.
Definition: Xvt.hpp:153
gnsstk::EllipsoidModel
Definition: EllipsoidModel.hpp:56
gnsstk::EllipsoidModel::c
virtual double c() const noexcept=0
gnsstk::RawRange::estTransmitFromObs
static std::tuple< bool, CommonTime > estTransmitFromObs(const CommonTime &receiveNominal, double pseudorange, NavLibrary &navLib, const NavSatelliteID &sat, SVHealth xmitHealth=SVHealth::Any, NavValidityType valid=NavValidityType::ValidOnly, NavSearchOrder order=NavSearchOrder::User)
Definition: RawRange.cpp:347
gnsstk::RawRange::computeRange
static std::tuple< double, Xvt > computeRange(const Position &rxPos, const CommonTime &receive, const Xvt &svXvt, const CommonTime &transmit, const EllipsoidModel &ellipsoid, bool smallAngleApprox=false)
Definition: RawRange.cpp:371
gnsstk::RawRange::rotateECEF
static Triple rotateECEF(const Triple &vec, double dt, const EllipsoidModel &ellipsoid, bool smallAngleApprox=false)
Definition: RawRange.cpp:420
EllipsoidModel.hpp


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