Code covered by the BSD License  

Highlights from
SAT_ORBIT

from SAT_ORBIT by Andrea monti guarnieri
LEO satellite orbit propagation starting from TLE file

norad4(tlefile, satname, Nsv2, DTm)
function [satrec rV] = norad4(tlefile, satname, Nsv2, DTm)
%% ORBIT propagation by NORAD's SGP4
% [sat_rec rV] = tle2sv(tlefile, satname, Nsv2, [DTm])
% Reads a tle file and provide orbit propagation.
% INPUTS:
%   tlefile = filename including path (three line elements)
%   satname = symbolic satellite name to extract orbit
%   Nsv2 = half number of SV, spacing is DTm minutes
%   DTm = spacing in minutes
%   The state vectors are extracted centered in the epoch written in TLE file
%
% OUTPUTS:
%   satrec = structure with satellite parameters extracted from tle-file
%   rV.R, rV,V    = state vectors (space, velocity), size [2*Nsv+1, 3]
%   rV,t = sv times, in matlab time format
%
%  Author: Andrea Monti Guarnieri rearranged the present interface.
%   Origianl code is from:
%   Jeff Beck
%   beckja@alumni.lehigh.edu
%   david vallado
%           http://www.centerforspace.com/downloads/files/sgp4/AIAA-2006-6753Code.zip
%% Initializations: scan TLE file and read satellite elements
if nargin < 4
    DTm = 1;
end

% DTm should be taken integer
DTm=ceil(DTm);

fp=fopen(tlefile,'r');
if(fp == -1)
    error('Cannot open file');
end

% scan file until satname found
found = 0;
while (~feof(fp)) && (~found),
    line=fgetl(fp);
    found = strcmp(line,satname);
end

if ~found
    error('Cannot find that sat')
end

% read and create orbit info
line1=fgetl(fp); % read first line
line2=fgetl(fp); % read second line
fclose(fp);

%% Call SGP4 propagator once
whichconst = 84;
typerun = 'c';
typeinput = 'e';
satrec = twoline2rv(whichconst, line1, line2, typerun, typeinput);

% Call the propagator to get the initial state vector value
satrec = sgp4 (satrec,  0.0);

%% call SGP4 propagator for the times of interest
tvect = -Nsv2*DTm : DTm : +Nsv2*DTm;
Ntot = length(tvect);
R=zeros(Ntot,3);
V=zeros(Ntot,3);
for jj=1:Ntot
    tsince = tvect(jj);
    [satrec, R(jj,:), V(jj,:)] = sgp4 (satrec,  tsince);
    if (satrec.error > 0)
        error(['# *** error: t:=' strnum(tsince) ' *** code =', strnum(satrec.error)]);
    end
end

%% Create outputs
rV.r=R';
rV.v=V';
t0=datenum(satrec.epochyear,0,satrec.epochdays);
rV.time=t0+tvect/60/24;

%%  -----------------------------------------------------------------------------
%
%                            procedure 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:
%   Jeff Beck
%   beckja@alumni.lehigh.edu
%   1.0  aug  6, 2006 - update for paper dav
%   2.0  mar  8, 2007 - misc fixes and manual operation updates
%   2.01 may  9, 2007 - fix for correction to year of 57
%   2.02 oct  8, 2007 - fix for manual jdstart jdstop matlab formats
% original comments from Vallado C++ version:
%   author        : david vallado                  719-573-2600    1 mar 2001
%
%   inputs        :
%   longstr1      - TLE character string
%   longstr2      - TLE character string
%   typerun       - character for mode of SGP4 execution
%                   'c' = catalog mode (propagates at 20 min timesteps from
%                           one day before epoch to one day after)
%                   'v' = verification mode (propagates according to start,
%                           stop, and timestep specified in longstr2)
%                   'm' = manual mode (prompts user for start, stop, and
%                           timestep for propagation)
%   typeinput     - type of manual input           mfe 'm', epoch 'e', dayofyr 'd'
%
%   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
%
% [satrec, startmfe, stopmfe, deltamin] = twoline2rv(whichconst, longstr1, ...
%          longstr2, typerun,typeinput)
%  ------------------------------------------------------------------------
%  ----*/
function [satrec, startmfe, stopmfe, deltamin] = twoline2rv(whichconst, ...
    longstr1, longstr2, typerun,typeinput,deltamin)
