IonoModel.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: IonoModel.cpp 164 2006-09-29 16:57:16Z architest $"
00002 
00003 
00004 
00005 //============================================================================
00006 //
00007 //  This file is part of GPSTk, the GPS Toolkit.
00008 //
00009 //  The GPSTk is free software; you can redistribute it and/or modify
00010 //  it under the terms of the GNU Lesser General Public License as published
00011 //  by the Free Software Foundation; either version 2.1 of the License, or
00012 //  any later version.
00013 //
00014 //  The GPSTk is distributed in the hope that it will be useful,
00015 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 //  GNU Lesser General Public License for more details.
00018 //
00019 //  You should have received a copy of the GNU Lesser General Public
00020 //  License along with GPSTk; if not, write to the Free Software Foundation,
00021 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //  
00023 //  Copyright 2004, The University of Texas at Austin
00024 //
00025 //============================================================================
00026 
00027 //============================================================================
00028 //
00029 //This software developed by Applied Research Laboratories at the University of
00030 //Texas at Austin, under contract to an agency or agencies within the U.S. 
00031 //Department of Defense. The U.S. Government retains all rights to use,
00032 //duplicate, distribute, disclose, or release this software. 
00033 //
00034 //Pursuant to DoD Directive 523024 
00035 //
00036 // DISTRIBUTION STATEMENT A: This software has been approved for public 
00037 //                           release, distribution is unlimited.
00038 //
00039 //=============================================================================
00040 
00041 
00042 
00043 
00044 
00045 
00051 #include <math.h>
00052 #include "icd_200_constants.hpp"
00053 #include "IonoModel.hpp"
00054 #include "geometry.hpp"
00055 
00056 namespace gpstk
00057 {
00058    IonoModel::IonoModel(const double a[4], const double b[4]) throw()
00059    {
00060         setModel(a, b);
00061    }
00062 
00063    IonoModel::IonoModel(const EngAlmanac& engalm)
00064       throw()
00065    {
00066       try
00067       {
00068          engalm.getIon(alpha, beta);
00069          valid = true;
00070       }
00071       catch(InvalidRequest& e)
00072       {
00073          valid = false;
00074       }
00075    }
00076    
00077 
00078    void IonoModel::setModel(const double a[4], const double b[4]) throw()
00079    {
00080       for (int n = 0; n < 4; n++)
00081       {
00082          alpha[n] = a[n];
00083          beta[n] = b[n];
00084       }
00085       valid = true;
00086    }
00087 
00088 
00089    double IonoModel::getCorrection(const DayTime& time,
00090                                    const Geodetic& rxgeo,
00091                                    double svel,
00092                                    double svaz,
00093                                    Frequency freq) const
00094       throw(IonoModel::InvalidIonoModel)
00095    {
00096 
00097       if (!valid)
00098       {
00099          InvalidIonoModel e("Alpha and beta parameters invalid.");
00100          GPSTK_THROW(e);
00101       }
00102       
00103          // all angle units are in semi-circles (radians / TWO_PI)
00104          // Note: math functions (cos, sin, etc.) require arguments in
00105          // radians so all semi-circles must be multiplied by TWO_PI
00106 
00107       double azRad = svaz * DEG_TO_RAD;
00108       double svE = svel / 180.0;
00109 
00110       double phi_u = rxgeo.getLatitude() / 180.0;
00111       double lambda_u = rxgeo.getLongitude() / 180.0;
00112       
00113       double psi = (0.0137 / (svE + 0.11)) - 0.022;
00114       
00115       double phi_i = phi_u + psi * cos(azRad);
00116       if (phi_i > 0.416)
00117          phi_i = 0.416;
00118       if (phi_i < -0.416)
00119          phi_i = -0.416;
00120 
00121       double lambda_i = lambda_u + psi * sin(azRad) / cos(phi_i*PI);
00122       
00123       double phi_m = phi_i + 0.064 * cos((lambda_i - 1.617)*PI);
00124       
00125       double iAMP = 0.0;
00126       double iPER = 0.0;
00127       iAMP = alpha[0]+phi_m*(alpha[1]+phi_m*(alpha[2]+phi_m*alpha[3]));
00128       iPER =  beta[0]+phi_m*( beta[1]+phi_m*( beta[2]+phi_m* beta[3]));
00129 
00130       if (iAMP < 0.0)
00131          iAMP = 0.0;
00132       if (iPER < 72000.0)
00133          iPER = 72000.0;
00134       
00135       double t = 43200.0 * lambda_i + time.DOYsecond();
00136       if (t >= 86400.0)
00137          t -= 86400.0;
00138       if (t < 0)
00139          t += 86400.0;
00140 
00141       double x = TWO_PI * (t - 50400.0) / iPER; // x is in radians
00142       
00143       double iF = 1.0 + 16.0 * (0.53 - svE)*(0.53 - svE)*(0.53 - svE);
00144 
00145       double t_iono = 0.0;
00146       if (fabs(x) < 1.57)
00147          t_iono = iF * (5.0e-9 + iAMP * (1 + x*x * (-0.5 + x*x/24.0)));
00148       else
00149          t_iono = iF * 5.0e-9;
00150       
00151       if (freq == L2)
00152       {
00153             // see ICD-GPS-200 20.3.3.3.3.2
00154          t_iono *= GAMMA_GPS;  //  GAMMA_GPS = (fL1 / fL2)^2
00155       }
00156       
00157       double correction = t_iono * C_GPS_M;
00158       
00159       return correction;
00160    }
00161    
00162    bool IonoModel::operator==(const IonoModel& right) const
00163       throw()
00164    {
00165       for (int n = 0; n < 4; n++)
00166       {
00167          if (alpha[n] != right.alpha[n] || beta[n] != right.beta[n])
00168             return false;
00169       }
00170       return true;
00171    }
00172 
00173    bool IonoModel::operator!=(const IonoModel&right) const
00174       throw()
00175    {
00176       return !(operator==(right));
00177    }   
00178 }
00179 
00180          
00181          
00182       

Generated on Thu Sep 9 03:30:54 2010 for GPS ToolKit Software Library by  doxygen 1.3.9.1