AtmosphericDrag.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: AtmosphericDrag.cpp 2457 2010-08-18 14:20:12Z coandrei $"
00002 
00003 
00011 //============================================================================
00012 //
00013 //  This file is part of GPSTk, the GPS Toolkit.
00014 //
00015 //  The GPSTk is free software; you can redistribute it and/or modify
00016 //  it under the terms of the GNU Lesser General Public License as published
00017 //  by the Free Software Foundation; either version 2.1 of the License, or
00018 //  any later version.
00019 //
00020 //  The GPSTk is distributed in the hope that it will be useful,
00021 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 //  GNU Lesser General Public License for more details.
00024 //
00025 //  You should have received a copy of the GNU Lesser General Public
00026 //  License along with GPSTk; if not, write to the Free Software Foundation,
00027 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028 //
00029 //  Wei Yan - Chinese Academy of Sciences . 2009, 2010
00030 //
00031 //============================================================================
00032 
00033 #include "AtmosphericDrag.hpp"
00034 #include "ReferenceFrames.hpp"
00035 
00036 namespace gpstk
00037 {
00038 
00039    const double AtmosphericDrag::rho_0[CIRA_SIZE] = 
00040    {
00041       1.057E-03, 3.206E-04, 8.770E-05, 1.905E-05, 3.396E-06, 5.297E-07,
00042       9.661E-08, 2.438E-08, 8.484E-09, 3.845E-09, 2.070E-09, 5.464E-10,
00043       2.789E-10, 7.248E-11, 2.418E-11, 9.158E-12, 3.725E-12, 1.585E-12, 
00044       6.967E-13, 1.454E-13, 3.614E-14, 1.170E-14, 5.245E-15, 3.019E-15
00045    };
00046 
00047    const double AtmosphericDrag::H[CIRA_SIZE] = 
00048    {
00049       8.382,   7.714,   6.549,   5.799,   5.382,   5.877,
00050       7.263,   9.473,   12.636,   16.149,   22.523,   29.740,
00051       37.105, 45.546, 53.628, 53.298, 58.515, 60.828,
00052       63.822, 71.835,   88.667, 124.64, 181.05, 268.0
00053    };
00054 
00055    const double AtmosphericDrag::h0[CIRA_SIZE] = 
00056    {
00057       50,  60,  70,   80,    90, 100,
00058       110, 120, 130, 140, 150, 180,
00059       200, 250, 300, 350, 400, 450,
00060       500, 600, 700, 800, 900, 1000
00061    };
00062 
00063    
00064       // this is the real one
00065    void AtmosphericDrag::doCompute(UTCTime utc, EarthBody& rb, Spacecraft& sc)
00066    {
00067       // To consist with STK
00068       double omega_e = 7.292115E-05;  // IERS 1996 conventions
00069       //double omega_e = rb.getSpinRate(utc);
00070 
00071       Vector<double> r = sc.R();   // satellite position in m
00072       Vector<double> v = sc.V();   // satellite velocity in m/s
00073 
00074       const double cd = sc.getDragCoeff();
00075       const double area = sc.getDragArea();
00076       const double mass = sc.getDryMass();
00077 
00078       double rmag = norm(r);
00079       double beta = cd * area / mass;  // [m^2/kg]
00080 
00081       // compute the atmospheric density
00082       double rho = computeDensity(utc, rb, r, v);   // [kg/m^3]
00083 
00084       // debuging...
00085       //rho  = 6.3097802844338E-12;
00086       
00087       // compute the relative velocity vector and magnitude
00088       Vector<double> we(3,0.0);
00089       we(2)= omega_e;
00090 
00091       Vector<double> wxr = cross(we,r);
00092       Vector<double> vr = v - wxr;
00093       double vrmag = norm(vr);
00094       
00095       // form -1/2 (Cd*A/m) rho
00096       double coeff = -0.5 * beta * rho;
00097       double coeff2 = coeff * vrmag;
00098 
00099       // compute the acceleration in ECI frame (km/s^2)
00100       a = vr * coeff2;                                  
00101 
00102       // Partial reference: Montenbruck,P248
00103 
00104       // form partial of drag wrt v  
00105       // da_dv = -0.5*Cd*(A/M)*p*(vr*transpose(vr)/vr+vr1)
00106       Matrix<double> tr(3,1,0.0);
00107       tr(0,0)=vr(0);
00108       tr(1,0)=vr(1);
00109       tr(2,0)=vr(2);
00110 
00111       Matrix<double> vrvrt = tr*transpose(tr); 
00112       vrvrt = vrvrt / vrmag;
00113       
00114       double eye3[3*3] = {1,0,0,0,1,0,0,0,1};
00115       Matrix<double> vrm(3,3,0.0);
00116       vrm = eye3;
00117 
00118       vrm = vrm * vrmag;
00119       da_dv = (vrvrt + vrm) * coeff;               
00120 
00121       // da_dr
00122       // da_dr = -0.5*Cd*(A/M)*vr*dp_dr-da_dv*X(w)
00123       da_dr.resize(3,3,0.0);
00124 
00125       Matrix<double> X(3,3,0.0);
00126       X(0,1) = -we(2);      // -wz
00127       X(0,2) = +we(1);      //  wy
00128       X(1,0) = +we(2);      // +wz
00129       X(1,2) = -we(0);      // -wx
00130       X(2,0) = -we(1);      // -wy
00131       X(2,1) = +we(0);      // +wx
00132       
00133       Matrix<double> part1(3,3,0.0);
00134       Matrix<double> part2(3,3,0.0);
00135       
00136    
00137       // Get the J2000 to TOD transformation
00138       Matrix<double> N = ReferenceFrames::J2kToTODMatrix(utc);
00139 
00140       // Transform r from J2000 to TOD
00141       Vector<double> r_tod = N * r;
00142       Position geoidPos(r_tod(0),r_tod(1),r_tod(3));
00143       
00144       // Satellite height
00145       double height = geoidPos.getAltitude()/1000.0;              //  convert to [km]
00146       
00147       const int n = CIRA_SIZE; ;
00148 
00149       int bracket = 0;
00150 
00151       if (height >= h0[n-1]) 
00152       {
00153          bracket = n - 1;
00154       }
00155       else 
00156       {
00157          for (int i = 0; i < (n-1); i++) 
00158          {
00159             if ((height >= h0[i]) && (height < h0[i+1]))
00160             {
00161                bracket = i;
00162             }
00163          }
00164       }  // End 'if (height >= h0[n-1]) '
00165       
00166       double Hh = H[bracket];
00167       double coeff4 = -1.0 / (Hh * rmag);
00168 
00169       Vector<double> drhodr = r*coeff4;
00170       
00171       Matrix<double> tr2(3,1,0.0);
00172       tr2(0,0) = drhodr(0);
00173       tr2(1,0) = drhodr(1);
00174       tr2(2,0) = drhodr(2);
00175 
00176       part1 = tr*transpose(tr2);      // //Matrix part1 = vr.outerProduct(drhodr);
00177       part1 = part1*coeff2;
00178 
00179       //part1 = dp_dr*a/rho;
00180       part2 =-da_dv*X;
00181       da_dr = part1-part2;
00182 
00183       // form partial of drag wrt cd
00184       double coeff3 = coeff2 / cd;
00185       this->dadcd = vr*coeff3;                        
00186 
00187       this->da_dcd(0,0) = dadcd(0);
00188       this->da_dcd(1,0) = dadcd(1);
00189       this->da_dcd(2,0) = dadcd(2);
00190 
00191    }  // End of method 'AtmosphericDrag::doCompute()'
00192 
00193 }  // End of namespace 'gpstk'
00194 
00195 
00196 

Generated on Tue May 22 03:30:56 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1