%global tumin radiusearthkm xke j2 j3 j4 j3oj2
global tumin

deg2rad  =   pi / 180.0;         %  0.01745329251994330;  % [deg/rad]
xpdotp   =  1440.0 / (2.0*pi);   % 229.1831180523293;  % [rev/day]/[rad/min]

%revnum = 0;
%elnum  = 0;
%year   = 0;
satrec.error = 0;

%     // set the implied decimal points since doing a formated read
%     // fixes for bad input data values (missing, ...)
for j = 11:16
    if (longstr1(j) == ' ')
        longstr1(j) = '_';
    end
end

if (longstr1(45) ~= ' ')
    longstr1(44) = longstr1(45);
end
longstr1(45) = '.';

if (longstr1(8) == ' ')
    longstr1(8) = 'U';
end

if (longstr1(10) == ' ')
    longstr1(10) = '.';
end

for j = 46:50
    if (longstr1(j) == ' ')
        longstr1(j) = '0';
    end
end
if (longstr1(52) == ' ')
    longstr1(52) = '0';
end
if (longstr1(54) ~= ' ')
    longstr1(53) = longstr1(54);
end
longstr1(54) = '.';

longstr2(26) = '.';

for j = 27:33
    if (longstr2(j) == ' ')
        longstr2(j) = '0';
    end
end

if (longstr1(63) == ' ')
    longstr1(63) = '0';
end

if ((length(longstr1) < 68) || (longstr1(68) == ' '))
    longstr1(68) = '0';
end

% parse first line
%carnumb = str2num(longstr1(1));
satrec.satnum = str2double(longstr1(3:7));
%classification = longstr1(8);
%intldesg = longstr1(10:17);
satrec.epochyr = str2double(longstr1(19:20));
satrec.epochdays = str2double(longstr1(21:32));
satrec.ndot = str2double(longstr1(34:43));
satrec.nddot = str2double(longstr1(44:50));
nexp = str2double(longstr1(51:52));
satrec.bstar = str2double(longstr1(53:59));
ibexp = str2double(longstr1(60:61));
%numb = str2double(longstr1(63));
%elnum = str2double(longstr1(65:68));

% parse second line
if typerun == 'v'
    %cardnumb = str2double(longstr2(1));
    satrec.satnum = str2double(longstr2(3:7));
    satrec.inclo = str2double(longstr2(8:16));
    satrec.nodeo = str2double(longstr2(17:25));
    satrec.ecco = str2double(longstr2(26:33));
    satrec.argpo = str2double(longstr2(34:42));
    satrec.mo = str2double(longstr2(43:51));
    satrec.no = str2double(longstr2(52:63));
    %revnum = str2double(longstr2(64:68));
    startmfe = str2double(longstr2(70:81));
    stopmfe  = str2double(longstr2(83:96));
    deltamin = str2double(longstr2(97:105));
else
    %cardnumb = str2double(longstr2(1));
    satrec.satnum = str2double(longstr2(3:7));
    satrec.inclo = str2double(longstr2(8:16));
    satrec.nodeo = str2double(longstr2(17:25));
    satrec.ecco = str2double(longstr2(26:33));
    satrec.argpo = str2double(longstr2(34:42));
    satrec.mo = str2double(longstr2(43:51));
    satrec.no = str2double(longstr2(52:63));
    % revnum = str2double(longstr2(64:68));
end

%     // ---- find no, ndot, nddot ----
satrec.no   = satrec.no / xpdotp; %//* rad/min
satrec.nddot= satrec.nddot * 10.0^nexp;
satrec.bstar= satrec.bstar * 10.0^ibexp;

