Changeset 7246 in ntrip


Ignore:
Timestamp:
Aug 24, 2015, 3:43:32 PM (9 years ago)
Author:
stuerze
Message:

ionosphere's class completed

Location:
trunk/BNC/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/src/pppModel.cpp

    r7240 r7246  
    4444
    4545#include "pppModel.h"
    46 #include "bncutils.h"
    4746
    4847using namespace BNC_PPP;
     
    387386///////////////////////////////////////////////////////////////////////////
    388387t_iono::t_iono() {
    389   _vTec = 0;
    390 }
    391 
    392 t_iono::~t_iono() {
    393   delete _vTec;
    394 }
    395 
    396 void t_iono::setTecData(const t_vTec* vTec) {
    397    delete _vTec;
    398   _vTec = new t_vTec(*vTec);
    399 }
    400 
    401 double t_iono::vtec() {
    402 
    403   return 0.0;
    404 }
     388  _psiPP = _phiPP = _lambdaPP = _lonS = 0.0;
     389}
     390
     391t_iono::~t_iono() {}
     392
     393double t_iono::stec(const t_vTec* vTec, double signalPropagationTime,
     394      const ColumnVector& rSat, const bncTime& epochTime,
     395      const ColumnVector& xyzSta) {
     396
     397  // Latitude, longitude, height are defined with respect to a spherical earth model
     398  // -------------------------------------------------------------------------------
     399  ColumnVector geocSta;
     400  xyz2geoc(xyzSta.data(), geocSta.data());
     401
     402  // satellite position rotated to the epoch of signal reception
     403  // -----------------------------------------------------------
     404  ColumnVector xyzSat;
     405  double omegaZ = t_CST::omega * signalPropagationTime;
     406  xyzSat[0] = rSat[0] * cos(omegaZ) + rSat[1] * sin(omegaZ);
     407  xyzSat[1] = rSat[1] * cos(omegaZ) - rSat[0] * sin(omegaZ);
     408  xyzSat[2] = rSat[2];
     409
     410  // elevation and azimuth with respect to a spherical earth model
     411  // -------------------------------------------------------------
     412  ColumnVector rhoV = xyzSat - xyzSta;
     413  double rho = rhoV.norm_Frobenius();
     414  ColumnVector neu(3);
     415  xyz2neu(geocSta.data(), rhoV.data(), neu.data());
     416  double sphEle = acos( sqrt(neu[0]*neu[0] + neu[1]*neu[1]) / rho );
     417  if (neu[2] < 0) {
     418    sphEle *= -1.0;
     419  }
     420  double sphAzi = atan2(neu[1], neu[0]);
     421
     422  double epoch = fmod(epochTime.gpssec(), 86400.0);
     423
     424  double stec = 0.0;
     425  for (unsigned ii = 0; ii < vTec->_layers.size(); ii++) {
     426    double layerHeight = vTec->_layers[ii]._height * 1000.0; // m
     427    piercePoint(layerHeight, epoch, geocSta.data(), sphEle, sphAzi);
     428    double vtec = vtecSingleLayerContribution(vTec->_layers[ii]);
     429    stec += vtec * sin(sphEle * _psiPP);
     430  }
     431  return stec;
     432}
     433
     434double t_iono::vtecSingleLayerContribution(const t_vTecLayer& vTecLayer) {
     435
     436  double vtec = 0.0;
     437  int N = vTecLayer._C.Nrows()-1;
     438  int M = vTecLayer._C.Ncols()-1;
     439  double fac;
     440
     441  for (int n = 0; n <= N; n++) {
     442    for (int m = 0; m <= min(n, M); m++) {
     443      double pnm = associatedLegendreFunction(n, m, sin(_phiPP));
     444      double a = double(factorial(n - m));
     445      double b = double(factorial(n + m));
     446      if (m == 0) {
     447        fac = sqrt(2.0 * n + 1);
     448      }
     449      else {
     450        fac = sqrt(2.0 * (2.0 * n + 1) * a / b);
     451      }
     452      pnm *= fac;
     453      double Cnm_mlambda = vTecLayer._C[n][m] * cos(m * _lonS);
     454      double Snm_mlambda = vTecLayer._S[n][m] * sin(m * _lonS);
     455      vtec += (Snm_mlambda + Cnm_mlambda) * pnm;
     456    }
     457  }
     458
     459  if (vtec < 0.0) {
     460    return 0.0;
     461  }
     462  return vtec;
     463}
     464
     465void t_iono::piercePoint(double layerHeight, double epoch, const double* geocSta,
     466    double sphEle, double sphAzi) {
     467
     468  double q = (t_CST::rgeoc + geocSta[2]) / (t_CST::rgeoc + layerHeight);
     469
     470  _psiPP = M_PI / 2 - sphEle - asin(q * cos(sphEle));
     471
     472  _phiPP = asin(sin(geocSta[0]) * cos(_psiPP) + cos(geocSta[0]) * sin(_psiPP) * cos(sphAzi));
     473
     474  if (( (geocSta[0]*180.0/M_PI > 0) && (  tan(_psiPP) * cos(sphAzi)  > tan(M_PI/2 - geocSta[0])) )  ||
     475      ( (geocSta[0]*180.0/M_PI < 0) && (-(tan(_psiPP) * cos(sphAzi)) > tan(M_PI/2 + geocSta[0])) ))  {
     476    _lambdaPP = geocSta[1] + M_PI - asin((sin(_psiPP) * sin(sphAzi) / cos(_phiPP)));
     477  } else {
     478    _lambdaPP = geocSta[1]        + asin((sin(_psiPP) * sin(sphAzi) / cos(_phiPP)));
     479  }
     480
     481  _lonS = fmod((_lambdaPP + (epoch - 50400) * (M_PI / 43200)), 2*M_PI);
     482
     483  return;
     484}
     485
  • trunk/BNC/src/pppModel.h

    r7240 r7246  
    77#include "t_prn.h"
    88#include "satObs.h"
     9#include "bncutils.h"
    910
    1011namespace BNC_PPP {
     
    6364  t_iono();
    6465  ~t_iono();
    65   void setTecData(const t_vTec* vTec);
    66   double vtec();
     66  double stec(const t_vTec* vTec, double signalPropagationTime,
     67      const ColumnVector& rSat, const bncTime& epochTime,
     68      const ColumnVector& xyzSta);
    6769 private:
    68   t_vTec*   _vTec;
    69   int       _layer;
    70   double    _layerHeight;
    71   double    _roverHeight;
     70  double vtecSingleLayerContribution(const t_vTecLayer& vTecLayer);
     71  void piercePoint(double layerHeight, double epoch, const double* geocSta,
     72      double sphEle, double sphAzi);
     73  double _psiPP;
     74  double _phiPP;
     75  double _lambdaPP;
     76  double _lonS;
    7277
    7378
Note: See TracChangeset for help on using the changeset viewer.