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

📄 tropmodel.cpp

📁 GPS定位中对流层模型改正
💻 CPP
📖 第 1 页 / 共 5 页
字号:
         // normalize      double norm=(ho-height)/5;      return map/norm;   }  // end GGHeightTropModel::dry_mapping_function(elevation)      // Compute and return the mapping function for wet component      // of the troposphere      // @param elevation Elevation of satellite as seen at receiver,      //                  in degrees   double GGHeightTropModel::wet_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 rs=(371900.0e-3/Ts-12.92e-3)/Ts;      double ho=11.385*(1255/Ts+0.05)/rs;      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 i=1; i<8; i++) rn[i]=rn[i-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 j=0; j<8; j++) map += al[j]*rn[j];         // normalize map function      double norm=(ho-height)/5;      return map/norm;   }  // end GGHeightTropModel::wet_mapping_function(elevation)      // Re-define the weather data.      // Typically called just before correction().      // @param T temperature in degrees Celsius      // @param P atmospheric pressure in millibars      // @param H relative humidity in percent   void GGHeightTropModel::setWeather(const double& T,                                      const double& P,                                      const double& H)      throw(InvalidParameter)   {      try      {         TropModel::setWeather(T,P,H);         validWeather = true;         valid = validWeather && validHeights && validRxHeight;      }      catch(InvalidParameter& e)      {         valid = validWeather = false;         GPSTK_RETHROW(e);      }   }  // end GGHeightTropModel::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 GGHeightTropModel::setWeather(const WxObservation& wx)      throw(InvalidParameter)   {      try      {         TropModel::setWeather(wx);         validWeather = true;                  valid = validWeather && validHeights && validRxHeight;      }      catch(InvalidParameter& e)      {         valid = validWeather = false;         GPSTK_RETHROW(e);      }   }         // Re-define the heights at which the weather parameters apply.      // Typically called just before correction().      // @param hT height (m) at which temperature applies      // @param hP height (m) at which atmospheric pressure applies      // @param hH height (m) at which relative humidity applies   void GGHeightTropModel::setHeights(const double& hT,                                      const double& hP,                                      const double& hH)   {      htemp = hT;                 // height (m) at which temp applies      hpress = hP;                // height (m) at which press applies      hhumid = hH;                // height (m) at which humid applies      validHeights = true;      valid = validWeather && validHeights && validRxHeight;   }  // end GGHeightTropModel::setHeights(hT,hP,hH)      // Define the receiver height; this required before calling      // correction() or any of the zenith_delay or mapping_function routines.   void GGHeightTropModel::setReceiverHeight(const double& ht)   {      height = ht;      validRxHeight = true;      if(!validHeights) {         htemp = hpress = hhumid = ht;         validHeights = true;      }      valid = validWeather && validHeights && validRxHeight;   }  // end GGHeightTropModel::setReceiverHeight(const double& ht)   // -------------------------------------------------------------------------------   // Tropospheric model developed by University of New Brunswick and described in   // "A Tropospheric Delay Model for the User of the Wide Area Augmentation   // System," J. Paul Collins and Richard B. Langley, Technical Report No. 187,   // Dept. of Geodesy and Geomatics Engineering, University of New Brunswick,   // 1997. See particularly Appendix C.   //   // This model includes a wet and dry component, and was designed for the user   // without access to measurements of temperature, pressure and relative humidity   // at ground level. It requires input of the latitude, day of year and height   // above the ellipsoid, and it interpolates a table of values, using these   // inputs, to get the ground level weather parameters plus other parameters and   // the mapping function constants.   //   // NB in this model, units of temp are degrees Celsius, and humid is the water   // vapor partial pressure.   static const double NBRd=287.054;   // J/kg/K = m*m*K/s*s   static const double NBg=9.80665;    // m/s*s   static const double NBk1=77.604;    // K/mbar   static const double NBk3p=382000;   // K*K/mbar   static const double NBLat[5]={   15.0,   30.0,   45.0,   60.0,   75.0};   // zenith delays, averages   static const double NBZP0[5]={1013.25,1017.25,1015.75,1011.75,1013.00};   static const double NBZT0[5]={ 299.65, 294.15, 283.15, 272.15, 263.65};   static const double NBZW0[5]={  26.31,  21.79,  11.66,   6.78,   4.11};   static const double NBZB0[5]={6.30e-3,6.05e-3,5.58e-3,5.39e-3,4.53e-3};   static const double NBZL0[5]={   2.77,   3.15,   2.57,   1.81,   1.55};   // zenith delays, amplitudes   static const double NBZPa[5]={    0.0,  -3.75,  -2.25,  -1.75,  -0.50};   static const double NBZTa[5]={    0.0,    7.0,   11.0,   15.0,   14.5};   static const double NBZWa[5]={    0.0,   8.85,   7.24,   5.36,   3.39};   static const double NBZBa[5]={    0.0,0.25e-3,0.32e-3,0.81e-3,0.62e-3};   static const double NBZLa[5]={    0.0,   0.33,   0.46,   0.74,   0.30};   // mapping function, dry, averages   static const double NBMad[5]={1.2769934e-3,1.2683230e-3,1.2465397e-3,1.2196049e-3,                                 1.2045996e-3};   static const double NBMbd[5]={2.9153695e-3,2.9152299e-3,2.9288445e-3,2.9022565e-3,                                 2.9024912e-3};   static const double NBMcd[5]={62.610505e-3,62.837393e-3,63.721774e-3,63.824265e-3,                                 64.258455e-3};   // mapping function, dry, amplitudes   static const double NBMaa[5]={0.0,1.2709626e-5,2.6523662e-5,3.4000452e-5,                                 4.1202191e-5};   static const double NBMba[5]={0.0,2.1414979e-5,3.0160779e-5,7.2562722e-5,                                 11.723375e-5};   static const double NBMca[5]={0.0,9.0128400e-5,4.3497037e-5,84.795348e-5,                                 170.37206e-5};   // mapping function, wet, averages (there are no amplitudes for wet)   static const double NBMaw[5]={5.8021897e-4,5.6794847e-4,5.8118019e-4,5.9727542e-4,                           6.1641693e-4};   static const double NBMbw[5]={1.4275268e-3,1.5138625e-3,1.4572752e-3,1.5007428e-3,                           1.7599082e-3};   static const double NBMcw[5]={4.3472961e-2,4.6729510e-2,4.3908931e-2,4.4626982e-2,                           5.4736038e-2};   // labels for use with the interpolation routine   enum TableEntry { ZP=1, ZT, ZW, ZB, ZL, Mad, Mbd, Mcd, Maw, Mbw, Mcw };   // the interpolation routine   static double NB_Interpolate(double lat, int doy, TableEntry entry)   {      const double *pave, *pamp;      double ret, day=double(doy);         // assign pointer to the right array      switch(entry) {         case ZP:  pave=&NBZP0[0]; pamp=&NBZPa[0]; break;         case ZT:  pave=&NBZT0[0]; pamp=&NBZTa[0]; break;         case ZW:  pave=&NBZW0[0]; pamp=&NBZWa[0]; break;         case ZB:  pave=&NBZB0[0]; pamp=&NBZBa[0]; break;         case ZL:  pave=&NBZL0[0]; pamp=&NBZLa[0]; break;         case Mad: pave=&NBMad[0]; pamp=&NBMaa[0]; break;         case Mbd: pave=&NBMbd[0]; pamp=&NBMba[0]; break;         case Mcd: pave=&NBMcd[0]; pamp=&NBMca[0]; break;         case Maw: pave=&NBMaw[0];                 break;         case Mbw: pave=&NBMbw[0];                 break;         case Mcw: pave=&NBMcw[0];                 break;      }            // find the index i such that NBLat[i] <= lat < NBLat[i+1]      int i = int(ABS(lat)/15.0)-1;         if(i>=0 && i<=3) {               // mid-latitude -> regular interpolation         double m=(ABS(lat)-NBLat[i])/(NBLat[i+1]-NBLat[i]);         ret = pave[i]+m*(pave[i+1]-pave[i]);         if(entry < Maw)            ret -= (pamp[i]+m*(pamp[i+1]-pamp[i]))               * std::cos(TWO_PI*(day-28.0)/365.25);      }      else {                           // < 15 or > 75 -> simpler interpolation         if(i<0) i=0; else i=4;         ret = pave[i];         if(entry < Maw)            ret -= pamp[i]*std::cos(TWO_PI*(day-28.0)/365.25);      }         return ret;   }  // end double NB_Interpolate(lat,doy,entry)      // Default constructor   NBTropModel::NBTropModel(void)   {      validWeather = false;      validRxLatitude = false;      validDOY = false;      validRxHeight = false;   } // end NBTropModel::NBTropModel()      // Create a trop model using the minimum information: latitude and doy.      // Interpolate the weather unless setWeather (optional) is called.      // @param lat Latitude of the receiver in degrees.      // @param day Day of year.   NBTropModel::NBTropModel(const double& lat,                            const int& day)   {      validRxHeight = false;      setReceiverLatitude(lat);      setDayOfYear(day);      setWeather();   }  // end NBTropModel::NBTropModel(lat, day);      // Create a trop model with weather.      // @param lat Latitude of the receiver in degrees.      // @param day Day of year.      // @param wx the weather to use for this correction.   NBTropModel::NBTropModel(const double& lat,                            const int& day,                            const WxObservation& wx)      throw(InvalidParameter)   {      validRxHeight = false;      setReceiverLatitude(lat);      setDayOfYear(day);      setWeather(wx);   }  // end NBTropModel::NBTropModel(weather)      // Create a tropospheric model from explicit weather data      // @param lat Latitude of the receiver in degrees.      // @param day Day of year.      // @param T temperature in degrees Celsius      // @param P atmospheric pressure in millibars      // @param H relative humidity in percent   NBTropModel::NBTropModel(const double& lat,                            const int& day,                            const double& T,                            const double& P,                            const double& H)      throw(InvalidParameter)   {      validRxHeight = false;      setReceiverLatitude(lat);      setDayOfYear(day);      setWeather(T,P,H);   } // end NBTropModel::NBTropModel()      // Create a valid model from explicit input (weather will be estimated      // internally by this model).      // @param ht Height of the receiver in meters.      // @param lat Latitude of the receiver in degrees.      // @param d Day of year.   NBTropModel::NBTropModel(const double& ht,                            const double& lat,                            const int& day)   {      setReceiverHeight(ht);      setReceiverLatitude(lat);      setDayOfYear(day);      setWeather();   }      // re-define this to get the throws   double NBTropModel::correction(double elevation) const      throw(TropModel::InvalidTropModel)   {      if(!valid) {         if(!validWeather)            GPSTK_THROW(InvalidTropModel("Invalid NB trop model: weather"));         if(!validRxLatitude)            GPSTK_THROW(InvalidTropModel("Invalid NB trop model: Rx Latitude"));         if(!validRxHeight)            GPSTK_THROW(InvalidTropModel("Invalid NB trop model: Rx Height"));         if(!validDOY)            GPSTK_THROW(InvalidTropModel("Invalid NB trop model: day of year"));      }      if(elevation < 0.0) return 0.0;      return (dry_zenith_delay() * dry_mapping_function(elevation)            + wet_zenith_delay() * wet_mapping_function(elevation));   }  // end NBTropModel::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 NBTropModel::correction(const Position& RX,

⌨️ 快捷键说明

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