diff --git a/CHANGELOG.md b/CHANGELOG.md index ae2d678..bde5d4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## Changelog +### 2.0.3 (2018-09-15) + +- `satrec` object is not cloned in `sgp4` and `sg4init` functions due to performance reasons. + ### 2.0.2 (2018-04-16) - [Wrong predictions for Molniya 3-47 orbits](https://github.com/shashwatak/satellite-js/issues/43) are fixed. Special diff --git a/package.json b/package.json index bd2a3a4..dae11ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "satellite.js", - "version": "2.0.2", + "version": "2.0.3", "description": "SGP4/SDP4 calculation library", "main": "lib/index.js", "jsnext:main": "dist/satellite.es.js", diff --git a/src/io.js b/src/io.js index 6afb332..de46cb2 100644 --- a/src/io.js +++ b/src/io.js @@ -144,7 +144,7 @@ export default function twoline2satrec(longstr1, longstr2) { satrec.jdsatepoch = jday(year, mon, day, hr, minute, sec); // ---------------- initialize the orbit at sgp4epoch ------------------- - return sgp4init(satrec, { + sgp4init(satrec, { opsmode, satn: satrec.satnum, epoch: satrec.jdsatepoch - 2433281.5, @@ -156,4 +156,6 @@ export default function twoline2satrec(longstr1, longstr2) { xno: satrec.no, xnodeo: satrec.nodeo, }); + + return satrec; } diff --git a/src/propagation/sgp4.js b/src/propagation/sgp4.js index 0e016b9..27d420c 100644 --- a/src/propagation/sgp4.js +++ b/src/propagation/sgp4.js @@ -98,7 +98,7 @@ import dspace from './dspace'; * vallado, crawford, hujsak, kelso 2006 ----------------------------------------------------------------------------*/ export default function sgp4(satrec, tsince) { - const rec = { ...satrec }; + /* eslint-disable no-param-reassign */ let coseo1; let sineo1; @@ -138,76 +138,76 @@ export default function sgp4(satrec, tsince) { const vkmpersec = (earthRadius * xke) / 60.0; // --------------------- clear sgp4 error flag ----------------- - rec.t = tsince; - rec.error = 0; + satrec.t = tsince; + satrec.error = 0; // ------- update for secular gravity and atmospheric drag ----- - const xmdf = rec.mo + (rec.mdot * rec.t); - const argpdf = rec.argpo + (rec.argpdot * rec.t); - const nodedf = rec.nodeo + (rec.nodedot * rec.t); + const xmdf = satrec.mo + (satrec.mdot * satrec.t); + const argpdf = satrec.argpo + (satrec.argpdot * satrec.t); + const nodedf = satrec.nodeo + (satrec.nodedot * satrec.t); argpm = argpdf; mm = xmdf; - const t2 = rec.t * rec.t; - nodem = nodedf + (rec.nodecf * t2); - tempa = 1.0 - (rec.cc1 * rec.t); - tempe = rec.bstar * rec.cc4 * rec.t; - templ = rec.t2cof * t2; - - if (rec.isimp !== 1) { - delomg = rec.omgcof * rec.t; + const t2 = satrec.t * satrec.t; + nodem = nodedf + (satrec.nodecf * t2); + tempa = 1.0 - (satrec.cc1 * satrec.t); + tempe = satrec.bstar * satrec.cc4 * satrec.t; + templ = satrec.t2cof * t2; + + if (satrec.isimp !== 1) { + delomg = satrec.omgcof * satrec.t; // sgp4fix use mutliply for speed instead of pow - const delmtemp = 1.0 + (rec.eta * Math.cos(xmdf)); - delm = rec.xmcof * ((delmtemp * delmtemp * delmtemp) - rec.delmo); + const delmtemp = 1.0 + (satrec.eta * Math.cos(xmdf)); + delm = satrec.xmcof * ((delmtemp * delmtemp * delmtemp) - satrec.delmo); temp = delomg + delm; mm = xmdf + temp; argpm = argpdf - temp; - t3 = t2 * rec.t; - t4 = t3 * rec.t; - tempa = tempa - (rec.d2 * t2) - (rec.d3 * t3) - (rec.d4 * t4); - tempe += rec.bstar * rec.cc5 * (Math.sin(mm) - rec.sinmao); - templ = templ + (rec.t3cof * t3) + (t4 * (rec.t4cof + (rec.t * rec.t5cof))); + t3 = t2 * satrec.t; + t4 = t3 * satrec.t; + tempa = tempa - (satrec.d2 * t2) - (satrec.d3 * t3) - (satrec.d4 * t4); + tempe += satrec.bstar * satrec.cc5 * (Math.sin(mm) - satrec.sinmao); + templ = templ + (satrec.t3cof * t3) + (t4 * (satrec.t4cof + (satrec.t * satrec.t5cof))); } - nm = rec.no; - let em = rec.ecco; - inclm = rec.inclo; - if (rec.method === 'd') { - tc = rec.t; + nm = satrec.no; + let em = satrec.ecco; + inclm = satrec.inclo; + if (satrec.method === 'd') { + tc = satrec.t; const dspaceOptions = { - irez: rec.irez, - d2201: rec.d2201, - d2211: rec.d2211, - d3210: rec.d3210, - d3222: rec.d3222, - d4410: rec.d4410, - d4422: rec.d4422, - d5220: rec.d5220, - d5232: rec.d5232, - d5421: rec.d5421, - d5433: rec.d5433, - dedt: rec.dedt, - del1: rec.del1, - del2: rec.del2, - del3: rec.del3, - didt: rec.didt, - dmdt: rec.dmdt, - dnodt: rec.dnodt, - domdt: rec.domdt, - argpo: rec.argpo, - argpdot: rec.argpdot, - t: rec.t, + irez: satrec.irez, + d2201: satrec.d2201, + d2211: satrec.d2211, + d3210: satrec.d3210, + d3222: satrec.d3222, + d4410: satrec.d4410, + d4422: satrec.d4422, + d5220: satrec.d5220, + d5232: satrec.d5232, + d5421: satrec.d5421, + d5433: satrec.d5433, + dedt: satrec.dedt, + del1: satrec.del1, + del2: satrec.del2, + del3: satrec.del3, + didt: satrec.didt, + dmdt: satrec.dmdt, + dnodt: satrec.dnodt, + domdt: satrec.domdt, + argpo: satrec.argpo, + argpdot: satrec.argpdot, + t: satrec.t, tc, - gsto: rec.gsto, - xfact: rec.xfact, - xlamo: rec.xlamo, - no: rec.no, - atime: rec.atime, + gsto: satrec.gsto, + xfact: satrec.xfact, + xlamo: satrec.xlamo, + no: satrec.no, + atime: satrec.atime, em, argpm, inclm, - xli: rec.xli, + xli: satrec.xli, mm, - xni: rec.xni, + xni: satrec.xni, nodem, nm, }; @@ -226,7 +226,7 @@ export default function sgp4(satrec, tsince) { if (nm <= 0.0) { // printf("// error nm %f\n", nm); - rec.error = 2; + satrec.error = 2; // sgp4fix add return return [false, false]; } @@ -239,7 +239,7 @@ export default function sgp4(satrec, tsince) { // sgp4fix am is fixed from the previous nm check if (em >= 1.0 || em < -0.001) { // || (am < 0.95) // printf("// error em %f\n", em); - rec.error = 1; + satrec.error = 1; // sgp4fix to return if there is an error in eccentricity return [false, false]; } @@ -248,7 +248,7 @@ export default function sgp4(satrec, tsince) { if (em < 1.0e-6) { em = 1.0e-6; } - mm += rec.no * templ; + mm += satrec.no * templ; xlm = mm + argpm + nodem; nodem %= twoPi; @@ -268,19 +268,19 @@ export default function sgp4(satrec, tsince) { mp = mm; sinip = sinim; cosip = cosim; - if (rec.method === 'd') { + if (satrec.method === 'd') { const dpperParameters = { - inclo: rec.inclo, + inclo: satrec.inclo, init: 'n', ep, inclp: xincp, nodep, argpp, mp, - opsmode: rec.operationmod, + opsmode: satrec.operationmod, }; - const dpperResult = dpper(rec, dpperParameters); + const dpperResult = dpper(satrec, dpperParameters); ({ ep, @@ -298,30 +298,30 @@ export default function sgp4(satrec, tsince) { } if (ep < 0.0 || ep > 1.0) { // printf("// error ep %f\n", ep); - rec.error = 3; + satrec.error = 3; // sgp4fix add return return [false, false]; } } // -------------------- long period periodics ------------------ - if (rec.method === 'd') { + if (satrec.method === 'd') { sinip = Math.sin(xincp); cosip = Math.cos(xincp); - rec.aycof = -0.5 * j3oj2 * sinip; + satrec.aycof = -0.5 * j3oj2 * sinip; // sgp4fix for divide by zero for xincp = 180 deg if (Math.abs(cosip + 1.0) > 1.5e-12) { - rec.xlcof = (-0.25 * j3oj2 * sinip * (3.0 + (5.0 * cosip))) / (1.0 + cosip); + satrec.xlcof = (-0.25 * j3oj2 * sinip * (3.0 + (5.0 * cosip))) / (1.0 + cosip); } else { - rec.xlcof = (-0.25 * j3oj2 * sinip * (3.0 + (5.0 * cosip))) / temp4; + satrec.xlcof = (-0.25 * j3oj2 * sinip * (3.0 + (5.0 * cosip))) / temp4; } } const axnl = ep * Math.cos(argpp); temp = 1.0 / (am * (1.0 - (ep * ep))); - const aynl = (ep * Math.sin(argpp)) + (temp * rec.aycof); - const xl = mp + argpp + nodep + (temp * rec.xlcof * axnl); + const aynl = (ep * Math.sin(argpp)) + (temp * satrec.aycof); + const xl = mp + argpp + nodep + (temp * satrec.xlcof * axnl); // --------------------- solve kepler's equation --------------- const u = (xl - nodep) % twoPi; @@ -354,7 +354,7 @@ export default function sgp4(satrec, tsince) { const pl = am * (1.0 - el2); if (pl < 0.0) { // printf("// error pl %f\n", pl); - rec.error = 4; + satrec.error = 4; // sgp4fix add return return [false, false]; } @@ -374,20 +374,20 @@ export default function sgp4(satrec, tsince) { const temp2 = temp1 * temp; // -------------- update for short period periodics ------------ - if (rec.method === 'd') { + if (satrec.method === 'd') { cosisq = cosip * cosip; - rec.con41 = (3.0 * cosisq) - 1.0; - rec.x1mth2 = 1.0 - cosisq; - rec.x7thm1 = (7.0 * cosisq) - 1.0; + satrec.con41 = (3.0 * cosisq) - 1.0; + satrec.x1mth2 = 1.0 - cosisq; + satrec.x7thm1 = (7.0 * cosisq) - 1.0; } - const mrt = (rl * (1.0 - (1.5 * temp2 * betal * rec.con41))) + - (0.5 * temp1 * rec.x1mth2 * cos2u); - su -= 0.25 * temp2 * rec.x7thm1 * sin2u; + const mrt = (rl * (1.0 - (1.5 * temp2 * betal * satrec.con41))) + + (0.5 * temp1 * satrec.x1mth2 * cos2u); + su -= 0.25 * temp2 * satrec.x7thm1 * sin2u; const xnode = nodep + (1.5 * temp2 * cosip * sin2u); const xinc = xincp + (1.5 * temp2 * cosip * sinip * cos2u); - const mvt = rdotl - ((nm * temp1 * rec.x1mth2 * sin2u) / xke); - const rvdot = rvdotl + ((nm * temp1 * ((rec.x1mth2 * cos2u) + (1.5 * rec.con41))) / xke); + const mvt = rdotl - ((nm * temp1 * satrec.x1mth2 * sin2u) / xke); + const rvdot = rvdotl + ((nm * temp1 * ((satrec.x1mth2 * cos2u) + (1.5 * satrec.con41))) / xke); // --------------------- orientation vectors ------------------- const sinsu = Math.sin(su); @@ -420,17 +420,17 @@ export default function sgp4(satrec, tsince) { // sgp4fix for decaying satellites if (mrt < 1.0) { // printf("// decay condition %11.6f \n",mrt); - rec.error = 6; + satrec.error = 6; return { position: false, velocity: false, - satrec: rec, }; } return { position: r, velocity: v, - satrec: rec, }; + + /* eslint-enable no-param-reassign */ } diff --git a/src/propagation/sgp4init.js b/src/propagation/sgp4init.js index 268d6c1..f0a1db0 100644 --- a/src/propagation/sgp4init.js +++ b/src/propagation/sgp4init.js @@ -95,7 +95,7 @@ import sgp4 from './sgp4'; * vallado, crawford, hujsak, kelso 2006 ----------------------------------------------------------------------------*/ export default function sgp4init(satrec, options) { - const rec = { ...satrec }; + /* eslint-disable no-param-reassign */ const { opsmode, @@ -174,52 +174,52 @@ export default function sgp4init(satrec, options) { const temp4 = 1.5e-12; // ----------- set all near earth variables to zero ------------ - rec.isimp = 0; rec.method = 'n'; rec.aycof = 0.0; - rec.con41 = 0.0; rec.cc1 = 0.0; rec.cc4 = 0.0; - rec.cc5 = 0.0; rec.d2 = 0.0; rec.d3 = 0.0; - rec.d4 = 0.0; rec.delmo = 0.0; rec.eta = 0.0; - rec.argpdot = 0.0; rec.omgcof = 0.0; rec.sinmao = 0.0; - rec.t = 0.0; rec.t2cof = 0.0; rec.t3cof = 0.0; - rec.t4cof = 0.0; rec.t5cof = 0.0; rec.x1mth2 = 0.0; - rec.x7thm1 = 0.0; rec.mdot = 0.0; rec.nodedot = 0.0; - rec.xlcof = 0.0; rec.xmcof = 0.0; rec.nodecf = 0.0; + 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 ------------ - rec.irez = 0; rec.d2201 = 0.0; rec.d2211 = 0.0; - rec.d3210 = 0.0; rec.d3222 = 0.0; rec.d4410 = 0.0; - rec.d4422 = 0.0; rec.d5220 = 0.0; rec.d5232 = 0.0; - rec.d5421 = 0.0; rec.d5433 = 0.0; rec.dedt = 0.0; - rec.del1 = 0.0; rec.del2 = 0.0; rec.del3 = 0.0; - rec.didt = 0.0; rec.dmdt = 0.0; rec.dnodt = 0.0; - rec.domdt = 0.0; rec.e3 = 0.0; rec.ee2 = 0.0; - rec.peo = 0.0; rec.pgho = 0.0; rec.pho = 0.0; - rec.pinco = 0.0; rec.plo = 0.0; rec.se2 = 0.0; - rec.se3 = 0.0; rec.sgh2 = 0.0; rec.sgh3 = 0.0; - rec.sgh4 = 0.0; rec.sh2 = 0.0; rec.sh3 = 0.0; - rec.si2 = 0.0; rec.si3 = 0.0; rec.sl2 = 0.0; - rec.sl3 = 0.0; rec.sl4 = 0.0; rec.gsto = 0.0; - rec.xfact = 0.0; rec.xgh2 = 0.0; rec.xgh3 = 0.0; - rec.xgh4 = 0.0; rec.xh2 = 0.0; rec.xh3 = 0.0; - rec.xi2 = 0.0; rec.xi3 = 0.0; rec.xl2 = 0.0; - rec.xl3 = 0.0; rec.xl4 = 0.0; rec.xlamo = 0.0; - rec.zmol = 0.0; rec.zmos = 0.0; rec.atime = 0.0; - rec.xli = 0.0; rec.xni = 0.0; - - // sgp4fix - note the following variables are also passed directly via rec. + 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 rec.* values first. we + // variables, but the user would need to set the satrec.* values first. we // include the additional assignments in case twoline2rv is not used. - rec.bstar = xbstar; - rec.ecco = xecco; - rec.argpo = xargpo; - rec.inclo = xinclo; - rec.mo = xmo; - rec.no = xno; - rec.nodeo = xnodeo; + satrec.bstar = xbstar; + satrec.ecco = xecco; + satrec.argpo = xargpo; + satrec.inclo = xinclo; + satrec.mo = xmo; + satrec.no = xno; + satrec.nodeo = xnodeo; // sgp4fix add opsmode - rec.operationmode = opsmode; + satrec.operationmode = opsmode; // ------------------------ earth constants ----------------------- // sgp4fix identify constants and allow alternate values @@ -229,19 +229,19 @@ export default function sgp4init(satrec, options) { const qzms2ttemp = (120.0 - 78.0) / earthRadius; const qzms2t = qzms2ttemp * qzms2ttemp * qzms2ttemp * qzms2ttemp; - rec.init = 'y'; - rec.t = 0.0; + satrec.init = 'y'; + satrec.t = 0.0; const initlOptions = { satn, - ecco: rec.ecco, + ecco: satrec.ecco, epoch, - inclo: rec.inclo, - no: rec.no, + inclo: satrec.inclo, + no: satrec.no, - method: rec.method, - opsmode: rec.operationmode, + method: satrec.method, + opsmode: satrec.operationmode, }; const initlResult = initl(initlOptions); @@ -259,10 +259,10 @@ export default function sgp4init(satrec, options) { sinio, } = initlResult; - rec.no = initlResult.no; - rec.con41 = initlResult.con41; - rec.gsto = initlResult.gsto; - rec.error = 0; + satrec.no = initlResult.no; + satrec.con41 = initlResult.con41; + satrec.gsto = initlResult.gsto; + satrec.error = 0; // sgp4fix remove this check as it is unnecessary // the mrt check in sgp4 handles decaying satellite cases even if the starting @@ -270,13 +270,13 @@ export default function sgp4init(satrec, options) { // if (rp < 1.0) // { // printf("// *** satn%d epoch elts sub-orbital ***\n", satn); - // rec.error = 5; + // satrec.error = 5; // } - if (omeosq >= 0.0 || rec.no >= 0.0) { - rec.isimp = 0; + if (omeosq >= 0.0 || satrec.no >= 0.0) { + satrec.isimp = 0; if ((rp < 220.0 / earthRadius) + 1.0) { - rec.isimp = 1; + satrec.isimp = 1; } sfour = ss; qzms24 = qzms2t; @@ -297,150 +297,150 @@ export default function sgp4init(satrec, options) { pinvsq = 1.0 / posq; tsi = 1.0 / (ao - sfour); - rec.eta = ao * rec.ecco * tsi; - etasq = rec.eta * rec.eta; - eeta = rec.ecco * rec.eta; + satrec.eta = ao * satrec.ecco * tsi; + etasq = satrec.eta * satrec.eta; + eeta = satrec.ecco * satrec.eta; psisq = Math.abs(1.0 - etasq); coef = qzms24 * (tsi ** 4.0); coef1 = coef / (psisq ** 3.5); - cc2 = coef1 * rec.no * ((ao * (1.0 + (1.5 * etasq) + (eeta * (4.0 + etasq)))) + - (((0.375 * j2 * tsi) / psisq) * rec.con41 * + 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))))); - rec.cc1 = rec.bstar * cc2; + satrec.cc1 = satrec.bstar * cc2; cc3 = 0.0; - if (rec.ecco > 1.0e-4) { - cc3 = (-2.0 * coef * tsi * j3oj2 * rec.no * sinio) / rec.ecco; + if (satrec.ecco > 1.0e-4) { + cc3 = (-2.0 * coef * tsi * j3oj2 * satrec.no * sinio) / satrec.ecco; } - rec.x1mth2 = 1.0 - cosio2; - rec.cc4 = 2.0 * rec.no * coef1 * ao * omeosq * ( - ((rec.eta * (2.0 + (0.5 * etasq))) + - (rec.ecco * (0.5 + (2.0 * etasq)))) - + 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 * rec.con41 * ((1.0 - (2.0 * eeta)) + (etasq * (1.5 - (0.5 * eeta))))) + - (0.75 * rec.x1mth2 * + ((-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))) * - Math.cos(2.0 * rec.argpo)))) + Math.cos(2.0 * satrec.argpo)))) ); - rec.cc5 = 2.0 * coef1 * ao * omeosq * (1.0 + (2.75 * (etasq + eeta)) + (eeta * etasq)); + satrec.cc5 = 2.0 * coef1 * ao * omeosq * (1.0 + (2.75 * (etasq + eeta)) + (eeta * etasq)); cosio4 = cosio2 * cosio2; - temp1 = 1.5 * j2 * pinvsq * rec.no; + temp1 = 1.5 * j2 * pinvsq * satrec.no; temp2 = 0.5 * temp1 * j2 * pinvsq; - temp3 = -0.46875 * j4 * pinvsq * pinvsq * rec.no; - rec.mdot = rec.no + (0.5 * temp1 * rteosq * rec.con41) + + 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))); - rec.argpdot = (-0.5 * temp1 * con42) + + 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; - rec.nodedot = xhdot1 + (((0.5 * temp2 * (4.0 - (19.0 * cosio2))) + + satrec.nodedot = xhdot1 + (((0.5 * temp2 * (4.0 - (19.0 * cosio2))) + (2.0 * temp3 * (3.0 - (7.0 * cosio2)))) * cosio); - xpidot = rec.argpdot + rec.nodedot; - rec.omgcof = rec.bstar * cc3 * Math.cos(rec.argpo); - rec.xmcof = 0.0; - if (rec.ecco > 1.0e-4) { - rec.xmcof = (-x2o3 * coef * rec.bstar) / eeta; + xpidot = satrec.argpdot + satrec.nodedot; + satrec.omgcof = satrec.bstar * cc3 * Math.cos(satrec.argpo); + satrec.xmcof = 0.0; + if (satrec.ecco > 1.0e-4) { + satrec.xmcof = (-x2o3 * coef * satrec.bstar) / eeta; } - rec.nodecf = 3.5 * omeosq * xhdot1 * rec.cc1; - rec.t2cof = 1.5 * rec.cc1; + satrec.nodecf = 3.5 * omeosq * xhdot1 * satrec.cc1; + satrec.t2cof = 1.5 * satrec.cc1; // sgp4fix for divide by zero with xinco = 180 deg if (Math.abs(cosio + 1.0) > 1.5e-12) { - rec.xlcof = (-0.25 * j3oj2 * sinio * (3.0 + (5.0 * cosio))) / (1.0 + cosio); + satrec.xlcof = (-0.25 * j3oj2 * sinio * (3.0 + (5.0 * cosio))) / (1.0 + cosio); } else { - rec.xlcof = (-0.25 * j3oj2 * sinio * (3.0 + (5.0 * cosio))) / temp4; + satrec.xlcof = (-0.25 * j3oj2 * sinio * (3.0 + (5.0 * cosio))) / temp4; } - rec.aycof = -0.5 * j3oj2 * sinio; + satrec.aycof = -0.5 * j3oj2 * sinio; // sgp4fix use multiply for speed instead of pow - const delmotemp = 1.0 + (rec.eta * Math.cos(rec.mo)); - rec.delmo = delmotemp * delmotemp * delmotemp; - rec.sinmao = Math.sin(rec.mo); - rec.x7thm1 = (7.0 * cosio2) - 1.0; + const delmotemp = 1.0 + (satrec.eta * Math.cos(satrec.mo)); + satrec.delmo = delmotemp * delmotemp * delmotemp; + satrec.sinmao = Math.sin(satrec.mo); + satrec.x7thm1 = (7.0 * cosio2) - 1.0; // --------------- deep space initialization ------------- - if ((2 * pi) / rec.no >= 225.0) { - rec.method = 'd'; - rec.isimp = 1; + if ((2 * pi) / satrec.no >= 225.0) { + satrec.method = 'd'; + satrec.isimp = 1; tc = 0.0; - inclm = rec.inclo; + inclm = satrec.inclo; const dscomOptions = { epoch, - ep: rec.ecco, - argpp: rec.argpo, + ep: satrec.ecco, + argpp: satrec.argpo, tc, - inclp: rec.inclo, - nodep: rec.nodeo, + inclp: satrec.inclo, + nodep: satrec.nodeo, - np: rec.no, + np: satrec.no, - e3: rec.e3, - ee2: rec.ee2, + e3: satrec.e3, + ee2: satrec.ee2, - peo: rec.peo, - pgho: rec.pgho, - pho: rec.pho, - pinco: rec.pinco, + peo: satrec.peo, + pgho: satrec.pgho, + pho: satrec.pho, + pinco: satrec.pinco, - plo: rec.plo, - se2: rec.se2, - se3: rec.se3, + plo: satrec.plo, + se2: satrec.se2, + se3: satrec.se3, - sgh2: rec.sgh2, - sgh3: rec.sgh3, - sgh4: rec.sgh4, + sgh2: satrec.sgh2, + sgh3: satrec.sgh3, + sgh4: satrec.sgh4, - sh2: rec.sh2, - sh3: rec.sh3, - si2: rec.si2, - si3: rec.si3, + sh2: satrec.sh2, + sh3: satrec.sh3, + si2: satrec.si2, + si3: satrec.si3, - sl2: rec.sl2, - sl3: rec.sl3, - sl4: rec.sl4, + sl2: satrec.sl2, + sl3: satrec.sl3, + sl4: satrec.sl4, - xgh2: rec.xgh2, - xgh3: rec.xgh3, - xgh4: rec.xgh4, - xh2: rec.xh2, + xgh2: satrec.xgh2, + xgh3: satrec.xgh3, + xgh4: satrec.xgh4, + xh2: satrec.xh2, - xh3: rec.xh3, - xi2: rec.xi2, - xi3: rec.xi3, - xl2: rec.xl2, + xh3: satrec.xh3, + xi2: satrec.xi2, + xi3: satrec.xi3, + xl2: satrec.xl2, - xl3: rec.xl3, - xl4: rec.xl4, + xl3: satrec.xl3, + xl4: satrec.xl4, - zmol: rec.zmol, - zmos: rec.zmos, + zmol: satrec.zmol, + zmos: satrec.zmos, }; const dscomResult = dscom(dscomOptions); - rec.e3 = dscomResult.e3; - rec.ee2 = dscomResult.ee2; + satrec.e3 = dscomResult.e3; + satrec.ee2 = dscomResult.ee2; - rec.peo = dscomResult.peo; - rec.pgho = dscomResult.pgho; - rec.pho = dscomResult.pho; + satrec.peo = dscomResult.peo; + satrec.pgho = dscomResult.pgho; + satrec.pho = dscomResult.pho; - rec.pinco = dscomResult.pinco; - rec.plo = dscomResult.plo; - rec.se2 = dscomResult.se2; - rec.se3 = dscomResult.se3; + satrec.pinco = dscomResult.pinco; + satrec.plo = dscomResult.plo; + satrec.se2 = dscomResult.se2; + satrec.se3 = dscomResult.se3; - rec.sgh2 = dscomResult.sgh2; - rec.sgh3 = dscomResult.sgh3; - rec.sgh4 = dscomResult.sgh4; - rec.sh2 = dscomResult.sh2; - rec.sh3 = dscomResult.sh3; + satrec.sgh2 = dscomResult.sgh2; + satrec.sgh3 = dscomResult.sgh3; + satrec.sgh4 = dscomResult.sgh4; + satrec.sh2 = dscomResult.sh2; + satrec.sh3 = dscomResult.sh3; - rec.si2 = dscomResult.si2; - rec.si3 = dscomResult.si3; - rec.sl2 = dscomResult.sl2; - rec.sl3 = dscomResult.sl3; - rec.sl4 = dscomResult.sl4; + satrec.si2 = dscomResult.si2; + satrec.si3 = dscomResult.si3; + satrec.sl2 = dscomResult.sl2; + satrec.sl3 = dscomResult.sl3; + satrec.sl4 = dscomResult.sl4; ({ sinim, @@ -467,18 +467,18 @@ export default function sgp4init(satrec, options) { sz33, } = dscomResult); - rec.xgh2 = dscomResult.xgh2; - rec.xgh3 = dscomResult.xgh3; - rec.xgh4 = dscomResult.xgh4; - rec.xh2 = dscomResult.xh2; - rec.xh3 = dscomResult.xh3; - rec.xi2 = dscomResult.xi2; - rec.xi3 = dscomResult.xi3; - rec.xl2 = dscomResult.xl2; - rec.xl3 = dscomResult.xl3; - rec.xl4 = dscomResult.xl4; - rec.zmol = dscomResult.zmol; - rec.zmos = dscomResult.zmos; + satrec.xgh2 = dscomResult.xgh2; + satrec.xgh3 = dscomResult.xgh3; + satrec.xgh4 = dscomResult.xgh4; + satrec.xh2 = dscomResult.xh2; + satrec.xh3 = dscomResult.xh3; + satrec.xi2 = dscomResult.xi2; + satrec.xi3 = dscomResult.xi3; + satrec.xl2 = dscomResult.xl2; + satrec.xl3 = dscomResult.xl3; + satrec.xl4 = dscomResult.xl4; + satrec.zmol = dscomResult.zmol; + satrec.zmos = dscomResult.zmos; ({ nm, @@ -494,22 +494,22 @@ export default function sgp4init(satrec, options) { const dpperOptions = { inclo: inclm, - init: rec.init, - ep: rec.ecco, - inclp: rec.inclo, - nodep: rec.nodeo, - argpp: rec.argpo, - mp: rec.mo, - opsmode: rec.operationmode, + init: satrec.init, + ep: satrec.ecco, + inclp: satrec.inclo, + nodep: satrec.nodeo, + argpp: satrec.argpo, + mp: satrec.mo, + opsmode: satrec.operationmode, }; - const dpperResult = dpper(rec, dpperOptions); + const dpperResult = dpper(satrec, dpperOptions); - rec.ecco = dpperResult.ep; - rec.inclo = dpperResult.inclp; - rec.nodeo = dpperResult.nodep; - rec.argpo = dpperResult.argpp; - rec.mo = dpperResult.mp; + satrec.ecco = dpperResult.ep; + satrec.inclo = dpperResult.inclp; + satrec.nodeo = dpperResult.nodep; + satrec.argpo = dpperResult.argpp; + satrec.mo = dpperResult.mp; argpm = 0.0; nodem = 0.0; @@ -518,7 +518,7 @@ export default function sgp4init(satrec, options) { const dsinitOptions = { cosim, emsq, - argpo: rec.argpo, + argpo: satrec.argpo, s1, s2, s3, @@ -538,14 +538,14 @@ export default function sgp4init(satrec, options) { sz23, sz31, sz33, - t: rec.t, + t: satrec.t, tc, - gsto: rec.gsto, - mo: rec.mo, - mdot: rec.mdot, - no: rec.no, - nodeo: rec.nodeo, - nodedot: rec.nodedot, + gsto: satrec.gsto, + mo: satrec.mo, + mdot: satrec.mdot, + no: satrec.no, + nodeo: satrec.nodeo, + nodedot: satrec.nodedot, xpidot, z1, z3, @@ -555,7 +555,7 @@ export default function sgp4init(satrec, options) { z23, z31, z33, - ecco: rec.ecco, + ecco: satrec.ecco, eccsq, em, argpm, @@ -563,91 +563,91 @@ export default function sgp4init(satrec, options) { mm, nm, nodem, - irez: rec.irez, - atime: rec.atime, - d2201: rec.d2201, - d2211: rec.d2211, - d3210: rec.d3210, - d3222: rec.d3222, - d4410: rec.d4410, - d4422: rec.d4422, - d5220: rec.d5220, - d5232: rec.d5232, - d5421: rec.d5421, - d5433: rec.d5433, - dedt: rec.dedt, - didt: rec.didt, - dmdt: rec.dmdt, - dnodt: rec.dnodt, - domdt: rec.domdt, - del1: rec.del1, - del2: rec.del2, - del3: rec.del3, - xfact: rec.xfact, - xlamo: rec.xlamo, - xli: rec.xli, - xni: rec.xni, + irez: satrec.irez, + atime: satrec.atime, + d2201: satrec.d2201, + d2211: satrec.d2211, + d3210: satrec.d3210, + d3222: satrec.d3222, + d4410: satrec.d4410, + d4422: satrec.d4422, + d5220: satrec.d5220, + d5232: satrec.d5232, + d5421: satrec.d5421, + d5433: satrec.d5433, + dedt: satrec.dedt, + didt: satrec.didt, + dmdt: satrec.dmdt, + dnodt: satrec.dnodt, + domdt: satrec.domdt, + del1: satrec.del1, + del2: satrec.del2, + del3: satrec.del3, + xfact: satrec.xfact, + xlamo: satrec.xlamo, + xli: satrec.xli, + xni: satrec.xni, }; const dsinitResult = dsinit(dsinitOptions); - rec.irez = dsinitResult.irez; - rec.atime = dsinitResult.atime; - rec.d2201 = dsinitResult.d2201; - rec.d2211 = dsinitResult.d2211; - - rec.d3210 = dsinitResult.d3210; - rec.d3222 = dsinitResult.d3222; - rec.d4410 = dsinitResult.d4410; - rec.d4422 = dsinitResult.d4422; - rec.d5220 = dsinitResult.d5220; - - rec.d5232 = dsinitResult.d5232; - rec.d5421 = dsinitResult.d5421; - rec.d5433 = dsinitResult.d5433; - rec.dedt = dsinitResult.dedt; - rec.didt = dsinitResult.didt; - - rec.dmdt = dsinitResult.dmdt; - rec.dnodt = dsinitResult.dnodt; - rec.domdt = dsinitResult.domdt; - rec.del1 = dsinitResult.del1; - - rec.del2 = dsinitResult.del2; - rec.del3 = dsinitResult.del3; - rec.xfact = dsinitResult.xfact; - rec.xlamo = dsinitResult.xlamo; - rec.xli = dsinitResult.xli; - - rec.xni = dsinitResult.xni; + satrec.irez = dsinitResult.irez; + satrec.atime = dsinitResult.atime; + satrec.d2201 = dsinitResult.d2201; + satrec.d2211 = dsinitResult.d2211; + + satrec.d3210 = dsinitResult.d3210; + satrec.d3222 = dsinitResult.d3222; + satrec.d4410 = dsinitResult.d4410; + satrec.d4422 = dsinitResult.d4422; + satrec.d5220 = dsinitResult.d5220; + + satrec.d5232 = dsinitResult.d5232; + satrec.d5421 = dsinitResult.d5421; + satrec.d5433 = dsinitResult.d5433; + satrec.dedt = dsinitResult.dedt; + satrec.didt = dsinitResult.didt; + + satrec.dmdt = dsinitResult.dmdt; + satrec.dnodt = dsinitResult.dnodt; + satrec.domdt = dsinitResult.domdt; + satrec.del1 = dsinitResult.del1; + + satrec.del2 = dsinitResult.del2; + satrec.del3 = dsinitResult.del3; + satrec.xfact = dsinitResult.xfact; + satrec.xlamo = dsinitResult.xlamo; + satrec.xli = dsinitResult.xli; + + satrec.xni = dsinitResult.xni; } // ----------- set variables if not deep space ----------- - if (rec.isimp !== 1) { - cc1sq = rec.cc1 * rec.cc1; - rec.d2 = 4.0 * ao * tsi * cc1sq; - temp = (rec.d2 * tsi * rec.cc1) / 3.0; - rec.d3 = ((17.0 * ao) + sfour) * temp; - rec.d4 = 0.5 * temp * ao * tsi * ((221.0 * ao) + (31.0 * sfour)) * rec.cc1; - rec.t3cof = rec.d2 + (2.0 * cc1sq); - rec.t4cof = 0.25 * ((3.0 * rec.d3) + (rec.cc1 * ((12.0 * rec.d2) + (10.0 * cc1sq)))); - rec.t5cof = 0.2 * ( - (3.0 * rec.d4) + - (12.0 * rec.cc1 * rec.d3) + - (6.0 * rec.d2 * rec.d2) + - (15.0 * cc1sq * ((2.0 * rec.d2) + cc1sq)) + 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)) ); } /* finally propogate to zero epoch to initialize all others. */ // sgp4fix take out check to let satellites process until they are actually below earth surface - // if(rec.error == 0) + // if(satrec.error == 0) } - const { satrec: resultRec } = sgp4(rec, 0.0); + sgp4(satrec, 0, 0); - resultRec.init = 'n'; + satrec.init = 'n'; - // resultRec.error contains any error codes - return resultRec; + /* eslint-enable no-param-reassign */ } diff --git a/src/transforms.js b/src/transforms.js index a8f5563..0023bb3 100644 --- a/src/transforms.js +++ b/src/transforms.js @@ -22,12 +22,12 @@ export function degreesLong(radians) { return radiansToDegrees(radians); } -export function geodeticToEcf(geodeticCoords) { +export function geodeticToEcf(geodetic) { const { longitude, latitude, height, - } = geodeticCoords; + } = geodetic; const a = 6378.137; const b = 6356.7523142; @@ -46,15 +46,15 @@ export function geodeticToEcf(geodeticCoords) { }; } -export function eciToGeodetic(eciCoords, gmst) { +export function eciToGeodetic(eci, gmst) { // http://www.celestrak.com/columns/v02n03/ const a = 6378.137; const b = 6356.7523142; - const R = Math.sqrt((eciCoords.x * eciCoords.x) + (eciCoords.y * eciCoords.y)); + const R = Math.sqrt((eci.x * eci.x) + (eci.y * eci.y)); const f = (a - b) / a; const e2 = ((2 * f) - (f * f)); - let longitude = Math.atan2(eciCoords.y, eciCoords.x) - gmst; + let longitude = Math.atan2(eci.y, eci.x) - gmst; while (longitude < -pi) { longitude += twoPi; } @@ -65,33 +65,33 @@ export function eciToGeodetic(eciCoords, gmst) { const kmax = 20; let k = 0; let latitude = Math.atan2( - eciCoords.z, - Math.sqrt((eciCoords.x * eciCoords.x) + (eciCoords.y * eciCoords.y)), + eci.z, + Math.sqrt((eci.x * eci.x) + (eci.y * eci.y)), ); let C; while (k < kmax) { C = 1 / Math.sqrt(1 - (e2 * (Math.sin(latitude) * Math.sin(latitude)))); - latitude = Math.atan2(eciCoords.z + (a * C * e2 * Math.sin(latitude)), R); + latitude = Math.atan2(eci.z + (a * C * e2 * Math.sin(latitude)), R); k += 1; } const height = (R / Math.cos(latitude)) - (a * C); return { longitude, latitude, height }; } -export function ecfToEci(ecfCoords, gmst) { +export function ecfToEci(ecf, gmst) { // ccar.colorado.edu/ASEN5070/handouts/coordsys.doc // // [X] [C -S 0][X] // [Y] = [S C 0][Y] // [Z]eci [0 0 1][Z]ecf // - const X = (ecfCoords.x * Math.cos(gmst)) - (ecfCoords.y * Math.sin(gmst)); - const Y = (ecfCoords.x * (Math.sin(gmst))) + (ecfCoords.y * Math.cos(gmst)); - const Z = ecfCoords.z; + const X = (ecf.x * Math.cos(gmst)) - (ecf.y * Math.sin(gmst)); + const Y = (ecf.x * (Math.sin(gmst))) + (ecf.y * Math.cos(gmst)); + const Z = ecf.z; return { x: X, y: Y, z: Z }; } -export function eciToEcf(eciCoords, gmst) { +export function eciToEcf(eci, gmst) { // ccar.colorado.edu/ASEN5070/handouts/coordsys.doc // // [X] [C -S 0][X] @@ -104,9 +104,9 @@ export function eciToEcf(eciCoords, gmst) { // [Y] = [-S C 0][Y] // [Z]ecf [0 0 1][Z]eci - const x = (eciCoords.x * Math.cos(gmst)) + (eciCoords.y * Math.sin(gmst)); - const y = (eciCoords.x * (-Math.sin(gmst))) + (eciCoords.y * Math.cos(gmst)); - const { z } = eciCoords; + const x = (eci.x * Math.cos(gmst)) + (eci.y * Math.sin(gmst)); + const y = (eci.x * (-Math.sin(gmst))) + (eci.y * Math.cos(gmst)); + const { z } = eci; return { x, @@ -115,7 +115,7 @@ export function eciToEcf(eciCoords, gmst) { }; } -function topocentric(observerCoords, satelliteCoords) { +function topocentric(observerGeodetic, satelliteEcf) { // http://www.celestrak.com/columns/v02n02/ // TS Kelso's method, except I'm using ECF frame // and he uses ECI. @@ -123,13 +123,13 @@ function topocentric(observerCoords, satelliteCoords) { const { longitude, latitude, - } = observerCoords; + } = observerGeodetic; - const observerEcf = geodeticToEcf(observerCoords); + const observerEcf = geodeticToEcf(observerGeodetic); - const rx = satelliteCoords.x - observerEcf.x; - const ry = satelliteCoords.y - observerEcf.y; - const rz = satelliteCoords.z - observerEcf.z; + const rx = satelliteEcf.x - observerEcf.x; + const ry = satelliteEcf.y - observerEcf.y; + const rz = satelliteEcf.z - observerEcf.z; const topS = ((Math.sin(latitude) * Math.cos(longitude) * rx) + @@ -168,7 +168,7 @@ function topocentricToLookAngles(tc) { }; } -export function ecfToLookAngles(observerCoordsEcf, satelliteCoordsEcf) { - const topocentricCoords = topocentric(observerCoordsEcf, satelliteCoordsEcf); +export function ecfToLookAngles(observerGeodetic, satelliteEcf) { + const topocentricCoords = topocentric(observerGeodetic, satelliteEcf); return topocentricToLookAngles(topocentricCoords); }