00001 #pragma ident "$Id: ObsRngDev.cpp 2741 2011-06-22 16:37:02Z nwu $"
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
00038
00044 #include <typeinfo>
00045
00046 #include "EphemerisRange.hpp"
00047 #include "EngEphemeris.hpp"
00048 #include "GPSEphemerisStore.hpp"
00049 #include "MiscMath.hpp"
00050 #include "icd_200_constants.hpp"
00051
00052 #include "ObsRngDev.hpp"
00053
00054 namespace gpstk
00055 {
00056
00057
00058 static const double GAMMA = 1.64694444444444444;
00059 static const double IGAMMA = 1-GAMMA;
00060
00061 bool ObsRngDev::debug=false;
00062
00063 ObsRngDev::ObsRngDev(
00064 const double prange,
00065 const SatID& svid,
00066 const DayTime& time,
00067 const ECEF& rxpos,
00068 const XvtStore<SatID>& eph,
00069 GeoidModel& gm,
00070 bool svTime)
00071 : obstime(time), svid(svid), ord(0), wonky(false)
00072 {
00073 computeOrd(prange, rxpos, eph, gm, svTime);
00074 Geodetic gx(rxpos, &gm);
00075 NBTropModel nb(gx.getAltitude(), gx.getLatitude(), time.DOYday());
00076 computeTrop(nb);
00077 }
00078
00079 ObsRngDev::ObsRngDev(
00080 const double prange,
00081 const SatID& svid,
00082 const DayTime& time,
00083 const ECEF& rxpos,
00084 const XvtStore<SatID>& eph,
00085 GeoidModel& gm,
00086 const IonoModelStore& ion,
00087 IonoModel::Frequency fq,
00088 bool svTime)
00089 : obstime(time), svid(svid), ord(0), wonky(false)
00090 {
00091 computeOrd(prange, rxpos, eph, gm, svTime);
00092 Geodetic gx(rxpos, &gm);
00093 NBTropModel nb(gx.getAltitude(), gx.getLatitude(), time.DOYday());
00094 computeTrop(nb);
00095 iono = ion.getCorrection(time, gx, elevation, azimuth, fq);
00096 ord -= iono;
00097 }
00098
00099 ObsRngDev::ObsRngDev(
00100 const double prange,
00101 const SatID& svid,
00102 const DayTime& time,
00103 const ECEF& rxpos,
00104 const XvtStore<SatID>& eph,
00105 GeoidModel& gm,
00106 const TropModel& tm,
00107 bool svTime)
00108 : obstime(time), svid(svid), ord(0), wonky(false)
00109 {
00110 computeOrd(prange, rxpos, eph, gm, svTime);
00111 computeTrop(tm);
00112 }
00113
00114 ObsRngDev::ObsRngDev(
00115 const double prange,
00116 const SatID& svid,
00117 const DayTime& time,
00118 const ECEF& rxpos,
00119 const XvtStore<SatID>& eph,
00120 GeoidModel& gm,
00121 const TropModel& tm,
00122 const IonoModelStore& ion,
00123 IonoModel::Frequency fq,
00124 bool svTime)
00125 : obstime(time), svid(svid), ord(0), wonky(false)
00126 {
00127 computeOrd(prange, rxpos, eph, gm, svTime);
00128 computeTrop(tm);
00129 Geodetic gx(rxpos, &gm);
00130 iono = ion.getCorrection(time, gx, elevation, azimuth, fq);
00131 ord -= iono;
00132 }
00133
00134
00135 ObsRngDev::ObsRngDev(
00136 const double prange1,
00137 const double prange2,
00138 const SatID& svid,
00139 const DayTime& time,
00140 const ECEF& rxpos,
00141 const XvtStore<SatID>& eph,
00142 GeoidModel& gm,
00143 bool svTime)
00144 : obstime(time), svid(svid), ord(0), wonky(false)
00145 {
00146
00147 double icpr = (prange2 - GAMMA * prange1)/IGAMMA;
00148 iono = prange1 - icpr;
00149
00150 computeOrd(icpr, rxpos, eph, gm, svTime);
00151 Geodetic gx(rxpos, &gm);
00152 NBTropModel nb(gx.getAltitude(), gx.getLatitude(), time.DOYday());
00153 computeTrop(nb);
00154 }
00155
00156
00157 ObsRngDev::ObsRngDev(
00158 const double prange1,
00159 const double prange2,
00160 const SatID& svid,
00161 const DayTime& time,
00162 const ECEF& rxpos,
00163 const XvtStore<SatID>& eph,
00164 const GeoidModel& gm,
00165 const TropModel& tm,
00166 bool svTime)
00167 : obstime(time), svid(svid), ord(0), wonky(false)
00168 {
00169
00170 double icpr = (prange2 - GAMMA * prange1)/IGAMMA;
00171 iono = prange1 - icpr;
00172
00173 computeOrd(icpr, rxpos, eph, gm, svTime);
00174 computeTrop(tm);
00175 }
00176
00177
00178 void ObsRngDev::computeOrdRx(
00179 const double obs,
00180 const ECEF& rxpos,
00181 const XvtStore<SatID>& eph,
00182 const GeoidModel& gm)
00183 {
00184 CorrectedEphemerisRange cer;
00185 rho = cer.ComputeAtTransmitTime(obstime, obs, rxpos, svid, eph);
00186 azimuth = cer.azimuth;
00187 elevation = cer.elevation;
00188 ord = obs - rho;
00189
00190 if (typeid(eph) == typeid(GPSEphemerisStore))
00191 {
00192 const GPSEphemerisStore& bce = dynamic_cast<const GPSEphemerisStore&>(eph);
00193 const EngEphemeris& eph = bce.findEphemeris(svid, obstime);
00194 iodc = eph.getIODC();
00195 health = eph.getHealth();
00196 }
00197
00198 if (debug)
00199 {
00200 std::ios::fmtflags oldFlags = std::cout.flags();
00201 std::cout << *this << std::endl
00202 << std::setprecision(3) << std::fixed
00203 << " obs=" << obs
00204 << ", rho=" << (double)rho
00205 << ", obs-rho=" << (double)ord
00206 << std::endl
00207 << " rx.x=" << rxpos
00208 << std::setprecision(4) << std::scientific
00209 << ", sv bias=" << cer.svclkbias
00210 << ", sv drift=" << cer.svclkdrift
00211 << std::endl;
00212 std::cout.flags(oldFlags);
00213 }
00214 }
00215
00216
00217
00218 void ObsRngDev::computeOrdTx(
00219 double obs,
00220 const ECEF& rxpos,
00221 const XvtStore<SatID>& eph,
00222 const GeoidModel& gm)
00223 {
00224 CorrectedEphemerisRange cer;
00225 rho = cer.ComputeAtTransmitSvTime(obstime, obs, rxpos, svid, eph);
00226 azimuth = cer.azimuth;
00227 elevation = cer.elevation;
00228 ord = obs - rho;
00229 if (debug)
00230 {
00231 std::ios::fmtflags oldFlags = std::cout.flags();
00232 std::cout << *this << std::endl
00233 << std::setprecision(3) << std::fixed
00234 << " obs=" << obs
00235 << ", rho=" << (double)rho
00236 << ", obs-rho=" << (double)ord
00237 << std::endl
00238 << std::setprecision(3)
00239 << " sv.x=" << cer.svPosVel.x
00240 << ", sv.v=" << cer.svPosVel.v
00241 << std::endl
00242 << " rx.x=" << rxpos
00243 << std::setprecision(4) << std::scientific
00244 << ", sv bias=" << cer.svPosVel.dtime
00245 << ", sv drift=" << cer.svPosVel.ddtime
00246 << std::endl;
00247 std::cout.flags(oldFlags);
00248 }
00249 }
00250
00251 void ObsRngDev::computeTrop(const TropModel& tm)
00252 {
00253 trop = tm.correction(elevation);
00254 ord -= trop;
00255 }
00256
00257 std::ostream& operator<<(std::ostream& s, const ObsRngDev& ord)
00258 throw()
00259 {
00260 std::ios::fmtflags oldFlags = s.flags();
00261 s << "t=" << ord.obstime.printf("%Y/%03j %02H:%02M:%04.1f")
00262 << " prn=" << std::setw(2) << ord.svid.id
00263 << std::setprecision(4)
00264 << " az=" << std::setw(3) << ord.azimuth
00265 << " el=" << std::setw(2) << ord.elevation
00266 << std::hex
00267 << " h=" << std::setw(1) << ord.health
00268 << std::dec << std::setprecision(4)
00269 << " ord=" << ord.ord
00270 << " ion=" << ord.iono
00271 << " trop=" << ord.trop
00272 << std::hex
00273 << " iodc=" << ord.iodc
00274 << " wonky=" << ord.wonky;
00275 s.flags(oldFlags);
00276 return s;
00277 }
00278 }