PreciseRange.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 
44 // system includes
45 #include <sstream> // for ostringstream
46 #include <tuple>
47 // GNSSTk includes
48 #include "GNSSconstants.hpp"
49 #include "EllipsoidModel.hpp"
50 #include "GPSEllipsoid.hpp"
51 #include "MiscMath.hpp"
52 #include "Xvt.hpp"
53 #include "RawRange.hpp"
54 
55 // geomatics
56 #include "SolarPosition.hpp"
57 #include "SunEarthSatGeometry.hpp"
58 
59 #include "PreciseRange.hpp"
60 
61 using namespace std;
62 
63 namespace gnsstk
64 {
65  double PreciseRange::ComputeAtTransmitTime(const CommonTime& nomRecTime,
66  const double pr,
67  const Position& rxPos,
68  const SatID sat,
69  const AntexData& antenna,
70  const std::string& freq1,
71  const std::string& freq2,
72  SolarSystem& solSys,
73  NavLibrary& eph,
74  bool isCOM,
75  const EllipsoidModel& ellipsoid)
76  {
77  try
78  {
79  bool success;
80  Xvt svPosVel;
81 
82  // Initial transmit time estimate from pseudorange
83  std::tie(success, transmit) =
84  RawRange::estTransmitFromObs(nomRecTime, pr, eph,
85  NavSatelliteID(sat));
86  if(!success)
87  {
88  InvalidRequest ir("getXvt failed");
89  GNSSTK_THROW(ir);
90  }
91 
92  if(!eph.getXvt(NavSatelliteID(sat), transmit, svPosVel))
93  {
94  InvalidRequest ir("getXvt failed");
95  GNSSTK_THROW(ir);
96  }
97 
98  SatR.setECEF(svPosVel.x);
99 
100  /* Sagnac effect
101  ref. Ashby and Spilker, GPS: Theory and Application, 1996 Vol 1, pg
102  673. this is w(Earth) * (SatR cross rxPos).Z() / c*c in seconds beware
103  numerical error by differencing very large to get very small */
104  Sagnac = ((SatR.X() / ellipsoid.c()) * (rxPos.Y() / ellipsoid.c()) -
105  (SatR.Y() / ellipsoid.c()) * (rxPos.X() / ellipsoid.c())) *
106  ellipsoid.angVelocity();
107  transmit -= Sagnac;
108 
109  /* compute other delays -- very small
110  2GM/c^2 = 0.00887005608 m^3/s^2 * s^2/m^2 = m */
111  double rx = rxPos.radius();
112  if (::fabs(rx) < 1.e-8)
113  {
114  GNSSTK_THROW(Exception("Rx at origin!"));
115  }
116  double rs = SatR.radius();
117  double dr;
118  std::tie(dr, std::ignore) =
119  RawRange::computeRange(rxPos, SatR, 0, ellipsoid);
120  relativity2 = -0.00887005608 * ::log((rx + rs + dr) / (rx + rs - dr));
121  transmit -= relativity2 / ellipsoid.c();
122 
123  // iterate satellite position
124  if(! eph.getXvt(NavSatelliteID(sat), transmit, svPosVel))
125  {
126  InvalidRequest ir("getXvt failed");
127  GNSSTK_THROW(ir);
128  }
129 
130  // ----------------------------------------------------------
131  // save relativity and satellite clock
132  relativity = svPosVel.relcorr * ellipsoid.c();
133  satclkbias = svPosVel.clkbias * ellipsoid.c();
134  satclkdrift = svPosVel.clkdrift * ellipsoid.c();
135 
136  // correct for Earth rotation
137  std::tie(rawrange, std::ignore) =
138  RawRange::computeRange(rxPos, SatR, 0, ellipsoid);
139  double dt = rawrange / ellipsoid.c();
140  std::tie(rawrange, svPosVel) =
141  RawRange::computeRange(rxPos, svPosVel, dt, ellipsoid);
142 
143  // Do NOT replace these with Xvt
144  SatR.setECEF(svPosVel.x);
145  SatV.setECEF(svPosVel.v);
146 
147  // Compute line of sight, satellite to receiver
148  Triple S2R(rxPos.X() - SatR.X(), rxPos.Y() - SatR.Y(), rxPos.Z() - SatR.Z());
149  S2R = S2R.unitVector();
150 
151  // ----------------------------------------------------------
152  // satellite antenna pco and pcv
153  if (isCOM && antenna.isValid())
154  {
155  // must combine PCO/V from freq1,2
156  unsigned int freq1num(strtoul(freq1.substr(1).c_str(), 0, 10));
157  unsigned int freq2num(strtoul(freq2.substr(1).c_str(), 0, 10));
158  double alpha(getAlpha(sat.system, freq1num, freq2num));
159  double fact1((alpha + 1.0) / alpha);
160  double fact2(-1.0 / alpha);
161 
162  // if single frequency, freq2==alpha==0, fact's=nan
163  if (freq2num == 0)
164  {
165  fact1 = 1.0;
166  fact2 = 0.0;
167  }
168 
169  // rotation matrix from satellite attitude: Rot*[XYZ]=[body frame]
170  Matrix<double> SVAtt;
171 
172  // get satellite attitude from SolarSystem; if not valid, get low
173  // accuracy version from SunEarthSatGeometry and SolarPosition.
174  if (solSys.EphNumber() != -1)
175  {
176  SVAtt = solSys.satelliteAttitude(transmit, SatR);
177  }
178  else
179  {
180  double AR; // angular radius of sun
181  Position Sun = solarPosition(transmit, AR);
182  SVAtt = satelliteAttitude(SatR, Sun);
183  }
184 
185  // phase center offset vector in body frame
186  Vector<double> PCO(3);
187  Triple pco2, pco1(antenna.getPhaseCenterOffset(freq1));
188  if (freq2num != 0)
189  {
190  pco2 = antenna.getPhaseCenterOffset(freq2);
191  }
192  for (unsigned int i = 0; i < 3; i++)
193  {
194  // body frame, mm -> m, iono-free combo
195  PCO(i) = (fact1 * pco1[i] + fact2 * pco2[i]) / 1000.0;
196  }
197 
198  // PCO vector (from COM to PC) in ECEF XYZ frame, m
199  SatPCOXYZ = transpose(SVAtt) * PCO;
200 
201  Triple pcoxyz(SatPCOXYZ(0), SatPCOXYZ(1), SatPCOXYZ(2));
202  // line of sight phase center offset
203  satLOSPCO = pcoxyz.dot(S2R); // meters
204 
205  // phase center variation TD should this should be subtracted from
206  // rawrange? get the body frame azimuth and nadir angles
207  double nadir, az, pcv1, pcv2(0.0);
208  satelliteNadirAzimuthAngles(SatR, rxPos, SVAtt, nadir, az);
209  pcv1 = antenna.getPhaseCenterVariation(freq1, az, nadir);
210  if (freq2num != 0)
211  {
212  pcv2 = antenna.getPhaseCenterVariation(freq2, az, nadir);
213  }
214  satLOSPCV = 0.001 * (fact1 * pcv1 + fact2 * pcv2);
215  }
216  else
217  {
218  satLOSPCO = satLOSPCV = 0.0;
219  SatPCOXYZ = Vector<double>(3, 0.0);
220  }
221 
222  // ----------------------------------------------------------
223  // direction cosines
224  for (unsigned int i = 0; i < 3; i++)
225  {
226  cosines[i] = -S2R[i]; // receiver to satellite
227  }
228 
229  // elevation and azimuth
230  elevation = rxPos.elevation(SatR);
231  azimuth = rxPos.azimuth(SatR);
232  elevationGeodetic = rxPos.elevationGeodetic(SatR);
233  azimuthGeodetic = rxPos.azimuthGeodetic(SatR);
234 
235  // return corrected ephemeris range
236  return (rawrange - satclkbias - relativity - relativity2 - satLOSPCO +
237  satLOSPCV);
238 
239  } // end try
240  catch (gnsstk::Exception& e)
241  {
242  GNSSTK_RETHROW(e);
243  }
244 
245  } // end PreciseRange::ComputeAtTransmitTime
246 
247 } // namespace gnsstk
Xvt.hpp
SunEarthSatGeometry.hpp
SolarPosition.hpp
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
gnsstk::SatID
Definition: SatID.hpp:89
gnsstk::EllipsoidModel::angVelocity
virtual double angVelocity() const noexcept=0
gnsstk::Position::Y
double Y() const noexcept
return Y coordinate (meters)
Definition: Position.cpp:364
gnsstk::Position::Z
double Z() const noexcept
return Z coordinate (meters)
Definition: Position.cpp:375
gnsstk::Xvt::v
Triple v
satellite velocity in ECEF Cartesian, meters/second
Definition: Xvt.hpp:152
GNSSconstants.hpp
gnsstk::Triple
Definition: Triple.hpp:68
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::Triple::unitVector
Triple unitVector() const
Definition: Triple.cpp:134
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
gnsstk::SolarSystemEphemeris::EphNumber
int EphNumber() const
Definition: SolarSystemEphemeris.hpp:303
gnsstk::getAlpha
double getAlpha(SatelliteSystem sys, int na, int nb) noexcept
Definition: FreqConsts.hpp:286
gnsstk::Position::azimuthGeodetic
double azimuthGeodetic(const Position &Target) const
Definition: Position.cpp:1391
MiscMath.hpp
gnsstk::Exception
Definition: Exception.hpp:151
gnsstk::Xvt::x
Triple x
Sat position ECEF Cartesian (X,Y,Z) meters.
Definition: Xvt.hpp:151
gnsstk::Triple::dot
double dot(const Triple &right) const noexcept
Definition: Triple.cpp:107
gnsstk::satelliteNadirAzimuthAngles
void satelliteNadirAzimuthAngles(const Position &sv, const Position &rx, const Matrix< double > &rot, double &nadir, double &azimuth)
Definition: SunEarthSatGeometry.cpp:377
gnsstk::transpose
SparseMatrix< T > transpose(const SparseMatrix< T > &M)
transpose
Definition: SparseMatrix.hpp:829
gnsstk::satelliteAttitude
Matrix< double > satelliteAttitude(const Position &sat, const Position &sun)
Definition: SunEarthSatGeometry.cpp:266
PreciseRange.hpp
gnsstk::NavLibrary
Definition: NavLibrary.hpp:944
gnsstk::Matrix< double >
gnsstk::AntexData
Definition: AntexData.hpp:120
gnsstk::AntexData::isValid
bool isValid() const
Convenience function returns true only if a valid object.
Definition: AntexData.hpp:311
gnsstk::Position::radius
double radius() const noexcept
Definition: Position.cpp:444
gnsstk::CommonTime
Definition: CommonTime.hpp:84
log
#define log
Definition: DiscCorr.cpp:625
gnsstk::Xvt::clkdrift
double clkdrift
satellite clock drift in seconds/second
Definition: Xvt.hpp:154
RawRange.hpp
gnsstk::Xvt
Definition: Xvt.hpp:60
gnsstk::solarPosition
Position solarPosition(const CommonTime &t, double &AR)
Definition: SolarPosition.cpp:96
GNSSTK_RETHROW
#define GNSSTK_RETHROW(exc)
Definition: Exception.hpp:369
gnsstk::Vector< double >
gnsstk::SatID::system
SatelliteSystem system
System for this satellite.
Definition: SatID.hpp:156
GPSEllipsoid.hpp
gnsstk::Position::X
double X() const noexcept
return X coordinate (meters)
Definition: Position.cpp:353
std
Definition: Angle.hpp:142
gnsstk::AntexData::getPhaseCenterOffset
Triple getPhaseCenterOffset(const std::string &freq) const
Definition: AntexData.cpp:205
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::EllipsoidModel
Definition: EllipsoidModel.hpp:56
gnsstk::AntexData::getPhaseCenterVariation
double getPhaseCenterVariation(const std::string &freq, double azimuth, double elev_nadir) const
Definition: AntexData.cpp:234
gnsstk::SolarSystem::satelliteAttitude
Matrix< double > satelliteAttitude(const EphTime &tt, const Position &SV)
Definition: SolarSystem.hpp:373
gnsstk::EllipsoidModel::c
virtual double c() const noexcept=0
gnsstk::Position::elevationGeodetic
double elevationGeodetic(const Position &Target) const
Definition: Position.cpp:1331
gnsstk::SolarSystem
Definition: SolarSystem.hpp:162
gnsstk::Position::elevation
double elevation(const Position &Target) const
Definition: Position.cpp:1308
EllipsoidModel.hpp


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