From 1f621928f945440d93417bde66679d8c68a3ec2b Mon Sep 17 00:00:00 2001 From: Chris Lewicki Date: Sun, 28 Jul 2019 18:38:49 -0700 Subject: [PATCH 1/4] Bring current with 7 dec 15 vallado CPP version io.py 1. Rename afspc_mode to opsmode, take a/i as input instead of True/False 2. Clarify which mean anomaly (no) is used, satrec.no variable renamed to satrec.no_kozai, internal updates to support name change 3. Make more internal variables available available to satrec propagation.py 1. Rename afspc_mode to opsmode, take a/i as input instead of True/False 2. Initialize whichconst variables internally once, make values accessible in satrec 3. delete unused variables in initl test.py 1. Replace deprecated assertRaisesRegexp with assertRaisesRegex Notes: - Confirmed SGP4-VER.TLE is still current - Confirmed unit tests pass with python -m unittest discover sgp4 --- sgp4/io.py | 31 ++++--- sgp4/propagation.py | 194 +++++++++++++++++++++++++++----------------- sgp4/tests.py | 6 +- 3 files changed, 136 insertions(+), 95 deletions(-) diff --git a/sgp4/io.py b/sgp4/io.py index 8ee220b..38a5315 100644 --- a/sgp4/io.py +++ b/sgp4/io.py @@ -81,7 +81,7 @@ * typerun - type of run verification 'v', catalog 'c', * manual 'm' * typeinput - type of manual input mfe 'm', epoch 'e', dayofyr 'd' -* afspc_mode - True for afspc calculations, False for 'improved' mode +* opsmode - mode of operation afspc or improved 'a', 'i' * whichconst - which set of constants to use 72, 84 * * outputs : @@ -99,7 +99,7 @@ --------------------------------------------------------------------------- */ """ -def twoline2rv(longstr1, longstr2, whichconst, afspc_mode=False): +def twoline2rv(longstr1, longstr2, whichconst, opsmode='i'): """Return a Satellite imported from two lines of TLE data. Provide the two TLE lines as strings `longstr1` and `longstr2`, @@ -112,7 +112,7 @@ def twoline2rv(longstr1, longstr2, whichconst, afspc_mode=False): Normally, computations are made using various recent improvements to the algorithm. If you want to turn some of these off and go - back into "afspc" mode, then set `afspc_mode` to `True`. + back into "opsmode" mode, then set `opsmode` to `a`. """ @@ -139,8 +139,9 @@ def twoline2rv(longstr1, longstr2, whichconst, afspc_mode=False): line[63] == ' '): _saved_satnum = satrec.satnum = int(line[2:7]) - # classification = line[7] or 'U' - # intldesg = line[9:17] + satrec.line1 = line + satrec.classification = line[7] or 'U' + satrec.intldesg = line[9:17] two_digit_year = int(line[18:20]) satrec.epochdays = float(line[20:32]) satrec.ndot = float(line[33:43]) @@ -148,8 +149,8 @@ def twoline2rv(longstr1, longstr2, whichconst, afspc_mode=False): nexp = int(line[50:52]) satrec.bstar = float(line[53] + '.' + line[54:59]) ibexp = int(line[59:61]) - # numb = int(line[62]) - # elnum = int(line[64:68]) + satrec.ephtype = line[62] + satrec.elnum = int(line[64:68]) else: raise ValueError(error_message.format(1, LINE1, line)) @@ -171,24 +172,24 @@ def twoline2rv(longstr1, longstr2, whichconst, afspc_mode=False): if _saved_satnum != satrec.satnum: raise ValueError('Object numbers in lines 1 and 2 do not match') + satrec.line2 = line satrec.inclo = float(line[8:16]) satrec.nodeo = float(line[17:25]) satrec.ecco = float('0.' + line[26:33].replace(' ', '0')) satrec.argpo = float(line[34:42]) satrec.mo = float(line[43:51]) - satrec.no = float(line[52:63]) - #revnum = line[63:68] + satrec.no_kozai = float(line[52:63]) + satrec.revnum = line[63:68] #except (AssertionError, IndexError, ValueError): else: raise ValueError(error_message.format(2, LINE2, line)) # ---- find no, ndot, nddot ---- - satrec.no = satrec.no / xpdotp; # rad/min + satrec.no_kozai = satrec.no_kozai / 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); @@ -198,8 +199,6 @@ def twoline2rv(longstr1, longstr2, whichconst, afspc_mode=False): 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; """ // ---------------------------------------------------------------- @@ -225,9 +224,9 @@ def twoline2rv(longstr1, longstr2, whichconst, afspc_mode=False): int(sec_fraction * 1000000.0 // 1.0)) # ---------------- initialize the orbit at sgp4epoch ------------------- - sgp4init(whichconst, afspc_mode, satrec.satnum, satrec.jdsatepoch-2433281.5, satrec.bstar, - satrec.ecco, satrec.argpo, satrec.inclo, satrec.mo, satrec.no, - satrec.nodeo, satrec) + sgp4init(whichconst, opsmode, satrec.satnum, satrec.jdsatepoch-2433281.5, satrec.bstar, + satrec.ndot, satrec.nddot, satrec.ecco, satrec.argpo, satrec.inclo, satrec.mo, + satrec.no_kozai, satrec.nodeo, satrec) return satrec diff --git a/sgp4/propagation.py b/sgp4/propagation.py index c5228c4..c90de20 100644 --- a/sgp4/propagation.py +++ b/sgp4/propagation.py @@ -51,17 +51,21 @@ def partial_fake_jit(jit_this, **jit_options): * * companion code for * fundamentals of astrodynamics and applications -* 2007 +* 2013 * by david vallado * -* (w) 719-573-2600, email dvallado@agi.com +* (w) 719-573-2600, email dvallado@agi.com, davallado@gmail.com * * current : -* 30 Aug 10 david vallado -* delete unused variables in initl -* replace pow inetger 2, 3 with multiplies for speed +* 7 dec 15 david vallado +* fix jd, jdfrac * changes : -* 3 Nov 08 david vallado +* 3 nov 14 david vallado +* update to msvs2013 c++ +* 30 aug 10 david vallado +* delete unused variables in initl +* replace pow integer 2, 3 with multiplies for speed +* 3 nov 08 david vallado * put returns in for error codes * 29 sep 08 david vallado * fix atime for faster operation in dspace @@ -160,7 +164,7 @@ def partial_fake_jit(jit_this, **jit_options): ----------------------------------------------------------------------------*/ """ -def _dpper(satrec, inclo, init, ep, inclp, nodep, argpp, mp, afspc_mode): +def _dpper(satrec, inclo, init, ep, inclp, nodep, argpp, mp, opsmode): # Copy satellite attributes into local variables for convenience # and symmetry in writing formulae. @@ -282,14 +286,14 @@ def _dpper(satrec, inclo, init, ep, inclp, nodep, argpp, mp, afspc_mode): nodep = nodep % twopi if nodep >= 0.0 else -(-nodep % twopi) # sgp4fix for afspc written intrinsic functions # nodep used without a trigonometric function ahead - if nodep < 0.0 and afspc_mode: + if nodep < 0.0 and opsmode == 'a': nodep = nodep + twopi; xls = mp + argpp + pl + pgh + (cosip - pinc * sinip) * nodep xnoh = nodep; nodep = atan2(alfdp, betdp); # sgp4fix for afspc written intrinsic functions # nodep used without a trigonometric function ahead - if nodep < 0.0 and afspc_mode: + if nodep < 0.0 and opsmode == 'a': nodep = nodep + twopi; if fabs(xnoh - nodep) > pi: if nodep < xnoh: @@ -650,7 +654,9 @@ def _dscom( """ def _dsinit( - whichconst, + # sgp4fix no longer needed pass in xke + # whichconst, + xke, cosim, emsq, argpo, s1, s2, s3, s4, s5, sinim, ss1, ss2, ss3, ss4, ss5, sz1, @@ -682,8 +688,9 @@ def _dsinit( znl = 1.5835218e-4; zns = 1.19459e-5; - # sgp4fix identify constants and allow alternate values - xke = whichconst.xke + # sgp4fix identify constants and allow alternate values + # just xke is used here so pass it in rather than have multiple calls + # xke = whichconst.xke # -------------------- deep space initialization ------------ irez = 0; @@ -1092,11 +1099,13 @@ def _dspace( * author : david vallado 719-573-2600 28 jun 2005 * * inputs : +* satn - satellite number - not needed, placed in satrec +* xke - reciprocal of tumin +* j2 - j2 zonal harmonic * 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 @@ -1123,7 +1132,7 @@ def _dspace( * po - * * coupling : -* getgravconst +* getgravconst- no longer used * gstime - find greenwich sidereal time from the julian date * * references : @@ -1135,17 +1144,22 @@ def _dspace( """ def _initl( - satn, whichconst, + # not needeed. included in satrec if needed later + # satn, + # sgp4fix assin xke and j2 + # whichconst, + xke, j2, ecco, epoch, inclo, no, method, - afspc_mode, + opsmode, ): # sgp4fix use old way of finding gst # ----------------------- earth constants ---------------------- # sgp4fix identify constants and allow alternate values - tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 = whichconst + # only xke and j2 are used here so pass them in directly + # tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 = whichconst x2o3 = 2.0 / 3.0; # ------------- calculate auxillary epoch quantities ---------- @@ -1175,7 +1189,7 @@ def _initl( method = 'n'; # sgp4fix modern approach to finding sidereal time - if afspc_mode: + if opsmode == 'a': # sgp4fix use old way of finding gst # count integer number of days from 0 jan 1970 @@ -1212,7 +1226,7 @@ def _initl( * author : david vallado 719-573-2600 28 jun 2005 * * inputs : -* afspc_mode - use afspc or improved mode of operation +* 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 @@ -1287,9 +1301,9 @@ def _initl( """ def sgp4init( - whichconst, afspc_mode, satn, epoch, - xbstar, xecco, xargpo, - xinclo, xmo, xno, + whichconst, opsmode, satn, epoch, + xbstar, xndot, xnddot, xecco, xargpo, + xinclo, xmo, xno_kozai, xnodeo, satrec, ): @@ -1333,6 +1347,18 @@ def sgp4init( satrec.zmol = 0.0; satrec.zmos = 0.0; satrec.atime = 0.0; satrec.xli = 0.0; satrec.xni = 0.0; + # ------------------------ earth constants ----------------------- + # sgp4fix identify constants and allow alternate values + # this is now the only call for the constants + (satrec.tumin, satrec.mu, satrec.radiusearthkm, satrec.xke, + satrec.j2, satrec.j3, satrec.j4, satrec.j3oj2) = whichconst; + + # ------------------------------------------------------------------------- + + satrec.error = 0; + satrec.operationmode = opsmode; + satrec.satnum = satn; + """ // sgp4fix - note the following variables are also passed directly via satrec. // it is possible to streamline the sgp4init call by deleting the "x" @@ -1340,59 +1366,66 @@ def sgp4init( // include the additional assignments in case twoline2rv is not used. """ satrec.bstar = xbstar; + # sgp4fix allow additional parameters in the struct + satrec.ndot = xndot; + satrec.nddot = xnddot; satrec.ecco = xecco; satrec.argpo = xargpo; satrec.inclo = xinclo; satrec.mo = xmo; - satrec.no = xno; + # sgp4fix rename variables to clarify which mean motion is intended + satrec.no_kozai= xno_kozai; satrec.nodeo = xnodeo; - # sgp4fix add opsmode - satrec.afspc_mode = afspc_mode; + # single averaged mean elements + satrec.am = satrec.em = satrec.im = satrec.Om = satrec.mm = satrec.nm = 0.0; - # ------------------------ earth constants ----------------------- - # sgp4fix identify constants and allow alternate values - tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 = whichconst - ss = 78.0 / radiusearthkm + 1.0; + # ------------------------ earth constants ----------------------- */ + # sgp4fix identify constants and allow alternate values no longer needed + # getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 ); + ss = 78.0 / satrec.radiusearthkm + 1.0; # sgp4fix use multiply for speed instead of pow - qzms2ttemp = (120.0 - 78.0) / radiusearthkm; + qzms2ttemp = (120.0 - 78.0) / satrec.radiusearthkm; qzms2t = qzms2ttemp * qzms2ttemp * qzms2ttemp * qzms2ttemp; x2o3 = 2.0 / 3.0; satrec.init = 'y'; satrec.t = 0.0; + # sgp4fix remove satn as it is not needed in initl ( - satrec.no, + satrec.no_unkozai, method, ainv, ao, satrec.con41, con42, cosio, cosio2,eccsq, omeosq, posq, rp, rteosq,sinio , satrec.gsto, ) = _initl( - satn, whichconst, satrec.ecco, epoch, satrec.inclo, satrec.no, satrec.method, - satrec.afspc_mode + satrec.xke, satrec.j2, satrec.ecco, epoch, satrec.inclo, satrec.no_kozai, satrec.method, + satrec.operationmode ); - satrec.error = 0; + satrec.a = pow( satrec.no_unkozai*satrec.tumin , (-2.0/3.0) ); + satrec.alta = satrec.a*(1.0 + satrec.ecco) - 1.0; + satrec.altp = satrec.a*(1.0 - satrec.ecco) - 1.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 (rp < 1.0) + // { + // printf("# *** satn%d epoch elts sub-orbital ***\n", satn); + // satrec.error = 5; + // } """ - if omeosq >= 0.0 or satrec.no >= 0.0: + if omeosq >= 0.0 or satrec.no_unkozai >= 0.0: satrec.isimp = 0; - if rp < 220.0 / radiusearthkm + 1.0: + if rp < 220.0 / satrec.radiusearthkm + 1.0: satrec.isimp = 1; sfour = ss; qzms24 = qzms2t; - perige = (rp - 1.0) * radiusearthkm; + perige = (rp - 1.0) * satrec.radiusearthkm; # - for perigees below 156 km, s and qoms2t are altered - if perige < 156.0: @@ -1401,9 +1434,9 @@ def sgp4init( if perige < 98.0: sfour = 20.0; # sgp4fix use multiply for speed instead of pow - qzms24temp = (120.0 - sfour) / radiusearthkm; + qzms24temp = (120.0 - sfour) / satrec.radiusearthkm; qzms24 = qzms24temp * qzms24temp * qzms24temp * qzms24temp; - sfour = sfour / radiusearthkm + 1.0; + sfour = sfour / satrec.radiusearthkm + 1.0; pinvsq = 1.0 / posq; @@ -1414,27 +1447,27 @@ def sgp4init( 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 * + cc2 = coef1 * satrec.no_unkozai * (ao * (1.0 + 1.5 * etasq + eeta * + (4.0 + etasq)) + 0.375 * satrec.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; + cc3 = -2.0 * coef * tsi * satrec.j3oj2 * satrec.no_unkozai * sinio / satrec.ecco; satrec.x1mth2 = 1.0 - cosio2; - satrec.cc4 = 2.0* satrec.no * coef1 * ao * omeosq * \ + satrec.cc4 = 2.0* satrec.no_unkozai * coef1 * ao * omeosq * \ (satrec.eta * (2.0 + 0.5 * etasq) + satrec.ecco * - (0.5 + 2.0 * etasq) - j2 * tsi / (ao * psisq) * + (0.5 + 2.0 * etasq) - satrec.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 * \ + temp1 = 1.5 * satrec.j2 * pinvsq * satrec.no_unkozai; + temp2 = 0.5 * temp1 * satrec.j2 * pinvsq; + temp3 = -0.46875 * satrec.j4 * pinvsq * pinvsq * satrec.no_unkozai; + satrec.mdot = satrec.no_unkozai + 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) + @@ -1451,10 +1484,10 @@ def sgp4init( 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); + satrec.xlcof = -0.25 * satrec.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; + satrec.xlcof = -0.25 * satrec.j3oj2 * sinio * (3.0 + 5.0 * cosio) / temp4; + satrec.aycof = -0.5 * satrec.j3oj2 * sinio; # sgp4fix use multiply for speed instead of pow delmotemp = 1.0 + satrec.eta * cos(satrec.mo); satrec.delmo = delmotemp * delmotemp * delmotemp; @@ -1462,7 +1495,7 @@ def sgp4init( satrec.x7thm1 = 7.0 * cosio2 - 1.0; # --------------- deep space initialization ------------- - if 2*pi / satrec.no >= 225.0: + if 2*pi / satrec.no_unkozai >= 225.0: satrec.method = 'd'; satrec.isimp = 1; @@ -1489,7 +1522,7 @@ def sgp4init( satrec.zmos ) = _dscom( epoch, satrec.ecco, satrec.argpo, tc, satrec.inclo, satrec.nodeo, - satrec.no, + satrec.no_unkozai, satrec.e3, satrec.ee2, satrec.peo, satrec.pgho, satrec.pho, satrec.pinco, satrec.plo, satrec.se2, satrec.se3, @@ -1505,7 +1538,7 @@ def sgp4init( ) = _dpper( satrec, inclm, satrec.init, satrec.ecco, satrec.inclo, satrec.nodeo, satrec.argpo, satrec.mo, - satrec.afspc_mode + satrec.operationmode ); argpm = 0.0; @@ -1523,10 +1556,10 @@ def sgp4init( satrec.del1, satrec.del2, satrec.del3, satrec.xfact, satrec.xlamo, satrec.xli, satrec.xni ) = _dsinit( - whichconst, + satrec.xke, 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.gsto, satrec.mo, satrec.mdot, satrec.no_unkozai, 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, @@ -1675,8 +1708,8 @@ def sgp4(satrec, tsince, whichconst=None): twopi = 2.0 * pi; x2o3 = 2.0 / 3.0; # sgp4fix identify constants and allow alternate values - tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 = whichconst - vkmpersec = radiusearthkm * xke/60.0; + # tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 = whichconst + vkmpersec = satrec.radiusearthkm * satrec.xke/60.0; # --------------------- clear sgp4 error flag ----------------- satrec.t = tsince; @@ -1715,7 +1748,7 @@ def sgp4(satrec, tsince, whichconst=None): templ = templ + satrec.t3cof * t3 + t4 * (satrec.t4cof + satrec.t * satrec.t5cof); - nm = satrec.no; + nm = satrec.no_unkozai; em = satrec.ecco; inclm = satrec.inclo; if satrec.method == 'd': @@ -1734,7 +1767,7 @@ def sgp4(satrec, tsince, whichconst=None): satrec.dmdt, satrec.dnodt, satrec.domdt, satrec.argpo, satrec.argpdot, satrec.t, tc, satrec.gsto, satrec.xfact, satrec.xlamo, - satrec.no, satrec.atime, + satrec.no_unkozai, satrec.atime, em, argpm, inclm, satrec.xli, mm, satrec.xni, nodem, nm ); @@ -1747,8 +1780,8 @@ def sgp4(satrec, tsince, whichconst=None): # sgp4fix add return return false, false; - am = pow((xke / nm),x2o3) * tempa * tempa; - nm = xke / pow(am, 1.5); + am = pow((satrec.xke / nm),x2o3) * tempa * tempa; + nm = satrec.xke / pow(am, 1.5); em = em - tempe; # fix tolerance for error recognition @@ -1764,7 +1797,7 @@ def sgp4(satrec, tsince, whichconst=None): # sgp4fix fix tolerance to avoid a divide by zero if em < 1.0e-6: em = 1.0e-6; - mm = mm + satrec.no * templ; + mm = mm + satrec.no_unkozai * templ; xlm = mm + argpm + nodem; emsq = em * em; temp = 1.0 - emsq; @@ -1773,6 +1806,15 @@ def sgp4(satrec, tsince, whichconst=None): argpm = argpm % twopi xlm = xlm % twopi mm = (xlm - argpm - nodem) % twopi + + # sgp4fix recover singly averaged mean elements + satrec.am = am; + satrec.em = em; + satrec.im = inclm; + satrec.Om = nodem; + satrec.om = argpm; + satrec.mm = mm; + satrec.nm = nm; # ----------------- compute extra mean quantities ------------- sinim = sin(inclm); @@ -1790,7 +1832,7 @@ def sgp4(satrec, tsince, whichconst=None): ep, xincp, nodep, argpp, mp = _dpper( satrec, satrec.inclo, - 'n', ep, xincp, nodep, argpp, mp, satrec.afspc_mode + 'n', ep, xincp, nodep, argpp, mp, satrec.operationmode ); if xincp < 0.0: @@ -1811,12 +1853,12 @@ def sgp4(satrec, tsince, whichconst=None): sinip = sin(xincp); cosip = cos(xincp); - satrec.aycof = -0.5*j3oj2*sinip; + satrec.aycof = -0.5*satrec.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); + satrec.xlcof = -0.25 * satrec.j3oj2 * sinip * (3.0 + 5.0 * cosip) / (1.0 + cosip); else: - satrec.xlcof = -0.25 * j3oj2 * sinip * (3.0 + 5.0 * cosip) / temp4; + satrec.xlcof = -0.25 * satrec.j3oj2 * sinip * (3.0 + 5.0 * cosip) / temp4; axnl = ep * cos(argpp); temp = 1.0 / (am * (1.0 - ep * ep)); @@ -1867,7 +1909,7 @@ def sgp4(satrec, tsince, whichconst=None): sin2u = (cosu + cosu) * sinu; cos2u = 1.0 - 2.0 * sinu * sinu; temp = 1.0 / pl; - temp1 = 0.5 * j2 * temp; + temp1 = 0.5 * satrec.j2 * temp; temp2 = temp1 * temp; # -------------- update for short period periodics ------------ @@ -1883,9 +1925,9 @@ def sgp4(satrec, tsince, whichconst=None): 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; + mvt = rdotl - nm * temp1 * satrec.x1mth2 * sin2u / satrec.xke; rvdot = rvdotl + nm * temp1 * (satrec.x1mth2 * cos2u + - 1.5 * satrec.con41) / xke; + 1.5 * satrec.con41) / satrec.xke; # --------------------- orientation vectors ------------------- sinsu = sin(su); @@ -1904,7 +1946,7 @@ def sgp4(satrec, tsince, whichconst=None): vz = sini * cossu; # --------- position and velocity (in km and km/sec) ---------- - _mr = mrt * radiusearthkm + _mr = mrt * satrec.radiusearthkm r = (_mr * ux, _mr * uy, _mr * uz) v = ((mvt * ux + rvdot * vx) * vkmpersec, (mvt * uy + rvdot * vy) * vkmpersec, diff --git a/sgp4/tests.py b/sgp4/tests.py index 2de3a3e..e5145b1 100644 --- a/sgp4/tests.py +++ b/sgp4/tests.py @@ -132,7 +132,7 @@ def test_bad_tle_checksumx(self): self.assertRaises(ValueError, io.verify_checksum, bad) def test_bad_first_line(self): - with self.assertRaisesRegexp(ValueError, re.escape("""TLE format error + with self.assertRaisesRegex(ValueError, re.escape("""TLE format error The Two-Line Element (TLE) format was designed for punch cards, and so is very strict about the position of every period, space, and digit. @@ -144,7 +144,7 @@ def test_bad_first_line(self): io.twoline2rv(good1.replace('23 ', '234'), good2, wgs72) def test_bad_second_line(self): - with self.assertRaisesRegexp(ValueError, re.escape("""TLE format error + with self.assertRaisesRegex(ValueError, re.escape("""TLE format error The Two-Line Element (TLE) format was designed for punch cards, and so is very strict about the position of every period, space, and digit. @@ -157,7 +157,7 @@ def test_bad_second_line(self): def test_mismatched_lines(self): msg = "Object numbers in lines 1 and 2 do not match" - with self.assertRaisesRegexp(ValueError, re.escape(msg)): + with self.assertRaisesRegex(ValueError, re.escape(msg)): io.twoline2rv(good1, bad2, wgs72) From fd53dadc310fa0e03bf9d90b26562f643ac80a10 Mon Sep 17 00:00:00 2001 From: Chris Lewicki Date: Sun, 13 Oct 2019 12:26:04 -0700 Subject: [PATCH 2/4] Handle deprecated assertRaisesRegexp --- sgp4/tests.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sgp4/tests.py b/sgp4/tests.py index e5145b1..5bddede 100644 --- a/sgp4/tests.py +++ b/sgp4/tests.py @@ -20,6 +20,9 @@ error = 2e-7 rad = 180.0 / pi +# Handle deprecated assertRaisesRegexp, but allow its use Python 2.7 +if sys.version_info[:2] == (2, 7): + TestCase.assertRaisesRegex = TestCase.assertRaisesRegexp class Tests(TestCase): From e64fef9da1187717a9b08b60d1503181018b9d77 Mon Sep 17 00:00:00 2001 From: Chris Lewicki Date: Sun, 13 Oct 2019 12:30:34 -0700 Subject: [PATCH 3/4] Use assertRaisesRegexp for Python 2.6/2.7 --- sgp4/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sgp4/tests.py b/sgp4/tests.py index 5bddede..640b289 100644 --- a/sgp4/tests.py +++ b/sgp4/tests.py @@ -20,8 +20,8 @@ error = 2e-7 rad = 180.0 / pi -# Handle deprecated assertRaisesRegexp, but allow its use Python 2.7 -if sys.version_info[:2] == (2, 7): +# Handle deprecated assertRaisesRegexp, but allow its use Python 2.6 and 2.7 +if sys.version_info[:2] == (2, 7) or sys.version_info[:2] == (2, 6): TestCase.assertRaisesRegex = TestCase.assertRaisesRegexp class Tests(TestCase): From db9686ce31ff0482eb04f9eaf3b878f458cf87d5 Mon Sep 17 00:00:00 2001 From: Chris Lewicki Date: Sun, 13 Oct 2019 17:20:15 -0700 Subject: [PATCH 4/4] Fix initialization of averaged mean elements --- sgp4/propagation.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sgp4/propagation.py b/sgp4/propagation.py index c90de20..2810c94 100644 --- a/sgp4/propagation.py +++ b/sgp4/propagation.py @@ -1378,7 +1378,12 @@ def sgp4init( satrec.nodeo = xnodeo; # single averaged mean elements - satrec.am = satrec.em = satrec.im = satrec.Om = satrec.mm = satrec.nm = 0.0; + satrec.am = 0.0 + satrec.em = 0.0 + satrec.im = 0.0 + satrec.Om = 0.0 + satrec.mm = 0.0 + satrec.nm = 0.0 # ------------------------ earth constants ----------------------- */ # sgp4fix identify constants and allow alternate values no longer needed