⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tropmodel.cpp

📁 GPS定位中对流层模型改正
💻 CPP
📖 第 1 页 / 共 5 页
字号:
   {      if(!valid)         GPSTK_THROW(InvalidTropModel("Invalid model"));      return (Cwetdelay * GGwetscale);   }  // end GGTropModel::wet_zenith_delay()   double GGTropModel::dry_mapping_function(double elevation) const      throw(TropModel::InvalidTropModel)   {      if(!valid)         GPSTK_THROW(InvalidTropModel("Invalid model"));      if(elevation < 0.0) return 0.0;      GPSGeoid geoid;      double ce=std::cos(elevation*DEG_TO_RAD), se=std::sin(elevation*DEG_TO_RAD);      double ad = -se/Cdrymap;      double bd = -ce*ce/(2.0*geoid.a()*Cdrymap);      double Rd = SQRT((geoid.a()+Cdrymap)*(geoid.a()+Cdrymap)                - geoid.a()*geoid.a()*ce*ce) - geoid.a()*se;      double Ad[9], ad2=ad*ad, bd2=bd*bd;      Ad[0] = 1.0;      Ad[1] = 4.0*ad;      Ad[2] = 6.0*ad2 + 4.0*bd;      Ad[3] = 4.0*ad*(ad2+3.0*bd);      Ad[4] = ad2*ad2 + 12.0*ad2*bd + 6.0*bd2;      Ad[5] = 4.0*ad*bd*(ad2+3.0*bd);      Ad[6] = bd2*(6.0*ad2+4.0*bd);      Ad[7] = 4.0*ad*bd*bd2;      Ad[8] = bd2*bd2;         // compute dry component of the mapping function      double sumd=0.0;      for(int j=9; j>=1; j--) {         sumd += Ad[j-1]/double(j);         sumd *= Rd;      }      return sumd/GGdryscale;   }  // end GGTropModel::dry_mapping_function(elev)      // compute wet component of the mapping function   double GGTropModel::wet_mapping_function(double elevation) const      throw(TropModel::InvalidTropModel)   {      if(!valid)         GPSTK_THROW(InvalidTropModel("Invalid model"));      if(elevation < 0.0) return 0.0;      GPSGeoid geoid;      double ce = std::cos(elevation*DEG_TO_RAD), se = std::sin(elevation*DEG_TO_RAD);      double aw = -se/Cwetmap;      double bw = -ce*ce/(2.0*geoid.a()*Cwetmap);      double Rw = SQRT((geoid.a()+Cwetmap)*(geoid.a()+Cwetmap)                - geoid.a()*geoid.a()*ce*ce) - geoid.a()*se;      double Aw[9], aw2=aw*aw, bw2=bw*bw;      Aw[0] = 1.0;      Aw[1] = 4.0*aw;      Aw[2] = 6.0*aw2 + 4.0*bw;      Aw[3] = 4.0*aw*(aw2+3.0*bw);      Aw[4] = aw2*aw2 + 12.0*aw2*bw + 6.0*bw2;      Aw[5] = 4.0*aw*bw*(aw2+3.0*bw);      Aw[6] = bw2*(6.0*aw2+4.0*bw);      Aw[7] = 4.0*aw*bw*bw2;      Aw[8] = bw2*bw2;      double sumw=0.0;      for(int j=9; j>=1; j--) {         sumw += Aw[j-1]/double(j);         sumw *= Rw;      }      return sumw/GGwetscale;   }  // end GGTropModel::wet_mapping_function(elev)   void GGTropModel::setWeather(const double& T,                                const double& P,                                const double& H)      throw(InvalidParameter)   {      TropModel::setWeather(T,P,H);      double th=300./temp;         // water vapor partial pressure (mb)         // this comes from Leick and is not good.         // double wvpp=6.108*(RHum*0.01)*exp((17.15*Tk-4684.0)/(Tk-38.45));      double wvpp=2.409e9*humid*th*th*th*th*std::exp(-22.64*th);      Cdrydelay = 7.7624e-5*press/temp;      Cwetdelay = 1.0e-6*(-12.92+3.719e+05/temp)*(wvpp/temp);      Cdrymap = (5.0*0.002277*press)/Cdrydelay;      Cwetmap = (5.0*0.002277/Cwetdelay)*(1255.0/temp+0.5)*wvpp;      valid = true;   }  // end GGTropModel::setWeather(T,P,H)      // Re-define the tropospheric model with explicit weather data.      // Typically called just before correction().      // @param wx the weather to use for this correction          void GGTropModel::setWeather(const WxObservation& wx)      throw(InvalidParameter)   {      TropModel::setWeather(wx);   }   // -------------------------------------------------------------------------------   // Tropospheric model with heights based on Goad and Goodman(1974),   // "A Modified Hopfield Tropospheric Refraction Correction Model," Paper   // presented at the Fall Annual Meeting of the American Geophysical Union,   // San Francisco, December 1974.   // (Not the same as GGTropModel because this has height dependence,   // and the computation of this model does not break cleanly into   // wet and dry components.)      // Default constructor   GGHeightTropModel::GGHeightTropModel(void)   {      validWeather = false; //setWeather(20.0,980.0,50.0);      validHeights = false; //setHeights(0.0,0.0,0.0);      validRxHeight = false;   }      // Creates a trop model from a weather observation      // @param wx the weather to use for this correction.   GGHeightTropModel::GGHeightTropModel(const WxObservation& wx)      throw(InvalidParameter)   {      valid = validRxHeight = validHeights = false;      setWeather(wx);   }      // Create a tropospheric model from explicit weather data      // @param T temperature in degrees Celsius      // @param P atmospheric pressure in millibars      // @param H relative humidity in percent   GGHeightTropModel::GGHeightTropModel(const double& T,                                        const double& P,                                        const double& H)      throw(InvalidParameter)   {      validRxHeight = validHeights = false;      setWeather(T,P,H);   }      // Create a valid model from explicit input.      // @param T temperature in degrees Celsius      // @param P atmospheric pressure in millibars      // @param H relative humidity in percent      // @param hT height at which temperature applies in meters.      // @param hP height at which atmospheric pressure applies in meters.      // @param hH height at which relative humidity applies in meters.   GGHeightTropModel::GGHeightTropModel(const double& T,                                        const double& P,                                        const double& H,                                        const double hT,                                        const double hP,                                        const double hH)      throw(InvalidParameter)   {      validRxHeight = false;      setWeather(T,P,H);      setHeights(hT,hP,hH);   }      // re-define this to get the throws   double GGHeightTropModel::correction(double elevation) const      throw(TropModel::InvalidTropModel)   {      if(!valid)      {         if(!validWeather)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Weather"));         if(!validHeights)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Heights"));         if(!validRxHeight)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Rx Height"));      }      if(elevation < 0.0) return 0.0;      return (dry_zenith_delay() * dry_mapping_function(elevation)            + wet_zenith_delay() * wet_mapping_function(elevation));   }  // end GGHeightTropModel::correction(elevation)      // Compute and return the full tropospheric delay, given the positions of      // receiver and satellite and the time tag. This version is most useful      // within positioning algorithms, where the receiver position and timetag      // may vary; it computes the elevation (and other receiver location      // information) and passes them to appropriate set...() routines and      // the correction(elevation) routine.      // @param RX  Receiver position      // @param SV  Satellite position      // @param tt  Time tag of the signal    double GGHeightTropModel::correction(const Position& RX,                                        const Position& SV,                                        const DayTime& tt)      throw(TropModel::InvalidTropModel)   {      if(!valid)      {         if(!validWeather)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Weather"));         if(!validHeights)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Heights"));         if(!validRxHeight)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Rx Height"));      }      // compute height from RX      setReceiverHeight(RX.getHeight());      return TropModel::correction(RX.elevation(SV));   }  // end GGHeightTropModel::correction(RX,SV,TT)      // Compute and return the full tropospheric delay, given the positions of      // receiver and satellite and the time tag. This version is most useful      // within positioning algorithms, where the receiver position and timetag      // may vary; it computes the elevation (and other receiver location      // information) and passes them to appropriate set...() routines and      // the correction(elevation) routine.      // @param RX  Receiver position in ECEF cartesian coordinates (meters)      // @param SV  Satellite position in ECEF cartesian coordinates (meters)      // @param tt  Time tag of the signal       // This function is deprecated; use the Position version   double GGHeightTropModel::correction(const Xvt& RX,                                        const Xvt& SV,                                        const DayTime& tt)      throw(TropModel::InvalidTropModel)   {      Position R(RX),S(SV);      return GGHeightTropModel::correction(R,S,tt);   }      // Compute and return the zenith delay for dry component of the troposphere   double GGHeightTropModel::dry_zenith_delay(void) const      throw(TropModel::InvalidTropModel)   {      if(!valid) {         if(!validWeather)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Weather"));         if(!validHeights)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Heights"));         if(!validRxHeight)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Rx Height"));      }      double hrate=6.5e-3;      double Ts=temp+hrate*height;      double em=978.77/(2.8704e4*hrate);      double Tp=Ts-hrate*hpress;      double ps=press*std::pow(Ts/Tp,em)/1000.0;      double rs=77.624e-3/Ts;      double ho=11.385/rs;      rs *= ps;      double zen=(ho-height)/ho;      zen = rs*zen*zen*zen*zen;         // normalize      zen *= (ho-height)/5;      return zen;   }  // end GGHeightTropModel::dry_zenith_delay()      // Compute and return the zenith delay for wet component of the troposphere   double GGHeightTropModel::wet_zenith_delay(void) const      throw(TropModel::InvalidTropModel)   {      if(!valid) {         if(!validWeather)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Weather"));         if(!validHeights)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Heights"));         if(!validRxHeight)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Rx Height"));      }      double hrate=6.5e-3; //   deg K / m      double Th=temp-273.15-hrate*(hhumid-htemp);      double Ta=7.5*Th/(237.3+Th);         // water vapor partial pressure      double e0=6.11e-5*humid*std::pow(10.0,Ta);      double Ts=temp+hrate*htemp;      double em=978.77/(2.8704e4*hrate);      double Tk=Ts-hrate*hhumid;      double es=e0*std::pow(Ts/Tk,4.0*em);      double rs=(371900.0e-3/Ts-12.92e-3)/Ts;      double ho=11.385*(1255/Ts+0.05)/rs;      double zen=(ho-height)/ho;      zen = rs*es*zen*zen*zen*zen;         //normalize      zen *= (ho-height)/5;      return zen;         }  // end GGHeightTropModel::wet_zenith_delay()      // Compute and return the mapping function for dry component      // of the troposphere      // @param elevation Elevation of satellite as seen at receiver,      //                  in degrees   double GGHeightTropModel::dry_mapping_function(double elevation) const      throw(TropModel::InvalidTropModel)   {      if(!valid) {         if(!validWeather)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Weather"));         if(!validHeights)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Heights"));         if(!validRxHeight)            GPSTK_THROW(InvalidTropModel("Invalid GGH trop model: Rx Height"));      }      if(elevation < 0.0) return 0.0;      double hrate=6.5e-3;      double Ts=temp+hrate*htemp;      double ho=(11.385/77.624e-3)*Ts;      double se=std::sin(elevation*DEG_TO_RAD);      if(se < 0.0) se=0.0;      GPSGeoid geoid;      double rt,a,b,rn[8],al[8],er=geoid.a();      rt = (er+ho)/(er+height);      rt = rt*rt - (1.0-se*se);      if(rt < 0) rt=0.0;      rt = (er+height)*(SQRT(rt)-se);      a = -se/(ho-height);      b = -(1.0-se*se)/(2.0*er*(ho-height));      rn[0] = rt*rt;      for(int j=1; j<8; j++) rn[j]=rn[j-1]*rt;      al[0] = 2*a;      al[1] = 2*a*a+4*b/3;      al[2] = a*(a*a+3*b);      al[3] = a*a*a*a/5+2.4*a*a*b+1.2*b*b;      al[4] = 2*a*b*(a*a+3*b)/3;      al[5] = b*b*(6*a*a+4*b)*0.1428571;      if(b*b > 1.0e-35) {         al[6] = a*b*b*b/2;         al[7] = b*b*b*b/9;      } else {         al[6] = 0.0;         al[7] = 0.0;      }      double map=rt;      for(int k=0; k<8; k++) map += al[k]*rn[k];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -