UNPKG

s2-tools

Version:

A collection of geospatial tools primarily designed for WGS84, Web Mercator, and S2.

511 lines 17 kB
import { earthRadius, j2, j3oj2, j4, pi, x2o3 } from '../util/constants'; import { dpper, dscom, dsinit, initl } from '.'; /** * ----------------------------------------------------------------------------- * * procedure sgp4init * * this procedure initializes variables for sgp4. * * author : david vallado 719-573-2600 28 jun 2005 * author : david vallado 719-573-2600 28 jun 2005 * * inputs : * opsmode - mode of operation afspc or improved 'a', 'i' * satn - satellite number * drag - 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 : * rec - common values for subsequent calls * return code - non-zero on error. * 1 - mean elements, ecc >= 1.0 or ecc < -0.001 or a < 0.95 er * 2 - mean motion less than 0.0 * 3 - pert elements, ecc < 0.0 or ecc > 1.0 * 4 - semi-latus rectum < 0.0 * 5 - epoch elements are sub-orbital * 6 - satellite has decayed * * locals : * cnodm , snodm , cosim , sinim , cosomm , sinomm * cc1sq , cc2 , cc3 * coef , coef1 * cosio4 - * day - * dndt - * em - eccentricity * emsq - eccentricity squared * eeta - * etasq - * gam - * argpm - argument of perigee * nodem - * inclm - inclination * mm - mean anomaly * nm - mean motion * perige - perigee * pinvsq - * psisq - * qzms24 - * rtemsq - * s1, s2, s3, s4, s5, s6, s7 - * sfour - * ss1, ss2, ss3, ss4, ss5, ss6, ss7 - * sz1, sz2, sz3 * sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33 - * tc - * temp - * temp1, temp2, temp3 - * tsi - * xpidot - * xhdot1 - * z1, z2, z3 - * z11, z12, z13, z21, z22, z23, z31, z32, z33 - * * coupling : * getgravconst- * initl - * dscom - * dpper - * dsinit - * sgp4 - * * references : * hoots, roehrich, norad spacetrack report #3 1980 * hoots, norad spacetrack report #6 1986 * hoots, schumacher and glover 2004 * vallado, crawford, hujsak, kelso 2006 * @param sat - Satellite object */ export function sgp4init(sat) { const epoch = sat.jdsatepoch - 2433281.5; let cosim; let sinim; let cc1sq; let cc2; let cc3; let coef; let coef1; let cosio4; let em; let emsq; let eeta; let etasq; let argpm; let nodem; let inclm; let mm; let nm; let perige; let pinvsq; let psisq; let qzms24; let s1; let s2; let s3; let s4; let s5; let sfour; let ss1; let ss2; let ss3; let ss4; let ss5; let sz1; let sz3; let sz11; let sz13; let sz21; let sz23; let sz31; let sz33; let tc; let temp; let temp1; let temp2; let temp3; let tsi; let xpidot; let xhdot1; let z1; let z3; let z11; let z13; let z21; let z23; let z31; let z33; /* ------------------------ initialization --------------------- */ // sgp4fix divisor for divide by zero check on inclination // the old check used 1.0 + Math.cos(pi-1.0e-9), but then compared it to // 1.5 e-12, so the threshold was changed to 1.5e-12 for consistency const temp4 = 1.5e-12; // sgp4fix - note the following variables are also passed directly via sat. // it is possible to streamline the sgp4init call by deleting the "x" // variables, but the user would need to set the sat.* values first. we // include the additional assignments in case twoline2rv is not used. // ------------------------ earth constants ----------------------- // sgp4fix identify constants and allow alternate values const ss = 78.0 / earthRadius + 1.0; // sgp4fix use multiply for speed instead of pow const qzms2ttemp = (120.0 - 78.0) / earthRadius; const qzms2t = qzms2ttemp * qzms2ttemp * qzms2ttemp * qzms2ttemp; sat.init = true; const initlOptions = { // satn, ecco: sat.eccentricity, epoch, inclo: sat.inclination, no: sat.motion, opsmode: sat.opsmode, }; const initlResult = initl(initlOptions); const { ao, con42, cosio, cosio2, eccsq, omeosq, posq, rp, rteosq, sinio } = initlResult; sat.motion = initlResult.no; sat.con41 = initlResult.con41; sat.gsto = initlResult.gsto; // const a = (sat.motion * tumin) ** (-2.0 / 3.0); // const alta = a * (1.0 + sat.eccentricity) - 1.0; // const altp = a * (1.0 - sat.eccentricity) - 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); // sat.error = 5; // } if (omeosq >= 0.0 || sat.motion >= 0.0) { sat.isimp = 0; if (rp < 220.0 / earthRadius + 1.0) { sat.isimp = 1; } sfour = ss; qzms24 = qzms2t; perige = (rp - 1.0) * earthRadius; // - for perigees below 156 km, s and qoms2t are altered - if (perige < 156.0) { sfour = perige - 78.0; if (perige < 98.0) { sfour = 20.0; } // sgp4fix use multiply for speed instead of pow const qzms24temp = (120.0 - sfour) / earthRadius; qzms24 = qzms24temp * qzms24temp * qzms24temp * qzms24temp; sfour = sfour / earthRadius + 1.0; } pinvsq = 1.0 / posq; tsi = 1.0 / (ao - sfour); sat.eta = ao * sat.eccentricity * tsi; etasq = sat.eta * sat.eta; eeta = sat.eccentricity * sat.eta; psisq = Math.abs(1.0 - etasq); coef = qzms24 * tsi ** 4.0; coef1 = coef / psisq ** 3.5; cc2 = coef1 * sat.motion * (ao * (1.0 + 1.5 * etasq + eeta * (4.0 + etasq)) + ((0.375 * j2 * tsi) / psisq) * sat.con41 * (8.0 + 3.0 * etasq * (8.0 + etasq))); sat.cc1 = sat.drag * cc2; cc3 = 0.0; if (sat.eccentricity > 1.0e-4) { cc3 = (-2.0 * coef * tsi * j3oj2 * sat.motion * sinio) / sat.eccentricity; } sat.x1mth2 = 1.0 - cosio2; sat.cc4 = 2.0 * sat.motion * coef1 * ao * omeosq * (sat.eta * (2.0 + 0.5 * etasq) + sat.eccentricity * (0.5 + 2.0 * etasq) - ((j2 * tsi) / (ao * psisq)) * (-3.0 * sat.con41 * (1.0 - 2.0 * eeta + etasq * (1.5 - 0.5 * eeta)) + 0.75 * sat.x1mth2 * (2.0 * etasq - eeta * (1.0 + etasq)) * Math.cos(2.0 * sat.perigee))); sat.cc5 = 2.0 * coef1 * ao * omeosq * (1.0 + 2.75 * (etasq + eeta) + eeta * etasq); cosio4 = cosio2 * cosio2; temp1 = 1.5 * j2 * pinvsq * sat.motion; temp2 = 0.5 * temp1 * j2 * pinvsq; temp3 = -0.46875 * j4 * pinvsq * pinvsq * sat.motion; sat.mdot = sat.motion + 0.5 * temp1 * rteosq * sat.con41 + 0.0625 * temp2 * rteosq * (13.0 - 78.0 * cosio2 + 137.0 * cosio4); sat.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; sat.nodedot = xhdot1 + (0.5 * temp2 * (4.0 - 19.0 * cosio2) + 2.0 * temp3 * (3.0 - 7.0 * cosio2)) * cosio; xpidot = sat.argpdot + sat.nodedot; sat.omgcof = sat.drag * cc3 * Math.cos(sat.perigee); sat.xmcof = 0.0; if (sat.eccentricity > 1.0e-4) { sat.xmcof = (-x2o3 * coef * sat.drag) / eeta; } sat.nodecf = 3.5 * omeosq * xhdot1 * sat.cc1; sat.t2cof = 1.5 * sat.cc1; // sgp4fix for divide by zero with xinco = 180 deg if (Math.abs(cosio + 1.0) > 1.5e-12) { sat.xlcof = (-0.25 * j3oj2 * sinio * (3.0 + 5.0 * cosio)) / (1.0 + cosio); } else { sat.xlcof = (-0.25 * j3oj2 * sinio * (3.0 + 5.0 * cosio)) / temp4; } sat.aycof = -0.5 * j3oj2 * sinio; // sgp4fix use multiply for speed instead of pow const delmotemp = 1.0 + sat.eta * Math.cos(sat.anomaly); sat.delmo = delmotemp * delmotemp * delmotemp; sat.sinmao = Math.sin(sat.anomaly); sat.x7thm1 = 7.0 * cosio2 - 1.0; // --------------- deep space initialization ------------- if ((2 * pi) / sat.motion >= 225.0) { sat.method = 'd'; sat.isimp = 1; tc = 0.0; inclm = sat.inclination; const dscomOptions = { epoch, ep: sat.eccentricity, argpp: sat.perigee, tc, inclp: sat.inclination, nodep: sat.ascension, np: sat.motion, e3: sat.e3, ee2: sat.ee2, peo: sat.peo, pgho: sat.pgho, pho: sat.pho, pinco: sat.pinco, plo: sat.plo, se2: sat.se2, se3: sat.se3, sgh2: sat.sgh2, sgh3: sat.sgh3, sgh4: sat.sgh4, sh2: sat.sh2, sh3: sat.sh3, si2: sat.si2, si3: sat.si3, sl2: sat.sl2, sl3: sat.sl3, sl4: sat.sl4, xgh2: sat.xgh2, xgh3: sat.xgh3, xgh4: sat.xgh4, xh2: sat.xh2, xh3: sat.xh3, xi2: sat.xi2, xi3: sat.xi3, xl2: sat.xl2, xl3: sat.xl3, xl4: sat.xl4, zmol: sat.zmol, zmos: sat.zmos, }; const dscomResult = dscom(dscomOptions); sat.e3 = dscomResult.e3; sat.ee2 = dscomResult.ee2; sat.peo = dscomResult.peo; sat.pgho = dscomResult.pgho; sat.pho = dscomResult.pho; sat.pinco = dscomResult.pinco; sat.plo = dscomResult.plo; sat.se2 = dscomResult.se2; sat.se3 = dscomResult.se3; sat.sgh2 = dscomResult.sgh2; sat.sgh3 = dscomResult.sgh3; sat.sgh4 = dscomResult.sgh4; sat.sh2 = dscomResult.sh2; sat.sh3 = dscomResult.sh3; sat.si2 = dscomResult.si2; sat.si3 = dscomResult.si3; sat.sl2 = dscomResult.sl2; sat.sl3 = dscomResult.sl3; sat.sl4 = dscomResult.sl4; ({ sinim, cosim, em, emsq, s1, s2, s3, s4, s5, ss1, ss2, ss3, ss4, ss5, sz1, sz3, sz11, sz13, sz21, sz23, sz31, sz33, } = dscomResult); sat.xgh2 = dscomResult.xgh2; sat.xgh3 = dscomResult.xgh3; sat.xgh4 = dscomResult.xgh4; sat.xh2 = dscomResult.xh2; sat.xh3 = dscomResult.xh3; sat.xi2 = dscomResult.xi2; sat.xi3 = dscomResult.xi3; sat.xl2 = dscomResult.xl2; sat.xl3 = dscomResult.xl3; sat.xl4 = dscomResult.xl4; sat.zmol = dscomResult.zmol; sat.zmos = dscomResult.zmos; ({ nm, z1, z3, z11, z13, z21, z23, z31, z33 } = dscomResult); const dpperOptions = { inclo: inclm, init: sat.init, ep: sat.eccentricity, inclp: sat.inclination, nodep: sat.ascension, argpp: sat.perigee, mp: sat.anomaly, opsmode: sat.opsmode, }; const dpperResult = dpper(sat, dpperOptions, 0); sat.eccentricity = dpperResult.ep; sat.inclination = dpperResult.inclp; sat.ascension = dpperResult.nodep; sat.perigee = dpperResult.argpp; sat.anomaly = dpperResult.mp; argpm = 0.0; nodem = 0.0; mm = 0.0; const dsinitOptions = { cosim, emsq, argpo: sat.perigee, s1, s2, s3, s4, s5, sinim, ss1, ss2, ss3, ss4, ss5, sz1, sz3, sz11, sz13, sz21, sz23, sz31, sz33, tc, gsto: sat.gsto, mo: sat.anomaly, mdot: sat.mdot, no: sat.motion, nodeo: sat.ascension, nodedot: sat.nodedot, xpidot, z1, z3, z11, z13, z21, z23, z31, z33, ecco: sat.eccentricity, eccsq, em, argpm, inclm, mm, nm, nodem, irez: sat.irez, atime: sat.atime, d2201: sat.d2201, d2211: sat.d2211, d3210: sat.d3210, d3222: sat.d3222, d4410: sat.d4410, d4422: sat.d4422, d5220: sat.d5220, d5232: sat.d5232, d5421: sat.d5421, d5433: sat.d5433, dedt: sat.dedt, didt: sat.didt, dmdt: sat.dmdt, dnodt: sat.dnodt, domdt: sat.domdt, del1: sat.del1, del2: sat.del2, del3: sat.del3, xfact: sat.xfact, xlamo: sat.xlamo, xli: sat.xli, xni: sat.xni, }; const dsinitResult = dsinit(dsinitOptions, 0); sat.irez = dsinitResult.irez; sat.atime = dsinitResult.atime; sat.d2201 = dsinitResult.d2201; sat.d2211 = dsinitResult.d2211; sat.d3210 = dsinitResult.d3210; sat.d3222 = dsinitResult.d3222; sat.d4410 = dsinitResult.d4410; sat.d4422 = dsinitResult.d4422; sat.d5220 = dsinitResult.d5220; sat.d5232 = dsinitResult.d5232; sat.d5421 = dsinitResult.d5421; sat.d5433 = dsinitResult.d5433; sat.dedt = dsinitResult.dedt; sat.didt = dsinitResult.didt; sat.dmdt = dsinitResult.dmdt; sat.dnodt = dsinitResult.dnodt; sat.domdt = dsinitResult.domdt; sat.del1 = dsinitResult.del1; sat.del2 = dsinitResult.del2; sat.del3 = dsinitResult.del3; sat.xfact = dsinitResult.xfact; sat.xlamo = dsinitResult.xlamo; sat.xli = dsinitResult.xli; sat.xni = dsinitResult.xni; } // ----------- set variables if not deep space ----------- if (sat.isimp !== 1) { cc1sq = sat.cc1 * sat.cc1; sat.d2 = 4.0 * ao * tsi * cc1sq; temp = (sat.d2 * tsi * sat.cc1) / 3.0; sat.d3 = (17.0 * ao + sfour) * temp; sat.d4 = 0.5 * temp * ao * tsi * (221.0 * ao + 31.0 * sfour) * sat.cc1; sat.t3cof = sat.d2 + 2.0 * cc1sq; sat.t4cof = 0.25 * (3.0 * sat.d3 + sat.cc1 * (12.0 * sat.d2 + 10.0 * cc1sq)); sat.t5cof = 0.2 * (3.0 * sat.d4 + 12.0 * sat.cc1 * sat.d3 + 6.0 * sat.d2 * sat.d2 + 15.0 * cc1sq * (2.0 * sat.d2 + cc1sq)); } } } //# sourceMappingURL=sgp4init.js.map