%     // ---- convert to sgp4 units ----
satrec.a    = (satrec.no*tumin)^(-2/3);                % [er]
satrec.ndot = satrec.ndot  / (xpdotp*1440.0);          % [rad/min^2]
satrec.nddot= satrec.nddot / (xpdotp*1440.0*1440);     % [rad/min^3]

%     // ---- 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 2le ------
if (satrec.epochyr < 57)
    year= satrec.epochyr + 2000;
else
    year= satrec.epochyr + 1900;
end;
satrec.epochyear=year;

%     [mon,day,hr,minute,sec] = days2mdh ( year,satrec.epochdays );
[myear mon day hr minute sec]=datevec(datenum(year,0,satrec.epochdays));
satrec.jdsatepoch = jday( year,mon,day,hr,minute,sec );

%     // input start stop times manually
if ((typerun ~= 'v') && (typerun ~= 'c'))
    % ------------- enter start/stop ymd hms values --------------------
    if (typeinput == 'e')
        startyear = input('input start year');
        startmon  = input('input start mon');
        startday  = input('input start day');
        starthr   = input('input start hr');
        startmin  = input('input start min');
        startsec  = input('input start sec');
        jdstart = jday( startyear,startmon,startday,starthr,startmin,startsec );

        stopyear = input('input stop year');
        stopmon  = input('input stop mon');
        stopday  = input('input stop day');
        stophr   = input('input stop hr');
        stopmin  = input('input stop min');
        stopsec  = input('input stop sec');
        jdstop = jday( stopyear,stopmon,stopday,stophr,stopmin,stopsec );

        startmfe = (jdstart - satrec.jdsatepoch) * 1440.0;
        stopmfe  = (jdstop - satrec.jdsatepoch) * 1440.0;
        deltamin = input('input time step in minutes ');
    end;
    % -------- enter start/stop year and days of year values -----------
    if (typeinput == 'd')
        startyear    = input('input start year');
        startdayofyr = input('input start dayofyr');
        stopyear     = input('input stop year');
        stopdayofyr  = input('input stop dayofyr');

        [mon,day,hr,minute,sec] = days2mdhms ( startyear,startdayofyr);
        jdstart = jday( startyear,mon,day,hr,minute,sec);
        [mon,day,hr,minute,sec] = days2mdhms ( stopyear,stopdayofyr);
        jdstop = jday( stopyear,mon,day,hr,minute,sec);

        startmfe = (jdstart - satrec.jdsatepoch) * 1440.0;
        stopmfe  = (jdstop - satrec.jdsatepoch) * 1440.0;
        deltamin = input('input time step in minutes ');
    end;
    % ------------------ enter start/stop mfe values -------------------
    if (typeinput == 'm')
        startmfe = input('input start mfe: ');
        stopmfe  = input('input stop mfe: ');
        deltamin = input('input time step in minutes: ');
    end;
end;
%     // perform complete catalog evaluation
if (typerun == 'c')
    startmfe =  -1440.0;
    stopmfe  =  1440.0;
    if nargin < 4
        deltamin = 20.0;
    end
end;

%     // ------------- initialize the orbit at sgp4epoch --------------
sgp4epoch = satrec.jdsatepoch - 2433281.5; % days since 0 Jan 1950
[satrec] = sgp4init(whichconst, satrec, satrec.bstar, satrec.ecco, sgp4epoch, ...
    satrec.argpo, satrec.inclo, satrec.mo, satrec.no, satrec.nodeo);




%% -----------------------------------------------------------------------------
%
%                            procedure dsinit
%
%   this procedure provides deep space contributions to mean motion dot due
%     to geopotential resonance with half day and one day orbits.
%
% Author: 
%   Jeff Beck 
%   beckja@alumni.lehigh.edu
%   1.0 (aug 7, 2006) - update for paper dav
% original comments from Vallado C++ version:
%   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
%  ----------------------------------------------------------------------------*/

