def InitializeByPosAndTheta(self, pos, theta): theta = theta % Globals.TwoPi if theta < 0.0: # "wrap" negative modulo theta += Globals.TwoPi r = math.sqrt(Globals.Sqr(pos.X) + Globals.Sqr(pos.Y)) e2 = Globals.F * (2.0 - Globals.F) lat = Globals.AcTan(pos.Z, r) DELTA = 1.0e-07 while True: phi = lat c = 1.0 / math.sqrt(1.0 - e2 * Globals.Sqr(math.sin(phi))) lat = Globals.AcTan( pos.Z + Globals.Xkmper * c * e2 * math.sin(phi), r) if math.fabs(lat - phi) <= DELTA: break self._latitudeRad = lat self._longitudeRad = theta self._altitude = (r / math.cos(lat)) - Globals.Xkmper * c return self
def GetLookAngle(self, eci): # Calculate the ECI coordinates for this Site object at the time of interest date = eci.Date eciSite = self.PositionEciByJulianTime(date) vecRgRate = Vector(eci.Velocity.X - eciSite.Velocity.X, eci.Velocity.Y - eciSite.Velocity.Y, eci.Velocity.Z - eciSite.Velocity.Z) x = eci.Position.X - eciSite.Position.X y = eci.Position.Y - eciSite.Position.Y z = eci.Position.Z - eciSite.Position.Z w = math.sqrt(Globals.Sqr(x) + Globals.Sqr(y) + Globals.Sqr(z)) vecRange = Vector(x, y, z, w) # The site`s Local Mean Sidereal Time at the time of interest. theta = date.ToLmst(self.LongitudeRad) sin_lat = math.sin(self.LatitudeRad) cos_lat = math.cos(self.LatitudeRad) sin_theta = math.sin(theta) cos_theta = math.cos(theta) top_s = sin_lat * cos_theta * vecRange.X +\ sin_lat * sin_theta * vecRange.Y -\ cos_lat * vecRange.Z top_e = -sin_theta * vecRange.X + cos_theta * vecRange.Y top_z = cos_lat * cos_theta * vecRange.X +\ cos_lat * sin_theta * vecRange.Y +\ sin_lat * vecRange.Z az = math.atan(-top_e/top_s) if top_s > 0.0: az += Globals.Pi if az < 0.0: az += 2.0 * Globals.Pi el = math.asin(top_z/vecRange.W) rate = (vecRange.X * vecRgRate.X +\ vecRange.Y * vecRgRate.Y +\ vecRange.Z * vecRgRate.Z)/vecRange.W topo = TopoTime().InitializeByRadAzAndRadElAndRangeAndRangeRateAndDate(az, el, vecRange.W, rate, eci.Date) # if WANT_ATMOSPHERIC_CORRECTION # endif return topo
def ConvertUnits(valNative, fld, units): if fld == Field.Inclination or fld == Field.Raan or fld == Field.ArgPerigee or fld == Field.MeanAnomaly: # The native TLE format is degrees if units == Unit.Radians: return Globals.ToRadians(valNative) return valNative
def GetPosition(self, tsince): # Update for secular gravity and atmospheric drag xmdf = self.Orbit.MeanAnomaly + self._m_xmdot * tsince omgadf = self.Orbit.ArgPerigee + self._m_omgdot * tsince xnoddf = self.Orbit.RAAN + self._m_xnodot * tsince tsq = tsince * tsince xnode = xnoddf * self._m_xnodcf * tsq tempa = 1.0 - self._m_c1 * tsince tempe = self.Orbit.BStar * self._m_c4 * tsince templ = self._m_t2cof * tsq xn = self._m_xnodp em = 0.0 xinc = 0.0 _, xmdf, omgadf, xnode, em, xinc, xn, tsince = self.DeepSecular( xmdf, omgadf, xnode, em, xinc, xn, tsince) a = math.pow(Globals.Xke / xn, 2.0 / 3.0) * Globals.Sqr(tempa) e = em - tempe xmam = xmdf + self._m_xnodp * templ _, e, xinc, omgadf, xnode, xmam = self.DeepPeriodics( e, xinc, omgadf, xnode, xmam, tsince) xl = xmam + omgadf + xnode xn = Globals.Xke / math.pow(a, 1.5) return self.FinalPosition(xinc, omgadf, e, a, xl, xnode, xn, tsince)
def InitializeByGeoAndDate(self, geo, date): lat = geo.LatitudeRad lon = geo.LongitudeRad alt = geo.Altitude # Calculate Local Mean Sidereal Time (theta) theta = date.ToLmst(lon) c = 1.0 / math.sqrt(1.0 + Globals.F * (Globals.F - 2.0) * Globals.Sqr(math.sin(lat))) s = Globals.Sqr(1.0 - Globals.F) * c achcp = (Globals.Xkmper * c + alt) * math.cos(lat) x = achcp * math.cos(theta) # km y = achcp * math.sin(theta) # km z = (Globals.Xkmper * s + alt) * math.sin(lat) # km w = math.sqrt(Globals.Sqr(x) + Globals.Sqr(y) + Globals.Sqr(z)) # range, km self._pos = Vector(x, y, z, w) mfactor = Globals.TwoPi * (Globals.OmegaE / Globals.SecPerDay) x = -mfactor * self._pos.Y # km / sec y = mfactor * self._pos.X # km / sec z = 0.0 # km / sec w = math.sqrt(Globals.Sqr(x) + Globals.Sqr(y)) # range rate km/sec^2 self._vel = Vector(x, y, z, w)
def __init__(self, tle): self._tle = tle self._epoch = tle.EpochJulian # Caching variables self._m_Period = datetime.timedelta(seconds=-1) # TLE caching variables self._m_Inclination = self.GetRad(Field.Inclination) self._m_Eccentricity = self._tle.GetFieldAsValue(Field.Eccentricity) self._m_RAAN = self.GetRad(Field.Raan) self._m_ArgPerigee = self.GetRad(Field.ArgPerigee) self._m_BStar = self._tle.GetFieldAsValue(Field.BStarDrag) self._m_Drag = self._tle.GetFieldAsValue(Field.MeanMotionDt) self._m_MeanAnomaly = self.GetRad(Field.MeanAnomaly) self._m_TleMeanMotion = self._tle.GetFieldAsValue(Field.MeanMotion) # Recover the original mean motion and semimajor axis from the input elements. mm = self.TleMeanMotion rpmin = mm * Globals.TwoPi / Globals.MinPerDay # rads per minute a1 = math.pow(Globals.Xke / rpmin, 2.0 / 3.0) e = self.Eccentricity i = self.Inclination temp = (1.5 * Globals.Ck2 * (3.0 * Globals.Sqr(math.cos(i)) - 1.0) / math.pow(1.0 - e * e, 1.5)) delta1 = temp / (a1 * a1) a0 = a1 * (1.0 - delta1 * ((1.0 / 3.0) + delta1 * (1.0 + 134.0 / 81.0 * delta1))) delta0 = temp / (a0 * a0) # Caching variables recovered from the input TLE elements self._m_rmMeanMotionRec = rpmin / (1.0 + delta0) # radians per minute self._m_aeAxisSemiMajorRec = a0 / (1.0 - delta0 ) # semimajor axis, in AE units self._m_aeAxisSemiMinorRec = self._m_aeAxisSemiMajorRec * math.sqrt( 1.0 - (e * e)) # semiminor axis, in AE units. self._m_kmPerigeeRec = Globals.Xkmper * (self._m_aeAxisSemiMajorRec * (1.0 - e) - Globals.Ae ) # perigee, in km self._m_kmApogeeRec = Globals.Xkmper * (self._m_aeAxisSemiMajorRec * (1.0 + e) - Globals.Ae ) # apogee, in km if (self.Period.total_seconds() / 60.0) >= 225.0: # SDP4 - period >= 225 minutes. self._noradModel = NoradSDP4(self) else: # SGP4 - period < 225 minutes. self._noradModel = NoradSGP4(self)
def DeepPeriodics(self, e, xincc, omgadf, xnode, xmam, tsince): # Lunar-solar periodics sinis = math.sin(xincc) cosis = math.cos(xincc) sghs = 0.0 shs = 0.0 shl = 0.0 pe = 0.0 pinc = 0.0 pl = 0.0 sghl = 0.0 zm = self._dp_zmos + NoradSDP4.zns * tsince zf = zm + 2.0 * NoradSDP4.zes * math.sin(zm) sinzf = math.sin(zf) f2 = 0.5 * sinzf * sinzf - 0.25 f3 = -0.5 * sinzf * math.cos(zf) ses = self._dp_se2 * f2 + self._dp_se3 * f3 sis = self._dp_si2 * f2 + self._dp_si3 * f3 sls = self._dp_sl2 * f2 + self._dp_sl3 * f3 + self._dp_sl4 * sinzf sghs = self._dp_sgh2 * f2 + self._dp_sgh3 * f3 + self._dp_sgh4 * sinzf shs = self._dp_sh2 * f2 + self._dp_sh3 * f3 zm = self._dp_zmol + NoradSDP4.znl * tsince zf = zm + 2.0 * NoradSDP4.zel * math.sin(zm) sinzf = math.sin(zf) f2 = 0.5 * sinzf * sinzf - 0.25 f3 = -0.5 * sinzf * math.cos(zf) sel = self._dp_ee2 * f2 + self._dp_e3 * f3 sil = self._dp_xi2 * f2 + self._dp_xi3 * f3 sll = self._dp_xl2 * f2 + self._dp_xl3 * f3 + self._dp_xl4 * sinzf sghl = self._dp_xgh2 * f2 + self._dp_xgh3 * f3 + self._dp_xgh4 * sinzf sh1 = self._dp_xh2 * f2 + self._dp_xh3 * f3 pe = ses + sel pinc = sis + sil pl = sls + sll pgh = sghs + sghl ph = shs + shl xincc = xincc + pinc e = e + pe if self._dp_xqncl >= 0.2: # Apply periodics directly ph = ph / self._m_sinio pgh = pgh - self._m_cosio * ph omgadf = omgadf + pgh xnode = xnode + ph xmam = xmam + pl else: # Apply periodics with Lyddane modification sinok = math.sin(xnode) cosok = math.cos(xnode) alfdp = sinis * sinok betdp = sinis * cosok dalf = ph * cosok + pinc * cosis * sinok dbet = -ph * sinok + pinc * cosis * cosok alfdp = alfdp + dalf betdp = betdp + dbet xls = xmam + omgadf + cosis * xnode dls = pl + pgh - pinc * xnode * sinis xls = xls + dls xnode = Globals.AcTan(alfdp, betdp) xmam = xmam + pl omgadf = xls - xmam - math.cos(xincc) * xnode return True, e, xincc, omgadf, xnode, xmam
def __init__(self, orbit): super().__init__(orbit) sinarg = math.sin(self.Orbit.ArgPerigee) cosarg = math.cos(self.Orbit.ArgPerigee) # Deep space initialization jd = self.Orbit.Epoch self._dp_thgr = jd.ToGmst() eq = self.Orbit.Eccentricity aqnv = 1.0 / self.Orbit.SemiMajor self._dp_xqncl = self.Orbit.Inclination xmao = self.Orbit.MeanAnomaly xpidot = self._m_omgdot + self._m_xnodot sinq = math.sin(self.Orbit.RAAN) cosq = math.cos(self.Orbit.RAAN) self._dp_omegaq = self.Orbit.ArgPerigee # region Lunar / Solar terms # Initialize lunar solar terms day = jd.FromJan0_12h_1900 dpi_xnodce = 4.5236020 - 9.2422029E-4 * day dpi_stem = math.sin(dpi_xnodce) dpi_ctem = math.cos(dpi_xnodce) dpi_zcosil = 0.91375164 - 0.03568096 * dpi_ctem dpi_zsinil = math.sqrt(1.0 - dpi_zcosil * dpi_zcosil) dpi_zsinhl = 0.089683511 * dpi_stem / dpi_zsinil dpi_zcoshl = math.sqrt(1.0 - dpi_zsinhl * dpi_zsinhl) dpi_c = 4.7199672 + 0.22997150 * day dpi_gam = 5.8351514 + 0.0019443680 * day self._dp_zmol = Globals.Fmod2p(dpi_c - dpi_gam) dpi_zx = 0.39785416 * dpi_stem / dpi_zsinil dpi_zy = dpi_zcoshl * dpi_ctem + 0.91744867 * dpi_zsinhl * dpi_stem dpi_zx = Globals.AcTan(dpi_zx, dpi_zy) + dpi_gam - dpi_xnodce dpi_zcosgl = math.cos(dpi_zx) dpi_zsingl = math.sin(dpi_zx) dp_zmos = 6.2565837 + 0.017201977 * day dp_zmos = Globals.Fmod2p(dp_zmos) zcosis = 0.91744867 zsinis = 0.39785416 zsings = -0.98088458 zcosgs = 0.1945905 c1ss = 2.9864797E-6 zcosg = zcosgs zsing = zsings zcosi = zcosis zsini = zsinis zcosh = cosq zsinh = sinq cc = c1ss zn = NoradSDP4.zns ze = NoradSDP4.zes xnoi = 1.0 / self.Orbit.MeanMotion se = 0.0 si = 0.0 sl = 0.0 sgh = 0.0 sh = 0.0 eosq = Globals.Sqr(self.Orbit.Eccentricity) # Apply the solar and lunar terms on the first pass, then re-apply the # solar terms again on the second pass for i in range(1, 3): # Do solar terms 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 = self._m_cosio * a7 + self._m_sinio * a8 a4 = self._m_cosio * a9 + self._m_sinio * a10 a5 = -self._m_sinio * a7 + self._m_cosio * a8 a6 = -self._m_sinio * a9 + self._m_cosio * a10 x1 = a1 * cosarg + a2 * sinarg x2 = a3 * cosarg + a4 * sinarg x3 = -a1 * sinarg + a2 * cosarg x4 = -a3 * sinarg + a4 * cosarg x5 = a5 * sinarg x6 = a6 * sinarg x7 = a5 * cosarg x8 = a6 * cosarg z31 = 12.0 * x1 * x1 - 3.0 * x3 * x3 z32 = 24.0 * x1 * x1 - 6.0 * x3 * x4 z33 = 12.0 * x2 * x2 - 3.0 * x4 * x4 z1 = 3.0 * (a1 * a1 + a2 * a2) + z31 * eosq z2 = 6.0 * (a1 * a3 + a2 * a4) + z32 * eosq z3 = 3.0 * (a3 * a3 + a4 * a4) + z33 * eosq z11 = -6.0 * a1 * a5 + eosq * (-24.0 * x1 * x7 - 6.0 * x3 * x5) z12 = -6.0 * (a1 * a6 + a3 * a5) + \ eosq * (-24.0 * (x2 * x7 + x1 * x8) - 6.0 * (x3 * x6 + x4 * x5)) z13 = -6.0 * a3 * a6 + eosq * (-24.0 * x2 * x8 - 6.0 * x4 * x6) z21 = 6.0 * a2 * a5 + eosq * (24.0 * x1 * x5 - 6.0 * x3 * x7) z22 = 6.0 * (a4 * a5 + a2 * a6) + \ eosq * (24.0 * (x2 * x5 + x1 * x6) - 6.0 * (x4 * x7 + x3 * x8)) z23 = 6.0 * a4 * a6 + eosq * (24.0 * x2 * x6 - 6.0 * x4 * x8) z1 = z1 + z1 + self._m_betao2 * z31 z2 = z2 + z2 + self._m_betao2 * z32 z3 = z3 + z3 + self._m_betao2 * z33 s3 = cc * xnoi s2 = -0.5 * s3 / self._m_betao s4 = s3 * self._m_betao s1 = -15.0 * eq * s4 s5 = x1 * x3 + x2 * x4 s6 = x2 * x3 + x1 * x4 s7 = x2 * x4 - x1 * x3 se = s1 * zn * s5 si = s2 * zn * (z11 + z13) sl = -zn * s3 * (z1 + z3 - 14.0 - 6.0 * eosq) sgh = s4 * zn * (z31 + z33 - 6.0) if self.Orbit.Inclination < 5.2359877E-2: sh = 0.0 else: sh = -zn * s2 * (z21 + z23) self._dp_ee2 = 2.0 * s1 * s6 self._dp_e3 = 2.0 * s1 * s7 self._dp_xi2 = 2.0 * s2 * z12 self._dp_xi3 = 2.0 * s2 * (z13 - z11) self._dp_xl2 = -2.0 * s3 * z2 self._dp_xl3 = -2.0 * s3 * (z3 - z1) self._dp_xl4 = -2.0 * s3 * (-21.0 - 9.0 * eosq) * ze self._dp_xgh2 = 2.0 * s4 * z32 self._dp_xgh3 = 2.0 * s4 * (z33 - z31) self._dp_xgh4 = -18.0 * s4 * ze self._dp_xh2 = -2.0 * s2 * z22 self._dp_xh3 = -2.0 * s2 * (z23 - z21) if i == 1: # Do lunar terms self._dp_sse = se self._dp_ssi = si self._dp_ssl = sl self._dp_ssh = sh / self._m_sinio self._dp_ssg = sgh - self._m_cosio * self._dp_ssh self._dp_se2 = self._dp_ee2 self._dp_si2 = self._dp_xi2 self._dp_sl2 = self._dp_xl2 self._dp_sgh2 = self._dp_xgh2 self._dp_sh2 = self._dp_xh2 self._dp_se3 = self._dp_e3 self._dp_si3 = self._dp_xi3 self._dp_sl3 = self._dp_xl3 self._dp_sgh3 = self._dp_xgh3 self._dp_sh3 = self._dp_xh3 self._dp_sl4 = self._dp_xl4 self._dp_sgh4 = self._dp_xgh4 zcosg = dpi_zcosgl zsing = dpi_zsingl zcosi = dpi_zcosil zsini = dpi_zsinil zcosh = dpi_zcoshl * cosq + dpi_zsinhl * sinq zsinh = sinq * dpi_zcoshl - cosq * dpi_zsinhl zn = NoradSDP4.znl c1l = 4.7968065E-7 cc = c1l ze = NoradSDP4.zel # endregion self._dp_sse = self._dp_sse + se self._dp_ssi = self._dp_ssi + si self._dp_ssl = self._dp_ssl + sl self._dp_ssg = self._dp_ssg + sgh - self._m_cosio / self._m_sinio * sh self._dp_ssh = self._dp_ssh + sh / self._m_sinio # Geopotential resonance initialization for 12 hour orbits self._gp_reso = False # geopotential resonant self._gp_sync = False # geopotential synchronous g310 = 0.0 f220 = 0.0 bfact = 0.0 # Determine if orbit is 12- or 24-hour resonant. # Mean motion is given in radians per minute. if self.Orbit.MeanMotion > 0.0034906585 and self.Orbit.MeanMotion < 0.0052359877: # Orbit is within the Clarke Belt (period is 24-hour resonant) # Synchronous reasonance terms initialization self._gp_reso = True self._gp_sync = True # region 24-hour resonant g200 = 1.0 + eosq * (-2.5 + 0.8125 * eosq) g310 = 1.0 + 2.0 * eosq g300 = 1.0 + eosq * (-6.0 + 6.60937 * eosq) f220 = 0.75 * (1.0 + self._m_cosio) * (1.0 + self._m_cosio) f311 = 0.9375 * self._m_sinio * self._m_sinio * ( 1.0 + 3 * self._m_cosio) - 0.75 * (1.0 + self._m_cosio) f330 = 1.0 + self._m_cosio f330 = 1.875 * f330 * f330 * f330 q22 = 1.7891679e-06 q33 = 2.2123015e-07 q31 = 2.1460748e-06 self._dp_del1 = 3.0 * self._m_xnodp * self._m_xnodp * aqnv * aqnv self._dp_del2 = 2.0 * self._dp_del1 * f220 * g200 * q22 self._dp_del3 = 3.0 * self._dp_del1 * f330 * g300 * q33 * aqnv self._dp_del1 = self._dp_del1 * f311 * g310 * q31 * aqnv self._dp_xlamo = xmao + self.Orbit.RAAN + self.Orbit.ArgPerigee - self._dp_thgr bfact = self._m_xmdot + xpidot - NoradSDP4.thdt bfact = bfact + self._dp_ssl + self._dp_ssg + self._dp_ssh # endregion elif self.Orbit.MeanMotion >= 8.26E-3 and self.Orbit.MeanMotion <= 9.24E-3 and eq >= 0.5: # Period is 12-hour resonant self._gp_reso = True # region 12-hour resonant eoc = eq * eosq g201 = -0.306 - (eq - 0.64) * 0.440 if eq <= 0.65: g211 = 3.616 - 13.247 * eq + 16.290 * eosq g310 = -19.302 + 117.390 * eq - 228.419 * eosq + 156.591 * eoc g322 = -18.9068 + 109.7927 * eq - 214.6334 * eosq + 146.5816 * eoc g410 = -41.122 + 242.694 * eq - 471.094 * eosq + 313.953 * eoc g422 = -146.407 + 841.880 * eq - 1629.014 * eosq + 1083.435 * eoc g520 = -532.114 + 3017.977 * eq - 5740.0 * eosq + 3708.276 * eoc else: g211 = -72.099 + 331.819 * eq - 508.738 * eosq + 266.724 * eoc g310 = -346.844 + 1582.851 * eq - 2415.925 * eosq + 1246.113 * eoc g322 = -342.585 + 1554.908 * eq - 2366.899 * eosq + 1215.972 * eoc g410 = -1052.797 + 4758.686 * eq - 7193.992 * eosq + 3651.957 * eoc g422 = -3581.69 + 16178.11 * eq - 24462.77 * eosq + 12422.52 * eoc if eq <= 0.715: g520 = 1464.74 - 4664.75 * eq + 3763.64 * eosq else: g520 = -5149.66 + 29936.92 * eq - 54087.36 * eosq + 31324.56 * eoc if eq < 0.7: g533 = -919.2277 + 4988.61 * eq - 9064.77 * eosq + 5542.21 * eoc g521 = -822.71072 + 4568.6173 * eq - 8491.4146 * eosq + 5337.524 * eoc g532 = -853.666 + 4690.25 * eq - 8624.77 * eosq + 5341.4 * eoc else: g533 = -37995.78 + 161616.52 * eq - 229838.2 * eosq + 109377.94 * eoc g521 = -51752.104 + 218913.95 * eq - 309468.16 * eosq + 146349.42 * eoc g532 = -40023.88 + 170470.89 * eq - 242699.48 * eosq + 115605.82 * eoc sini2 = self._m_sinio * self._m_sinio cosi2 = self._m_cosio * self._m_cosio f220 = 0.75 * (1.0 + 2.0 * self._m_cosio + cosi2) f221 = 1.5 * sini2 f321 = 1.875 * self._m_sinio * (1.0 - 2.0 * self._m_cosio - 3.0 * cosi2) f322 = -1.875 * self._m_sinio * (1.0 + 2.0 * self._m_cosio - 3.0 * cosi2) f441 = 35.0 * sini2 * f220 f442 = 39.3750 * sini2 * sini2 f522 = 9.84375 * self._m_sinio * ( sini2 * (1.0 - 2.0 * self._m_cosio - 5.0 * cosi2) + 0.33333333 * (-2.0 + 4.0 * self._m_cosio + 6.0 * cosi2)) f523 = self._m_sinio * ( 4.92187512 * sini2 * (-2.0 - 4.0 * self._m_cosio + 10.0 * cosi2) + 6.56250012 * (1.0 + 2.0 * self._m_cosio - 3.0 * cosi2)) f542 = 29.53125 * self._m_sinio * ( 2.0 - 8.0 * self._m_cosio + cosi2 * (-12.0 + 8.0 * self._m_cosio + 10.0 * cosi2)) f543 = 29.53125 * self._m_sinio * ( -2.0 - 8.0 * self._m_cosio + cosi2 * (12.0 + 8.0 * self._m_cosio - 10.0 * cosi2)) xno2 = self._m_xnodp * self._m_xnodp ainv2 = aqnv * aqnv temp1 = 3.0 * xno2 * ainv2 root22 = 1.7891679E-6 root32 = 3.7393792E-7 root44 = 7.3636953E-9 root52 = 1.1428639E-7 root54 = 2.1765803E-9 temp = temp1 * root22 self._dp_d2201 = temp * f220 * g201 self._dp_d2211 = temp * f221 * g211 temp1 = temp1 * aqnv temp = temp1 * root32 self._dp_d3210 = temp * f321 * g310 self._dp_d3222 = temp * f322 * g322 temp1 = temp1 * aqnv temp = 2.0 * temp1 * root44 self._dp_d4410 = temp * f441 * g410 self._dp_d4422 = temp * f442 * g422 temp1 = temp1 * aqnv temp = temp1 * root52 self._dp_d5220 = temp * f522 * g520 self._dp_d5232 = temp * f523 * g532 temp = 2.0 * temp1 * root54 self._dp_d5421 = temp * f542 * g521 self._dp_d5433 = temp * f543 * g533 self._dp_xlamo = xmao + self.Orbit.RAAN + self.Orbit.RAAN - self._dp_thgr - self._dp_thgr bfact = self._m_xmdot + self._m_xnodot + self._m_xnodot - NoradSDP4.thdt - NoradSDP4.thdt bfact = bfact + self._dp_ssl + self._dp_ssh + self._dp_ssh # endregion if self._gp_reso or self._gp_sync: self._dp_xfact = bfact - self._m_xnodp # Initialize integrator self._dp_xli = self._dp_xlamo self._dp_xni = self._m_xnodp dp_atime = 0.0 # performed by runtime self._dp_stepp = 720.0 self._dp_stepn = -720.0 self._dp_step2 = 259200.0
def GetPosition(self, tsince): # For m_perigee less than 220 kilometers, the isimp flag is set and # the equations are truncated to linear variation in square root of a # and quadratic variation in mean anomaly. Also, the m_c3 term, the # delta omega term, and the delta m term are dropped. isimp = False if (self._m_aodp * (1.0 - self._m_satEcc) / Globals.Ae) < (220.0 / Globals.Xkmper + Globals.Ae): isimp = True d2 = 0.0 d3 = 0.0 d4 = 0.0 t3cof = 0.0 t4cof = 0.0 t5cof = 0.0 if not isimp: c1sq = self._m_c1 * self._m_c1 d2 = 4.0 * self._m_aodp * self._m_tsi * c1sq temp = d2 * self._m_tsi * self._m_c1 / 3.0 d3 = (17.0 * self._m_aodp + self._m_s4) * temp d4 = 0.5 * temp * self._m_aodp * self._m_tsi * ( 221.0 * self._m_aodp + 31.0 * self._m_s4) * self._m_c1 t3cof = d2 + 2.0 * c1sq t4cof = 0.25 * (3.0 * d3 + self._m_c1 * (12.0 * d2 + 10.0 * c1sq)) t5cof = 0.2 * (3.0 * d4 + 12.0 * self._m_c1 * d3 + 6.0 * d2 * d2 + 15.0 * c1sq * (2.0 * d2 + c1sq)) # Update for secular gravity and atmospheric drag. xmdf = self.Orbit.MeanAnomaly + self._m_xmdot * tsince omgadf = self.Orbit.ArgPerigee + self._m_omgdot * tsince xnoddf = self.Orbit.RAAN + self._m_xnodot * tsince omega = omgadf xmp = xmdf tsq = tsince * tsince xnode = xnoddf + self._m_xnodcf * tsq tempa = 1.0 - self._m_c1 * tsince tempe = self.Orbit.BStar * self._m_c4 * tsince templ = self._m_t2cof * tsq if not isimp: delomg = self._m_omgcof * tsince delm = self._m_xmcof * (math.pow( 1.0 + self._m_eta * math.cos(xmdf), 3.0) - self._m_delmo) temp = delomg + delm xmp = xmdf + temp omega = omgadf - temp tcube = tsq * tsince tfour = tsince * tcube tempa = tempa - d2 * tsq - d3 * tcube - d4 * tfour tempe = tempe + self.Orbit.BStar * self._m_c5 * (math.sin(xmp) - self._m_sinmo) templ = templ + t3cof * tcube + tfour * (t4cof + tsince * t5cof) a = self._m_aodp * Globals.Sqr(tempa) e = self._m_satEcc - tempe xl = xmp + omega + xnode + self._m_xnodp * templ xn = Globals.Xke / math.pow(a, 1.5) return self.FinalPosition(self._m_satInc, omgadf, e, a, xl, xnode, xn, tsince)
def InitializeByDegLatAndDegLonAndKmAltAndName(self, degLat, degLon, kmAlt, name=""): self._geo = Geo().InitializeByRadLatAndRadLonAndKmAlt(Globals.ToRadians(degLat), Globals.ToRadians(degLon), kmAlt) self._name = name return self
def FinalPosition(self, incl, omega, e, a, xl, xnode, xn, tsince): if (e * e) > 1.0: raise ValueError("Error in satellite data") beta = math.sqrt(1.0 - e * e) # Long period periodics axn = e * math.cos(omega) temp = 1.0 / (a * beta * beta) xll = temp * self._m_xlcof * axn aynl = temp * self._m_aycof xlt = xl + xll ayn = e * math.sin(omega) + aynl # Solve Kepler`s Equation capu = Globals.Fmod2p(xlt - xnode) temp2 = capu temp3 = 0.0 temp4 = 0.0 temp5 = 0.0 temp6 = 0.0 sinepw = 0.0 cosepw = 0.0 fDone = False i = 1 while ((i <= 10) and (not fDone)): sinepw = math.sin(temp2) cosepw = math.cos(temp2) temp3 = axn * sinepw temp4 = ayn * cosepw temp5 = axn * cosepw temp6 = ayn * sinepw epw = (capu - temp4 + temp3 - temp2) / (1.0 - temp5 - temp6) + temp2 if math.fabs(epw - temp2) <= 1.0e-06: fDone = True else: temp2 = epw i += 1 # Short period preliminary quantities ecose = temp5 + temp6 esine = temp3 - temp4 elsq = axn * axn + ayn * ayn temp = 1.0 - elsq pl = a * temp r = a * (1.0 - ecose) temp1 = 1.0 / r rdot = Globals.Xke * math.sqrt(a) * esine * temp1 rfdot = Globals.Xke * math.sqrt(pl) * temp1 temp2 = a * temp1 betal = math.sqrt(temp) temp3 = 1.0 / (1.0 + betal) cosu = temp2 * (cosepw - axn + ayn * esine * temp3) sinu = temp2 * (sinepw - ayn - axn * esine * temp3) u = Globals.AcTan(sinu, cosu) sin2u = 2.0 * sinu * cosu cos2u = 2.0 * cosu * cosu - 1.0 temp = 1.0 / pl temp1 = Globals.Ck2 * temp temp2 = temp1 * temp # Update for short periodics rk = r * (1.0 - 1.5 * temp2 * betal * self._m_x3thm1) + 0.5 * temp1 * self._m_x1mth2 * cos2u uk = u - 0.25 * temp2 * self._m_x7thm1 * sin2u xnodek = xnode + 1.5 * temp2 * self._m_cosio * sin2u xinck = incl + 1.5 * temp2 * self._m_cosio * self._m_sinio * cos2u rdotk = rdot - xn * temp1 * self._m_x1mth2 * sin2u rfdotk = rfdot + xn * temp1 * (self._m_x1mth2 * cos2u + 1.5 * self._m_x3thm1) # Orientation vectors sinuk = math.sin(uk) cosuk = math.cos(uk) sinik = math.sin(xinck) cosik = math.cos(xinck) sinnok = math.sin(xnodek) cosnok = math.cos(xnodek) xmx = -sinnok * cosik xmy = cosnok * cosik ux = xmx * sinuk + cosnok * cosuk uy = xmy * sinuk + sinnok * cosuk uz = sinik * sinuk vx = xmx * cosuk - cosnok * sinuk vy = xmy * cosuk - sinnok * sinuk vz = sinik * cosuk # Position x = rk * ux y = rk * uy z = rk * uz vecPos = Vector(x, y, z) gmt = self.Orbit.EpochTime + datetime.timedelta(minutes=tsince) # Validate on altitude altKm = (vecPos.Magnitude() * (Globals.Xkmper / Globals.Ae)) if altKm < Globals.Xkmper: raise ValueError(str(gmt) + self.Orbit.SatNameLong) # Velocity xdot = rdotk * ux + rfdotk * vx ydot = rdotk * uy + rfdotk * vy zdot = rdotk * uz + rfdotk * vz vecVel = Vector(xdot, ydot, zdot) return EciTime().InitializeByPosAndVelAndDate( vecPos, vecVel, Julian().InitializeByUTC(gmt))
def LongitudeDeg(self): return Globals.ToDegrees(self._longitudeRad)
def LatitudeDeg(self): return Globals.ToDegrees(self._latitudeRad)
def ElevationDeg(self): return Globals.ToDegrees(self._elevationRad)
def AzimuthDeg(self): return Globals.ToDegrees(self._azimuthRad)
def InitializeByEciAndDate(self, eci, date): self.InitializeByPosAndTheta( eci.Position, (Globals.AcTan(eci.Position.Y, eci.Position.X) - date.ToGmst()) % Globals.TwoPi) return self