Grady Hillhouse / SGP4_vallado

Files at this revision

API Documentation at this revision

Comitter:
gradyhillhouse
Date:
Tue Aug 11 22:42:13 2015 +0000
Commit message:
Port of SGP4 library by Vallado

Changed in this revision

sgp4coord.cpp Show annotated file Show diff for this revision Revisions of this file
sgp4coord.h Show annotated file Show diff for this revision Revisions of this file
sgp4ext.cpp Show annotated file Show diff for this revision Revisions of this file
sgp4ext.h Show annotated file Show diff for this revision Revisions of this file
sgp4io.cpp Show annotated file Show diff for this revision Revisions of this file
sgp4io.h Show annotated file Show diff for this revision Revisions of this file
sgp4unit.cpp Show annotated file Show diff for this revision Revisions of this file
sgp4unit.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sgp4coord.cpp	Tue Aug 11 22:42:13 2015 +0000
@@ -0,0 +1,387 @@
+/*     
+sgp4coord.cpp
+
+This file contains miscellaneous functions required for coordinate transformation.
+Functions were originally written for Matlab as companion code for "Fundamentals of Astrodynamics 
+and Applications" by David Vallado (2007). (w) 719-573-2600, email dvallado@agi.com
+
+Ported to C++ by Grady Hillhouse with some modifications, July 2015.
+*/
+#include "sgp4coord.h"
+#include "sgp4ext.h"
+
+/*
+teme2ecef
+
+This function transforms a vector from a true equator mean equinox (TEME)
+frame to an earth-centered, earth-fixed (ECEF) frame.
+
+Author: David Vallado, 2007
+Ported to C++ by Grady Hillhouse with some modifications, July 2015.
+
+INPUTS          DESCRIPTION                     RANGE/UNITS
+rteme           Position vector (TEME)          km
+vteme           Velocity vector (TEME)          km/s
+jdut1           Julian date                     days
+
+OUTPUTS         DESCRIPTION                     RANGE/UNITS
+recef           Position vector (ECEF)          km  
+vecef           Velocity vector (ECEF)          km/s
+*/
+
+void teme2ecef(double rteme[3], double vteme[3], double jdut1, double recef[3], double vecef[3])
+{
+    double gmst;
+    double st[3][3];
+    double rpef[3];
+    double vpef[3];
+    double pm[3][3];
+    double omegaearth[3];
+    
+    //Get Greenwich mean sidereal time
+    gmst = gstime(jdut1);
+    
+    //st is the pef - tod matrix
+    st[0][0] = cos(gmst);
+    st[0][1] = -sin(gmst);
+    st[0][2] = 0.0;
+    st[1][0] = sin(gmst);
+    st[1][1] = cos(gmst);
+    st[1][2] = 0.0;
+    st[2][0] = 0.0;
+    st[2][1] = 0.0;
+    st[2][2] = 1.0;
+    
+    //Get pseudo earth fixed position vector by multiplying the inverse pef-tod matrix by rteme
+    rpef[0] = st[0][0] * rteme[0] + st[1][0] * rteme[1] + st[2][0] * rteme[2];
+    rpef[1] = st[0][1] * rteme[0] + st[1][1] * rteme[1] + st[2][1] * rteme[2];
+    rpef[2] = st[0][2] * rteme[0] + st[1][2] * rteme[1] + st[2][2] * rteme[2];
+    
+    //Get polar motion vector
+    polarm(jdut1, pm);
+    
+    //ECEF postion vector is the inverse of the polar motion vector multiplied by rpef
+    recef[0] = pm[0][0] * rpef[0] + pm[1][0] * rpef[1] + pm[2][0] * rpef[2];
+    recef[1] = pm[0][1] * rpef[0] + pm[1][1] * rpef[1] + pm[2][1] * rpef[2];
+    recef[2] = pm[0][2] * rpef[0] + pm[1][2] * rpef[1] + pm[2][2] * rpef[2];
+    
+    //Earth's angular rotation vector (omega)
+    //Note: I don't have a good source for LOD. Historically it has been on the order of 2 ms so I'm just using that as a constant. The effect is very small.
+    omegaearth[0] = 0.0;
+    omegaearth[1] = 0.0;
+    omegaearth[2] = 7.29211514670698e-05 * (1.0  - 0.002/86400.0);
+    
+    //Pseudo Earth Fixed velocity vector is st'*vteme - omegaearth X rpef
+    vpef[0] = st[0][0] * vteme[0] + st[1][0] * vteme[1] + st[2][0] * vteme[2] - (omegaearth[1]*rpef[2] - omegaearth[2]*rpef[1]);
+    vpef[1] = st[0][1] * vteme[0] + st[1][1] * vteme[1] + st[2][1] * vteme[2] - (omegaearth[2]*rpef[0] - omegaearth[0]*rpef[2]);
+    vpef[2] = st[0][2] * vteme[0] + st[1][2] * vteme[1] + st[2][2] * vteme[2] - (omegaearth[0]*rpef[1] - omegaearth[1]*rpef[0]);
+    
+    //ECEF velocty vector is the inverse of the polar motion vector multiplied by vpef
+    vecef[0] = pm[0][0] * vpef[0] + pm[1][0] * vpef[1] + pm[2][0] * vpef[2];
+    vecef[1] = pm[0][1] * vpef[0] + pm[1][1] * vpef[1] + pm[2][1] * vpef[2];
+    vecef[2] = pm[0][2] * vpef[0] + pm[1][2] * vpef[1] + pm[2][2] * vpef[2];
+}
+
+/*
+polarm
+
+This function calulates the transformation matrix that accounts for polar
+motion. Polar motion coordinates are estimated using IERS Bulletin
+rather than directly input for simplicity.
+
+Author: David Vallado, 2007
+Ported to C++ by Grady Hillhouse with some modifications, July 2015.
+
+INPUTS          DESCRIPTION                     RANGE/UNITS
+jdut1           Julian date                     days
+
+OUTPUTS         DESCRIPTION
+pm              Transformation matrix for ECEF - PEF
+*/
+
+void polarm(double jdut1, double pm[3][3])
+{
+    double MJD; //Julian Date - 2,400,000.5 days
+    double A;
+    double C;
+    double xp; //Polar motion coefficient in radians
+    double yp; //Polar motion coefficient in radians
+    
+    //Predict polar motion coefficients using IERS Bulletin - A (Vol. XXVIII No. 030)
+    MJD = jdut1 - 2400000.5;
+    A = 2 * pi * (MJD - 57226) / 365.25;
+    C = 2 * pi * (MJD - 57226) / 435;
+    
+    xp = (0.1033 + 0.0494*cos(A) + 0.0482*sin(A) + 0.0297*cos(C) + 0.0307*sin(C)) * 4.84813681e-6;
+    yp = (0.3498 + 0.0441*cos(A) - 0.0393*sin(A) + 0.0307*cos(C) - 0.0297*sin(C)) * 4.84813681e-6;
+    
+    pm[0][0] = cos(xp);
+    pm[0][1] = 0.0;
+    pm[0][2] = -sin(xp);
+    pm[1][0] = sin(xp) * sin(yp);
+    pm[1][1] = cos(yp);
+    pm[1][2] = cos(xp) * sin(yp);
+    pm[2][0] = sin(xp) * cos(yp);
+    pm[2][1] = -sin(yp);
+    pm[2][2] = cos(xp) * cos(yp);
+}
+
+/*
+ijk2ll
+
+This function calulates the latitude, longitude and altitude
+given the ECEF position matrix.
+
+Author: David Vallado, 2007
+Ported to C++ by Grady Hillhouse with some modifications, July 2015.
+
+INPUTS          DESCRIPTION                     RANGE/UNITS
+r               Position matrix (ECEF)          km
+
+OUTPUTS         DESCRIPTION
+latlongh        Latitude, longitude, and altitude (rad, rad, and km)
+*/
+
+void ijk2ll(double r[3], double latlongh[3])
+{
+    double twopi = 2.0*pi;
+    double small = 0.00000001;          //small value for tolerances
+    double re = 6378.137;               //radius of earth in km
+    double eesqrd = 0.006694385000;     //eccentricity of earth sqrd
+    double magr, temp, rtasc;
+    
+    magr = mag(r);
+    temp = sqrt(r[0]*r[0] + r[1]*r[1]);
+ 
+    if(abs(temp) < small)
+    {
+        rtasc = sgn(r[2]) * pi * 0.5;
+    }
+    else
+    {
+        rtasc = atan2(r[1], r[0]);
+    }
+    
+    latlongh[1] = rtasc;
+    
+    if (abs(latlongh[1]) >= pi)
+    {
+        if (latlongh[1] < 0.0)
+        {
+            latlongh[1] += twopi;
+        }
+        else
+        {
+            latlongh[1] -= twopi;
+        }
+    }
+    
+    latlongh[0] = asin(r[2] / magr);
+    
+    //Iterate to find geodetic latitude
+    int i = 1;
+    double olddelta = latlongh[0] + 10.0;
+    double sintemp, c;
+    
+    while ( (abs(olddelta - latlongh[0]) >= small) && (i < 10) )
+    {
+        olddelta = latlongh[0];
+        sintemp = sin(latlongh[0]);
+        c = re / sqrt(1.0 - eesqrd*sintemp*sintemp);
+        latlongh[0] = atan( (r[2] + c*eesqrd*sintemp) / temp );
+        i++;
+    }
+    
+    if (0.5*pi - abs(latlongh[0]) > pi/180.0)
+    {
+        latlongh[2] = (temp/cos(latlongh[0])) - c;
+    }
+    else
+    {
+        latlongh[2] = r[2]/sin(latlongh[0]) - c*(1.0 - eesqrd);
+    }
+}
+
+/*
+site
+
+This function finds the position and velocity vectors for a site. The
+outputs are in the ECEF coordinate system. Note that the velocity vector
+is zero because the coordinate system rotates with the earth.
+
+Author: David Vallado, 2007
+Ported to C++ by Grady Hillhouse with some modifications, July 2015.
+
+INPUTS          DESCRIPTION                     RANGE/UNITS
+latgd           Site geodetic latitude          -pi/2 to pi/2 in radians
+lon             Longitude                       -2pi to 2pi in radians
+alt             Site altitude                   km
+
+OUTPUTS         DESCRIPTION
+rs              Site position vector            km
+vs              Site velocity vector            km/s
+*/
+
+void site(double latgd, double lon, double alt, double rs[3], double vs[3])
+{
+    double sinlat, re, eesqrd, cearth, rdel, rk;
+    re = 6378.137;              //radius of earth in km
+    eesqrd = 0.006694385000;    //eccentricity of earth sqrd
+    
+    //Find rdel and rk components of site vector
+    sinlat = sin(latgd);
+    cearth = re / sqrt( 1.0 - (eesqrd*sinlat*sinlat) );
+    rdel = (cearth + alt) * cos(latgd);
+    rk = ((1.0 - eesqrd) * cearth + alt ) * sinlat;
+    
+    //Find site position vector (ECEF)
+    rs[0] = rdel * cos( lon );
+    rs[1] = rdel * sin( lon );
+    rs[2] = rk;
+    
+    //Velocity of site is zero because the coordinate system is rotating with the earth
+    vs[0] = 0.0;
+    vs[1] = 0.0;
+    vs[2] = 0.0;
+}
+
+
+/*
+rv2azel
+
+This function calculates the range, elevation, and azimuth (and their rates)
+from the TEME vectors output by the SGP4 function.
+
+Author: David Vallado, 2007
+Ported to C++ by Grady Hillhouse with some modifications, July 2015.
+
+INPUTS          DESCRIPTION                     RANGE/UNITS
+ro              Sat. position vector (TEME)     km
+vo              Sat. velocity vector (TEME)     km/s
+latgd           Site geodetic latitude          -pi/2 to pi/2 in radians
+lon             Site longitude                  -2pi to 2pi in radians
+alt             Site altitude                   km
+jdut1           Julian date                     days
+
+OUTPUTS         DESCRIPTION
+razel           Range, azimuth, and elevation matrix
+razelrates      Range rate, azimuth rate, and elevation rate matrix
+*/
+
+void rv2azel(double ro[3], double vo[3], double latgd, double lon, double alt, double jdut1, double razel[3], double razelrates[3])
+{
+    //Locals
+    double halfpi = pi * 0.5;
+    double small  = 0.00000001;
+    double temp;
+    double rs[3];
+    double vs[3];
+    double recef[3];
+    double vecef[3];
+    double rhoecef[3];
+    double drhoecef[3];
+    double tempvec[3];
+    double rhosez[3];
+    double drhosez[3];
+    double magrhosez;
+    double rho, az, el;
+    double drho, daz, del;
+    
+    //Get site vector in ECEF coordinate system
+    site(latgd, lon, alt, rs, vs);
+    
+    //Convert TEME vectors to ECEF coordinate system
+    teme2ecef(ro, vo, jdut1, recef, vecef);
+    
+    //Find ECEF range vectors
+    for (int i = 0; i < 3; i++)
+    {
+        rhoecef[i] = recef[i] - rs[i];
+        drhoecef[i] = vecef[i];
+    }
+    rho = mag(rhoecef); //Range in km
+    
+    //Convert to SEZ (topocentric horizon coordinate system)
+    rot3(rhoecef, lon, tempvec);
+    rot2(tempvec, (halfpi-latgd), rhosez);
+    
+    rot3(drhoecef, lon, tempvec);
+    rot2(tempvec, (halfpi-latgd), drhosez);
+    
+    //Calculate azimuth, and elevation
+    temp = sqrt(rhosez[0]*rhosez[0] + rhosez[1]*rhosez[1]);
+    if (temp < small)
+    {
+        el = sgn(rhosez[2]) * halfpi;
+        az = atan2(drhosez[1], -drhosez[0]);
+    }
+    else
+    {
+        magrhosez = mag(rhosez);
+        el = asin(rhosez[2]/magrhosez);
+        az = atan2(rhosez[1]/temp, -rhosez[0]/temp);
+    }
+    
+    //Calculate rates for range, azimuth, and elevation
+    drho = dot(rhosez,drhosez) / rho;
+    
+    if(abs(temp*temp) > small)
+    {
+        daz = (drhosez[0]*rhosez[1] - drhosez[1]*rhosez[0]) / (temp * temp);
+    }
+    else
+    {
+        daz = 0.0;
+    }
+    
+    if(abs(temp) > small)
+    {
+        del = (drhosez[2] - drho*sin(el)) / temp;
+    }
+    else
+    {
+        del = 0.0;
+    }
+    
+    //Move values to output vectors
+    razel[0] = rho;             //Range (km)
+    razel[1] = az;              //Azimuth (radians)
+    razel[2] = el;              //Elevation (radians)
+    
+    razelrates[0] = drho;       //Range rate (km/s)
+    razelrates[1] = daz;        //Azimuth rate (rad/s)
+    razelrates[2] = del;        //Elevation rate (rad/s)
+}
+
+void rot3(double invec[3], double xval, double outvec[3])
+{
+    double temp = invec[1];
+    double c = cos(xval);
+    double s = sin(xval);
+    
+    outvec[1] = c*invec[1] - s*invec[0];
+    outvec[0] = c*invec[0] + s*temp;
+    outvec[2] = invec[2];
+}
+
+void rot2(double invec[3], double xval, double outvec[3])
+{
+    double temp = invec[2];
+    double c = cos(xval);
+    double s = sin(xval);
+    
+    outvec[2] = c*invec[2] + s*invec[0];
+    outvec[0] = c*invec[0] - s*temp;
+    outvec[1] = invec[1];
+}
+
+/*
+getJulianFromUnix
+
+returns the Julian Date from Unix Time
+*/
+
+double getJulianFromUnix(double unixSecs)
+{
+   return ( unixSecs / 86400.0 ) + 2440587.5;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sgp4coord.h	Tue Aug 11 22:42:13 2015 +0000
@@ -0,0 +1,33 @@
+#ifndef _sgp4coord_
+#define _sgp4coord_
+
+/*     
+sgp4coord.h
+
+This file contains miscellaneous functions required for coordinate transformation.
+Functions were originally written for Matlab as companion code for "Fundamentals of Astrodynamics 
+and Applications" by David Vallado (2007). (w) 719-573-2600, email dvallado@agi.com
+
+Ported to C++ by Grady Hillhouse with some modifications, July 2015.
+*/
+
+#include <math.h>
+#include <string.h>
+
+void teme2ecef(double rteme[3], double vteme[3], double jdut1, double recef[3], double vecef[3]);
+
+void polarm(double jdut1, double pm[3][3]);
+
+void ijk2ll(double r[3], double latlongh[3]);
+
+void site(double latgd, double lon, double alt, double rs[3], double vs[3]);
+
+void rv2azel(double ro[3], double vo[3], double latgd, double lon, double alt, double jdut1, double razel[3], double razelrates[3]);
+
+void rot3(double invec[3], double xval, double outvec[3]);
+
+void rot2(double invec[3], double xval, double outvec[3]);
+
+double getJulianFromUnix(double unixSecs);
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sgp4ext.cpp	Tue Aug 11 22:42:13 2015 +0000
@@ -0,0 +1,721 @@
+/*     ----------------------------------------------------------------
+*
+*                               sgp4ext.cpp
+*
+*    this file contains extra routines needed for the main test program for sgp4.
+*    these routines are derived from the astro libraries.
+*
+*                            companion code for
+*               fundamentals of astrodynamics and applications
+*                                    2007
+*                              by david vallado
+*
+*       (w) 719-573-2600, email dvallado@agi.com
+*
+*    current :
+*               7 may 08  david vallado
+*                           fix sgn
+*    changes :
+*               2 apr 07  david vallado
+*                           fix jday floor and str lengths
+*                           updates for constants
+*              14 aug 06  david vallado
+*                           original baseline
+*       ----------------------------------------------------------------      */
+
+#include "sgp4ext.h"
+
+
+double  sgn
+        (
+          double x
+        )
+   {
+     if (x < 0.0)
+       {
+          return -1.0;
+       }
+       else
+       {
+          return 1.0;
+       }
+
+   }  // end sgn
+
+/* -----------------------------------------------------------------------------
+*
+*                           function mag
+*
+*  this procedure finds the magnitude of a vector.  the tolerance is set to
+*    0.000001, thus the 1.0e-12 for the squared test of underflows.
+*
+*  author        : david vallado                  719-573-2600    1 mar 2001
+*
+*  inputs          description                    range / units
+*    vec         - vector
+*
+*  outputs       :
+*    vec         - answer stored in fourth component
+*
+*  locals        :
+*    none.
+*
+*  coupling      :
+*    none.
+* --------------------------------------------------------------------------- */
+
+double  mag
+        (
+          double x[3]
+        )
+   {
+     return sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
+   }  // end mag
+
+/* -----------------------------------------------------------------------------
+*
+*                           procedure cross
+*
+*  this procedure crosses two vectors.
+*
+*  author        : david vallado                  719-573-2600    1 mar 2001
+*
+*  inputs          description                    range / units
+*    vec1        - vector number 1
+*    vec2        - vector number 2
+*
+*  outputs       :
+*    outvec      - vector result of a x b
+*
+*  locals        :
+*    none.
+*
+*  coupling      :
+*    mag           magnitude of a vector
+ ---------------------------------------------------------------------------- */
+
+void    cross
+        (
+          double vec1[3], double vec2[3], double outvec[3]
+        )
+   {
+     outvec[0]= vec1[1]*vec2[2] - vec1[2]*vec2[1];
+     outvec[1]= vec1[2]*vec2[0] - vec1[0]*vec2[2];
+     outvec[2]= vec1[0]*vec2[1] - vec1[1]*vec2[0];
+   }  // end cross
+
+
+/* -----------------------------------------------------------------------------
+*
+*                           function dot
+*
+*  this function finds the dot product of two vectors.
+*
+*  author        : david vallado                  719-573-2600    1 mar 2001
+*
+*  inputs          description                    range / units
+*    vec1        - vector number 1
+*    vec2        - vector number 2
+*
+*  outputs       :
+*    dot         - result
+*
+*  locals        :
+*    none.
+*
+*  coupling      :
+*    none.
+*
+* --------------------------------------------------------------------------- */
+
+double  dot
+        (
+          double x[3], double y[3]
+        )
+   {
+     return (x[0]*y[0] + x[1]*y[1] + x[2]*y[2]);
+   }  // end dot
+
+/* -----------------------------------------------------------------------------
+*
+*                           procedure angle
+*
+*  this procedure calculates the angle between two vectors.  the output is
+*    set to 999999.1 to indicate an undefined value.  be sure to check for
+*    this at the output phase.
+*
+*  author        : david vallado                  719-573-2600    1 mar 2001
+*
+*  inputs          description                    range / units
+*    vec1        - vector number 1
+*    vec2        - vector number 2
+*
+*  outputs       :
+*    theta       - angle between the two vectors  -pi to pi
+*
+*  locals        :
+*    temp        - temporary real variable
+*
+*  coupling      :
+*    dot           dot product of two vectors
+* --------------------------------------------------------------------------- */
+
+double  angle
+        (
+          double vec1[3],
+          double vec2[3]
+        )
+   {
+     double small, undefined, magv1, magv2, temp;
+     small     = 0.00000001;
+     undefined = 999999.1;
+
+     magv1 = mag(vec1);
+     magv2 = mag(vec2);
+
+     if (magv1*magv2 > small*small)
+       {
+         temp= dot(vec1,vec2) / (magv1*magv2);
+         if (fabs( temp ) > 1.0)
+             temp= sgn(temp) * 1.0;
+         return acos( temp );
+       }
+       else
+         return undefined;
+   }  // end angle
+
+
+/* -----------------------------------------------------------------------------
+*
+*                           function asinh
+*
+*  this function evaluates the inverse hyperbolic sine function.
+*
+*  author        : david vallado                  719-573-2600    1 mar 2001
+*
+*  inputs          description                    range / units
+*    xval        - angle value                                  any real
+*
+*  outputs       :
+*    arcsinh     - result                                       any real
+*
+*  locals        :
+*    none.
+*
+*  coupling      :
+*    none.
+*
+* Note: This function appears to be defined in std since 2011. I commented it out. - Grady Hillhouse 2015
+* --------------------------------------------------------------------------- */
+
+/*double  asinh
+        (
+          double xval
+        )
+   {
+     return log( xval + sqrt( xval*xval + 1.0 ) );
+   }  // end asinh
+*/
+
+/* -----------------------------------------------------------------------------
+*
+*                           function newtonnu
+*
+*  this function solves keplers equation when the true anomaly is known.
+*    the mean and eccentric, parabolic, or hyperbolic anomaly is also found.
+*    the parabolic limit at 168ø is arbitrary. the hyperbolic anomaly is also
+*    limited. the hyperbolic sine is used because it's not double valued.
+*
+*  author        : david vallado                  719-573-2600   27 may 2002
+*
+*  revisions
+*    vallado     - fix small                                     24 sep 2002
+*
+*  inputs          description                    range / units
+*    ecc         - eccentricity                   0.0  to
+*    nu          - true anomaly                   -2pi to 2pi rad
+*
+*  outputs       :
+*    e0          - eccentric anomaly              0.0  to 2pi rad       153.02 ø
+*    m           - mean anomaly                   0.0  to 2pi rad       151.7425 ø
+*
+*  locals        :
+*    e1          - eccentric anomaly, next value  rad
+*    sine        - sine of e
+*    cose        - cosine of e
+*    ktr         - index
+*
+*  coupling      :
+*    asinh       - arc hyperbolic sine
+*
+*  references    :
+*    vallado       2007, 85, alg 5
+* --------------------------------------------------------------------------- */
+
+void newtonnu
+     (
+       double ecc, double nu,
+       double& e0, double& m
+     )
+     {
+       double small, sine, cose;
+
+     // ---------------------  implementation   ---------------------
+     e0= 999999.9;
+     m = 999999.9;
+     small = 0.00000001;
+
+     // --------------------------- circular ------------------------
+     if ( fabs( ecc ) < small  )
+       {
+         m = nu;
+         e0= nu;
+       }
+       else
+         // ---------------------- elliptical -----------------------
+         if ( ecc < 1.0-small  )
+           {
+             sine= ( sqrt( 1.0 -ecc*ecc ) * sin(nu) ) / ( 1.0 +ecc*cos(nu) );
+             cose= ( ecc + cos(nu) ) / ( 1.0  + ecc*cos(nu) );
+             e0  = atan2( sine,cose );
+             m   = e0 - ecc*sin(e0);
+           }
+           else
+             // -------------------- hyperbolic  --------------------
+             if ( ecc > 1.0 + small  )
+               {
+                 if ((ecc > 1.0 ) && (fabs(nu)+0.00001 < pi-acos(1.0 /ecc)))
+                   {
+                     sine= ( sqrt( ecc*ecc-1.0  ) * sin(nu) ) / ( 1.0  + ecc*cos(nu) );
+                     e0  = asinh( sine );
+                     m   = ecc*sinh(e0) - e0;
+                   }
+                }
+               else
+                 // ----------------- parabolic ---------------------
+                 if ( fabs(nu) < 168.0*pi/180.0  )
+                   {
+                     e0= tan( nu*0.5  );
+                     m = e0 + (e0*e0*e0)/3.0;
+                   }
+
+     if ( ecc < 1.0  )
+       {
+         m = fmod( m,2.0 *pi );
+         if ( m < 0.0  )
+             m = m + 2.0 *pi;
+         e0 = fmod( e0,2.0 *pi );
+       }
+   }  // end newtonnu
+
+
+/* -----------------------------------------------------------------------------
+*
+*                           function rv2coe
+*
+*  this function finds the classical orbital elements given the geocentric
+*    equatorial position and velocity vectors.
+*
+*  author        : david vallado                  719-573-2600   21 jun 2002
+*
+*  revisions
+*    vallado     - fix special cases                              5 sep 2002
+*    vallado     - delete extra check in inclination code        16 oct 2002
+*    vallado     - add constant file use                         29 jun 2003
+*    vallado     - add mu                                         2 apr 2007
+*
+*  inputs          description                    range / units
+*    r           - ijk position vector            km
+*    v           - ijk velocity vector            km / s
+*    mu          - gravitational parameter        km3 / s2
+*
+*  outputs       :
+*    p           - semilatus rectum               km
+*    a           - semimajor axis                 km
+*    ecc         - eccentricity
+*    incl        - inclination                    0.0  to pi rad
+*    omega       - longitude of ascending node    0.0  to 2pi rad
+*    argp        - argument of perigee            0.0  to 2pi rad
+*    nu          - true anomaly                   0.0  to 2pi rad
+*    m           - mean anomaly                   0.0  to 2pi rad
+*    arglat      - argument of latitude      (ci) 0.0  to 2pi rad
+*    truelon     - true longitude            (ce) 0.0  to 2pi rad
+*    lonper      - longitude of periapsis    (ee) 0.0  to 2pi rad
+*
+*  locals        :
+*    hbar        - angular momentum h vector      km2 / s
+*    ebar        - eccentricity     e vector
+*    nbar        - line of nodes    n vector
+*    c1          - v**2 - u/r
+*    rdotv       - r dot v
+*    hk          - hk unit vector
+*    sme         - specfic mechanical energy      km2 / s2
+*    i           - index
+*    e           - eccentric, parabolic,
+*                  hyperbolic anomaly             rad
+*    temp        - temporary variable
+*    typeorbit   - type of orbit                  ee, ei, ce, ci
+*
+*  coupling      :
+*    mag         - magnitude of a vector
+*    cross       - cross product of two vectors
+*    angle       - find the angle between two vectors
+*    newtonnu    - find the mean anomaly
+*
+*  references    :
+*    vallado       2007, 126, alg 9, ex 2-5
+* --------------------------------------------------------------------------- */
+
+void rv2coe
+     (
+       double r[3], double v[3], double mu,
+       double& p, double& a, double& ecc, double& incl, double& omega, double& argp,
+       double& nu, double& m, double& arglat, double& truelon, double& lonper
+     )
+     {
+       double undefined, small, hbar[3], nbar[3], magr, magv, magn, ebar[3], sme,
+              rdotv, infinite, temp, c1, hk, twopi, magh, halfpi, e;
+
+       int i;
+       char typeorbit[3];
+
+     twopi  = 2.0 * pi;
+     halfpi = 0.5 * pi;
+     small  = 0.00000001;
+     undefined = 999999.1;
+     infinite  = 999999.9;
+
+     // -------------------------  implementation   -----------------
+     magr = mag( r );
+     magv = mag( v );
+
+     // ------------------  find h n and e vectors   ----------------
+     cross( r,v, hbar );
+     magh = mag( hbar );
+     if ( magh > small )
+       {
+         nbar[0]= -hbar[1];
+         nbar[1]=  hbar[0];
+         nbar[2]=   0.0;
+         magn = mag( nbar );
+         c1 = magv*magv - mu /magr;
+         rdotv = dot( r,v );
+         for (i= 0; i <= 2; i++)
+             ebar[i]= (c1*r[i] - rdotv*v[i])/mu;
+         ecc = mag( ebar );
+
+         // ------------  find a e and semi-latus rectum   ----------
+         sme= ( magv*magv*0.5  ) - ( mu /magr );
+         if ( fabs( sme ) > small )
+             a= -mu  / (2.0 *sme);
+           else
+             a= infinite;
+         p = magh*magh/mu;
+
+         // -----------------  find inclination   -------------------
+         hk= hbar[2]/magh;
+         incl= acos( hk );
+
+         // --------  determine type of orbit for later use  --------
+         // ------ elliptical, parabolic, hyperbolic inclined -------
+         strcpy(typeorbit,"ei");
+         if ( ecc < small )
+           {
+             // ----------------  circular equatorial ---------------
+             if  ((incl<small) | (fabs(incl-pi)<small))
+                 strcpy(typeorbit,"ce");
+               else
+                 // --------------  circular inclined ---------------
+                 strcpy(typeorbit,"ci");
+           }
+           else
+           {
+             // - elliptical, parabolic, hyperbolic equatorial --
+             if  ((incl<small) | (fabs(incl-pi)<small))
+                 strcpy(typeorbit,"ee");
+           }
+
+         // ----------  find longitude of ascending node ------------
+         if ( magn > small )
+           {
+             temp= nbar[0] / magn;
+             if ( fabs(temp) > 1.0  )
+                 temp= sgn(temp);
+             omega= acos( temp );
+             if ( nbar[1] < 0.0  )
+                 omega= twopi - omega;
+           }
+           else
+             omega= undefined;
+
+         // ---------------- find argument of perigee ---------------
+         if ( strcmp(typeorbit,"ei") == 0 )
+           {
+             argp = angle( nbar,ebar);
+             if ( ebar[2] < 0.0  )
+                 argp= twopi - argp;
+           }
+           else
+             argp= undefined;
+
+         // ------------  find true anomaly at epoch    -------------
+         if ( typeorbit[0] == 'e' )
+           {
+             nu =  angle( ebar,r);
+             if ( rdotv < 0.0  )
+                 nu= twopi - nu;
+           }
+           else
+             nu= undefined;
+
+         // ----  find argument of latitude - circular inclined -----
+         if ( strcmp(typeorbit,"ci") == 0 )
+           {
+             arglat = angle( nbar,r );
+             if ( r[2] < 0.0  )
+                 arglat= twopi - arglat;
+             m = arglat;
+           }
+           else
+             arglat= undefined;
+
+         // -- find longitude of perigee - elliptical equatorial ----
+         if  (( ecc>small ) && (strcmp(typeorbit,"ee") == 0))
+           {
+             temp= ebar[0]/ecc;
+             if ( fabs(temp) > 1.0  )
+                 temp= sgn(temp);
+             lonper= acos( temp );
+             if ( ebar[1] < 0.0  )
+                 lonper= twopi - lonper;
+             if ( incl > halfpi )
+                 lonper= twopi - lonper;
+           }
+           else
+             lonper= undefined;
+
+         // -------- find true longitude - circular equatorial ------
+         if  (( magr>small ) && ( strcmp(typeorbit,"ce") == 0 ))
+           {
+             temp= r[0]/magr;
+             if ( fabs(temp) > 1.0  )
+                 temp= sgn(temp);
+             truelon= acos( temp );
+             if ( r[1] < 0.0  )
+                 truelon= twopi - truelon;
+             if ( incl > halfpi )
+                 truelon= twopi - truelon;
+             m = truelon;
+           }
+           else
+             truelon= undefined;
+
+         // ------------ find mean anomaly for all orbits -----------
+         if ( typeorbit[0] == 'e' )
+             newtonnu(ecc,nu,  e, m);
+     }
+      else
+     {
+        p    = undefined;
+        a    = undefined;
+        ecc  = undefined;
+        incl = undefined;
+        omega= undefined;
+        argp = undefined;
+        nu   = undefined;
+        m    = undefined;
+        arglat = undefined;
+        truelon= undefined;
+        lonper = undefined;
+     }
+   }  // end rv2coe
+
+/* -----------------------------------------------------------------------------
+*
+*                           procedure jday
+*
+*  this procedure finds the julian date given the year, month, day, and time.
+*    the julian date is defined by each elapsed day since noon, jan 1, 4713 bc.
+*
+*  algorithm     : calculate the answer in one step for efficiency
+*
+*  author        : david vallado                  719-573-2600    1 mar 2001
+*
+*  inputs          description                    range / units
+*    year        - year                           1900 .. 2100
+*    mon         - month                          1 .. 12
+*    day         - day                            1 .. 28,29,30,31
+*    hr          - universal time hour            0 .. 23
+*    min         - universal time min             0 .. 59
+*    sec         - universal time sec             0.0 .. 59.999
+*
+*  outputs       :
+*    jd          - julian date                    days from 4713 bc
+*
+*  locals        :
+*    none.
+*
+*  coupling      :
+*    none.
+*
+*  references    :
+*    vallado       2007, 189, alg 14, ex 3-14
+*
+* --------------------------------------------------------------------------- */
+
+void    jday
+        (
+          int year, int mon, int day, int hr, int minute, double sec,
+          double& jd
+        )
+   {
+     jd = 367.0 * year -
+          floor((7 * (year + floor((mon + 9) / 12.0))) * 0.25) +
+          floor( 275 * mon / 9.0 ) +
+          day + 1721013.5 +
+          ((sec / 60.0 + minute) / 60.0 + hr) / 24.0;  // ut in days
+          // - 0.5*sgn(100.0*year + mon - 190002.5) + 0.5;
+   }  // end jday
+
+
+/* -----------------------------------------------------------------------------
+*
+*                           procedure days2mdhms
+*
+*  this procedure converts the day of the year, days, to the equivalent month
+*    day, hour, minute and second.
+*
+*  algorithm     : set up array for the number of days per month
+*                  find leap year - use 1900 because 2000 is a leap year
+*                  loop through a temp value while the value is < the days
+*                  perform int conversions to the correct day and month
+*                  convert remainder into h m s using type conversions
+*
+*  author        : david vallado                  719-573-2600    1 mar 2001
+*
+*  inputs          description                    range / units
+*    year        - year                           1900 .. 2100
+*    days        - julian day of the year         0.0  .. 366.0
+*
+*  outputs       :
+*    mon         - month                          1 .. 12
+*    day         - day                            1 .. 28,29,30,31
+*    hr          - hour                           0 .. 23
+*    min         - minute                         0 .. 59
+*    sec         - second                         0.0 .. 59.999
+*
+*  locals        :
+*    dayofyr     - day of year
+*    temp        - temporary extended values
+*    inttemp     - temporary int value
+*    i           - index
+*    lmonth[12]  - int array containing the number of days per month
+*
+*  coupling      :
+*    none.
+* --------------------------------------------------------------------------- */
+
+void    days2mdhms
+        (
+          int year, double days,
+          int& mon, int& day, int& hr, int& minute, double& sec
+        )
+   {
+     int i, inttemp, dayofyr;
+     double    temp;
+     int lmonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+     dayofyr = (int)floor(days);
+     /* ----------------- find month and day of month ---------------- */
+     if ( (year % 4) == 0 )
+       lmonth[1] = 29;
+
+     i = 1;
+     inttemp = 0;
+     while ((dayofyr > inttemp + lmonth[i-1]) && (i < 12))
+     {
+       inttemp = inttemp + lmonth[i-1];
+       i++;
+     }
+     mon = i;
+     day = dayofyr - inttemp;
+
+     /* ----------------- find hours minutes and seconds ------------- */
+     temp = (days - dayofyr) * 24.0;
+     hr   = (int)floor(temp);
+     temp = (temp - hr) * 60.0;
+     minute  = (int)floor(temp);
+     sec  = (temp - minute) * 60.0;
+   }  // end days2mdhms
+
+/* -----------------------------------------------------------------------------
+*
+*                           procedure invjday
+*
+*  this procedure finds the year, month, day, hour, minute and second
+*  given the julian date. tu can be ut1, tdt, tdb, etc.
+*
+*  algorithm     : set up starting values
+*                  find leap year - use 1900 because 2000 is a leap year
+*                  find the elapsed days through the year in a loop
+*                  call routine to find each individual value
+*
+*  author        : david vallado                  719-573-2600    1 mar 2001
+*
+*  inputs          description                    range / units
+*    jd          - julian date                    days from 4713 bc
+*
+*  outputs       :
+*    year        - year                           1900 .. 2100
+*    mon         - month                          1 .. 12
+*    day         - day                            1 .. 28,29,30,31
+*    hr          - hour                           0 .. 23
+*    min         - minute                         0 .. 59
+*    sec         - second                         0.0 .. 59.999
+*
+*  locals        :
+*    days        - day of year plus fractional
+*                  portion of a day               days
+*    tu          - julian centuries from 0 h
+*                  jan 0, 1900
+*    temp        - temporary double values
+*    leapyrs     - number of leap years from 1900
+*
+*  coupling      :
+*    days2mdhms  - finds month, day, hour, minute and second given days and year
+*
+*  references    :
+*    vallado       2007, 208, alg 22, ex 3-13
+* --------------------------------------------------------------------------- */
+
+void    invjday
+        (
+          double jd,
+          int& year, int& mon, int& day,
+          int& hr, int& minute, double& sec
+        )
+   {
+     int leapyrs;
+     double    days, tu, temp;
+
+     /* --------------- find year and days of the year --------------- */
+     temp    = jd - 2415019.5;
+     tu      = temp / 365.25;
+     year    = 1900 + (int)floor(tu);
+     leapyrs = (int)floor((year - 1901) * 0.25);
+
+     // optional nudge by 8.64x10-7 sec to get even outputs
+     days    = temp - ((year - 1900) * 365.0 + leapyrs) + 0.00000000001;
+
+     /* ------------ check for case of beginning of a year ----------- */
+     if (days < 1.0)
+       {
+         year    = year - 1;
+         leapyrs = (int)floor((year - 1901) * 0.25);
+         days    = temp - ((year - 1900) * 365.0 + leapyrs);
+       }
+
+     /* ----------------- find remaing data  ------------------------- */
+     days2mdhms(year, days, mon, day, hr, minute, sec);
+     sec = sec - 0.00000086400;
+   }  // end invjday
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sgp4ext.h	Tue Aug 11 22:42:13 2015 +0000
@@ -0,0 +1,98 @@
+#ifndef _sgp4ext_
+#define _sgp4ext_
+/*     ----------------------------------------------------------------
+*
+*                                 sgp4ext.h
+*
+*    this file contains extra routines needed for the main test program for sgp4.
+*    these routines are derived from the astro libraries.
+*
+*                            companion code for
+*               fundamentals of astrodynamics and applications
+*                                    2007
+*                              by david vallado
+*
+*       (w) 719-573-2600, email dvallado@agi.com
+*
+*    current :
+*              20 apr 07  david vallado
+*                           misc documentation updates
+*    changes :
+*              14 aug 06  david vallado
+*                           original baseline
+*               27 jun 15 grady hillhouse
+                            commented out asinh function
+*       ----------------------------------------------------------------      */
+
+#include <string.h>
+#include <math.h>
+
+#include "sgp4unit.h"
+
+
+// ------------------------- function declarations -------------------------
+
+double  sgn
+        (
+          double x
+        );
+
+double  mag
+        (
+          double x[3]
+        );
+
+void    cross
+        (
+          double vec1[3], double vec2[3], double outvec[3]
+        );
+
+double  dot
+        (
+          double x[3], double y[3]
+        );
+
+double  angle
+        (
+          double vec1[3],
+          double vec2[3]
+        );
+
+void    newtonnu
+        (
+          double ecc, double nu,
+          double& e0, double& m
+        );
+
+/*double  asinh
+        (
+          double xval
+        );
+*/
+void    rv2coe
+        (
+          double r[3], double v[3], double mu,
+          double& p, double& a, double& ecc, double& incl, double& omega, double& argp,
+          double& nu, double& m, double& arglat, double& truelon, double& lonper
+        );
+
+void    jday
+        (
+          int year, int mon, int day, int hr, int minute, double sec,
+          double& jd
+        );
+
+void    days2mdhms
+        (
+          int year, double days,
+          int& mon, int& day, int& hr, int& minute, double& sec
+        );
+
+void    invjday
+        (
+          double jd,
+          int& year, int& mon, int& day,
+          int& hr, int& minute, double& sec
+        );
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sgp4io.cpp	Tue Aug 11 22:42:13 2015 +0000
@@ -0,0 +1,262 @@
+/*     ----------------------------------------------------------------
+*
+*                               sgp4io.cpp
+*
+*    this file contains a function to read two line element sets. while 
+*    not formerly part of the sgp4 mathematical theory, it is 
+*    required for practical implemenation.
+*
+*                            companion code for
+*               fundamentals of astrodynamics and applications
+*                                    2007
+*                              by david vallado
+*
+*       (w) 719-573-2600, email dvallado@agi.com
+*
+*    current :
+*              27 Aug 10  david vallado
+*                           fix input format and delete unused variables in twoline2rv
+*    changes :
+*               3 sep 08  david vallado
+*                           add operationmode for afspc (a) or improved (i)
+*               9 may 07  david vallado
+*                           fix year correction to 57
+*              27 mar 07  david vallado
+*                           misc fixes to manual inputs
+*              14 aug 06  david vallado
+*                           original baseline
+*       ----------------------------------------------------------------      */
+
+#include "sgp4io.h"
+
+/* -----------------------------------------------------------------------------
+*
+*                           function twoline2rv
+*
+*  this function converts the two line element set character string data to
+*    variables and initializes the sgp4 variables. several intermediate varaibles
+*    and quantities are determined. note that the result is a structure so multiple
+*    satellites can be processed simultaneously without having to reinitialize. the
+*    verification mode is an important option that permits quick checks of any
+*    changes to the underlying technical theory. this option works using a
+*    modified tle file in which the start, stop, and delta time values are
+*    included at the end of the second line of data. this only works with the
+*    verification mode. the catalog mode simply propagates from -1440 to 1440 min
+*    from epoch and is useful when performing entire catalog runs.
+*
+*  author        : david vallado                  719-573-2600    1 mar 2001
+*
+*  inputs        :
+*    longstr1    - first line of the tle
+*    longstr2    - second line of the tle
+*    typerun     - type of run                    verification 'v', catalog 'c', 
+*                                                 manual 'm'
+*    typeinput   - type of manual input           mfe 'm', epoch 'e', dayofyr 'd'
+*    opsmode     - mode of operation afspc or improved 'a', 'i'
+*    whichconst  - which set of constants to use  72, 84
+*
+*  outputs       :
+*    satrec      - structure containing all the sgp4 satellite information
+*
+*  coupling      :
+*    getgravconst-
+*    days2mdhms  - conversion of days to month, day, hour, minute, second
+*    jday        - convert day month year hour minute second into julian date
+*    sgp4init    - initialize the sgp4 variables
+*
+*  references    :
+*    norad spacetrack report #3
+*    vallado, crawford, hujsak, kelso  2006
+  --------------------------------------------------------------------------- */
+
+void twoline2rv
+     (
+      char      longstr1[130], char longstr2[130],
+      char      typerun,  char typeinput, char opsmode,
+      gravconsttype       whichconst,
+      double& startmfe, double& stopmfe, double& deltamin,
+      elsetrec& satrec
+     )
+     {
+       const double deg2rad  =   pi / 180.0;         //   0.0174532925199433
+       const double xpdotp   =  1440.0 / (2.0 *pi);  // 229.1831180523293
+
+       double sec, mu, radiusearthkm, tumin, xke, j2, j3, j4, j3oj2;
+       double startsec, stopsec, startdayofyr, stopdayofyr, jdstart, jdstop;
+       int startyear, stopyear, startmon, stopmon, startday, stopday,
+           starthr, stophr, startmin, stopmin;
+       int cardnumb, numb, j;
+       long revnum = 0, elnum = 0;
+       char classification, intldesg[11];
+       int year = 0;
+       int mon, day, hr, minute, nexp, ibexp;
+
+       getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 );
+
+       satrec.error = 0;
+
+       // set the implied decimal points since doing a formated read
+       // fixes for bad input data values (missing, ...)
+       for (j = 10; j <= 15; j++)
+           if (longstr1[j] == ' ')
+               longstr1[j] = '_';
+
+       if (longstr1[44] != ' ')
+           longstr1[43] = longstr1[44];
+       longstr1[44] = '.';
+       if (longstr1[7] == ' ')
+           longstr1[7] = 'U';
+       if (longstr1[9] == ' ')
+           longstr1[9] = '.';
+       for (j = 45; j <= 49; j++)
+           if (longstr1[j] == ' ')
+               longstr1[j] = '0';
+       if (longstr1[51] == ' ')
+           longstr1[51] = '0';
+       if (longstr1[53] != ' ')
+           longstr1[52] = longstr1[53];
+       longstr1[53] = '.';
+       longstr2[25] = '.';
+       for (j = 26; j <= 32; j++)
+           if (longstr2[j] == ' ')
+               longstr2[j] = '0';
+       if (longstr1[62] == ' ')
+           longstr1[62] = '0';
+       if (longstr1[68] == ' ')
+           longstr1[68] = '0';
+
+       sscanf(longstr1,"%2d %5ld %1c %10s %2d %12lf %11lf %7lf %2d %7lf %2d %2d %6ld ",
+                       &cardnumb,&satrec.satnum,&classification, intldesg, &satrec.epochyr,
+                       &satrec.epochdays,&satrec.ndot, &satrec.nddot, &nexp, &satrec.bstar,
+                       &ibexp, &numb, &elnum );
+
+       if (typerun == 'v')  // run for specified times from the file
+         {
+           if (longstr2[52] == ' ')
+               sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld %lf %lf %lf \n",
+                       &cardnumb,&satrec.satnum, &satrec.inclo,
+                       &satrec.nodeo,&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no,
+                       &revnum, &startmfe, &stopmfe, &deltamin );
+             else
+               sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld %lf %lf %lf \n",
+                       &cardnumb,&satrec.satnum, &satrec.inclo,
+                       &satrec.nodeo,&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no,
+                       &revnum, &startmfe, &stopmfe, &deltamin );
+         }
+         else  // simply run -1 day to +1 day or user input times
+         {
+           if (longstr2[52] == ' ')
+               sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld \n",
+                       &cardnumb,&satrec.satnum, &satrec.inclo,
+                       &satrec.nodeo,&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no,
+                       &revnum );
+             else
+               sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld \n",
+                       &cardnumb,&satrec.satnum, &satrec.inclo,
+                       &satrec.nodeo,&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no,
+                       &revnum );
+         }
+
+       // ---- find no, ndot, nddot ----
+       satrec.no   = satrec.no / xpdotp; //* rad/min
+       satrec.nddot= satrec.nddot * pow(10.0, nexp);
+       satrec.bstar= satrec.bstar * pow(10.0, ibexp);
+
+       // ---- convert to sgp4 units ----
+       satrec.a    = pow( satrec.no*tumin , (-2.0/3.0) );
+       satrec.ndot = satrec.ndot  / (xpdotp*1440.0);  //* ? * minperday
+       satrec.nddot= satrec.nddot / (xpdotp*1440.0*1440);
+
+       // ---- find standard orbital elements ----
+       satrec.inclo = satrec.inclo  * deg2rad;
+       satrec.nodeo = satrec.nodeo  * deg2rad;
+       satrec.argpo = satrec.argpo  * deg2rad;
+       satrec.mo    = satrec.mo     * deg2rad;
+
+       satrec.alta = satrec.a*(1.0 + satrec.ecco) - 1.0;
+       satrec.altp = satrec.a*(1.0 - satrec.ecco) - 1.0;
+
+       // ----------------------------------------------------------------
+       // find sgp4epoch time of element set
+       // remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch)
+       // and minutes from the epoch (time)
+       // ----------------------------------------------------------------
+
+       // ---------------- temp fix for years from 1957-2056 -------------------
+       // --------- correct fix will occur when year is 4-digit in tle ---------
+       if (satrec.epochyr < 57)
+           year= satrec.epochyr + 2000;
+         else
+           year= satrec.epochyr + 1900;
+
+       days2mdhms ( year,satrec.epochdays, mon,day,hr,minute,sec );
+       jday( year,mon,day,hr,minute,sec, satrec.jdsatepoch );
+
+       // ---- input start stop times manually
+       if ((typerun != 'v') && (typerun != 'c'))
+         {
+         // ------------- enter start/stop ymd hms values --------------------
+           if (typeinput == 'e')
+             {
+               printf("input start prop year mon day hr min sec \n");
+               // make sure there is no space at the end of the format specifiers in scanf!
+               scanf( "%i %i %i %i %i %lf",&startyear, &startmon, &startday, &starthr, &startmin, &startsec);
+               fflush(stdin);
+               jday( startyear,startmon,startday,starthr,startmin,startsec, jdstart );
+
+               printf("input stop prop year mon day hr min sec \n");
+               scanf( "%i %i %i %i %i %lf",&stopyear, &stopmon, &stopday, &stophr, &stopmin, &stopsec);
+               fflush(stdin);
+               jday( stopyear,stopmon,stopday,stophr,stopmin,stopsec, jdstop );
+
+               startmfe = (jdstart - satrec.jdsatepoch) * 1440.0;
+               stopmfe  = (jdstop - satrec.jdsatepoch) * 1440.0;
+
+               printf("input time step in minutes \n");
+               scanf( "%lf",&deltamin );
+             }
+           // -------- enter start/stop year and days of year values -----------
+           if (typeinput == 'd')
+             {
+               printf("input start year dayofyr \n");
+               scanf( "%i %lf",&startyear, &startdayofyr );
+               printf("input stop year dayofyr \n");
+               scanf( "%i %lf",&stopyear, &stopdayofyr );
+
+               days2mdhms ( startyear,startdayofyr, mon,day,hr,minute,sec );
+               jday( startyear,mon,day,hr,minute,sec, jdstart );
+               days2mdhms ( stopyear,stopdayofyr, mon,day,hr,minute,sec );
+               jday( stopyear,mon,day,hr,minute,sec, jdstop );
+
+               startmfe = (jdstart - satrec.jdsatepoch) * 1440.0;
+               stopmfe  = (jdstop - satrec.jdsatepoch) * 1440.0;
+
+               printf("input time step in minutes \n");
+               scanf( "%lf",&deltamin );
+             }
+           // ------------------ enter start/stop mfe values -------------------
+           if (typeinput == 'm')
+             {
+               printf("input start min from epoch \n");
+               scanf( "%lf",&startmfe );
+               printf("input stop min from epoch \n");
+               scanf( "%lf",&stopmfe );
+               printf("input time step in minutes \n");
+               scanf( "%lf",&deltamin );
+             }
+         }
+
+       // ------------ perform complete catalog evaluation, -+ 1 day ----------- 
+       if (typerun == 'c')
+         {
+           startmfe = -1440.0;
+           stopmfe  =  1440.0;
+           deltamin =    10.0;
+         }
+
+       // ---------------- initialize the orbit at sgp4epoch -------------------
+       sgp4init( whichconst, opsmode, satrec.satnum, satrec.jdsatepoch-2433281.5, satrec.bstar,
+                 satrec.ecco, satrec.argpo, satrec.inclo, satrec.mo, satrec.no,
+                 satrec.nodeo, satrec);
+    } // end twoline2rv
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sgp4io.h	Tue Aug 11 22:42:13 2015 +0000
@@ -0,0 +1,45 @@
+#ifndef _sgp4io_
+#define _sgp4io_
+/*     ----------------------------------------------------------------
+*
+*                                 sgp4io.h;
+*
+*    this file contains a function to read two line element sets. while 
+*    not formerly part of the sgp4 mathematical theory, it is 
+*    required for practical implemenation.
+*
+*                            companion code for
+*               fundamentals of astrodynamics and applications
+*                                    2007
+*                              by david vallado
+*
+*       (w) 719-573-2600, email dvallado@agi.com
+*
+*    current :
+*               3 sep 07  david vallado
+*                           add operationmode for afspc (a) or improved (i)
+*    changes :
+*              20 apr 07  david vallado
+*                           misc updates for manual operation
+*              14 aug 06  david vallado
+*                           original baseline
+*       ----------------------------------------------------------------      */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "sgp4ext.h"    // for several misc routines
+#include "sgp4unit.h"   // for sgp4init and getgravconst
+
+// ------------------------- function declarations -------------------------
+
+void twoline2rv
+     (
+      char      longstr1[130], char longstr2[130],
+      char      typerun,  char typeinput, char opsmode,
+      gravconsttype       whichconst,
+      double& startmfe, double& stopmfe, double& deltamin,
+      elsetrec& satrec
+     );
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sgp4unit.cpp	Tue Aug 11 22:42:13 2015 +0000
@@ -0,0 +1,2123 @@
+/*     ----------------------------------------------------------------
+*
+*                               sgp4unit.cpp
+*
+*    this file contains the sgp4 procedures for analytical propagation
+*    of a satellite. the code was originally released in the 1980 and 1986
+*    spacetrack papers. a detailed discussion of the theory and history
+*    may be found in the 2006 aiaa paper by vallado, crawford, hujsak,
+*    and kelso.
+*
+*                            companion code for
+*               fundamentals of astrodynamics and applications
+*                                    2007
+*                              by david vallado
+*
+*       (w) 719-573-2600, email dvallado@agi.com
+*
+*    current :
+*              30 Aug 10  david vallado
+*                           delete unused variables in initl
+*                           replace pow inetger 2, 3 with multiplies for speed
+*    changes :
+*               3 Nov 08  david vallado
+*                           put returns in for error codes
+*              29 sep 08  david vallado
+*                           fix atime for faster operation in dspace
+*                           add operationmode for afspc (a) or improved (i)
+*                           performance mode
+*              16 jun 08  david vallado
+*                           update small eccentricity check
+*              16 nov 07  david vallado
+*                           misc fixes for better compliance
+*              20 apr 07  david vallado
+*                           misc fixes for constants
+*              11 aug 06  david vallado
+*                           chg lyddane choice back to strn3, constants, misc doc
+*              15 dec 05  david vallado
+*                           misc fixes
+*              26 jul 05  david vallado
+*                           fixes for paper
+*                           note that each fix is preceded by a
+*                           comment with "sgp4fix" and an explanation of
+*                           what was changed
+*              10 aug 04  david vallado
+*                           2nd printing baseline working
+*              14 may 01  david vallado
+*                           2nd edition baseline
+*                     80  norad
+*                           original baseline
+*       ----------------------------------------------------------------      */
+
+#include "sgp4unit.h"
+
+//const char help = 'n'; //Not sure what this does. Commented out. - Grady Hillhouse 2015
+//FILE *dbgfile;
+
+
+/* ----------- local functions - only ever used internally by sgp4 ---------- */
+static void dpper
+     (
+       double e3,     double ee2,    double peo,     double pgho,   double pho,
+       double pinco,  double plo,    double se2,     double se3,    double sgh2,
+       double sgh3,   double sgh4,   double sh2,     double sh3,    double si2,
+       double si3,    double sl2,    double sl3,     double sl4,    double t,
+       double xgh2,   double xgh3,   double xgh4,    double xh2,    double xh3,
+       double xi2,    double xi3,    double xl2,     double xl3,    double xl4,
+       double zmol,   double zmos,   double inclo,
+       char init,
+       double& ep,    double& inclp, double& nodep,  double& argpp, double& mp,
+       char opsmode
+     );
+
+static void dscom
+     (
+       double epoch,  double ep,     double argpp,   double tc,     double inclp,
+       double nodep,  double np,
+       double& snodm, double& cnodm, double& sinim,  double& cosim, double& sinomm,
+       double& cosomm,double& day,   double& e3,     double& ee2,   double& em,
+       double& emsq,  double& gam,   double& peo,    double& pgho,  double& pho,
+       double& pinco, double& plo,   double& rtemsq, double& se2,   double& se3,
+       double& sgh2,  double& sgh3,  double& sgh4,   double& sh2,   double& sh3,
+       double& si2,   double& si3,   double& sl2,    double& sl3,   double& sl4,
+       double& s1,    double& s2,    double& s3,     double& s4,    double& s5,
+       double& s6,    double& s7,    double& ss1,    double& ss2,   double& ss3,
+       double& ss4,   double& ss5,   double& ss6,    double& ss7,   double& sz1,
+       double& sz2,   double& sz3,   double& sz11,   double& sz12,  double& sz13,
+       double& sz21,  double& sz22,  double& sz23,   double& sz31,  double& sz32,
+       double& sz33,  double& xgh2,  double& xgh3,   double& xgh4,  double& xh2,
+       double& xh3,   double& xi2,   double& xi3,    double& xl2,   double& xl3,
+       double& xl4,   double& nm,    double& z1,     double& z2,    double& z3,
+       double& z11,   double& z12,   double& z13,    double& z21,   double& z22,
+       double& z23,   double& z31,   double& z32,    double& z33,   double& zmol,
+       double& zmos
+     );
+
+static void dsinit
+     (
+       gravconsttype whichconst,
+       double cosim,  double emsq,   double argpo,   double s1,     double s2,
+       double s3,     double s4,     double s5,      double sinim,  double ss1,
+       double ss2,    double ss3,    double ss4,     double ss5,    double sz1,
+       double sz3,    double sz11,   double sz13,    double sz21,   double sz23,
+       double sz31,   double sz33,   double t,       double tc,     double gsto,
+       double mo,     double mdot,   double no,      double nodeo,  double nodedot,
+       double xpidot, double z1,     double z3,      double z11,    double z13,
+       double z21,    double z23,    double z31,     double z33,    double ecco,
+       double eccsq,  double& em,    double& argpm,  double& inclm, double& mm,
+       double& nm,    double& nodem,
+       int& irez,
+       double& atime, double& d2201, double& d2211,  double& d3210, double& d3222,
+       double& d4410, double& d4422, double& d5220,  double& d5232, double& d5421,
+       double& d5433, double& dedt,  double& didt,   double& dmdt,  double& dndt,
+       double& dnodt, double& domdt, double& del1,   double& del2,  double& del3,
+       double& xfact, double& xlamo, double& xli,    double& xni
+     );
+
+static void dspace
+     (
+       int irez,
+       double d2201,  double d2211,  double d3210,   double d3222,  double d4410,
+       double d4422,  double d5220,  double d5232,   double d5421,  double d5433,
+       double dedt,   double del1,   double del2,    double del3,   double didt,
+       double dmdt,   double dnodt,  double domdt,   double argpo,  double argpdot,
+       double t,      double tc,     double gsto,    double xfact,  double xlamo,
+       double no,
+       double& atime, double& em,    double& argpm,  double& inclm, double& xli,
+       double& mm,    double& xni,   double& nodem,  double& dndt,  double& nm
+     );
+
+static void initl
+     (
+       int satn,      gravconsttype whichconst,
+       double ecco,   double epoch,  double inclo,   double& no,
+       char& method,
+       double& ainv,  double& ao,    double& con41,  double& con42, double& cosio,
+       double& cosio2,double& eccsq, double& omeosq, double& posq,
+       double& rp,    double& rteosq,double& sinio , double& gsto, char opsmode
+     );
+
+/* -----------------------------------------------------------------------------
+*
+*                           procedure dpper
+*
+*  this procedure provides deep space long period periodic contributions
+*    to the mean elements.  by design, these periodics are zero at epoch.
+*    this used to be dscom which included initialization, but it's really a
+*    recurring function.
+*
+*  author        : david vallado                  719-573-2600   28 jun 2005
+*
+*  inputs        :
+*    e3          -
+*    ee2         -
+*    peo         -
+*    pgho        -
+*    pho         -
+*    pinco       -
+*    plo         -
+*    se2 , se3 , sgh2, sgh3, sgh4, sh2, sh3, si2, si3, sl2, sl3, sl4 -
+*    t           -
+*    xh2, xh3, xi2, xi3, xl2, xl3, xl4 -
+*    zmol        -
+*    zmos        -
+*    ep          - eccentricity                           0.0 - 1.0
+*    inclo       - inclination - needed for lyddane modification
+*    nodep       - right ascension of ascending node
+*    argpp       - argument of perigee
+*    mp          - mean anomaly
+*
+*  outputs       :
+*    ep          - eccentricity                           0.0 - 1.0
+*    inclp       - inclination
+*    nodep        - right ascension of ascending node
+*    argpp       - argument of perigee
+*    mp          - mean anomaly
+*
+*  locals        :
+*    alfdp       -
+*    betdp       -
+*    cosip  , sinip  , cosop  , sinop  ,
+*    dalf        -
+*    dbet        -
+*    dls         -
+*    f2, f3      -
+*    pe          -
+*    pgh         -
+*    ph          -
+*    pinc        -
+*    pl          -
+*    sel   , ses   , sghl  , sghs  , shl   , shs   , sil   , sinzf , sis   ,
+*    sll   , sls
+*    xls         -
+*    xnoh        -
+*    zf          -
+*    zm          -
+*
+*  coupling      :
+*    none.
+*
+*  references    :
+*    hoots, roehrich, norad spacetrack report #3 1980
+*    hoots, norad spacetrack report #6 1986
+*    hoots, schumacher and glover 2004
+*    vallado, crawford, hujsak, kelso  2006
+  ----------------------------------------------------------------------------*/
+
+static void dpper
+     (
+       double e3,     double ee2,    double peo,     double pgho,   double pho,
+       double pinco,  double plo,    double se2,     double se3,    double sgh2,
+       double sgh3,   double sgh4,   double sh2,     double sh3,    double si2,
+       double si3,    double sl2,    double sl3,     double sl4,    double t,
+       double xgh2,   double xgh3,   double xgh4,    double xh2,    double xh3,
+       double xi2,    double xi3,    double xl2,     double xl3,    double xl4,
+       double zmol,   double zmos,   double inclo,
+       char init,
+       double& ep,    double& inclp, double& nodep,  double& argpp, double& mp,
+       char opsmode
+     )
+{
+     /* --------------------- local variables ------------------------ */
+     const double twopi = 2.0 * pi;
+     double alfdp, betdp, cosip, cosop, dalf, dbet, dls,
+          f2,    f3,    pe,    pgh,   ph,   pinc, pl ,
+          sel,   ses,   sghl,  sghs,  shll, shs,  sil,
+          sinip, sinop, sinzf, sis,   sll,  sls,  xls,
+          xnoh,  zf,    zm,    zel,   zes,  znl,  zns;
+
+     /* ---------------------- constants ----------------------------- */
+     zns   = 1.19459e-5;
+     zes   = 0.01675;
+     znl   = 1.5835218e-4;
+     zel   = 0.05490;
+
+     /* --------------- calculate time varying periodics ----------- */
+     zm    = zmos + zns * t;
+     // be sure that the initial call has time set to zero
+     if (init == 'y')
+         zm = zmos;
+     zf    = zm + 2.0 * zes * sin(zm);
+     sinzf = sin(zf);
+     f2    =  0.5 * sinzf * sinzf - 0.25;
+     f3    = -0.5 * sinzf * cos(zf);
+     ses   = se2* f2 + se3 * f3;
+     sis   = si2 * f2 + si3 * f3;
+     sls   = sl2 * f2 + sl3 * f3 + sl4 * sinzf;
+     sghs  = sgh2 * f2 + sgh3 * f3 + sgh4 * sinzf;
+     shs   = sh2 * f2 + sh3 * f3;
+     zm    = zmol + znl * t;
+     if (init == 'y')
+         zm = zmol;
+     zf    = zm + 2.0 * zel * sin(zm);
+     sinzf = sin(zf);
+     f2    =  0.5 * sinzf * sinzf - 0.25;
+     f3    = -0.5 * sinzf * cos(zf);
+     sel   = ee2 * f2 + e3 * f3;
+     sil   = xi2 * f2 + xi3 * f3;
+     sll   = xl2 * f2 + xl3 * f3 + xl4 * sinzf;
+     sghl  = xgh2 * f2 + xgh3 * f3 + xgh4 * sinzf;
+     shll  = xh2 * f2 + xh3 * f3;
+     pe    = ses + sel;
+     pinc  = sis + sil;
+     pl    = sls + sll;
+     pgh   = sghs + sghl;
+     ph    = shs + shll;
+
+     if (init == 'n')
+       {
+       pe    = pe - peo;
+       pinc  = pinc - pinco;
+       pl    = pl - plo;
+       pgh   = pgh - pgho;
+       ph    = ph - pho;
+       inclp = inclp + pinc;
+       ep    = ep + pe;
+       sinip = sin(inclp);
+       cosip = cos(inclp);
+
+       /* ----------------- apply periodics directly ------------ */
+       //  sgp4fix for lyddane choice
+       //  strn3 used original inclination - this is technically feasible
+       //  gsfc used perturbed inclination - also technically feasible
+       //  probably best to readjust the 0.2 limit value and limit discontinuity
+       //  0.2 rad = 11.45916 deg
+       //  use next line for original strn3 approach and original inclination
+       //  if (inclo >= 0.2)
+       //  use next line for gsfc version and perturbed inclination
+       if (inclp >= 0.2)
+         {
+           ph     = ph / sinip;
+           pgh    = pgh - cosip * ph;
+           argpp  = argpp + pgh;
+           nodep  = nodep + ph;
+           mp     = mp + pl;
+         }
+         else
+         {
+           /* ---- apply periodics with lyddane modification ---- */
+           sinop  = sin(nodep);
+           cosop  = cos(nodep);
+           alfdp  = sinip * sinop;
+           betdp  = sinip * cosop;
+           dalf   =  ph * cosop + pinc * cosip * sinop;
+           dbet   = -ph * sinop + pinc * cosip * cosop;
+           alfdp  = alfdp + dalf;
+           betdp  = betdp + dbet;
+           nodep  = fmod(nodep, twopi);
+           //  sgp4fix for afspc written intrinsic functions
+           // nodep used without a trigonometric function ahead
+           if ((nodep < 0.0) && (opsmode == 'a'))
+               nodep = nodep + twopi;
+           xls    = mp + argpp + cosip * nodep;
+           dls    = pl + pgh - pinc * nodep * sinip;
+           xls    = xls + dls;
+           xnoh   = nodep;
+           nodep  = atan2(alfdp, betdp);
+           //  sgp4fix for afspc written intrinsic functions
+           // nodep used without a trigonometric function ahead
+           if ((nodep < 0.0) && (opsmode == 'a'))
+               nodep = nodep + twopi;
+           if (fabs(xnoh - nodep) > pi)
+             if (nodep < xnoh)
+                nodep = nodep + twopi;
+               else
+                nodep = nodep - twopi;
+           mp    = mp + pl;
+           argpp = xls - mp - cosip * nodep;
+         }
+       }   // if init == 'n'
+
+//#include "debug1.cpp"
+}  // end dpper
+
+/*-----------------------------------------------------------------------------
+*
+*                           procedure dscom
+*
+*  this procedure provides deep space common items used by both the secular
+*    and periodics subroutines.  input is provided as shown. this routine
+*    used to be called dpper, but the functions inside weren't well organized.
+*
+*  author        : david vallado                  719-573-2600   28 jun 2005
+*
+*  inputs        :
+*    epoch       -
+*    ep          - eccentricity
+*    argpp       - argument of perigee
+*    tc          -
+*    inclp       - inclination
+*    nodep       - right ascension of ascending node
+*    np          - mean motion
+*
+*  outputs       :
+*    sinim  , cosim  , sinomm , cosomm , snodm  , cnodm
+*    day         -
+*    e3          -
+*    ee2         -
+*    em          - eccentricity
+*    emsq        - eccentricity squared
+*    gam         -
+*    peo         -
+*    pgho        -
+*    pho         -
+*    pinco       -
+*    plo         -
+*    rtemsq      -
+*    se2, se3         -
+*    sgh2, sgh3, sgh4        -
+*    sh2, sh3, si2, si3, sl2, sl3, sl4         -
+*    s1, s2, s3, s4, s5, s6, s7          -
+*    ss1, ss2, ss3, ss4, ss5, ss6, ss7, sz1, sz2, sz3         -
+*    sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33        -
+*    xgh2, xgh3, xgh4, xh2, xh3, xi2, xi3, xl2, xl3, xl4         -
+*    nm          - mean motion
+*    z1, z2, z3, z11, z12, z13, z21, z22, z23, z31, z32, z33         -
+*    zmol        -
+*    zmos        -
+*
+*  locals        :
+*    a1, a2, a3, a4, a5, a6, a7, a8, a9, a10         -
+*    betasq      -
+*    cc          -
+*    ctem, stem        -
+*    x1, x2, x3, x4, x5, x6, x7, x8          -
+*    xnodce      -
+*    xnoi        -
+*    zcosg  , zsing  , zcosgl , zsingl , zcosh  , zsinh  , zcoshl , zsinhl ,
+*    zcosi  , zsini  , zcosil , zsinil ,
+*    zx          -
+*    zy          -
+*
+*  coupling      :
+*    none.
+*
+*  references    :
+*    hoots, roehrich, norad spacetrack report #3 1980
+*    hoots, norad spacetrack report #6 1986
+*    hoots, schumacher and glover 2004
+*    vallado, crawford, hujsak, kelso  2006
+  ----------------------------------------------------------------------------*/
+
+static void dscom
+     (
+       double epoch,  double ep,     double argpp,   double tc,     double inclp,
+       double nodep,  double np,
+       double& snodm, double& cnodm, double& sinim,  double& cosim, double& sinomm,
+       double& cosomm,double& day,   double& e3,     double& ee2,   double& em,
+       double& emsq,  double& gam,   double& peo,    double& pgho,  double& pho,
+       double& pinco, double& plo,   double& rtemsq, double& se2,   double& se3,
+       double& sgh2,  double& sgh3,  double& sgh4,   double& sh2,   double& sh3,
+       double& si2,   double& si3,   double& sl2,    double& sl3,   double& sl4,
+       double& s1,    double& s2,    double& s3,     double& s4,    double& s5,
+       double& s6,    double& s7,    double& ss1,    double& ss2,   double& ss3,
+       double& ss4,   double& ss5,   double& ss6,    double& ss7,   double& sz1,
+       double& sz2,   double& sz3,   double& sz11,   double& sz12,  double& sz13,
+       double& sz21,  double& sz22,  double& sz23,   double& sz31,  double& sz32,
+       double& sz33,  double& xgh2,  double& xgh3,   double& xgh4,  double& xh2,
+       double& xh3,   double& xi2,   double& xi3,    double& xl2,   double& xl3,
+       double& xl4,   double& nm,    double& z1,     double& z2,    double& z3,
+       double& z11,   double& z12,   double& z13,    double& z21,   double& z22,
+       double& z23,   double& z31,   double& z32,    double& z33,   double& zmol,
+       double& zmos
+     )
+{
+     /* -------------------------- constants ------------------------- */
+     const double zes     =  0.01675;
+     const double zel     =  0.05490;
+     const double c1ss    =  2.9864797e-6;
+     const double c1l     =  4.7968065e-7;
+     const double zsinis  =  0.39785416;
+     const double zcosis  =  0.91744867;
+     const double zcosgs  =  0.1945905;
+     const double zsings  = -0.98088458;
+     const double twopi   =  2.0 * pi;
+
+     /* --------------------- local variables ------------------------ */
+     int lsflg;
+     double a1    , a2    , a3    , a4    , a5    , a6    , a7    ,
+        a8    , a9    , a10   , betasq, cc    , ctem  , stem  ,
+        x1    , x2    , x3    , x4    , x5    , x6    , x7    ,
+        x8    , xnodce, xnoi  , zcosg , zcosgl, zcosh , zcoshl,
+        zcosi , zcosil, zsing , zsingl, zsinh , zsinhl, zsini ,
+        zsinil, zx    , zy;
+
+     nm     = np;
+     em     = ep;
+     snodm  = sin(nodep);
+     cnodm  = cos(nodep);
+     sinomm = sin(argpp);
+     cosomm = cos(argpp);
+     sinim  = sin(inclp);
+     cosim  = cos(inclp);
+     emsq   = em * em;
+     betasq = 1.0 - emsq;
+     rtemsq = sqrt(betasq);
+
+     /* ----------------- initialize lunar solar terms --------------- */
+     peo    = 0.0;
+     pinco  = 0.0;
+     plo    = 0.0;
+     pgho   = 0.0;
+     pho    = 0.0;
+     day    = epoch + 18261.5 + tc / 1440.0;
+     xnodce = fmod(4.5236020 - 9.2422029e-4 * day, twopi);
+     stem   = sin(xnodce);
+     ctem   = cos(xnodce);
+     zcosil = 0.91375164 - 0.03568096 * ctem;
+     zsinil = sqrt(1.0 - zcosil * zcosil);
+     zsinhl = 0.089683511 * stem / zsinil;
+     zcoshl = sqrt(1.0 - zsinhl * zsinhl);
+     gam    = 5.8351514 + 0.0019443680 * day;
+     zx     = 0.39785416 * stem / zsinil;
+     zy     = zcoshl * ctem + 0.91744867 * zsinhl * stem;
+     zx     = atan2(zx, zy);
+     zx     = gam + zx - xnodce;
+     zcosgl = cos(zx);
+     zsingl = sin(zx);
+
+     /* ------------------------- do solar terms --------------------- */
+     zcosg = zcosgs;
+     zsing = zsings;
+     zcosi = zcosis;
+     zsini = zsinis;
+     zcosh = cnodm;
+     zsinh = snodm;
+     cc    = c1ss;
+     xnoi  = 1.0 / nm;
+
+     for (lsflg = 1; lsflg <= 2; lsflg++)
+       {
+         a1  =   zcosg * zcosh + zsing * zcosi * zsinh;
+         a3  =  -zsing * zcosh + zcosg * zcosi * zsinh;
+         a7  =  -zcosg * zsinh + zsing * zcosi * zcosh;
+         a8  =   zsing * zsini;
+         a9  =   zsing * zsinh + zcosg * zcosi * zcosh;
+         a10 =   zcosg * zsini;
+         a2  =   cosim * a7 + sinim * a8;
+         a4  =   cosim * a9 + sinim * a10;
+         a5  =  -sinim * a7 + cosim * a8;
+         a6  =  -sinim * a9 + cosim * a10;
+
+         x1  =  a1 * cosomm + a2 * sinomm;
+         x2  =  a3 * cosomm + a4 * sinomm;
+         x3  = -a1 * sinomm + a2 * cosomm;
+         x4  = -a3 * sinomm + a4 * cosomm;
+         x5  =  a5 * sinomm;
+         x6  =  a6 * sinomm;
+         x7  =  a5 * cosomm;
+         x8  =  a6 * cosomm;
+
+         z31 = 12.0 * x1 * x1 - 3.0 * x3 * x3;
+         z32 = 24.0 * x1 * x2 - 6.0 * x3 * x4;
+         z33 = 12.0 * x2 * x2 - 3.0 * x4 * x4;
+         z1  =  3.0 *  (a1 * a1 + a2 * a2) + z31 * emsq;
+         z2  =  6.0 *  (a1 * a3 + a2 * a4) + z32 * emsq;
+         z3  =  3.0 *  (a3 * a3 + a4 * a4) + z33 * emsq;
+         z11 = -6.0 * a1 * a5 + emsq *  (-24.0 * x1 * x7-6.0 * x3 * x5);
+         z12 = -6.0 *  (a1 * a6 + a3 * a5) + emsq *
+                (-24.0 * (x2 * x7 + x1 * x8) - 6.0 * (x3 * x6 + x4 * x5));
+         z13 = -6.0 * a3 * a6 + emsq * (-24.0 * x2 * x8 - 6.0 * x4 * x6);
+         z21 =  6.0 * a2 * a5 + emsq * (24.0 * x1 * x5 - 6.0 * x3 * x7);
+         z22 =  6.0 *  (a4 * a5 + a2 * a6) + emsq *
+                (24.0 * (x2 * x5 + x1 * x6) - 6.0 * (x4 * x7 + x3 * x8));
+         z23 =  6.0 * a4 * a6 + emsq * (24.0 * x2 * x6 - 6.0 * x4 * x8);
+         z1  = z1 + z1 + betasq * z31;
+         z2  = z2 + z2 + betasq * z32;
+         z3  = z3 + z3 + betasq * z33;
+         s3  = cc * xnoi;
+         s2  = -0.5 * s3 / rtemsq;
+         s4  = s3 * rtemsq;
+         s1  = -15.0 * em * s4;
+         s5  = x1 * x3 + x2 * x4;
+         s6  = x2 * x3 + x1 * x4;
+         s7  = x2 * x4 - x1 * x3;
+
+         /* ----------------------- do lunar terms ------------------- */
+         if (lsflg == 1)
+           {
+             ss1   = s1;
+             ss2   = s2;
+             ss3   = s3;
+             ss4   = s4;
+             ss5   = s5;
+             ss6   = s6;
+             ss7   = s7;
+             sz1   = z1;
+             sz2   = z2;
+             sz3   = z3;
+             sz11  = z11;
+             sz12  = z12;
+             sz13  = z13;
+             sz21  = z21;
+             sz22  = z22;
+             sz23  = z23;
+             sz31  = z31;
+             sz32  = z32;
+             sz33  = z33;
+             zcosg = zcosgl;
+             zsing = zsingl;
+             zcosi = zcosil;
+             zsini = zsinil;
+             zcosh = zcoshl * cnodm + zsinhl * snodm;
+             zsinh = snodm * zcoshl - cnodm * zsinhl;
+             cc    = c1l;
+          }
+       }
+
+     zmol = fmod(4.7199672 + 0.22997150  * day - gam, twopi);
+     zmos = fmod(6.2565837 + 0.017201977 * day, twopi);
+
+     /* ------------------------ do solar terms ---------------------- */
+     se2  =   2.0 * ss1 * ss6;
+     se3  =   2.0 * ss1 * ss7;
+     si2  =   2.0 * ss2 * sz12;
+     si3  =   2.0 * ss2 * (sz13 - sz11);
+     sl2  =  -2.0 * ss3 * sz2;
+     sl3  =  -2.0 * ss3 * (sz3 - sz1);
+     sl4  =  -2.0 * ss3 * (-21.0 - 9.0 * emsq) * zes;
+     sgh2 =   2.0 * ss4 * sz32;
+     sgh3 =   2.0 * ss4 * (sz33 - sz31);
+     sgh4 = -18.0 * ss4 * zes;
+     sh2  =  -2.0 * ss2 * sz22;
+     sh3  =  -2.0 * ss2 * (sz23 - sz21);
+
+     /* ------------------------ do lunar terms ---------------------- */
+     ee2  =   2.0 * s1 * s6;
+     e3   =   2.0 * s1 * s7;
+     xi2  =   2.0 * s2 * z12;
+     xi3  =   2.0 * s2 * (z13 - z11);
+     xl2  =  -2.0 * s3 * z2;
+     xl3  =  -2.0 * s3 * (z3 - z1);
+     xl4  =  -2.0 * s3 * (-21.0 - 9.0 * emsq) * zel;
+     xgh2 =   2.0 * s4 * z32;
+     xgh3 =   2.0 * s4 * (z33 - z31);
+     xgh4 = -18.0 * s4 * zel;
+     xh2  =  -2.0 * s2 * z22;
+     xh3  =  -2.0 * s2 * (z23 - z21);
+
+//#include "debug2.cpp"
+}  // end dscom
+
+/*-----------------------------------------------------------------------------
+*
+*                           procedure dsinit
+*
+*  this procedure provides deep space contributions to mean motion dot due
+*    to geopotential resonance with half day and one day orbits.
+*
+*  author        : david vallado                  719-573-2600   28 jun 2005
+*
+*  inputs        :
+*    cosim, sinim-
+*    emsq        - eccentricity squared
+*    argpo       - argument of perigee
+*    s1, s2, s3, s4, s5      -
+*    ss1, ss2, ss3, ss4, ss5 -
+*    sz1, sz3, sz11, sz13, sz21, sz23, sz31, sz33 -
+*    t           - time
+*    tc          -
+*    gsto        - greenwich sidereal time                   rad
+*    mo          - mean anomaly
+*    mdot        - mean anomaly dot (rate)
+*    no          - mean motion
+*    nodeo       - right ascension of ascending node
+*    nodedot     - right ascension of ascending node dot (rate)
+*    xpidot      -
+*    z1, z3, z11, z13, z21, z23, z31, z33 -
+*    eccm        - eccentricity
+*    argpm       - argument of perigee
+*    inclm       - inclination
+*    mm          - mean anomaly
+*    xn          - mean motion
+*    nodem       - right ascension of ascending node
+*
+*  outputs       :
+*    em          - eccentricity
+*    argpm       - argument of perigee
+*    inclm       - inclination
+*    mm          - mean anomaly
+*    nm          - mean motion
+*    nodem       - right ascension of ascending node
+*    irez        - flag for resonance           0-none, 1-one day, 2-half day
+*    atime       -
+*    d2201, d2211, d3210, d3222, d4410, d4422, d5220, d5232, d5421, d5433    -
+*    dedt        -
+*    didt        -
+*    dmdt        -
+*    dndt        -
+*    dnodt       -
+*    domdt       -
+*    del1, del2, del3        -
+*    ses  , sghl , sghs , sgs  , shl  , shs  , sis  , sls
+*    theta       -
+*    xfact       -
+*    xlamo       -
+*    xli         -
+*    xni
+*
+*  locals        :
+*    ainv2       -
+*    aonv        -
+*    cosisq      -
+*    eoc         -
+*    f220, f221, f311, f321, f322, f330, f441, f442, f522, f523, f542, f543  -
+*    g200, g201, g211, g300, g310, g322, g410, g422, g520, g521, g532, g533  -
+*    sini2       -
+*    temp        -
+*    temp1       -
+*    theta       -
+*    xno2        -
+*
+*  coupling      :
+*    getgravconst
+*
+*  references    :
+*    hoots, roehrich, norad spacetrack report #3 1980
+*    hoots, norad spacetrack report #6 1986
+*    hoots, schumacher and glover 2004
+*    vallado, crawford, hujsak, kelso  2006
+  ----------------------------------------------------------------------------*/
+
+static void dsinit
+     (
+       gravconsttype whichconst,
+       double cosim,  double emsq,   double argpo,   double s1,     double s2,
+       double s3,     double s4,     double s5,      double sinim,  double ss1,
+       double ss2,    double ss3,    double ss4,     double ss5,    double sz1,
+       double sz3,    double sz11,   double sz13,    double sz21,   double sz23,
+       double sz31,   double sz33,   double t,       double tc,     double gsto,
+       double mo,     double mdot,   double no,      double nodeo,  double nodedot,
+       double xpidot, double z1,     double z3,      double z11,    double z13,
+       double z21,    double z23,    double z31,     double z33,    double ecco,
+       double eccsq,  double& em,    double& argpm,  double& inclm, double& mm,
+       double& nm,    double& nodem,
+       int& irez,
+       double& atime, double& d2201, double& d2211,  double& d3210, double& d3222,
+       double& d4410, double& d4422, double& d5220,  double& d5232, double& d5421,
+       double& d5433, double& dedt,  double& didt,   double& dmdt,  double& dndt,
+       double& dnodt, double& domdt, double& del1,   double& del2,  double& del3,
+       double& xfact, double& xlamo, double& xli,    double& xni
+     )
+{
+     /* --------------------- local variables ------------------------ */
+     const double twopi = 2.0 * pi;
+
+     double ainv2 , aonv=0.0, cosisq, eoc, f220 , f221  , f311  ,
+          f321  , f322  , f330  , f441  , f442  , f522  , f523  ,
+          f542  , f543  , g200  , g201  , g211  , g300  , g310  ,
+          g322  , g410  , g422  , g520  , g521  , g532  , g533  ,
+          ses   , sgs   , sghl  , sghs  , shs   , shll  , sis   ,
+          sini2 , sls   , temp  , temp1 , theta , xno2  , q22   ,
+          q31   , q33   , root22, root44, root54, rptim , root32,
+          root52, x2o3  , xke   , znl   , emo   , zns   , emsqo,
+          tumin, mu, radiusearthkm, j2, j3, j4, j3oj2;
+
+     q22    = 1.7891679e-6;
+     q31    = 2.1460748e-6;
+     q33    = 2.2123015e-7;
+     root22 = 1.7891679e-6;
+     root44 = 7.3636953e-9;
+     root54 = 2.1765803e-9;
+     rptim  = 4.37526908801129966e-3; // this equates to 7.29211514668855e-5 rad/sec
+     root32 = 3.7393792e-7;
+     root52 = 1.1428639e-7;
+     x2o3   = 2.0 / 3.0;
+     znl    = 1.5835218e-4;
+     zns    = 1.19459e-5;
+
+     // sgp4fix identify constants and allow alternate values
+     getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 );
+
+     /* -------------------- deep space initialization ------------ */
+     irez = 0;
+     if ((nm < 0.0052359877) && (nm > 0.0034906585))
+         irez = 1;
+     if ((nm >= 8.26e-3) && (nm <= 9.24e-3) && (em >= 0.5))
+         irez = 2;
+
+     /* ------------------------ do solar terms ------------------- */
+     ses  =  ss1 * zns * ss5;
+     sis  =  ss2 * zns * (sz11 + sz13);
+     sls  = -zns * ss3 * (sz1 + sz3 - 14.0 - 6.0 * emsq);
+     sghs =  ss4 * zns * (sz31 + sz33 - 6.0);
+     shs  = -zns * ss2 * (sz21 + sz23);
+     // sgp4fix for 180 deg incl
+     if ((inclm < 5.2359877e-2) || (inclm > pi - 5.2359877e-2))
+       shs = 0.0;
+     if (sinim != 0.0)
+       shs = shs / sinim;
+     sgs  = sghs - cosim * shs;
+
+     /* ------------------------- do lunar terms ------------------ */
+     dedt = ses + s1 * znl * s5;
+     didt = sis + s2 * znl * (z11 + z13);
+     dmdt = sls - znl * s3 * (z1 + z3 - 14.0 - 6.0 * emsq);
+     sghl = s4 * znl * (z31 + z33 - 6.0);
+     shll = -znl * s2 * (z21 + z23);
+     // sgp4fix for 180 deg incl
+     if ((inclm < 5.2359877e-2) || (inclm > pi - 5.2359877e-2))
+         shll = 0.0;
+     domdt = sgs + sghl;
+     dnodt = shs;
+     if (sinim != 0.0)
+       {
+         domdt = domdt - cosim / sinim * shll;
+         dnodt = dnodt + shll / sinim;
+       }
+
+     /* ----------- calculate deep space resonance effects -------- */
+     dndt   = 0.0;
+     theta  = fmod(gsto + tc * rptim, twopi);
+     em     = em + dedt * t;
+     inclm  = inclm + didt * t;
+     argpm  = argpm + domdt * t;
+     nodem  = nodem + dnodt * t;
+     mm     = mm + dmdt * t;
+     //   sgp4fix for negative inclinations
+     //   the following if statement should be commented out
+     //if (inclm < 0.0)
+     //  {
+     //    inclm  = -inclm;
+     //    argpm  = argpm - pi;
+     //    nodem = nodem + pi;
+     //  }
+
+     /* -------------- initialize the resonance terms ------------- */
+     if (irez != 0)
+       {
+         aonv = pow(nm / xke, x2o3);
+
+         /* ---------- geopotential resonance for 12 hour orbits ------ */
+         if (irez == 2)
+           {
+             cosisq = cosim * cosim;
+             emo    = em;
+             em     = ecco;
+             emsqo  = emsq;
+             emsq   = eccsq;
+             eoc    = em * emsq;
+             g201   = -0.306 - (em - 0.64) * 0.440;
+
+             if (em <= 0.65)
+               {
+                 g211 =    3.616  -  13.2470 * em +  16.2900 * emsq;
+                 g310 =  -19.302  + 117.3900 * em - 228.4190 * emsq +  156.5910 * eoc;
+                 g322 =  -18.9068 + 109.7927 * em - 214.6334 * emsq +  146.5816 * eoc;
+                 g410 =  -41.122  + 242.6940 * em - 471.0940 * emsq +  313.9530 * eoc;
+                 g422 = -146.407  + 841.8800 * em - 1629.014 * emsq + 1083.4350 * eoc;
+                 g520 = -532.114  + 3017.977 * em - 5740.032 * emsq + 3708.2760 * eoc;
+               }
+               else
+               {
+                 g211 =   -72.099 +   331.819 * em -   508.738 * emsq +   266.724 * eoc;
+                 g310 =  -346.844 +  1582.851 * em -  2415.925 * emsq +  1246.113 * eoc;
+                 g322 =  -342.585 +  1554.908 * em -  2366.899 * emsq +  1215.972 * eoc;
+                 g410 = -1052.797 +  4758.686 * em -  7193.992 * emsq +  3651.957 * eoc;
+                 g422 = -3581.690 + 16178.110 * em - 24462.770 * emsq + 12422.520 * eoc;
+                 if (em > 0.715)
+                     g520 =-5149.66 + 29936.92 * em - 54087.36 * emsq + 31324.56 * eoc;
+                   else
+                     g520 = 1464.74 -  4664.75 * em +  3763.64 * emsq;
+               }
+             if (em < 0.7)
+               {
+                 g533 = -919.22770 + 4988.6100 * em - 9064.7700 * emsq + 5542.21  * eoc;
+                 g521 = -822.71072 + 4568.6173 * em - 8491.4146 * emsq + 5337.524 * eoc;
+                 g532 = -853.66600 + 4690.2500 * em - 8624.7700 * emsq + 5341.4  * eoc;
+               }
+               else
+               {
+                 g533 =-37995.780 + 161616.52 * em - 229838.20 * emsq + 109377.94 * eoc;
+                 g521 =-51752.104 + 218913.95 * em - 309468.16 * emsq + 146349.42 * eoc;
+                 g532 =-40023.880 + 170470.89 * em - 242699.48 * emsq + 115605.82 * eoc;
+               }
+
+             sini2=  sinim * sinim;
+             f220 =  0.75 * (1.0 + 2.0 * cosim+cosisq);
+             f221 =  1.5 * sini2;
+             f321 =  1.875 * sinim  *  (1.0 - 2.0 * cosim - 3.0 * cosisq);
+             f322 = -1.875 * sinim  *  (1.0 + 2.0 * cosim - 3.0 * cosisq);
+             f441 = 35.0 * sini2 * f220;
+             f442 = 39.3750 * sini2 * sini2;
+             f522 =  9.84375 * sinim * (sini2 * (1.0 - 2.0 * cosim- 5.0 * cosisq) +
+                     0.33333333 * (-2.0 + 4.0 * cosim + 6.0 * cosisq) );
+             f523 = sinim * (4.92187512 * sini2 * (-2.0 - 4.0 * cosim +
+                    10.0 * cosisq) + 6.56250012 * (1.0+2.0 * cosim - 3.0 * cosisq));
+             f542 = 29.53125 * sinim * (2.0 - 8.0 * cosim+cosisq *
+                    (-12.0 + 8.0 * cosim + 10.0 * cosisq));
+             f543 = 29.53125 * sinim * (-2.0 - 8.0 * cosim+cosisq *
+                    (12.0 + 8.0 * cosim - 10.0 * cosisq));
+             xno2  =  nm * nm;
+             ainv2 =  aonv * aonv;
+             temp1 =  3.0 * xno2 * ainv2;
+             temp  =  temp1 * root22;
+             d2201 =  temp * f220 * g201;
+             d2211 =  temp * f221 * g211;
+             temp1 =  temp1 * aonv;
+             temp  =  temp1 * root32;
+             d3210 =  temp * f321 * g310;
+             d3222 =  temp * f322 * g322;
+             temp1 =  temp1 * aonv;
+             temp  =  2.0 * temp1 * root44;
+             d4410 =  temp * f441 * g410;
+             d4422 =  temp * f442 * g422;
+             temp1 =  temp1 * aonv;
+             temp  =  temp1 * root52;
+             d5220 =  temp * f522 * g520;
+             d5232 =  temp * f523 * g532;
+             temp  =  2.0 * temp1 * root54;
+             d5421 =  temp * f542 * g521;
+             d5433 =  temp * f543 * g533;
+             xlamo =  fmod(mo + nodeo + nodeo-theta - theta, twopi);
+             xfact =  mdot + dmdt + 2.0 * (nodedot + dnodt - rptim) - no;
+             em    = emo;
+             emsq  = emsqo;
+           }
+
+         /* ---------------- synchronous resonance terms -------------- */
+         if (irez == 1)
+           {
+             g200  = 1.0 + emsq * (-2.5 + 0.8125 * emsq);
+             g310  = 1.0 + 2.0 * emsq;
+             g300  = 1.0 + emsq * (-6.0 + 6.60937 * emsq);
+             f220  = 0.75 * (1.0 + cosim) * (1.0 + cosim);
+             f311  = 0.9375 * sinim * sinim * (1.0 + 3.0 * cosim) - 0.75 * (1.0 + cosim);
+             f330  = 1.0 + cosim;
+             f330  = 1.875 * f330 * f330 * f330;
+             del1  = 3.0 * nm * nm * aonv * aonv;
+             del2  = 2.0 * del1 * f220 * g200 * q22;
+             del3  = 3.0 * del1 * f330 * g300 * q33 * aonv;
+             del1  = del1 * f311 * g310 * q31 * aonv;
+             xlamo = fmod(mo + nodeo + argpo - theta, twopi);
+             xfact = mdot + xpidot - rptim + dmdt + domdt + dnodt - no;
+           }
+
+         /* ------------ for sgp4, initialize the integrator ---------- */
+         xli   = xlamo;
+         xni   = no;
+         atime = 0.0;
+         nm    = no + dndt;
+       }
+
+//#include "debug3.cpp"
+}  // end dsinit
+
+/*-----------------------------------------------------------------------------
+*
+*                           procedure dspace
+*
+*  this procedure provides deep space contributions to mean elements for
+*    perturbing third body.  these effects have been averaged over one
+*    revolution of the sun and moon.  for earth resonance effects, the
+*    effects have been averaged over no revolutions of the satellite.
+*    (mean motion)
+*
+*  author        : david vallado                  719-573-2600   28 jun 2005
+*
+*  inputs        :
+*    d2201, d2211, d3210, d3222, d4410, d4422, d5220, d5232, d5421, d5433 -
+*    dedt        -
+*    del1, del2, del3  -
+*    didt        -
+*    dmdt        -
+*    dnodt       -
+*    domdt       -
+*    irez        - flag for resonance           0-none, 1-one day, 2-half day
+*    argpo       - argument of perigee
+*    argpdot     - argument of perigee dot (rate)
+*    t           - time
+*    tc          -
+*    gsto        - gst
+*    xfact       -
+*    xlamo       -
+*    no          - mean motion
+*    atime       -
+*    em          - eccentricity
+*    ft          -
+*    argpm       - argument of perigee
+*    inclm       - inclination
+*    xli         -
+*    mm          - mean anomaly
+*    xni         - mean motion
+*    nodem       - right ascension of ascending node
+*
+*  outputs       :
+*    atime       -
+*    em          - eccentricity
+*    argpm       - argument of perigee
+*    inclm       - inclination
+*    xli         -
+*    mm          - mean anomaly
+*    xni         -
+*    nodem       - right ascension of ascending node
+*    dndt        -
+*    nm          - mean motion
+*
+*  locals        :
+*    delt        -
+*    ft          -
+*    theta       -
+*    x2li        -
+*    x2omi       -
+*    xl          -
+*    xldot       -
+*    xnddt       -
+*    xndt        -
+*    xomi        -
+*
+*  coupling      :
+*    none        -
+*
+*  references    :
+*    hoots, roehrich, norad spacetrack report #3 1980
+*    hoots, norad spacetrack report #6 1986
+*    hoots, schumacher and glover 2004
+*    vallado, crawford, hujsak, kelso  2006
+  ----------------------------------------------------------------------------*/
+
+static void dspace
+     (
+       int irez,
+       double d2201,  double d2211,  double d3210,   double d3222,  double d4410,
+       double d4422,  double d5220,  double d5232,   double d5421,  double d5433,
+       double dedt,   double del1,   double del2,    double del3,   double didt,
+       double dmdt,   double dnodt,  double domdt,   double argpo,  double argpdot,
+       double t,      double tc,     double gsto,    double xfact,  double xlamo,
+       double no,
+       double& atime, double& em,    double& argpm,  double& inclm, double& xli,
+       double& mm,    double& xni,   double& nodem,  double& dndt,  double& nm
+     )
+{
+     const double twopi = 2.0 * pi;
+     int iretn, iret;
+     double delt, ft, theta, x2li, x2omi, xl, xldot , xnddt, xndt, xomi, g22, g32,
+          g44, g52, g54, fasx2, fasx4, fasx6, rptim , step2, stepn , stepp;
+
+     fasx2 = 0.13130908;
+     fasx4 = 2.8843198;
+     fasx6 = 0.37448087;
+     g22   = 5.7686396;
+     g32   = 0.95240898;
+     g44   = 1.8014998;
+     g52   = 1.0508330;
+     g54   = 4.4108898;
+     rptim = 4.37526908801129966e-3; // this equates to 7.29211514668855e-5 rad/sec
+     stepp =    720.0;
+     stepn =   -720.0;
+     step2 = 259200.0;
+
+     /* ----------- calculate deep space resonance effects ----------- */
+     dndt   = 0.0;
+     theta  = fmod(gsto + tc * rptim, twopi);
+     em     = em + dedt * t;
+
+     inclm  = inclm + didt * t;
+     argpm  = argpm + domdt * t;
+     nodem  = nodem + dnodt * t;
+     mm     = mm + dmdt * t;
+
+     //   sgp4fix for negative inclinations
+     //   the following if statement should be commented out
+     //  if (inclm < 0.0)
+     // {
+     //    inclm = -inclm;
+     //    argpm = argpm - pi;
+     //    nodem = nodem + pi;
+     //  }
+
+     /* - update resonances : numerical (euler-maclaurin) integration - */
+     /* ------------------------- epoch restart ----------------------  */
+     //   sgp4fix for propagator problems
+     //   the following integration works for negative time steps and periods
+     //   the specific changes are unknown because the original code was so convoluted
+
+     // sgp4fix take out atime = 0.0 and fix for faster operation
+     ft    = 0.0;
+     if (irez != 0)
+       {
+         // sgp4fix streamline check
+         if ((atime == 0.0) || (t * atime <= 0.0) || (fabs(t) < fabs(atime)) )
+           {
+             atime  = 0.0;
+             xni    = no;
+             xli    = xlamo;
+           }
+           // sgp4fix move check outside loop
+           if (t > 0.0)
+               delt = stepp;
+             else
+               delt = stepn;
+
+         iretn = 381; // added for do loop
+         iret  =   0; // added for loop
+         while (iretn == 381)
+           {
+             /* ------------------- dot terms calculated ------------- */
+             /* ----------- near - synchronous resonance terms ------- */
+             if (irez != 2)
+               {
+                 xndt  = del1 * sin(xli - fasx2) + del2 * sin(2.0 * (xli - fasx4)) +
+                         del3 * sin(3.0 * (xli - fasx6));
+                 xldot = xni + xfact;
+                 xnddt = del1 * cos(xli - fasx2) +
+                         2.0 * del2 * cos(2.0 * (xli - fasx4)) +
+                         3.0 * del3 * cos(3.0 * (xli - fasx6));
+                 xnddt = xnddt * xldot;
+               }
+               else
+               {
+                 /* --------- near - half-day resonance terms -------- */
+                 xomi  = argpo + argpdot * atime;
+                 x2omi = xomi + xomi;
+                 x2li  = xli + xli;
+                 xndt  = d2201 * sin(x2omi + xli - g22) + d2211 * sin(xli - g22) +
+                       d3210 * sin(xomi + xli - g32)  + d3222 * sin(-xomi + xli - g32)+
+                       d4410 * sin(x2omi + x2li - g44)+ d4422 * sin(x2li - g44) +
+                       d5220 * sin(xomi + xli - g52)  + d5232 * sin(-xomi + xli - g52)+
+                       d5421 * sin(xomi + x2li - g54) + d5433 * sin(-xomi + x2li - g54);
+                 xldot = xni + xfact;
+                 xnddt = d2201 * cos(x2omi + xli - g22) + d2211 * cos(xli - g22) +
+                       d3210 * cos(xomi + xli - g32) + d3222 * cos(-xomi + xli - g32) +
+                       d5220 * cos(xomi + xli - g52) + d5232 * cos(-xomi + xli - g52) +
+                       2.0 * (d4410 * cos(x2omi + x2li - g44) +
+                       d4422 * cos(x2li - g44) + d5421 * cos(xomi + x2li - g54) +
+                       d5433 * cos(-xomi + x2li - g54));
+                 xnddt = xnddt * xldot;
+               }
+
+             /* ----------------------- integrator ------------------- */
+             // sgp4fix move end checks to end of routine
+             if (fabs(t - atime) >= stepp)
+               {
+                 iret  = 0;
+                 iretn = 381;
+               }
+               else // exit here
+               {
+                 ft    = t - atime;
+                 iretn = 0;
+               }
+
+             if (iretn == 381)
+               {
+                 xli   = xli + xldot * delt + xndt * step2;
+                 xni   = xni + xndt * delt + xnddt * step2;
+                 atime = atime + delt;
+               }
+           }  // while iretn = 381
+
+         nm = xni + xndt * ft + xnddt * ft * ft * 0.5;
+         xl = xli + xldot * ft + xndt * ft * ft * 0.5;
+         if (irez != 1)
+           {
+             mm   = xl - 2.0 * nodem + 2.0 * theta;
+             dndt = nm - no;
+           }
+           else
+           {
+             mm   = xl - nodem - argpm + theta;
+             dndt = nm - no;
+           }
+         nm = no + dndt;
+       }
+
+//#include "debug4.cpp"
+}  // end dsspace
+
+/*-----------------------------------------------------------------------------
+*
+*                           procedure initl
+*
+*  this procedure initializes the spg4 propagator. all the initialization is
+*    consolidated here instead of having multiple loops inside other routines.
+*
+*  author        : david vallado                  719-573-2600   28 jun 2005
+*
+*  inputs        :
+*    ecco        - eccentricity                           0.0 - 1.0
+*    epoch       - epoch time in days from jan 0, 1950. 0 hr
+*    inclo       - inclination of satellite
+*    no          - mean motion of satellite
+*    satn        - satellite number
+*
+*  outputs       :
+*    ainv        - 1.0 / a
+*    ao          - semi major axis
+*    con41       -
+*    con42       - 1.0 - 5.0 cos(i)
+*    cosio       - cosine of inclination
+*    cosio2      - cosio squared
+*    eccsq       - eccentricity squared
+*    method      - flag for deep space                    'd', 'n'
+*    omeosq      - 1.0 - ecco * ecco
+*    posq        - semi-parameter squared
+*    rp          - radius of perigee
+*    rteosq      - square root of (1.0 - ecco*ecco)
+*    sinio       - sine of inclination
+*    gsto        - gst at time of observation               rad
+*    no          - mean motion of satellite
+*
+*  locals        :
+*    ak          -
+*    d1          -
+*    del         -
+*    adel        -
+*    po          -
+*
+*  coupling      :
+*    getgravconst
+*    gstime      - find greenwich sidereal time from the julian date
+*
+*  references    :
+*    hoots, roehrich, norad spacetrack report #3 1980
+*    hoots, norad spacetrack report #6 1986
+*    hoots, schumacher and glover 2004
+*    vallado, crawford, hujsak, kelso  2006
+  ----------------------------------------------------------------------------*/
+
+static void initl
+     (
+       int satn,      gravconsttype whichconst,
+       double ecco,   double epoch,  double inclo,   double& no,
+       char& method,
+       double& ainv,  double& ao,    double& con41,  double& con42, double& cosio,
+       double& cosio2,double& eccsq, double& omeosq, double& posq,
+       double& rp,    double& rteosq,double& sinio , double& gsto,
+       char opsmode
+     )
+{
+     /* --------------------- local variables ------------------------ */
+     double ak, d1, del, adel, po, x2o3, j2, xke,
+            tumin, mu, radiusearthkm, j3, j4, j3oj2;
+
+     // sgp4fix use old way of finding gst
+     double ds70;
+     double ts70, tfrac, c1, thgr70, fk5r, c1p2p;
+     const double twopi = 2.0 * pi;
+
+     /* ----------------------- earth constants ---------------------- */
+     // sgp4fix identify constants and allow alternate values
+     getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 );
+     x2o3   = 2.0 / 3.0;
+
+     /* ------------- calculate auxillary epoch quantities ---------- */
+     eccsq  = ecco * ecco;
+     omeosq = 1.0 - eccsq;
+     rteosq = sqrt(omeosq);
+     cosio  = cos(inclo);
+     cosio2 = cosio * cosio;
+
+     /* ------------------ un-kozai the mean motion ----------------- */
+     ak    = pow(xke / no, x2o3);
+     d1    = 0.75 * j2 * (3.0 * cosio2 - 1.0) / (rteosq * omeosq);
+     del   = d1 / (ak * ak);
+     adel  = ak * (1.0 - del * del - del *
+             (1.0 / 3.0 + 134.0 * del * del / 81.0));
+     del   = d1/(adel * adel);
+     no    = no / (1.0 + del);
+
+     ao    = pow(xke / no, x2o3);
+     sinio = sin(inclo);
+     po    = ao * omeosq;
+     con42 = 1.0 - 5.0 * cosio2;
+     con41 = -con42-cosio2-cosio2;
+     ainv  = 1.0 / ao;
+     posq  = po * po;
+     rp    = ao * (1.0 - ecco);
+     method = 'n';
+
+     // sgp4fix modern approach to finding sidereal time
+     if (opsmode == 'a')
+        {
+         // sgp4fix use old way of finding gst
+         // count integer number of days from 0 jan 1970
+         ts70  = epoch - 7305.0;
+         ds70 = floor(ts70 + 1.0e-8);
+         tfrac = ts70 - ds70;
+         // find greenwich location at epoch
+         c1    = 1.72027916940703639e-2;
+         thgr70= 1.7321343856509374;
+         fk5r  = 5.07551419432269442e-15;
+         c1p2p = c1 + twopi;
+         gsto  = fmod( thgr70 + c1*ds70 + c1p2p*tfrac + ts70*ts70*fk5r, twopi);
+         if ( gsto < 0.0 )
+             gsto = gsto + twopi;
+       }
+       else
+        gsto = gstime(epoch + 2433281.5);
+
+
+//#include "debug5.cpp"
+}  // end initl
+
+/*-----------------------------------------------------------------------------
+*
+*                             procedure sgp4init
+*
+*  this procedure initializes variables for sgp4.
+*
+*  author        : david vallado                  719-573-2600   28 jun 2005
+*
+*  inputs        :
+*    opsmode     - mode of operation afspc or improved 'a', 'i'
+*    whichconst  - which set of constants to use  72, 84
+*    satn        - satellite number
+*    bstar       - sgp4 type drag coefficient              kg/m2er
+*    ecco        - eccentricity
+*    epoch       - epoch time in days from jan 0, 1950. 0 hr
+*    argpo       - argument of perigee (output if ds)
+*    inclo       - inclination
+*    mo          - mean anomaly (output if ds)
+*    no          - mean motion
+*    nodeo       - right ascension of ascending node
+*
+*  outputs       :
+*    satrec      - common values for subsequent calls
+*    return code - non-zero on error.
+*                   1 - mean elements, ecc >= 1.0 or ecc < -0.001 or a < 0.95 er
+*                   2 - mean motion less than 0.0
+*                   3 - pert elements, ecc < 0.0  or  ecc > 1.0
+*                   4 - semi-latus rectum < 0.0
+*                   5 - epoch elements are sub-orbital
+*                   6 - satellite has decayed
+*
+*  locals        :
+*    cnodm  , snodm  , cosim  , sinim  , cosomm , sinomm
+*    cc1sq  , cc2    , cc3
+*    coef   , coef1
+*    cosio4      -
+*    day         -
+*    dndt        -
+*    em          - eccentricity
+*    emsq        - eccentricity squared
+*    eeta        -
+*    etasq       -
+*    gam         -
+*    argpm       - argument of perigee
+*    nodem       -
+*    inclm       - inclination
+*    mm          - mean anomaly
+*    nm          - mean motion
+*    perige      - perigee
+*    pinvsq      -
+*    psisq       -
+*    qzms24      -
+*    rtemsq      -
+*    s1, s2, s3, s4, s5, s6, s7          -
+*    sfour       -
+*    ss1, ss2, ss3, ss4, ss5, ss6, ss7         -
+*    sz1, sz2, sz3
+*    sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33        -
+*    tc          -
+*    temp        -
+*    temp1, temp2, temp3       -
+*    tsi         -
+*    xpidot      -
+*    xhdot1      -
+*    z1, z2, z3          -
+*    z11, z12, z13, z21, z22, z23, z31, z32, z33         -
+*
+*  coupling      :
+*    getgravconst-
+*    initl       -
+*    dscom       -
+*    dpper       -
+*    dsinit      -
+*    sgp4        -
+*
+*  references    :
+*    hoots, roehrich, norad spacetrack report #3 1980
+*    hoots, norad spacetrack report #6 1986
+*    hoots, schumacher and glover 2004
+*    vallado, crawford, hujsak, kelso  2006
+  ----------------------------------------------------------------------------*/
+
+bool sgp4init
+     (
+       gravconsttype whichconst, char opsmode,   const int satn,     const double epoch,
+       const double xbstar,  const double xecco, const double xargpo,
+       const double xinclo,  const double xmo,   const double xno,
+       const double xnodeo,  elsetrec& satrec
+     )
+{
+     /* --------------------- local variables ------------------------ */
+     double ao, ainv,   con42, cosio, sinio, cosio2, eccsq,
+          omeosq, posq,   rp,     rteosq,
+          cnodm , snodm , cosim , sinim , cosomm, sinomm, cc1sq ,
+          cc2   , cc3   , coef  , coef1 , cosio4, day   , dndt  ,
+          em    , emsq  , eeta  , etasq , gam   , argpm , nodem ,
+          inclm , mm    , nm    , perige, pinvsq, psisq , qzms24,
+          rtemsq, s1    , s2    , s3    , s4    , s5    , s6    ,
+          s7    , sfour , ss1   , ss2   , ss3   , ss4   , ss5   ,
+          ss6   , ss7   , sz1   , sz2   , sz3   , sz11  , sz12  ,
+          sz13  , sz21  , sz22  , sz23  , sz31  , sz32  , sz33  ,
+          tc    , temp  , temp1 , temp2 , temp3 , tsi   , xpidot,
+          xhdot1, z1    , z2    , z3    , z11   , z12   , z13   ,
+          z21   , z22   , z23   , z31   , z32   , z33,
+          qzms2t, ss, j2, j3oj2, j4, x2o3, r[3], v[3],
+          tumin, mu, radiusearthkm, xke, j3, delmotemp, qzms2ttemp, qzms24temp;
+
+     /* ------------------------ initialization --------------------- */
+     // sgp4fix divisor for divide by zero check on inclination
+     // the old check used 1.0 + cos(pi-1.0e-9), but then compared it to
+     // 1.5 e-12, so the threshold was changed to 1.5e-12 for consistency
+     const double temp4    =   1.5e-12;
+
+     /* ----------- set all near earth variables to zero ------------ */
+     satrec.isimp   = 0;   satrec.method = 'n'; satrec.aycof    = 0.0;
+     satrec.con41   = 0.0; satrec.cc1    = 0.0; satrec.cc4      = 0.0;
+     satrec.cc5     = 0.0; satrec.d2     = 0.0; satrec.d3       = 0.0;
+     satrec.d4      = 0.0; satrec.delmo  = 0.0; satrec.eta      = 0.0;
+     satrec.argpdot = 0.0; satrec.omgcof = 0.0; satrec.sinmao   = 0.0;
+     satrec.t       = 0.0; satrec.t2cof  = 0.0; satrec.t3cof    = 0.0;
+     satrec.t4cof   = 0.0; satrec.t5cof  = 0.0; satrec.x1mth2   = 0.0;
+     satrec.x7thm1  = 0.0; satrec.mdot   = 0.0; satrec.nodedot  = 0.0;
+     satrec.xlcof   = 0.0; satrec.xmcof  = 0.0; satrec.nodecf   = 0.0;
+
+     /* ----------- set all deep space variables to zero ------------ */
+     satrec.irez  = 0;   satrec.d2201 = 0.0; satrec.d2211 = 0.0;
+     satrec.d3210 = 0.0; satrec.d3222 = 0.0; satrec.d4410 = 0.0;
+     satrec.d4422 = 0.0; satrec.d5220 = 0.0; satrec.d5232 = 0.0;
+     satrec.d5421 = 0.0; satrec.d5433 = 0.0; satrec.dedt  = 0.0;
+     satrec.del1  = 0.0; satrec.del2  = 0.0; satrec.del3  = 0.0;
+     satrec.didt  = 0.0; satrec.dmdt  = 0.0; satrec.dnodt = 0.0;
+     satrec.domdt = 0.0; satrec.e3    = 0.0; satrec.ee2   = 0.0;
+     satrec.peo   = 0.0; satrec.pgho  = 0.0; satrec.pho   = 0.0;
+     satrec.pinco = 0.0; satrec.plo   = 0.0; satrec.se2   = 0.0;
+     satrec.se3   = 0.0; satrec.sgh2  = 0.0; satrec.sgh3  = 0.0;
+     satrec.sgh4  = 0.0; satrec.sh2   = 0.0; satrec.sh3   = 0.0;
+     satrec.si2   = 0.0; satrec.si3   = 0.0; satrec.sl2   = 0.0;
+     satrec.sl3   = 0.0; satrec.sl4   = 0.0; satrec.gsto  = 0.0;
+     satrec.xfact = 0.0; satrec.xgh2  = 0.0; satrec.xgh3  = 0.0;
+     satrec.xgh4  = 0.0; satrec.xh2   = 0.0; satrec.xh3   = 0.0;
+     satrec.xi2   = 0.0; satrec.xi3   = 0.0; satrec.xl2   = 0.0;
+     satrec.xl3   = 0.0; satrec.xl4   = 0.0; satrec.xlamo = 0.0;
+     satrec.zmol  = 0.0; satrec.zmos  = 0.0; satrec.atime = 0.0;
+     satrec.xli   = 0.0; satrec.xni   = 0.0;
+
+     // sgp4fix - note the following variables are also passed directly via satrec.
+     // it is possible to streamline the sgp4init call by deleting the "x"
+     // variables, but the user would need to set the satrec.* values first. we
+     // include the additional assignments in case twoline2rv is not used.
+     satrec.bstar   = xbstar;
+     satrec.ecco    = xecco;
+     satrec.argpo   = xargpo;
+     satrec.inclo   = xinclo;
+     satrec.mo      = xmo;
+     satrec.no      = xno;
+     satrec.nodeo   = xnodeo;
+
+     // sgp4fix add opsmode
+     satrec.operationmode = opsmode;
+
+     /* ------------------------ earth constants ----------------------- */
+     // sgp4fix identify constants and allow alternate values
+     getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 );
+     ss     = 78.0 / radiusearthkm + 1.0;
+     // sgp4fix use multiply for speed instead of pow
+     qzms2ttemp = (120.0 - 78.0) / radiusearthkm;
+     qzms2t = qzms2ttemp * qzms2ttemp * qzms2ttemp * qzms2ttemp;
+     x2o3   =  2.0 / 3.0;
+
+     satrec.init = 'y';
+     satrec.t    = 0.0;
+
+     initl
+         (
+           satn, whichconst, satrec.ecco, epoch, satrec.inclo, satrec.no, satrec.method,
+           ainv, ao, satrec.con41, con42, cosio, cosio2, eccsq, omeosq,
+           posq, rp, rteosq, sinio, satrec.gsto, satrec.operationmode
+         );
+     satrec.error = 0;
+
+     // sgp4fix remove this check as it is unnecessary
+     // the mrt check in sgp4 handles decaying satellite cases even if the starting
+     // condition is below the surface of te earth
+//     if (rp < 1.0)
+//       {
+//         printf("# *** satn%d epoch elts sub-orbital ***\n", satn);
+//         satrec.error = 5;
+//       }
+
+     if ((omeosq >= 0.0 ) || ( satrec.no >= 0.0))
+       {
+         satrec.isimp = 0;
+         if (rp < (220.0 / radiusearthkm + 1.0))
+             satrec.isimp = 1;
+         sfour  = ss;
+         qzms24 = qzms2t;
+         perige = (rp - 1.0) * radiusearthkm;
+
+         /* - for perigees below 156 km, s and qoms2t are altered - */
+         if (perige < 156.0)
+           {
+             sfour = perige - 78.0;
+             if (perige < 98.0)
+                 sfour = 20.0;
+             // sgp4fix use multiply for speed instead of pow
+             qzms24temp =  (120.0 - sfour) / radiusearthkm;
+             qzms24 = qzms24temp * qzms24temp * qzms24temp * qzms24temp;
+             sfour  = sfour / radiusearthkm + 1.0;
+           }
+         pinvsq = 1.0 / posq;
+
+         tsi  = 1.0 / (ao - sfour);
+         satrec.eta  = ao * satrec.ecco * tsi;
+         etasq = satrec.eta * satrec.eta;
+         eeta  = satrec.ecco * satrec.eta;
+         psisq = fabs(1.0 - etasq);
+         coef  = qzms24 * pow(tsi, 4.0);
+         coef1 = coef / pow(psisq, 3.5);
+         cc2   = coef1 * satrec.no * (ao * (1.0 + 1.5 * etasq + eeta *
+                        (4.0 + etasq)) + 0.375 * j2 * tsi / psisq * satrec.con41 *
+                        (8.0 + 3.0 * etasq * (8.0 + etasq)));
+         satrec.cc1   = satrec.bstar * cc2;
+         cc3   = 0.0;
+         if (satrec.ecco > 1.0e-4)
+             cc3 = -2.0 * coef * tsi * j3oj2 * satrec.no * sinio / satrec.ecco;
+         satrec.x1mth2 = 1.0 - cosio2;
+         satrec.cc4    = 2.0* satrec.no * coef1 * ao * omeosq *
+                           (satrec.eta * (2.0 + 0.5 * etasq) + satrec.ecco *
+                           (0.5 + 2.0 * etasq) - j2 * tsi / (ao * psisq) *
+                           (-3.0 * satrec.con41 * (1.0 - 2.0 * eeta + etasq *
+                           (1.5 - 0.5 * eeta)) + 0.75 * satrec.x1mth2 *
+                           (2.0 * etasq - eeta * (1.0 + etasq)) * cos(2.0 * satrec.argpo)));
+         satrec.cc5 = 2.0 * coef1 * ao * omeosq * (1.0 + 2.75 *
+                        (etasq + eeta) + eeta * etasq);
+         cosio4 = cosio2 * cosio2;
+         temp1  = 1.5 * j2 * pinvsq * satrec.no;
+         temp2  = 0.5 * temp1 * j2 * pinvsq;
+         temp3  = -0.46875 * j4 * pinvsq * pinvsq * satrec.no;
+         satrec.mdot     = satrec.no + 0.5 * temp1 * rteosq * satrec.con41 + 0.0625 *
+                            temp2 * rteosq * (13.0 - 78.0 * cosio2 + 137.0 * cosio4);
+         satrec.argpdot  = -0.5 * temp1 * con42 + 0.0625 * temp2 *
+                             (7.0 - 114.0 * cosio2 + 395.0 * cosio4) +
+                             temp3 * (3.0 - 36.0 * cosio2 + 49.0 * cosio4);
+         xhdot1            = -temp1 * cosio;
+         satrec.nodedot = xhdot1 + (0.5 * temp2 * (4.0 - 19.0 * cosio2) +
+                              2.0 * temp3 * (3.0 - 7.0 * cosio2)) * cosio;
+         xpidot            =  satrec.argpdot+ satrec.nodedot;
+         satrec.omgcof   = satrec.bstar * cc3 * cos(satrec.argpo);
+         satrec.xmcof    = 0.0;
+         if (satrec.ecco > 1.0e-4)
+             satrec.xmcof = -x2o3 * coef * satrec.bstar / eeta;
+         satrec.nodecf = 3.5 * omeosq * xhdot1 * satrec.cc1;
+         satrec.t2cof   = 1.5 * satrec.cc1;
+         // sgp4fix for divide by zero with xinco = 180 deg
+         if (fabs(cosio+1.0) > 1.5e-12)
+             satrec.xlcof = -0.25 * j3oj2 * sinio * (3.0 + 5.0 * cosio) / (1.0 + cosio);
+           else
+             satrec.xlcof = -0.25 * j3oj2 * sinio * (3.0 + 5.0 * cosio) / temp4;
+         satrec.aycof   = -0.5 * j3oj2 * sinio;
+         // sgp4fix use multiply for speed instead of pow
+         delmotemp = 1.0 + satrec.eta * cos(satrec.mo);
+         satrec.delmo   = delmotemp * delmotemp * delmotemp;
+         satrec.sinmao  = sin(satrec.mo);
+         satrec.x7thm1  = 7.0 * cosio2 - 1.0;
+
+         /* --------------- deep space initialization ------------- */
+         if ((2*pi / satrec.no) >= 225.0)
+           {
+             satrec.method = 'd';
+             satrec.isimp  = 1;
+             tc    =  0.0;
+             inclm = satrec.inclo;
+
+             dscom
+                 (
+                   epoch, satrec.ecco, satrec.argpo, tc, satrec.inclo, satrec.nodeo,
+                   satrec.no, snodm, cnodm,  sinim, cosim,sinomm,     cosomm,
+                   day, satrec.e3, satrec.ee2, em,         emsq, gam,
+                   satrec.peo,  satrec.pgho,   satrec.pho, satrec.pinco,
+                   satrec.plo,  rtemsq,        satrec.se2, satrec.se3,
+                   satrec.sgh2, satrec.sgh3,   satrec.sgh4,
+                   satrec.sh2,  satrec.sh3,    satrec.si2, satrec.si3,
+                   satrec.sl2,  satrec.sl3,    satrec.sl4, s1, s2, s3, s4, s5,
+                   s6,   s7,   ss1,  ss2,  ss3,  ss4,  ss5,  ss6,  ss7, sz1, sz2, sz3,
+                   sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33,
+                   satrec.xgh2, satrec.xgh3,   satrec.xgh4, satrec.xh2,
+                   satrec.xh3,  satrec.xi2,    satrec.xi3,  satrec.xl2,
+                   satrec.xl3,  satrec.xl4,    nm, z1, z2, z3, z11,
+                   z12, z13, z21, z22, z23, z31, z32, z33,
+                   satrec.zmol, satrec.zmos
+                 );
+             dpper
+                 (
+                   satrec.e3, satrec.ee2, satrec.peo, satrec.pgho,
+                   satrec.pho, satrec.pinco, satrec.plo, satrec.se2,
+                   satrec.se3, satrec.sgh2, satrec.sgh3, satrec.sgh4,
+                   satrec.sh2, satrec.sh3, satrec.si2,  satrec.si3,
+                   satrec.sl2, satrec.sl3, satrec.sl4,  satrec.t,
+                   satrec.xgh2,satrec.xgh3,satrec.xgh4, satrec.xh2,
+                   satrec.xh3, satrec.xi2, satrec.xi3,  satrec.xl2,
+                   satrec.xl3, satrec.xl4, satrec.zmol, satrec.zmos, inclm, satrec.init,
+                   satrec.ecco, satrec.inclo, satrec.nodeo, satrec.argpo, satrec.mo,
+                   satrec.operationmode
+                 );
+
+             argpm  = 0.0;
+             nodem  = 0.0;
+             mm     = 0.0;
+
+             dsinit
+                 (
+                   whichconst,
+                   cosim, emsq, satrec.argpo, s1, s2, s3, s4, s5, sinim, ss1, ss2, ss3, ss4,
+                   ss5, sz1, sz3, sz11, sz13, sz21, sz23, sz31, sz33, satrec.t, tc,
+                   satrec.gsto, satrec.mo, satrec.mdot, satrec.no, satrec.nodeo,
+                   satrec.nodedot, xpidot, z1, z3, z11, z13, z21, z23, z31, z33,
+                   satrec.ecco, eccsq, em, argpm, inclm, mm, nm, nodem,
+                   satrec.irez,  satrec.atime,
+                   satrec.d2201, satrec.d2211, satrec.d3210, satrec.d3222 ,
+                   satrec.d4410, satrec.d4422, satrec.d5220, satrec.d5232,
+                   satrec.d5421, satrec.d5433, satrec.dedt,  satrec.didt,
+                   satrec.dmdt,  dndt,         satrec.dnodt, satrec.domdt ,
+                   satrec.del1,  satrec.del2,  satrec.del3,  satrec.xfact,
+                   satrec.xlamo, satrec.xli,   satrec.xni
+                 );
+           }
+
+       /* ----------- set variables if not deep space ----------- */
+       if (satrec.isimp != 1)
+         {
+           cc1sq          = satrec.cc1 * satrec.cc1;
+           satrec.d2    = 4.0 * ao * tsi * cc1sq;
+           temp           = satrec.d2 * tsi * satrec.cc1 / 3.0;
+           satrec.d3    = (17.0 * ao + sfour) * temp;
+           satrec.d4    = 0.5 * temp * ao * tsi * (221.0 * ao + 31.0 * sfour) *
+                            satrec.cc1;
+           satrec.t3cof = satrec.d2 + 2.0 * cc1sq;
+           satrec.t4cof = 0.25 * (3.0 * satrec.d3 + satrec.cc1 *
+                            (12.0 * satrec.d2 + 10.0 * cc1sq));
+           satrec.t5cof = 0.2 * (3.0 * satrec.d4 +
+                            12.0 * satrec.cc1 * satrec.d3 +
+                            6.0 * satrec.d2 * satrec.d2 +
+                            15.0 * cc1sq * (2.0 * satrec.d2 + cc1sq));
+         }
+       } // if omeosq = 0 ...
+
+       /* finally propogate to zero epoch to initialize all others. */
+       // sgp4fix take out check to let satellites process until they are actually below earth surface
+//       if(satrec.error == 0)
+       sgp4(whichconst, satrec, 0.0, r, v);
+
+       satrec.init = 'n';
+
+//#include "debug6.cpp"
+       //sgp4fix return boolean. satrec.error contains any error codes
+       return true;
+}  // end sgp4init
+
+/*-----------------------------------------------------------------------------
+*
+*                             procedure sgp4
+*
+*  this procedure is the sgp4 prediction model from space command. this is an
+*    updated and combined version of sgp4 and sdp4, which were originally
+*    published separately in spacetrack report #3. this version follows the
+*    methodology from the aiaa paper (2006) describing the history and
+*    development of the code.
+*
+*  author        : david vallado                  719-573-2600   28 jun 2005
+*
+*  inputs        :
+*    satrec  - initialised structure from sgp4init() call.
+*    tsince  - time eince epoch (minutes)
+*
+*  outputs       :
+*    r           - position vector                     km
+*    v           - velocity                            km/sec
+*  return code - non-zero on error.
+*                   1 - mean elements, ecc >= 1.0 or ecc < -0.001 or a < 0.95 er
+*                   2 - mean motion less than 0.0
+*                   3 - pert elements, ecc < 0.0  or  ecc > 1.0
+*                   4 - semi-latus rectum < 0.0
+*                   5 - epoch elements are sub-orbital
+*                   6 - satellite has decayed
+*
+*  locals        :
+*    am          -
+*    axnl, aynl        -
+*    betal       -
+*    cosim   , sinim   , cosomm  , sinomm  , cnod    , snod    , cos2u   ,
+*    sin2u   , coseo1  , sineo1  , cosi    , sini    , cosip   , sinip   ,
+*    cosisq  , cossu   , sinsu   , cosu    , sinu
+*    delm        -
+*    delomg      -
+*    dndt        -
+*    eccm        -
+*    emsq        -
+*    ecose       -
+*    el2         -
+*    eo1         -
+*    eccp        -
+*    esine       -
+*    argpm       -
+*    argpp       -
+*    omgadf      -
+*    pl          -
+*    r           -
+*    rtemsq      -
+*    rdotl       -
+*    rl          -
+*    rvdot       -
+*    rvdotl      -
+*    su          -
+*    t2  , t3   , t4    , tc
+*    tem5, temp , temp1 , temp2  , tempa  , tempe  , templ
+*    u   , ux   , uy    , uz     , vx     , vy     , vz
+*    inclm       - inclination
+*    mm          - mean anomaly
+*    nm          - mean motion
+*    nodem       - right asc of ascending node
+*    xinc        -
+*    xincp       -
+*    xl          -
+*    xlm         -
+*    mp          -
+*    xmdf        -
+*    xmx         -
+*    xmy         -
+*    nodedf      -
+*    xnode       -
+*    nodep       -
+*    np          -
+*
+*  coupling      :
+*    getgravconst-
+*    dpper
+*    dpspace
+*
+*  references    :
+*    hoots, roehrich, norad spacetrack report #3 1980
+*    hoots, norad spacetrack report #6 1986
+*    hoots, schumacher and glover 2004
+*    vallado, crawford, hujsak, kelso  2006
+  ----------------------------------------------------------------------------*/
+
+bool sgp4
+     (
+       gravconsttype whichconst, elsetrec& satrec,  double tsince,
+       double r[3],  double v[3]
+     )
+{
+     double am   , axnl  , aynl , betal ,  cosim , cnod  ,
+         cos2u, coseo1, cosi , cosip ,  cosisq, cossu , cosu,
+         delm , delomg, em   , emsq  ,  ecose , el2   , eo1 ,
+         ep   , esine , argpm, argpp ,  argpdf, pl,     mrt = 0.0,
+         mvt  , rdotl , rl   , rvdot ,  rvdotl, sinim ,
+         sin2u, sineo1, sini , sinip ,  sinsu , sinu  ,
+         snod , su    , t2   , t3    ,  t4    , tem5  , temp,
+         temp1, temp2 , tempa, tempe ,  templ , u     , ux  ,
+         uy   , uz    , vx   , vy    ,  vz    , inclm , mm  ,
+         nm   , nodem, xinc , xincp ,  xl    , xlm   , mp  ,
+         xmdf , xmx   , xmy  , nodedf, xnode , nodep, tc  , dndt,
+         twopi, x2o3  , j2   , j3    , tumin, j4 , xke   , j3oj2, radiusearthkm,
+         mu, vkmpersec, delmtemp;
+     int ktr;
+
+     /* ------------------ set mathematical constants --------------- */
+     // sgp4fix divisor for divide by zero check on inclination
+     // the old check used 1.0 + cos(pi-1.0e-9), but then compared it to
+     // 1.5 e-12, so the threshold was changed to 1.5e-12 for consistency
+     const double temp4 =   1.5e-12;
+     twopi = 2.0 * pi;
+     x2o3  = 2.0 / 3.0;
+     // sgp4fix identify constants and allow alternate values
+     getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 );
+     vkmpersec     = radiusearthkm * xke/60.0;
+
+     /* --------------------- clear sgp4 error flag ----------------- */
+     satrec.t     = tsince;
+     satrec.error = 0;
+
+     /* ------- update for secular gravity and atmospheric drag ----- */
+     xmdf    = satrec.mo + satrec.mdot * satrec.t;
+     argpdf  = satrec.argpo + satrec.argpdot * satrec.t;
+     nodedf  = satrec.nodeo + satrec.nodedot * satrec.t;
+     argpm   = argpdf;
+     mm      = xmdf;
+     t2      = satrec.t * satrec.t;
+     nodem   = nodedf + satrec.nodecf * t2;
+     tempa   = 1.0 - satrec.cc1 * satrec.t;
+     tempe   = satrec.bstar * satrec.cc4 * satrec.t;
+     templ   = satrec.t2cof * t2;
+
+     if (satrec.isimp != 1)
+       {
+         delomg = satrec.omgcof * satrec.t;
+         // sgp4fix use mutliply for speed instead of pow
+         delmtemp =  1.0 + satrec.eta * cos(xmdf);
+         delm   = satrec.xmcof *
+                  (delmtemp * delmtemp * delmtemp -
+                  satrec.delmo);
+         temp   = delomg + delm;
+         mm     = xmdf + temp;
+         argpm  = argpdf - temp;
+         t3     = t2 * satrec.t;
+         t4     = t3 * satrec.t;
+         tempa  = tempa - satrec.d2 * t2 - satrec.d3 * t3 -
+                          satrec.d4 * t4;
+         tempe  = tempe + satrec.bstar * satrec.cc5 * (sin(mm) -
+                          satrec.sinmao);
+         templ  = templ + satrec.t3cof * t3 + t4 * (satrec.t4cof +
+                          satrec.t * satrec.t5cof);
+       }
+
+     nm    = satrec.no;
+     em    = satrec.ecco;
+     inclm = satrec.inclo;
+     if (satrec.method == 'd')
+       {
+         tc = satrec.t;
+         dspace
+             (
+               satrec.irez,
+               satrec.d2201, satrec.d2211, satrec.d3210,
+               satrec.d3222, satrec.d4410, satrec.d4422,
+               satrec.d5220, satrec.d5232, satrec.d5421,
+               satrec.d5433, satrec.dedt,  satrec.del1,
+               satrec.del2,  satrec.del3,  satrec.didt,
+               satrec.dmdt,  satrec.dnodt, satrec.domdt,
+               satrec.argpo, satrec.argpdot, satrec.t, tc,
+               satrec.gsto, satrec.xfact, satrec.xlamo,
+               satrec.no, satrec.atime,
+               em, argpm, inclm, satrec.xli, mm, satrec.xni,
+               nodem, dndt, nm
+             );
+       } // if method = d
+
+     if (nm <= 0.0)
+       {
+//         printf("# error nm %f\n", nm);
+         satrec.error = 2;
+         // sgp4fix add return
+         return false;
+       }
+     am = pow((xke / nm),x2o3) * tempa * tempa;
+     nm = xke / pow(am, 1.5);
+     em = em - tempe;
+
+     // fix tolerance for error recognition
+     // sgp4fix am is fixed from the previous nm check
+     if ((em >= 1.0) || (em < -0.001)/* || (am < 0.95)*/ )
+       {
+//         printf("# error em %f\n", em);
+         satrec.error = 1;
+         // sgp4fix to return if there is an error in eccentricity
+         return false;
+       }
+     // sgp4fix fix tolerance to avoid a divide by zero
+     if (em < 1.0e-6)
+         em  = 1.0e-6;
+     mm     = mm + satrec.no * templ;
+     xlm    = mm + argpm + nodem;
+     emsq   = em * em;
+     temp   = 1.0 - emsq;
+
+     nodem  = fmod(nodem, twopi);
+     argpm  = fmod(argpm, twopi);
+     xlm    = fmod(xlm, twopi);
+     mm     = fmod(xlm - argpm - nodem, twopi);
+
+     /* ----------------- compute extra mean quantities ------------- */
+     sinim = sin(inclm);
+     cosim = cos(inclm);
+
+     /* -------------------- add lunar-solar periodics -------------- */
+     ep     = em;
+     xincp  = inclm;
+     argpp  = argpm;
+     nodep  = nodem;
+     mp     = mm;
+     sinip  = sinim;
+     cosip  = cosim;
+     if (satrec.method == 'd')
+       {
+         dpper
+             (
+               satrec.e3,   satrec.ee2,  satrec.peo,
+               satrec.pgho, satrec.pho,  satrec.pinco,
+               satrec.plo,  satrec.se2,  satrec.se3,
+               satrec.sgh2, satrec.sgh3, satrec.sgh4,
+               satrec.sh2,  satrec.sh3,  satrec.si2,
+               satrec.si3,  satrec.sl2,  satrec.sl3,
+               satrec.sl4,  satrec.t,    satrec.xgh2,
+               satrec.xgh3, satrec.xgh4, satrec.xh2,
+               satrec.xh3,  satrec.xi2,  satrec.xi3,
+               satrec.xl2,  satrec.xl3,  satrec.xl4,
+               satrec.zmol, satrec.zmos, satrec.inclo,
+               'n', ep, xincp, nodep, argpp, mp, satrec.operationmode
+             );
+         if (xincp < 0.0)
+           {
+             xincp  = -xincp;
+             nodep = nodep + pi;
+             argpp  = argpp - pi;
+           }
+         if ((ep < 0.0 ) || ( ep > 1.0))
+           {
+//            printf("# error ep %f\n", ep);
+             satrec.error = 3;
+             // sgp4fix add return
+             return false;
+           }
+       } // if method = d
+
+     /* -------------------- long period periodics ------------------ */
+     if (satrec.method == 'd')
+       {
+         sinip =  sin(xincp);
+         cosip =  cos(xincp);
+         satrec.aycof = -0.5*j3oj2*sinip;
+         // sgp4fix for divide by zero for xincp = 180 deg
+         if (fabs(cosip+1.0) > 1.5e-12)
+             satrec.xlcof = -0.25 * j3oj2 * sinip * (3.0 + 5.0 * cosip) / (1.0 + cosip);
+           else
+             satrec.xlcof = -0.25 * j3oj2 * sinip * (3.0 + 5.0 * cosip) / temp4;
+       }
+     axnl = ep * cos(argpp);
+     temp = 1.0 / (am * (1.0 - ep * ep));
+     aynl = ep* sin(argpp) + temp * satrec.aycof;
+     xl   = mp + argpp + nodep + temp * satrec.xlcof * axnl;
+
+     /* --------------------- solve kepler's equation --------------- */
+     u    = fmod(xl - nodep, twopi);
+     eo1  = u;
+     tem5 = 9999.9;
+     ktr = 1;
+     //   sgp4fix for kepler iteration
+     //   the following iteration needs better limits on corrections
+     while (( fabs(tem5) >= 1.0e-12) && (ktr <= 10) )
+       {
+         sineo1 = sin(eo1);
+         coseo1 = cos(eo1);
+         tem5   = 1.0 - coseo1 * axnl - sineo1 * aynl;
+         tem5   = (u - aynl * coseo1 + axnl * sineo1 - eo1) / tem5;
+         if(fabs(tem5) >= 0.95)
+             tem5 = tem5 > 0.0 ? 0.95 : -0.95;
+         eo1    = eo1 + tem5;
+         ktr = ktr + 1;
+       }
+
+     /* ------------- short period preliminary quantities ----------- */
+     ecose = axnl*coseo1 + aynl*sineo1;
+     esine = axnl*sineo1 - aynl*coseo1;
+     el2   = axnl*axnl + aynl*aynl;
+     pl    = am*(1.0-el2);
+     if (pl < 0.0)
+       {
+//         printf("# error pl %f\n", pl);
+         satrec.error = 4;
+         // sgp4fix add return
+         return false;
+       }
+       else
+       {
+         rl     = am * (1.0 - ecose);
+         rdotl  = sqrt(am) * esine/rl;
+         rvdotl = sqrt(pl) / rl;
+         betal  = sqrt(1.0 - el2);
+         temp   = esine / (1.0 + betal);
+         sinu   = am / rl * (sineo1 - aynl - axnl * temp);
+         cosu   = am / rl * (coseo1 - axnl + aynl * temp);
+         su     = atan2(sinu, cosu);
+         sin2u  = (cosu + cosu) * sinu;
+         cos2u  = 1.0 - 2.0 * sinu * sinu;
+         temp   = 1.0 / pl;
+         temp1  = 0.5 * j2 * temp;
+         temp2  = temp1 * temp;
+
+         /* -------------- update for short period periodics ------------ */
+         if (satrec.method == 'd')
+           {
+             cosisq                 = cosip * cosip;
+             satrec.con41  = 3.0*cosisq - 1.0;
+             satrec.x1mth2 = 1.0 - cosisq;
+             satrec.x7thm1 = 7.0*cosisq - 1.0;
+           }
+         mrt   = rl * (1.0 - 1.5 * temp2 * betal * satrec.con41) +
+                 0.5 * temp1 * satrec.x1mth2 * cos2u;
+         su    = su - 0.25 * temp2 * satrec.x7thm1 * sin2u;
+         xnode = nodep + 1.5 * temp2 * cosip * sin2u;
+         xinc  = xincp + 1.5 * temp2 * cosip * sinip * cos2u;
+         mvt   = rdotl - nm * temp1 * satrec.x1mth2 * sin2u / xke;
+         rvdot = rvdotl + nm * temp1 * (satrec.x1mth2 * cos2u +
+                 1.5 * satrec.con41) / xke;
+
+         /* --------------------- orientation vectors ------------------- */
+         sinsu =  sin(su);
+         cossu =  cos(su);
+         snod  =  sin(xnode);
+         cnod  =  cos(xnode);
+         sini  =  sin(xinc);
+         cosi  =  cos(xinc);
+         xmx   = -snod * cosi;
+         xmy   =  cnod * cosi;
+         ux    =  xmx * sinsu + cnod * cossu;
+         uy    =  xmy * sinsu + snod * cossu;
+         uz    =  sini * sinsu;
+         vx    =  xmx * cossu - cnod * sinsu;
+         vy    =  xmy * cossu - snod * sinsu;
+         vz    =  sini * cossu;
+
+         /* --------- position and velocity (in km and km/sec) ---------- */
+         r[0] = (mrt * ux)* radiusearthkm;
+         r[1] = (mrt * uy)* radiusearthkm;
+         r[2] = (mrt * uz)* radiusearthkm;
+         v[0] = (mvt * ux + rvdot * vx) * vkmpersec;
+         v[1] = (mvt * uy + rvdot * vy) * vkmpersec;
+         v[2] = (mvt * uz + rvdot * vz) * vkmpersec;
+       }  // if pl > 0
+
+     // sgp4fix for decaying satellites
+     if (mrt < 1.0)
+       {
+//         printf("# decay condition %11.6f \n",mrt);
+         satrec.error = 6;
+         return false;
+       }
+
+//#include "debug7.cpp"
+     return true;
+}  // end sgp4
+
+
+/* -----------------------------------------------------------------------------
+*
+*                           function gstime
+*
+*  this function finds the greenwich sidereal time.
+*
+*  author        : david vallado                  719-573-2600    1 mar 2001
+*
+*  inputs          description                    range / units
+*    jdut1       - julian date in ut1             days from 4713 bc
+*
+*  outputs       :
+*    gstime      - greenwich sidereal time        0 to 2pi rad
+*
+*  locals        :
+*    temp        - temporary variable for doubles   rad
+*    tut1        - julian centuries from the
+*                  jan 1, 2000 12 h epoch (ut1)
+*
+*  coupling      :
+*    none
+*
+*  references    :
+*    vallado       2004, 191, eq 3-45
+* --------------------------------------------------------------------------- */
+
+double  gstime
+        (
+          double jdut1
+        )
+   {
+     const double twopi = 2.0 * pi;
+     const double deg2rad = pi / 180.0;
+     double       temp, tut1;
+
+     tut1 = (jdut1 - 2451545.0) / 36525.0;
+     temp = -6.2e-6* tut1 * tut1 * tut1 + 0.093104 * tut1 * tut1 +
+             (876600.0*3600 + 8640184.812866) * tut1 + 67310.54841;  // sec
+     temp = fmod(temp * deg2rad / 240.0, twopi); //360/86400 = 1/240, to deg, to rad
+
+     // ------------------------ check quadrants ---------------------
+     if (temp < 0.0)
+         temp += twopi;
+
+     return temp;
+   }  // end gstime
+
+
+/* -----------------------------------------------------------------------------
+*
+*                           function getgravconst
+*
+*  this function gets constants for the propagator. note that mu is identified to
+*    facilitiate comparisons with newer models. the common useage is wgs72.
+*
+*  author        : david vallado                  719-573-2600   21 jul 2006
+*
+*  inputs        :
+*    whichconst  - which set of constants to use  wgs72old, wgs72, wgs84
+*
+*  outputs       :
+*    tumin       - minutes in one time unit
+*    mu          - earth gravitational parameter
+*    radiusearthkm - radius of the earth in km
+*    xke         - reciprocal of tumin
+*    j2, j3, j4  - un-normalized zonal harmonic values
+*    j3oj2       - j3 divided by j2
+*
+*  locals        :
+*
+*  coupling      :
+*    none
+*
+*  references    :
+*    norad spacetrack report #3
+*    vallado, crawford, hujsak, kelso  2006
+  --------------------------------------------------------------------------- */
+
+void getgravconst
+     (
+      gravconsttype whichconst,
+      double& tumin,
+      double& mu,
+      double& radiusearthkm,
+      double& xke,
+      double& j2,
+      double& j3,
+      double& j4,
+      double& j3oj2
+     )
+     {
+
+       switch (whichconst)
+         {
+           // -- wgs-72 low precision str#3 constants --
+           case wgs72old:
+           mu     = 398600.79964;        // in km3 / s2
+           radiusearthkm = 6378.135;     // km
+           xke    = 0.0743669161;
+           tumin  = 1.0 / xke;
+           j2     =   0.001082616;
+           j3     =  -0.00000253881;
+           j4     =  -0.00000165597;
+           j3oj2  =  j3 / j2;
+         break;
+           // ------------ wgs-72 constants ------------
+           case wgs72:
+           mu     = 398600.8;            // in km3 / s2
+           radiusearthkm = 6378.135;     // km
+           xke    = 60.0 / sqrt(radiusearthkm*radiusearthkm*radiusearthkm/mu);
+           tumin  = 1.0 / xke;
+           j2     =   0.001082616;
+           j3     =  -0.00000253881;
+           j4     =  -0.00000165597;
+           j3oj2  =  j3 / j2;
+         break;
+           case wgs84:
+           // ------------ wgs-84 constants ------------
+           mu     = 398600.5;            // in km3 / s2
+           radiusearthkm = 6378.137;     // km
+           xke    = 60.0 / sqrt(radiusearthkm*radiusearthkm*radiusearthkm/mu);
+           tumin  = 1.0 / xke;
+           j2     =   0.00108262998905;
+           j3     =  -0.00000253215306;
+           j4     =  -0.00000161098761;
+           j3oj2  =  j3 / j2;
+         break;
+         default:
+//           fprintf(stderr,"unknown gravity option (%d)\n",whichconst);
+         break;
+         }
+
+     }   // end getgravconst
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sgp4unit.h	Tue Aug 11 22:42:13 2015 +0000
@@ -0,0 +1,130 @@
+#ifndef _sgp4unit_
+#define _sgp4unit_
+/*     ----------------------------------------------------------------
+*
+*                                 sgp4unit.h
+*
+*    this file contains the sgp4 procedures for analytical propagation
+*    of a satellite. the code was originally released in the 1980 and 1986
+*    spacetrack papers. a detailed discussion of the theory and history
+*    may be found in the 2006 aiaa paper by vallado, crawford, hujsak,
+*    and kelso.
+*
+*                            companion code for
+*               fundamentals of astrodynamics and applications
+*                                    2007
+*                              by david vallado
+*
+*       (w) 719-573-2600, email dvallado@agi.com
+*
+*    current :
+*              30 Dec 11  david vallado
+*                           consolidate updated code version
+*              30 Aug 10  david vallado
+*                           delete unused variables in initl
+*                           replace pow inetger 2, 3 with multiplies for speed
+*    changes :
+*               3 Nov 08  david vallado
+*                           put returns in for error codes
+*              29 sep 08  david vallado
+*                           fix atime for faster operation in dspace
+*                           add operationmode for afspc (a) or improved (i)
+*                           performance mode
+*              20 apr 07  david vallado
+*                           misc fixes for constants
+*              11 aug 06  david vallado
+*                           chg lyddane choice back to strn3, constants, misc doc
+*              15 dec 05  david vallado
+*                           misc fixes
+*              26 jul 05  david vallado
+*                           fixes for paper
+*                           note that each fix is preceded by a
+*                           comment with "sgp4fix" and an explanation of
+*                           what was changed
+*              10 aug 04  david vallado
+*                           2nd printing baseline working
+*              14 may 01  david vallado
+*                           2nd edition baseline
+*                     80  norad
+*                           original baseline
+*       ----------------------------------------------------------------      */
+
+#include <math.h>
+#include <stdio.h>
+#define SGP4Version  "SGP4 Version 2011-12-30"
+
+#define pi 3.14159265358979323846
+
+// -------------------------- structure declarations ----------------------------
+typedef enum
+{
+  wgs72old,
+  wgs72,
+  wgs84
+} gravconsttype;
+
+typedef struct elsetrec
+{
+  long int  satnum;
+  int       epochyr, epochtynumrev;
+  int       error;
+  char      operationmode;
+  char      init, method;
+
+  /* Near Earth */
+  int    isimp;
+  double aycof  , con41  , cc1    , cc4      , cc5    , d2      , d3   , d4    ,
+         delmo  , eta    , argpdot, omgcof   , sinmao , t       , t2cof, t3cof ,
+         t4cof  , t5cof  , x1mth2 , x7thm1   , mdot   , nodedot, xlcof , xmcof ,
+         nodecf;
+
+  /* Deep Space */
+  int    irez;
+  double d2201  , d2211  , d3210  , d3222    , d4410  , d4422   , d5220 , d5232 ,
+         d5421  , d5433  , dedt   , del1     , del2   , del3    , didt  , dmdt  ,
+         dnodt  , domdt  , e3     , ee2      , peo    , pgho    , pho   , pinco ,
+         plo    , se2    , se3    , sgh2     , sgh3   , sgh4    , sh2   , sh3   ,
+         si2    , si3    , sl2    , sl3      , sl4    , gsto    , xfact , xgh2  ,
+         xgh3   , xgh4   , xh2    , xh3      , xi2    , xi3     , xl2   , xl3   ,
+         xl4    , xlamo  , zmol   , zmos     , atime  , xli     , xni;
+
+  double a      , altp   , alta   , epochdays, jdsatepoch       , nddot , ndot  ,
+         bstar  , rcse   , inclo  , nodeo    , ecco             , argpo , mo    ,
+         no;
+} elsetrec;
+
+
+// --------------------------- function declarations ----------------------------
+bool sgp4init
+     (
+       gravconsttype whichconst,  char opsmode,  const int satn,     const double epoch,
+       const double xbstar,  const double xecco, const double xargpo,
+       const double xinclo,  const double xmo,   const double xno,
+       const double xnodeo,  elsetrec& satrec
+     );
+
+bool sgp4
+     (
+       gravconsttype whichconst, elsetrec& satrec,  double tsince,
+       double r[3],  double v[3]
+     );
+
+double  gstime
+        (
+          double jdut1
+        );
+
+void getgravconst
+     (
+      gravconsttype whichconst,
+      double& tumin,
+      double& mu,
+      double& radiusearthkm,
+      double& xke,
+      double& j2,
+      double& j3,
+      double& j4,
+      double& j3oj2
+     );
+
+#endif