function [  em,     argpm,  inclm,  mm,     nm,     nodem, irez,...
            atime,  d2201,  d2211,  d3210,  d3222,  d4410,  d4422,...
            d5220,  d5232,  d5421,  d5433,  dedt,   didt,   dmdt,...
            dndt,   dnodt,  domdt,  del1,   del2,   del3,   xfact,...
            xlamo,  xli,    xni]...
          = dsinit( ...
            cosim,  emsq,   argpo,  s1,     s2,     s3,     s4,...
            s5,     sinim,  ss1,    ss2,    ss3,    ss4,    ss5,...
            sz1,    sz3,    sz11,   sz13,   sz21,   sz23,   sz31,...
            sz33,   t,      tc,     gsto,   mo,     mdot,   no,...
            nodeo, nodedot,       xpidot, z1,     z3,     z11,...
            z13,    z21,    z23,    z31,    z33,    em,     argpm,...
            inclm,  mm,     nm,     nodem, ecco,   eccsq)

   % /* --------------------- local variables ------------------------ */
   twopi = 2.0 * pi;
   aonv  = 0.0;
   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;
   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
   %global tumin mu radiusearthkm xke j2 j3 j4 j3oj2  
   global xke  

   % /* -------------------- deep space initialization ------------ */
   irez = 0;
   if ((nm < 0.0052359877) && (nm > 0.0034906585))
       irez = 1;
   end
   if ((nm >= 8.26e-3) && (nm <= 9.24e-3) && (em >= 0.5))
       irez = 2;
   end
   d2201 = 0;
   d2211 = 0;
   d3210 = 0;
   d3222 = 0;
   d4410 = 0;
   d4422 = 0;
   d5220 = 0;
   d5232 = 0;
   d5421 = 0;
   d5433 = 0;
   del1  = 0;
   del2  = 0;
   del3  = 0;
   atime = 0;
   xfact = 0;
   xlamo = 0;
   xli   = 0;
   xni   = 0;

   % /* ------------------------ 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;
   end
   if (sinim ~= 0.0)
       shs = shs / sinim;
   end
   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;
   end
   domdt = sgs + sghl;
   dnodt = shs;
   if (sinim ~= 0.0)
       domdt = domdt - cosim / sinim * shll;
       dnodt = dnodt + shll / sinim;
   end

   % /* ----------- calculate deep space resonance effects -------- */
   dndt   = 0.0;
   theta  = rem(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

   % /* -------------- initialize the resonance terms ------------- */
   if (irez ~= 0)
       aonv = (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;
               end
           end
           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;
           end

           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 =  rem(mo + nodeo + nodeo-theta - theta, twopi);
           xfact =  mdot + dmdt + 2.0 * (nodedot + dnodt - rptim) - no;
           em    = emo;
           emsq  = emsqo;
       end

       % /* ---------------- 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 = rem(mo + nodeo + argpo - theta, twopi);
           xfact = mdot + xpidot - rptim + dmdt + domdt + dnodt - no;
       end

       % /* ------------ for sgp4, initialize the integrator ---------- */
       xli   = xlamo;
       xni   = no;
       atime = 0.0;
       nm    = no + dndt;
   end

  




%% -----------------------------------------------------------------------------
%
%                            procedure initl
%
%   this procedure initializes the spg4 propagator. all the initialization is
%     consolidated here instead of having multiple loops inside other routines.
%
% Author:
%   Jeff Beck
%   beckja@alumni.lehigh.edu
%   1.0 (aug 7, 2006) - update for paper dav
%   1.1 nov 16, 2007 - update for better compliance
% original comments from Vallado C++ version:
%   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
%     einv        - 1.0 / e
%     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      :
%     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
%  ----------------------------------------------------------------------------*/

function [  ainv,   ao,     con41,  con42,  cosio,  cosio2, einv,...
    eccsq,  method, omeosq, posq,   rp,     rteosq, sinio,...
    gsto,   no]...
    = initl(  ecco,   epoch,  inclo,  no,     satn)

% /* -------------------- wgs-72 earth constants ----------------- */
%     // sgp4fix identify constants and allow alternate values
global xke j2
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    = (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    = (xke / no)^x2o3;
sinio = sin(inclo);
po    = ao * omeosq;
con42 = 1.0 - 5.0 * cosio2;
con41 = -con42-cosio2-cosio2;
ainv  = 1.0 / ao;
einv  = 1.0 / ecco;
posq  = po * po;
rp    = ao * (1.0 - ecco);
method = 'n';

% sgp4fix modern approach to finding sidereal time
% gsto = gstime(epoch + 2433281.5);

% sgp4fix use old way of finding gst
% count integer number of days from 0 jan 1970
ts70  = epoch - 7305.0;
ids70 = floor(ts70 + 1.0e-8);
ds70  = ids70;
tfrac = ts70 - ds70;
% find greenwich location at epoch
c1    = 1.72027916940703639e-2;
thgr70= 1.7321343856509374;
fk5r  = 5.07551419432269442e-15;
twopi = 2.0*pi;
c1p2p = c1 + twopi;
gsto  = rem( thgr70 + c1*ds70 + c1p2p*tfrac + ts70*ts70*fk5r, twopi);
if ( gsto < 0.0 )
    gsto = gsto + twopi;
end;


%% -----------------------------------------------------------------------------
%
%                              procedure sgp4init
%
%   this procedure initializes variables for sgp4.
%
% Author: 
%   Jeff Beck 
%   beckja@alumni.lehigh.edu
%   1.0 (aug 7, 2006) - update for paper dav
% original comments from Vallado C++ version:
%   author        : david vallado                  719-573-2600   28 jun 2005
%
%   inputs        :
%     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
%     ndem        -
%     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
%  ----------------------------------------------------------------------------*/

function [satrec] = sgp4init(whichconst, satrec, xbstar, xecco, epoch, ...
         xargpo, xinclo, xmo, xno, xnodeo)

   % /* ------------------------ initialization --------------------- */
   % /* ----------- 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 assignment 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;

   %     /* -------------------- wgs-72 earth constants ----------------- */
   %     // sgp4fix identify constants and allow alternate values
   global tumin mu radiusearthkm xke j2 j3 j4 j3oj2  
   [tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2] = getgravc( whichconst );

   ss     = 78.0 / radiusearthkm + 1.0;
   qzms2t = ((120.0 - 78.0) / radiusearthkm)^4;
   x2o3   =  2.0 / 3.0;
   % // sgp4fix divisor for divide by zero check on inclination
   temp4  =   1.0 + cos(pi-1.0e-9);

   satrec.init = 'y';
   satrec.t    = 0.0;

   [ainv,  ao,     satrec.con41,   con42,  cosio,  cosio2, einv,   eccsq,...
           satrec.method,  omeosq, posq,   rp,     rteosq, sinio,...
           satrec.gsto,    satrec.no]...
           = initl(...
           satrec.ecco,    epoch,  satrec.inclo,   satrec.no,...
           satrec.satnum);

   satrec.error = 0;
       
   if (rp < 1.0)
   %   printf("# *** satn%d epoch elts sub-orbital ***\n", satn);
       satrec.error = 5;
   end

   if ((omeosq >= 0.0 ) || ( satrec.no >= 0.0))
       satrec.isimp = 0;
       if (rp < (220.0 / radiusearthkm + 1.0))
           satrec.isimp = 1;
       end
       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;
           end
           qzms24 = ((120.0 - sfour) / radiusearthkm)^4.0;
           sfour  = sfour / radiusearthkm + 1.0;
       end
       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 = abs(1.0 - etasq);
       coef  = qzms24 * tsi^4.0;
       coef1 = coef / 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;
       end
       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;
       end
       satrec.nodecf = 3.5 * omeosq * xhdot1 * satrec.cc1;
       satrec.t2cof   = 1.5 * satrec.cc1;

       % // sgp4fix for divide by zero with xinco = 180 deg
       if (abs(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;
       end   
       satrec.aycof   = -0.5 * j3oj2 * sinio;
       satrec.delmo   = (1.0 + satrec.eta * cos(satrec.mo))^3;
       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;

           [sinim,cosim,sinomm,cosomm,snodm,cnodm,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] = ...
               dscom(epoch,satrec.ecco,satrec.argpo,tc,satrec.inclo,...
               satrec.nodeo,satrec.no);

           [satrec.ecco,satrec.inclo,satrec.nodeo,satrec.argpo,satrec.mo]...
               = 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);

           argpm  = 0.0;
           nodem  = 0.0;
           mm     = 0.0;

           [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,...
               ... %ses,sghl,sghs,sgs,shl,shs,sis,sls,theta,...
               satrec.xfact,satrec.xlamo,satrec.xli,satrec.xni] ...
               = dsinit(...
               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,em,...
               argpm,inclm,mm,nm,nodem,satrec.ecco,eccsq);
       end

       % /* ----------- 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));
       end
   end % // if omeosq = 0 ...

   % /* finally propogate to zero epoch to initialise all others. */
   if(satrec.error == 0)
       satrec = sgp4(satrec, 0.0);
   end

   satrec.init = 'n';

 





%% -----------------------------------------------------------------------------
%
%                              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: 
%   Jeff Beck 
%   beckja@alumni.lehigh.edu
%   1.0 (aug 7, 2006) - update for paper dav
% original comments from Vallado C++ version:
%   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      - longi of ascending node
%     xinc        -
%     xincp       -
%     xl          -
%     xlm         -
%     mp          -
%     xmdf        -
%     xmx         -
%     xmy         -
%     nodedf     -
%     xnode       -
%     nodep      -
%     np          -
%
%   coupling      :
%     getgravconst
%     dpper
%     dspace
%
%   references    :
%     hoots, roehrich, norad spacetrack report #3 1980
%     hoots, norad spacetrack report #6 1986
%     hoots, schumacher and glover 2004
%     vallado, crawford, hujsak, kelso  2006
%  ----------------------------------------------------------------------------*/

function [satrec, r, v] = sgp4(satrec,tsince)

   % /* ------------------ set mathematical constants --------------- */
   twopi = 2.0 * pi;
   x2o3  = 2.0 / 3.0;
   %  // sgp4fix divisor for divide by zero check on inclination
   temp4    =   1.0 + cos(pi-1.0e-9);

   %  // sgp4fix identify constants and allow alternate values
   %global tumin mu radiusearthkm xke j2 j3 j4 j3oj2 
   global radiusearthkm xke j2 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;
       delm   = satrec.xmcof *...
           ((1.0 + satrec.eta * cos(xmdf))^3 -...
           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);
   end

   nm    = satrec.no;
   em    = satrec.ecco;
   inclm = satrec.inclo;
   if (satrec.method == 'd')
       tc = satrec.t;
       [satrec.atime,em,argpm,inclm,satrec.xli,mm,...
           satrec.xni,nodem,dndt,nm] = dspace(...
           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.irez,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,nm);
   end % // if method = d

   if (nm <= 0.0)
%       fprintf(1,'# error nm %f\n', nm);
       satrec.error = 2;
   end
   am = (xke / nm)^x2o3 * tempa * tempa;
   nm = xke / am^1.5;
   em = em - tempe;

   % // fix tolerance for error recognition
   if ((em >= 1.0) || (em < -0.001) || (am < 0.95))
%       fprintf(1,'# error em %f\n', em);
       satrec.error = 1;
   end
   if (em < 0.0)
       em  = 1.0e-6;
   end
   mm     = mm + satrec.no * templ;
   xlm    = mm + argpm + nodem;
   emsq   = em * em;
   temp   = 1.0 - emsq;
   nodem  = rem(nodem, twopi);
   argpm  = rem(argpm, twopi);
   xlm    = rem(xlm, twopi);
   mm     = rem(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')
       [ep,xincp,nodep,argpp,mp] = 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,...
           satrec.init,ep,xincp,nodep,argpp,mp);
       if (xincp < 0.0)
           xincp  = -xincp;
           nodep = nodep + pi;
           argpp  = argpp - pi;
       end
       if ((ep < 0.0 ) || ( ep > 1.0))
%           fprintf(1,'# error ep %f\n', ep);
           satrec.error = 3;
       end
   end % // 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 with xinco = 180 deg
       if (abs(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;
       end;
   end
   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    = rem(xl - nodep, twopi);
   eo1  = u;
   tem5 = 9999.9;
   ktr = 1;
   % //   sgp4fix for kepler iteration
   % //   the following iteration needs better limits on corrections
   while (( abs(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(abs(tem5) >= 0.95)
           if tem5 > 0.0
               tem5 = 0.95;
           else
               tem5 = -0.95;
           end
       end
       eo1    = eo1 + tem5;
       ktr = ktr + 1;
   end

   % /* ------------- 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)
%       fprintf(1,'# error pl %f\n', pl);
       satrec.error = 4;
       r = [0;0;0];
       v = [0;0;0];
   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;
       end
       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(1) = (mrt * ux)* radiusearthkm;
       r(2) = (mrt * uy)* radiusearthkm;
       r(3) = (mrt * uz)* radiusearthkm;
       v(1) = (mvt * ux + rvdot * vx) * vkmpersec;
       v(2) = (mvt * uy + rvdot * vy) * vkmpersec;
       v(3) = (mvt * uz + rvdot * vz) * vkmpersec;
   end % // if pl > 0

       % // sgp4fix for decaying satellites
        if (mrt < 1.0)
   %         printf("# decay condition %11.6f \n",mrt);
            satrec.error = 6;
        end


%%  -----------------------------------------------------------------------------
%
%                            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:
%   Jeff Beck
%   beckja@alumni.lehigh.edu
%   1.0 (aug 7, 2006) - update for paper dav
% original comments from Vallado C++ version:
%   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
%  ----------------------------------------------------------------------------*/

function [  ep,     inclp,  nodep, argpp,  mp]...
    = dpper(...
    e3,     ee2,    peo,    pgho,   pho,    pinco,  plo,    se2,...
    se3,    sgh2,   sgh3,   sgh4,   sh2,    sh3,    si2,    si3,...
    sl2,    sl3,    sl4,    t,      xgh2,   xgh3,   xgh4,   xh2,...
    xh3,    xi2,    xi3,    xl2,    xl3,    xl4,    zmol,...
    zmos,   inclo,  init,   ep,     inclp,  nodep, argpp,  mp)

% /* --------------------- local variables ------------------------ */
twopi = 2.0 * pi;

% /* ---------------------- 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;
end
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;
end
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')
    %   //  0.2 rad = 11.45916 deg
    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
    %   //  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  = rem(nodep, twopi);
        % sgp4fix for afspc written intrinsic functions
        % nodep used without a trigonometric function ahead
        if (nodep < 0.0)
            nodep = nodep + twopi;
        end;
        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)
            nodep = nodep + twopi;
        end;
        if (abs(xnoh - nodep) > pi)
            if (nodep < xnoh)
                nodep = nodep + twopi;
            else
                nodep = nodep - twopi;
            end
        end
        mp    = mp + pl;
        argpp = xls - mp - cosip * nodep;
    end
end % // if init == 'n'
%% -----------------------------------------------------------------------------
%
%                           function getgravc
%
%  this function gets constants for the propagator. note that mu is identified to
%    facilitiate comparisons with newer models.
%
%  author        : david vallado                  719-573-2600   21 jul 2006
%
%  inputs        :
%    whichconst  - which set of constants to use  721, 72, 84
%
%  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      :
%
%  references    :
%    norad spacetrack report #3
%    vallado, crawford, hujsak, kelso  2006
% [tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2] = getgravc(whichconst);
%  --------------------------------------------------------------------------- */

function [vtumin, vmu, vradiusearthkm, vxke, vj2, vj3, vj4, vj3oj2] = ...
    getgravc(whichconst)

global tumin mu radiusearthkm xke j2 j3 j4 j3oj2
switch whichconst
    case 721
        % -- wgs-72 low precision str#3 constants --
        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;
    case 72
        % ------------ wgs-72 constants ------------
        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;
    case 84
        % ------------ 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;
    otherwise
        fprintf('unknown gravity option (%d)\n',whichconst);
end;  % case
vtumin=tumin;
vmu=mu;
vradiusearthkm=radiusearthkm;
vxke=xke;
vj2=j2;
vj3=j3;
vj4=j4;
vj3oj2=j3oj2;

%% -----------------------------------------------------------------------------
%
%                            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: 
%   Jeff Beck 
%   beckja@alumni.lehigh.edu
%   1.0 (aug 6, 2006) - update for paper dav
% original comments from Vallado C++ version:
%   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
%  ----------------------------------------------------------------------------*/

function [  atime,  em,     argpm,  inclm,  xli,    mm,     xni,...
            nodem, dndt,   nm] = dspace(...
            d2201,  d2211,  d3210,  d3222,  d4410,  d4422,  d5220,...
            d5232,  d5421,  d5433,  dedt,   del1,   del2,   del3,...
            didt,   dmdt,   dnodt,  domdt,  irez,   argpo,  argpdot,...
            t,      tc,     gsto,   xfact,  xlamo,  no,     atime,...
            em,     argpm,  inclm,  xli,    mm,     xni,    nodem,...
            nm)

   twopi = 2.0 * pi;

   ft = 0.0;
   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;
   stepp =    720.0;
   stepn =   -720.0;
   step2 = 259200.0;

   % /* ----------- calculate deep space resonance effects ----------- */
   dndt   = 0.0;
   theta  = rem(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

   ft    = 0.0;
   atime = 0.0;
   if (irez ~= 0)
       if ((atime == 0.0) || ((t >= 0.0) && (atime < 0.0)) || ...
               ((t < 0.0) && (atime >= 0.0)))
           if (t >= 0.0)
               delt = stepp;
           else
               delt = stepn;
           end
           atime  = 0.0;
           xni    = no;
           xli    = xlamo;
       end
       iretn = 381; %// added for do loop
       iret  =   0; %// added for loop
       while (iretn == 381)
           if ((abs(t) < abs(atime)) || (iret == 351))
               if (t >= 0.0)
                   delt = stepn;
               else
                   delt = stepp;
               end
               iret  = 351;
               iretn = 381;
           else
               if (t > 0.0)  %// error if prev if has atime:=0.0 and t:=0.0 (ge)
                   delt = stepp;
               else
                   delt = stepn;
               end
               if (abs(t - atime) >= stepp)
                   iret  = 0;
                   iretn = 381;
               else
                   ft    = t - atime;
                   iretn = 0;
               end
           end

           % /* ------------------- 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;
           end

           % /* ----------------------- integrator ------------------- */
           if (iretn == 381)
               xli   = xli + xldot * delt + xndt * step2;
               xni   = xni + xndt * delt + xnddt * step2;
               atime = atime + delt;
           end
       end %  // 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;
       end

       nm = no + dndt;
   end

 %% -----------------------------------------------------------------------------

%
%                            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: 
%   Jeff Beck 
%   beckja@alumni.lehigh.edu
%   1.0 (aug 7, 2006) - update for paper dav
% original comments from Vallado C++ version:
%   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
%  ----------------------------------------------------------------------------*/

function [ sinim,cosim,sinomm,cosomm,snodm,cnodm,day,e3,ee2,em,emsq,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,z1,z2,z3,z11,z12,z13,z21,z22,...
           z23,z31,z32,z33,zmol,zmos]...
         = dscom (epoch, ep, argpp, tc, inclp, nodep, np)

   % /* -------------------------- constants ------------------------- */
   zes     =  0.01675;
   zel     =  0.05490;
   c1ss    =  2.9864797e-6;
   c1l     =  4.7968065e-7;
   zsinis  =  0.39785416;
   zcosis  =  0.91744867;
   zcosgs  =  0.1945905;
   zsings  = -0.98088458;
   twopi   =  2.0 * pi;

   % /* --------------------- local variables ------------------------ */
   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 = rem(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:2
       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;
       end
   end

   zmol = rem(4.7199672 + 0.22997150  * day - gam, twopi);
   zmos = rem(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);

 %% ------------------------------------------------------------------------------

Contact us at files@mathworks.com