00001 #pragma ident "$Id: EphemerisRange.cpp 1264 2008-06-25 13:18:27Z ocibu $"
00002
00003
00004
00005
00006
00007
00008
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
00044 #include "EphemerisRange.hpp"
00045 #include "MiscMath.hpp"
00046 #include "GPSGeoid.hpp"
00047 #include "icd_200_constants.hpp"
00048 #include "geometry.hpp"
00049
00050 using namespace std;
00051 using namespace gpstk;
00052
00053 namespace gpstk
00054 {
00055
00056
00057
00058
00059
00060 double CorrectedEphemerisRange::ComputeAtReceiveTime(
00061 const DayTime& tr_nom,
00062 const Position& Rx,
00063 const SatID sat,
00064 const XvtStore<SatID>& Eph)
00065 {
00066 try {
00067 int nit;
00068 double tof,tof_old,wt,sx,sy;
00069 GPSGeoid geoid;
00070
00071 nit = 0;
00072 tof = 0.07;
00073 do {
00074
00075 transmit = tr_nom;
00076 transmit -= tof;
00077 tof_old = tof;
00078
00079 try {
00080 svPosVel = Eph.getXvt(sat, transmit);
00081 }
00082 catch(InvalidRequest& e) {
00083 GPSTK_RETHROW(e);
00084 }
00085
00086 rotateEarth(Rx);
00087
00088 rawrange = RSS(svPosVel.x[0]-Rx.X(),
00089 svPosVel.x[1]-Rx.Y(),
00090 svPosVel.x[2]-Rx.Z());
00091 tof = rawrange/geoid.c();
00092
00093 } while(ABS(tof-tof_old)>1.e-13 && ++nit<5);
00094
00095 updateCER(Rx);
00096
00097 return (rawrange-svclkbias-relativity);
00098 }
00099 catch(gpstk::Exception& e) {
00100 GPSTK_RETHROW(e);
00101 }
00102 }
00103
00104
00105
00106
00107
00108
00109 double CorrectedEphemerisRange::ComputeAtTransmitTime(
00110 const DayTime& tr_nom,
00111 const double& pr,
00112 const Position& Rx,
00113 const SatID sat,
00114 const XvtStore<SatID>& Eph)
00115 {
00116 try {
00117 DayTime tt;
00118
00119
00120 transmit = tr_nom;
00121 transmit -= pr/C_GPS_M;
00122 tt = transmit;
00123
00124
00125 for(int i=0; i<2; i++) {
00126
00127 try {
00128 svPosVel = Eph.getXvt(sat,tt);
00129 }
00130 catch(InvalidRequest& e) {
00131 GPSTK_RETHROW(e);
00132 }
00133 tt = transmit;
00134 tt -= svPosVel.dtime;
00135 }
00136
00137 rotateEarth(Rx);
00138
00139 rawrange = RSS(svPosVel.x[0]-Rx.X(),
00140 svPosVel.x[1]-Rx.Y(),
00141 svPosVel.x[2]-Rx.Z());
00142
00143 updateCER(Rx);
00144
00145 return (rawrange-svclkbias-relativity);
00146 }
00147 catch(gpstk::Exception& e) {
00148 GPSTK_RETHROW(e);
00149 }
00150 }
00151
00152
00153
00154 double CorrectedEphemerisRange::ComputeAtTransmitSvTime(
00155 const DayTime& tt_nom,
00156 const double& pr,
00157 const Position& rx,
00158 const SatID sat,
00159 const XvtStore<SatID>& eph)
00160 {
00161 try {
00162 svPosVel = eph.getXvt(sat, tt_nom);
00163
00164
00165
00166
00167 GPSGeoid gm;
00168 double rotation_angle = -gm.angVelocity() * (pr/gm.c() - svPosVel.dtime);
00169 svPosVel.x[0] = svPosVel.x[0] - svPosVel.x[1] * rotation_angle;
00170 svPosVel.x[1] = svPosVel.x[1] + svPosVel.x[0] * rotation_angle;
00171 svPosVel.x[2] = svPosVel.x[2];
00172
00173 rawrange =rx.slantRange(svPosVel.x);
00174 updateCER(rx);
00175
00176 return rawrange - svclkbias - relativity;
00177 }
00178 catch (Exception& e) {
00179 GPSTK_RETHROW(e);
00180 }
00181 }
00182
00183 void CorrectedEphemerisRange::updateCER(const Position& Rx)
00184 {
00185 relativity = RelativityCorrection(svPosVel) * C_GPS_M;
00186
00187
00188
00189 svclkbias = svPosVel.dtime*C_GPS_M - relativity;
00190 svclkdrift = svPosVel.ddtime * C_GPS_M;
00191
00192 cosines[0] = (Rx.X()-svPosVel.x[0])/rawrange;
00193 cosines[1] = (Rx.Y()-svPosVel.x[1])/rawrange;
00194 cosines[2] = (Rx.Z()-svPosVel.x[2])/rawrange;
00195
00196 Position SV(svPosVel);
00197 elevation = Rx.elevation(SV);
00198 azimuth = Rx.azimuth(SV);
00199 elevationGeodetic = Rx.elevationGeodetic(SV);
00200 azimuthGeodetic = Rx.azimuthGeodetic(SV);
00201 }
00202
00203
00204 void CorrectedEphemerisRange::rotateEarth(const Position& Rx)
00205 {
00206 GPSGeoid geoid;
00207 double tof = RSS(svPosVel.x[0]-Rx.X(),
00208 svPosVel.x[1]-Rx.Y(),
00209 svPosVel.x[2]-Rx.Z())/geoid.c();
00210 double wt = geoid.angVelocity()*tof;
00211 double sx = cos(wt)*svPosVel.x[0] + sin(wt)*svPosVel.x[1];
00212 double sy = -sin(wt)*svPosVel.x[0] + cos(wt)*svPosVel.x[1];
00213 svPosVel.x[0] = sx;
00214 svPosVel.x[1] = sy;
00215 sx = cos(wt)*svPosVel.v[0] + sin(wt)*svPosVel.v[1];
00216 sy = -sin(wt)*svPosVel.v[0] + cos(wt)*svPosVel.v[1];
00217 svPosVel.v[0] = sx;
00218 svPosVel.v[1] = sy;
00219 }
00220
00221
00222 double RelativityCorrection(const Xvt& svPosVel)
00223 {
00224
00225
00226
00227
00228 double dtr = ( -2.0 *( svPosVel.x[0] * svPosVel.v[0]
00229 + svPosVel.x[1] * svPosVel.v[1]
00230 + svPosVel.x[2] * svPosVel.v[2] ) / C_GPS_M ) / C_GPS_M;
00231 return dtr;
00232 }
00233
00234 }