AlmOrbit.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: AlmOrbit.cpp 2944 2011-10-27 08:04:41Z yanweignss $"
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 
00052 #include "icd_200_constants.hpp"
00053 #include "GPSGeoid.hpp"
00054 #include "AlmOrbit.hpp"
00055 #include <cmath>
00056 
00057 namespace gpstk
00058 {
00059    AlmOrbit :: AlmOrbit() throw()
00060    {
00061       ecc = i_offset = OMEGAdot = Ahalf = OMEGA0 = w = M0 = AF0 = AF1 = 0.0;
00062 
00063       Toa = xmit_time = 0;
00064 
00065       week = SV_health = 0;
00066    }
00067 
00068    AlmOrbit :: AlmOrbit(short prn, double aEcc, double ai_offset,
00069                         double aOMEGAdot, double aAhalf, double aOMEGA0,
00070                         double aw, double aM0, double aAF0, double aAF1,
00071                         long aToa, long axmit_time, short aweek,
00072                         short aSV_health)
00073          : ecc(aEcc), i_offset(ai_offset), OMEGAdot(aOMEGAdot), Ahalf(aAhalf),
00074            OMEGA0(aOMEGA0), w(aw), M0(aM0), AF0(aAF0), AF1(aAF1), Toa(aToa),
00075            xmit_time(axmit_time), week(aweek), SV_health(aSV_health), PRN(prn)
00076    {
00077    }
00078 
00079    Xvt AlmOrbit :: svXvt(const DayTime& t) const
00080       throw()
00081    {
00082       Xvt sv;
00083       GPSGeoid geoid;
00084 
00085       double elapt;                 /* elapsed time since Toa */
00086       double A;                     /* semi-major axis */
00087       double n;                       /* mean motion */
00088       double meana;                 /* mean anomoly */
00089       double ea;                    /* eccentric anomoly */
00090       short loop;                   /* counter */
00091       double f,g,delea,q,gsta,gcta; /* temp. variables */
00092       double dtc;                   /* corrected time */
00093       double ta;                    /* true anomoly */
00094       double sinea,cosea,sinu,cosu;
00095       double alat;                  /* arguement of latitude */
00096       double ualat;                 /* corrected arguement of latitude */
00097       double r;                     /* radius */
00098       double i;                     /* inclination */
00099       double anlon;                 /* corrected longitue of ascending node */
00100       double xip,yip,can,san,cinc,sinc,xef,yef,zef,dek,dlk,div,domk,duv,
00101          drv,dxp,dyp,vxef,vyef,vzef;
00102       double sqrtgm = ::sqrt(geoid.gm());
00103 
00104 /*   Compute time since Almanac epoch (Toa) including week change */
00105       elapt = t - getToaTime();
00106 
00107          /* compute mean motion from semi-major axis */
00108       A = Ahalf * Ahalf;
00109       n = sqrtgm / (Ahalf * A);
00110 
00111          /* compute the mean anomaly */
00112       meana = M0 + elapt * n;
00113       meana = ::fmod(meana, 2.0 * PI);
00114 
00115          /* compute eccentric anomaly by iteration */
00116 
00117       ea = meana + ecc * ::sin(meana);
00118       loop = 1;
00119 
00120       do {
00121          f = meana - (ea - ecc * ::sin(ea));
00122          g = 1.0 - ecc * ::cos(ea);
00123          delea = f / g;
00124          ea += delea;
00125          loop++;
00126       }  while ( ::fabs(delea) > 1.0e-11 && (loop <= 20));
00127 
00128          /* compute clock corrections (no relativistic correction computed) */
00129       dtc = AF0 + elapt * AF1;
00130       sv.dtime = dtc;
00131 
00132          /* compute the true anomaly */
00133       q = ::sqrt (1.0e0 - ecc * ecc);
00134       sinea = ::sin(ea);
00135       cosea = ::cos(ea);
00136       gsta = q * sinea;
00137       gcta = cosea  - ecc;
00138       ta = ::atan2(gsta,gcta);
00139 
00140          /* compute argument of latitude for orbit */
00141       alat = ta + w;
00142 
00143          /* compute correction terms ( no pertubation ) */
00144       ualat = alat;
00145       r = A * (1.0 - ecc * cosea);
00146       i = i_offset + 0.3e0 * PI;
00147 
00148          /* compute corrected longitude of ascending node */
00149       anlon = OMEGA0 +
00150          (OMEGAdot - geoid.angVelocity()) * elapt -
00151          geoid.angVelocity() * (double)Toa;
00152 
00153          /* compute positions in orbital plane */
00154       cosu = ::cos(ualat);
00155       sinu = ::sin(ualat);
00156       xip = r * cosu;
00157       yip = r * sinu;
00158 
00159          /* compute earch fixed coordinates (in meters) */
00160       can = ::cos (anlon);
00161       san = ::sin (anlon);
00162       cinc = ::cos(i);
00163       sinc = ::sin(i);
00164 
00165       xef = xip * can - yip * cinc * san;
00166       yef = xip * san + yip * cinc * can;
00167       zef =             yip * sinc;
00168 
00169       sv.x[0] = xef;
00170       sv.x[1] = yef;
00171       sv.x[2] = zef;
00172 
00173          /* compute velocity of rotation coordinates & velocity of sat. */
00174       dek = n * A / r;
00175       dlk = sqrtgm * Ahalf * q / (r * r);
00176       div = 0.0e0;
00177       domk = OMEGAdot - geoid.angVelocity();
00178       duv = dlk;
00179       drv = A * ecc * dek * sinea;
00180 
00181       dxp = drv * cosu - r * sinu * duv;
00182       dyp = drv * sinu + r * cosu * duv;
00183 
00184       vxef = dxp * can - xip * san * domk - dyp * cinc * san
00185          + yip * (sinc * san * div - cinc * can * domk);
00186       vyef = dxp * san + xip * can * domk + dyp * cinc * can
00187          - yip * (sinc * can * div + cinc * san * domk);
00188       vzef = dyp * sinc + yip * cinc * div;
00189 
00190       sv.v[0] = vxef;
00191       sv.v[1] = vyef;
00192       sv.v[2] = vzef;
00193 
00194       return sv;
00195    }
00196 
00197    DayTime AlmOrbit::getTransmitTime() const throw()
00198    {
00199       DayTime transmitTime(0.L);
00200       transmitTime.setGPSfullweek(getFullWeek(), (double)xmit_time);
00201       return transmitTime;
00202    }
00203 
00204    short AlmOrbit::getFullWeek() const throw()
00205    {
00206          // return value of the transmit week for the given PRN
00207       short xmit_week = week;
00208       double sow_diff = (double)(Toa - xmit_time);
00209       if (sow_diff < -DayTime::HALFWEEK)
00210          xmit_week--;
00211       else if (sow_diff > DayTime::HALFWEEK)
00212          xmit_week++;
00213 
00214       return xmit_week;
00215    }
00216 
00217    DayTime AlmOrbit::getToaTime() const throw()
00218    {
00219       DayTime toaTime(0.L);
00220       toaTime.setGPSfullweek(week, (double)Toa);
00221       return toaTime;
00222    }
00223 
00224    void AlmOrbit::dump(std::ostream& s, int verbosity) const
00225    {
00226       using std::endl;
00227       using std::setw;
00228 
00229       s << std::setprecision(4);
00230       s.setf(std::ios::scientific);
00231       switch (verbosity)
00232       {
00233          case 0:
00234             s << PRN       << ", "
00235               << Toa       << ", "
00236               << week       << ", "
00237               << std::hex
00238               << SV_health << ", "
00239               << std::dec
00240               << AF0       << ", "
00241               << AF1       << ", "
00242               << ecc       << ", "
00243               << w         << ", "
00244               << Ahalf     << ", "
00245               << M0        << ", "
00246               << OMEGA0    << ", "
00247               << OMEGAdot  << ", "
00248               << i_offset
00249               << endl;
00250             break;
00251 
00252          case 1:
00253             s << "PRN:" << PRN
00254               << " Toa:" << Toa
00255               << " H:" << SV_health
00256               << " AFO:" << AF0
00257               << " AF1:" << AF1
00258               << " Ecc:" << ecc
00259               << endl
00260               << "   w:" << w
00261               << " Ahalf:" << Ahalf
00262               << " M0:" << M0
00263               << endl
00264               << "   OMEGA0:" << OMEGA0
00265               << " OMEGAdot:" << OMEGAdot
00266               << " Ioff:" << i_offset
00267               << endl;
00268             break;
00269 
00270          default:
00271             s << "PRN:                   " << PRN << endl
00272               << "Toa:                   " << Toa << endl
00273               << "xmit_time:             " << xmit_time << endl
00274               << "week:                  " << week << endl
00275               << "SV_health:             " << SV_health << endl
00276               << "AFO:                   " << setw(12) << AF0  << " sec" << endl
00277               << "AF1:                   " << setw(12) << AF1  << " sec/sec" << endl
00278               << "Sqrt A:                " << setw(12) << Ahalf  << " sqrt meters" << endl
00279               << "Eccentricity:          " << setw(12) << ecc    << endl
00280               << "Arg of perigee:        " << setw(12) << w      << " rad" << endl
00281               << "Mean anomaly at epoch: " << setw(12) << M0     << " rad" << endl
00282               << "Right ascension:       " << setw(12) << OMEGA0 << " rad    " << setw(16) << OMEGAdot << " rad/sec" << endl
00283               << "Inclination offset:    " << setw(12) << i_offset << " rad    " << endl;
00284       }
00285    }
00286 
00287    std::ostream& operator<<(std::ostream& s, const AlmOrbit& ao)
00288    {
00289       ao.dump(s);
00290       return s;
00291    }
00292 
00293 } // namespace

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