00001 #pragma ident "$Id: PreciseRange.cpp 2293 2010-02-12 18:14:16Z btolman $"
00002
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "MiscMath.hpp"
00046 #include "GPSGeoid.hpp"
00047 #include "icd_200_constants.hpp"
00048 #include "geometry.hpp"
00049 #include "Xvt.hpp"
00050
00051 #include "SunEarthSatGeometry.hpp"
00052 #include "PreciseRange.hpp"
00053
00054 using namespace std;
00055
00056 namespace gpstk
00057 {
00058 double PreciseRange::ComputeAtTransmitTime(const DayTime& nomRecTime,
00059 const double pr,
00060 const Position& Receiver,
00061 const SatID sat,
00062 const AntexData& antenna,
00063 const SolarSystem& SSEph,
00064 const EarthOrientation& EO,
00065 const XvtStore<SatID>& Eph,
00066 const bool isCOM)
00067 throw(Exception)
00068 {
00069 try {
00070 int i;
00071 Position Rx(Receiver);
00072 GPSGeoid geoid;
00073 Xvt svPosVel;
00074
00075
00076 transmit = nomRecTime;
00077 transmit -= pr/geoid.c();
00078
00079
00080
00081 try {
00082 svPosVel = Eph.getXvt(sat,transmit);
00083 SatR.setECEF(svPosVel.x[0],svPosVel.x[1],svPosVel.x[2]);
00084 }
00085
00086 catch(InvalidRequest& e) { GPSTK_RETHROW(e); }
00087
00088
00089 transmit -= svPosVel.dtime;
00090
00091
00092
00093
00094
00095 Sagnac = ( (SatR.X()/geoid.c()) * (Rx.Y()/geoid.c())
00096 - (SatR.Y()/geoid.c()) * (Rx.X()/geoid.c()) ) * geoid.angVelocity();
00097 transmit -= Sagnac;
00098
00099
00100
00101 double rx = Rx.radius();
00102 double rs = SatR.radius();
00103 double dr = range(SatR,Rx);
00104 relativity2 = -0.00887005608 * ::log((rx+rs+dr)/(rx+rs-dr));
00105 transmit -= relativity2 / geoid.c();
00106
00107
00108 try {
00109 svPosVel = Eph.getXvt(sat,transmit);
00110
00111 SatR.setECEF(svPosVel.x[0],svPosVel.x[1],svPosVel.x[2]);
00112 SatV.setECEF(svPosVel.v[0],svPosVel.v[1],svPosVel.v[2]);
00113 }
00114 catch(InvalidRequest& e) { GPSTK_RETHROW(e); }
00115
00116
00117
00118 relativity = RelativityCorrection(SatR,SatV) * geoid.c();
00119
00120
00121
00122 satclkbias = svPosVel.dtime * geoid.c() - relativity;
00123 satclkdrift = svPosVel.ddtime * geoid.c();
00124
00125
00126 double sxyz[3], wt;
00127 rawrange = range(SatR,Rx);
00128 wt = geoid.angVelocity() * rawrange/geoid.c();
00129 sxyz[0] = ::cos(wt)*SatR.X() + ::sin(wt)*SatR.Y();
00130 sxyz[1] = -::sin(wt)*SatR.X() + ::cos(wt)*SatR.Y();
00131 sxyz[2] = SatR.Z();
00132 SatR.setECEF(sxyz);
00133 sxyz[0] = ::cos(wt)*SatV.X() + ::sin(wt)*SatV.Y();
00134 sxyz[1] = -::sin(wt)*SatV.X() + ::cos(wt)*SatV.Y();
00135 sxyz[2] = SatV.Z();
00136 SatV.setECEF(sxyz);
00137
00138
00139 rawrange = range(SatR,Rx);
00140
00141
00142 Triple S2R(Rx.X()-SatR.X(),Rx.Y()-SatR.Y(),Rx.Z()-SatR.Z());
00143 S2R = S2R.unitVector();
00144
00145
00146
00147 if(isCOM && antenna.isValid()) {
00148 double sf;
00149
00150 Matrix<double> Rotation;
00151 if(SSEph.JPLNumber() > -1) {
00152
00153 Rotation = SatelliteAttitude(transmit, SatR, SSEph, EO, sf);
00154 }
00155 else {
00156
00157 Rotation = SatelliteAttitude(transmit, SatR, sf);
00158 }
00159
00160
00161 Triple pco = antenna.getPhaseCenterOffset(1);
00162 Vector<double> PCO(3);
00163 for(i=0; i<3; i++) PCO(i) = pco[i]/1000.0;
00164
00165
00166 SatPCOXYZ = transpose(Rotation) * PCO;
00167
00168 Triple pcoxyz(SatPCOXYZ(0),SatPCOXYZ(1),SatPCOXYZ(2));
00169 satLOSPCO = pcoxyz.dot(S2R);
00170
00171
00172
00173 double nadir,az;
00174 SatelliteNadirAzimuthAngles(SatR, Rx, Rotation, nadir, az);
00175 satLOSPCV = antenna.getPhaseCenterVariation(1, az, nadir) / 1000.;
00176 }
00177 else {
00178 satLOSPCO = satLOSPCV = 0.0;
00179 SatPCOXYZ=Vector<double>(3,0.0);
00180 }
00181
00182
00183
00184
00185
00186
00187
00188 for(i=0; i<3; i++) cosines[i] = -S2R[i];
00189
00190
00191 elevation = Rx.elevation(SatR);
00192 azimuth = Rx.azimuth(SatR);
00193 elevationGeodetic = Rx.elevationGeodetic(SatR);
00194 azimuthGeodetic = Rx.azimuthGeodetic(SatR);
00195
00196
00197 return (rawrange-satclkbias-relativity-relativity2-satLOSPCO+satLOSPCV);
00198
00199 }
00200 catch(gpstk::Exception& e) { GPSTK_RETHROW(e); }
00201
00202 }
00203
00204
00205 double RelativityCorrection(const Position& R, const Position& V)
00206 {
00207
00208
00209
00210
00211 double dtr = -2*(R.X()/C_GPS_M)*(V.X()/C_GPS_M)
00212 -2*(R.Y()/C_GPS_M)*(V.Y()/C_GPS_M)
00213 -2*(R.Z()/C_GPS_M)*(V.Z()/C_GPS_M);
00214
00215 return dtr;
00216 }
00217
00218 }