SunPosition.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: SunPosition.cpp 1161 2008-03-27 17:16:22Z ckiesch $"
00002 
00009 //============================================================================
00010 //
00011 //  This file is part of GPSTk, the GPS Toolkit.
00012 //
00013 //  The GPSTk is free software; you can redistribute it and/or modify
00014 //  it under the terms of the GNU Lesser General Public License as published
00015 //  by the Free Software Foundation; either version 2.1 of the License, or
00016 //  any later version.
00017 //
00018 //  The GPSTk is distributed in the hope that it will be useful,
00019 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021 //  GNU Lesser General Public License for more details.
00022 //
00023 //  You should have received a copy of the GNU Lesser General Public
00024 //  License along with GPSTk; if not, write to the Free Software Foundation,
00025 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026 //  
00027 //  Dagoberto Salazar - gAGE ( http://www.gage.es ). 2007
00028 //
00029 //============================================================================
00030 
00031 
00032 #include "SunPosition.hpp"
00033 
00034 
00035 namespace gpstk
00036 {
00037 
00038 
00039       // Time of the first valid time
00040    const DayTime SunPosition::initialTime(1900, 3, 1, 0, 0, 0.0);
00041 
00042       // Time of the last valid time
00043    const DayTime SunPosition::finalTime(2100, 2, 28, 0, 0, 0.0);
00044 
00045 
00046       // Returns the position of Sun ECEF coordinates (meters) at the 
00047       // indicated time.
00048       // @param[in] t the time to look up
00049       // @return the position of the Sun at time (as a Triple)
00050       // @throw InvalidRequest If the request can not be completed for any
00051       //    reason, this is thrown. The text may have additional
00052       //    information as to why the request failed.
00053    Triple SunPosition::getPosition(const DayTime& t) const
00054       throw(InvalidRequest)
00055    {
00056 
00057          // Test if the time interval is correct
00058       if ( (t < SunPosition::initialTime) ||
00059            (t > SunPosition::finalTime) )
00060       {
00061          InvalidRequest ir("Provided epoch is out of bounds.");
00062          GPSTK_THROW(ir);
00063       }
00064 
00065          // We will store here the results
00066       Triple res;
00067 
00068       res = SunPosition::getPositionCIS(t);
00069       res = CIS2CTS(res, t);
00070 
00071       return res;
00072    } // End SunPosition::getPosition
00073 
00074 
00075 
00076       /* Function to compute Sun position in CIS system (coordinates 
00077        * in meters)
00078        * @param t Epoch
00079        */
00080    Triple SunPosition::getPositionCIS(const DayTime& t) const
00081       throw(InvalidRequest)
00082    {
00083 
00084          // Test if the time interval is correct
00085       if ( (t < SunPosition::initialTime) ||
00086            (t > SunPosition::finalTime) )
00087       {
00088          InvalidRequest ir("Provided epoch is out of bounds.");
00089          GPSTK_THROW(ir);
00090       }
00091 
00092          // Compute the years, and fraction of year, pased since J1900.0
00093       int y(t.year());    // Current year
00094       int doy(t.DOY());   // Day of current year
00095       double fd( (t.secOfDay()/86400.0 ) );   // Fraction of day
00096       int years( (y - 1900) );    // Integer number of years since J1900.0
00097       int iy4( ( ((y%4)+4)%4 ) ); // Is it a leap year?
00098 
00099          // Compute fraction of year
00100       double yearfrac = ( ( static_cast<double>(4*(doy-1/(iy4+1)) 
00101                             - iy4 - 2) + 4.0 * fd ) / 1461.0 );
00102 
00103       double time(years+yearfrac);
00104 
00105          // Compute the geometric mean longitude of the Sun
00106       double elm( fmod((4.881628 + TWO_PI*yearfrac + 
00107                         0.0001342*time), TWO_PI) );
00108 
00109          // Mean longitude of perihelion
00110       double gamma(4.90823 + 0.00030005*time);
00111 
00112          // Mean anomaly
00113       double em(elm-gamma);
00114 
00115          // Mean obliquity
00116       double eps0(0.40931975 - 2.27e-6*time);
00117 
00118          // Eccentricity
00119       double e(0.016751 - 4.2e-7*time);
00120       double esq(e*e);
00121 
00122          // True anomaly
00123       double v(em + 2.0*e*std::sin(em) + 1.25*esq*std::sin(2.0*em));
00124 
00125          // True ecliptic longitude
00126       double elt(v+gamma);
00127 
00128          // True distance
00129       double r( (1.0 - esq)/(1.0 + e*std::cos(v)) );
00130 
00131          // Moon's mean longitude
00132       double elmm( fmod((4.72 + 83.9971*time),TWO_PI) );
00133 
00134          // Useful definitions
00135       double coselt(std::cos(elt));
00136       double sineps(std::sin(eps0));
00137       double coseps(std::cos(eps0));
00138       double w1(-r*std::sin(elt));
00139       double selmm(std::sin(elmm));
00140       double celmm(std::cos(elmm));
00141 
00142       Triple result;
00143 
00144          // Sun position is the opposite of Earth position
00145       result.theArray[0] = (r*coselt+MeanEarthMoonBary*celmm)*AU_CONST;
00146       result.theArray[1] = (MeanEarthMoonBary*selmm-w1)*coseps*AU_CONST;
00147       result.theArray[2] = (-w1*sineps)*AU_CONST;
00148 
00149       return result;
00150    } // End SunPosition::getPositionCIS()
00151 
00152 
00153 } // end namespace gpstk

Generated on Wed Feb 8 03:31:03 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1