korba 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/korba/sgp4/elset_rec.rb +432 -0
- data/lib/korba/sgp4/sgp4.rb +2027 -0
- data/lib/korba/tle.rb +83 -5
- data/lib/korba/version.rb +1 -1
- data/lib/korba.rb +2 -0
- metadata +4 -2
@@ -0,0 +1,2027 @@
|
|
1
|
+
module Korba
|
2
|
+
class SGP4
|
3
|
+
# copied from https://github.com/aholinch/sgp4
|
4
|
+
# ----------------------------------------------------------------
|
5
|
+
#
|
6
|
+
# sgp4unit.cpp
|
7
|
+
#
|
8
|
+
# this file contains the sgp4 procedures for analytical propagation
|
9
|
+
# of a satellite. the code was originally released in the 1980 and 1986
|
10
|
+
# spacetrack papers. a detailed discussion of the theory and history
|
11
|
+
# may be found in the 2006 aiaa paper by vallado, crawford, hujsak,
|
12
|
+
# and kelso.
|
13
|
+
# このファイルには、衛星の解析的伝播のためのsgp4手順が含まれています。
|
14
|
+
# コードは元々1980年と1986年のスペーストラック論文で公開されました。
|
15
|
+
# 理論と歴史の詳細な議論は、ヴァラド、クロフォード、フジャック、
|
16
|
+
# ケルソによる2006年のAIAA論文に記載されています。
|
17
|
+
#
|
18
|
+
# companion code for
|
19
|
+
# fundamentals of astrodynamics and applications
|
20
|
+
# 2013
|
21
|
+
# by david vallado
|
22
|
+
#
|
23
|
+
# (w) 719-573-2600, email dvallado@agi.com, davallado@gmail.com
|
24
|
+
#
|
25
|
+
# current :
|
26
|
+
# 7 dec 15 david vallado
|
27
|
+
# fix jd, jdfrac
|
28
|
+
# changes :
|
29
|
+
# 3 nov 14 david vallado
|
30
|
+
# update to msvs2013 c++
|
31
|
+
# 30 aug 10 david vallado
|
32
|
+
# delete unused variables in initl
|
33
|
+
# replace pow integer 2, 3 with multiplies for speed
|
34
|
+
# 3 nov 08 david vallado
|
35
|
+
# put returns in for error codes
|
36
|
+
# 29 sep 08 david vallado
|
37
|
+
# fix atime for faster operation in dspace
|
38
|
+
# add operationmode for afspc (a) or improved (i)
|
39
|
+
# performance mode
|
40
|
+
# 16 jun 08 david vallado
|
41
|
+
# update small eccentricity check
|
42
|
+
# 16 nov 07 david vallado
|
43
|
+
# misc fixes for better compliance
|
44
|
+
# 20 apr 07 david vallado
|
45
|
+
# misc fixes for constants
|
46
|
+
# 11 aug 06 david vallado
|
47
|
+
# chg lyddane choice back to strn3, constants, misc doc
|
48
|
+
# 15 dec 05 david vallado
|
49
|
+
# misc fixes
|
50
|
+
# 26 jul 05 david vallado
|
51
|
+
# fixes for paper
|
52
|
+
# note that each fix is preceded by a
|
53
|
+
# comment with "sgp4fix" and an explanation of
|
54
|
+
# what was changed
|
55
|
+
# 10 aug 04 david vallado
|
56
|
+
# 2nd printing baseline working
|
57
|
+
# 14 may 01 david vallado
|
58
|
+
# 2nd edition baseline
|
59
|
+
# 80 norad
|
60
|
+
# original baseline
|
61
|
+
# ---------------------------------------------------------------- */
|
62
|
+
|
63
|
+
PI = Math::PI
|
64
|
+
TWOPI = 2.0 * Math::PI
|
65
|
+
DEG2RAD = PI / 180.0
|
66
|
+
|
67
|
+
WGS72old = 1
|
68
|
+
WGS72 = 2
|
69
|
+
WGS84 = 3
|
70
|
+
|
71
|
+
# -----------------------------------------------------------------------------
|
72
|
+
#
|
73
|
+
# procedure dpper
|
74
|
+
#
|
75
|
+
# this procedure provides deep space long period periodic contributions
|
76
|
+
# to the mean elements. by design, these periodics are zero at epoch.
|
77
|
+
# this used to be dscom which included initialization, but it's really a
|
78
|
+
# recurring function.
|
79
|
+
# この手順は、平均要素に対する深宇宙の長周期の周期的寄与を提供します。
|
80
|
+
# 設計上、これらの周期的寄与はエポック時にゼロです。
|
81
|
+
# 以前は初期化を含む dscom でしたが、実際には再帰的な関数です。
|
82
|
+
#
|
83
|
+
# author : david vallado 719-573-2600 28 jun 2005
|
84
|
+
#
|
85
|
+
# inputs :
|
86
|
+
# e3 -
|
87
|
+
# ee2 -
|
88
|
+
# peo -
|
89
|
+
# pgho -
|
90
|
+
# pho -
|
91
|
+
# pinco -
|
92
|
+
# plo -
|
93
|
+
# se2 , se3 , sgh2, sgh3, sgh4, sh2, sh3, si2, si3, sl2, sl3, sl4 -
|
94
|
+
# t -
|
95
|
+
# xh2, xh3, xi2, xi3, xl2, xl3, xl4 -
|
96
|
+
# zmol -
|
97
|
+
# zmos -
|
98
|
+
# ep - eccentricity 0.0 - 1.0
|
99
|
+
# inclo - inclination - needed for lyddane modification
|
100
|
+
# nodep - right ascension of ascending node
|
101
|
+
# argpp - argument of perigee
|
102
|
+
# mp - mean anomaly
|
103
|
+
#
|
104
|
+
# outputs :
|
105
|
+
# ep - eccentricity 0.0 - 1.0
|
106
|
+
# inclp - inclination
|
107
|
+
# nodep - right ascension of ascending node
|
108
|
+
# argpp - argument of perigee
|
109
|
+
# mp - mean anomaly
|
110
|
+
#
|
111
|
+
# locals :
|
112
|
+
# alfdp -
|
113
|
+
# betdp -
|
114
|
+
# cosip , sinip , cosop , sinop ,
|
115
|
+
# dalf -
|
116
|
+
# dbet -
|
117
|
+
# dls -
|
118
|
+
# f2, f3 -
|
119
|
+
# pe -
|
120
|
+
# pgh -
|
121
|
+
# ph -
|
122
|
+
# pinc -
|
123
|
+
# pl -
|
124
|
+
# sel , ses , sghl , sghs , shl , shs , sil , sinzf , sis ,
|
125
|
+
# sll , sls
|
126
|
+
# xls -
|
127
|
+
# xnoh -
|
128
|
+
# zf -
|
129
|
+
# zm -
|
130
|
+
#
|
131
|
+
# coupling :
|
132
|
+
# none.
|
133
|
+
#
|
134
|
+
# references :
|
135
|
+
# hoots, roehrich, norad spacetrack report #3 1980
|
136
|
+
# hoots, norad spacetrack report #6 1986
|
137
|
+
# hoots, schumacher and glover 2004
|
138
|
+
# vallado, crawford, hujsak, kelso 2006
|
139
|
+
#---------------------------------------------------------------------------*/
|
140
|
+
|
141
|
+
def self.dpper(e3, ee2, peo, pgho, pho, pinco, plo, se2, se3, sgh2,
|
142
|
+
sgh3, sgh4, sh2, sh3, si2, si3, sl2, sl3, sl4, t,
|
143
|
+
xgh2, xgh3, xgh4, xh2, xh3, xi2, xi3, xl2, xl3, xl4,
|
144
|
+
zmol, zmos, init, rec, opsmode)
|
145
|
+
|
146
|
+
# --------------------- local variables ------------------------ */
|
147
|
+
#double alfdp, betdp, cosip, cosop, dalf, dbet, dls,
|
148
|
+
# f2, f3, pe, pgh, ph, pinc, pl,
|
149
|
+
# sel, ses, sghl, sghs, shll, shs, sil,
|
150
|
+
# sinip, sinop, sinzf, sis, sll, sls, xls,
|
151
|
+
# xnoh, zf, zm, zel, zes, znl, zns
|
152
|
+
|
153
|
+
#/* ---------------------- constants ----------------------------- */
|
154
|
+
zns = 1.19459e-5
|
155
|
+
zes = 0.01675
|
156
|
+
znl = 1.5835218e-4
|
157
|
+
zel = 0.05490
|
158
|
+
|
159
|
+
#/* --------------- calculate time varying periodics ----------- */
|
160
|
+
zm = zmos + zns * t
|
161
|
+
#// be sure that the initial call has time set to zero
|
162
|
+
if init == "y"
|
163
|
+
zm = zmos
|
164
|
+
end
|
165
|
+
|
166
|
+
zf = zm + 2.0 * zes * Math.sin(zm)
|
167
|
+
sinzf = Math.sin(zf)
|
168
|
+
f2 = 0.5 * sinzf * sinzf - 0.25
|
169
|
+
f3 = -0.5 * sinzf * Math.cos(zf)
|
170
|
+
ses = se2 * f2 + se3 * f3
|
171
|
+
sis = si2 * f2 + si3 * f3
|
172
|
+
sls = sl2 * f2 + sl3 * f3 + sl4 * sinzf
|
173
|
+
sghs = sgh2 * f2 + sgh3 * f3 + sgh4 * sinzf
|
174
|
+
shs = sh2 * f2 + sh3 * f3
|
175
|
+
zm = zmol + znl * t
|
176
|
+
if init == "y"
|
177
|
+
zm = zmol
|
178
|
+
end
|
179
|
+
|
180
|
+
zf = zm + 2.0 * zel * Math.sin(zm)
|
181
|
+
sinzf = Math.sin(zf)
|
182
|
+
f2 = 0.5 * sinzf * sinzf - 0.25
|
183
|
+
f3 = -0.5 * sinzf * Math.cos(zf)
|
184
|
+
sel = ee2 * f2 + e3 * f3
|
185
|
+
sil = xi2 * f2 + xi3 * f3
|
186
|
+
sll = xl2 * f2 + xl3 * f3 + xl4 * sinzf
|
187
|
+
sghl = xgh2 * f2 + xgh3 * f3 + xgh4 * sinzf
|
188
|
+
shll = xh2 * f2 + xh3 * f3
|
189
|
+
pe = ses + sel
|
190
|
+
pinc = sis + sil
|
191
|
+
pl = sls + sll
|
192
|
+
pgh = sghs + sghl
|
193
|
+
ph = shs + shll
|
194
|
+
|
195
|
+
if init == "n"
|
196
|
+
pe = pe - peo
|
197
|
+
pinc = pinc - pinco
|
198
|
+
pl = pl - plo
|
199
|
+
pgh = pgh - pgho
|
200
|
+
ph = ph - pho
|
201
|
+
rec.inclp = rec.inclp + pinc
|
202
|
+
rec.ep = rec.ep + pe
|
203
|
+
sinip = Math.sin(rec.inclp)
|
204
|
+
cosip = Math.cos(rec.inclp)
|
205
|
+
|
206
|
+
#/* ----------------- apply periodics directly ------------ */
|
207
|
+
#// sgp4fix for lyddane choice
|
208
|
+
#// strn3 used original inclination - this is technically feasible
|
209
|
+
#// gsfc used perturbed inclination - also technically feasible
|
210
|
+
#// probably best to readjust the 0.2 limit value and limit discontinuity
|
211
|
+
#// 0.2 rad = 11.45916 deg
|
212
|
+
#// use next line for original strn3 approach and original inclination
|
213
|
+
#// if (inclo >= 0.2)
|
214
|
+
#// use next line for gsfc version and perturbed inclination
|
215
|
+
if rec.inclp >= 0.2
|
216
|
+
ph = ph / sinip
|
217
|
+
pgh = pgh - cosip * ph
|
218
|
+
rec.argpp = rec.argpp + pgh
|
219
|
+
rec.nodep = rec.nodep + ph
|
220
|
+
rec.mp = rec.mp + pl
|
221
|
+
else
|
222
|
+
#/* ---- apply periodics with lyddane modification ---- */
|
223
|
+
sinop = Math.sin(rec.nodep)
|
224
|
+
cosop = Math.cos(rec.nodep)
|
225
|
+
alfdp = sinip * sinop
|
226
|
+
betdp = sinip * cosop
|
227
|
+
dalf = ph * cosop + pinc * cosip * sinop
|
228
|
+
dbet = -ph * sinop + pinc * cosip * cosop
|
229
|
+
alfdp = alfdp + dalf
|
230
|
+
betdp = betdp + dbet
|
231
|
+
rec.nodep = fmod(rec.nodep, TWOPI)
|
232
|
+
#// sgp4fix for afspc written intrinsic functions
|
233
|
+
#// nodep used without a trigonometric function ahead
|
234
|
+
if (rec.nodep < 0.0) and (opsmode == "a")
|
235
|
+
rec.nodep = rec.nodep + TWOPI
|
236
|
+
end
|
237
|
+
xls = rec.mp + rec.argpp + cosip * rec.nodep
|
238
|
+
dls = pl + pgh - pinc * rec.nodep * sinip
|
239
|
+
xls = xls + dls
|
240
|
+
xls = fmod(xls, TWOPI)
|
241
|
+
xnoh = rec.nodep
|
242
|
+
rec.nodep = Math.atan2(alfdp, betdp)
|
243
|
+
#// sgp4fix for afspc written intrinsic functions
|
244
|
+
#// nodep used without a trigonometric function ahead
|
245
|
+
if (rec.nodep < 0.0) and (opsmode == "a")
|
246
|
+
rec.nodep = rec.nodep + TWOPI
|
247
|
+
end
|
248
|
+
if (xnoh - rec.nodep).abs > PI
|
249
|
+
if (rec.nodep < xnoh)
|
250
|
+
rec.nodep = rec.nodep + TWOPI
|
251
|
+
else
|
252
|
+
rec.nodep = rec.nodep - TWOPI
|
253
|
+
end
|
254
|
+
end
|
255
|
+
rec.mp = rec.mp + pl
|
256
|
+
rec.argpp = xls - rec.mp - cosip * rec.nodep
|
257
|
+
end
|
258
|
+
# // if init == 'n'
|
259
|
+
end
|
260
|
+
|
261
|
+
#// dpper
|
262
|
+
end
|
263
|
+
|
264
|
+
#/*-----------------------------------------------------------------------------
|
265
|
+
#*
|
266
|
+
#* procedure dscom
|
267
|
+
#*
|
268
|
+
#* this procedure provides deep space common items used by both the secular
|
269
|
+
#* and periodics subroutines. input is provided as shown. this routine
|
270
|
+
#* used to be called dpper, but the functions inside weren't well organized.
|
271
|
+
#* この手順は、深宇宙の共通項目を提供し、世俗的および周期的なサブルーチンの両方で使用されます。
|
272
|
+
#* 入力は以下のように提供されます。このルーチンは以前はdpperと呼ばれていましたが、
|
273
|
+
#* 内部の関数がうまく整理されていませんでした。
|
274
|
+
#*
|
275
|
+
#* author : david vallado 719-573-2600 28 jun 2005
|
276
|
+
#*
|
277
|
+
#* inputs :
|
278
|
+
#* epoch -
|
279
|
+
#* ep - eccentricity
|
280
|
+
#* argpp - argument of perigee
|
281
|
+
#* tc -
|
282
|
+
#* inclp - inclination
|
283
|
+
#* nodep - right ascension of ascending node
|
284
|
+
#* np - mean motion
|
285
|
+
#*
|
286
|
+
#* outputs :
|
287
|
+
#* sinim , cosim , sinomm , cosomm , snodm , cnodm
|
288
|
+
#* day -
|
289
|
+
#* e3 -
|
290
|
+
#* ee2 -
|
291
|
+
#* em - eccentricity
|
292
|
+
#* emsq - eccentricity squared
|
293
|
+
#* gam -
|
294
|
+
#* peo -
|
295
|
+
#* pgho -
|
296
|
+
#* pho -
|
297
|
+
#* pinco -
|
298
|
+
#* plo -
|
299
|
+
#* rtemsq -
|
300
|
+
#* se2, se3 -
|
301
|
+
#* sgh2, sgh3, sgh4 -
|
302
|
+
#* sh2, sh3, si2, si3, sl2, sl3, sl4 -
|
303
|
+
#* s1, s2, s3, s4, s5, s6, s7 -
|
304
|
+
#* ss1, ss2, ss3, ss4, ss5, ss6, ss7, sz1, sz2, sz3 -
|
305
|
+
#* sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33 -
|
306
|
+
#* xgh2, xgh3, xgh4, xh2, xh3, xi2, xi3, xl2, xl3, xl4 -
|
307
|
+
#* nm - mean motion
|
308
|
+
#* z1, z2, z3, z11, z12, z13, z21, z22, z23, z31, z32, z33 -
|
309
|
+
#* zmol -
|
310
|
+
#* zmos -
|
311
|
+
#*
|
312
|
+
#* locals :
|
313
|
+
#* a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 -
|
314
|
+
#* betasq -
|
315
|
+
#* cc -
|
316
|
+
#* ctem, stem -
|
317
|
+
#* x1, x2, x3, x4, x5, x6, x7, x8 -
|
318
|
+
#* xnodce -
|
319
|
+
#* xnoi -
|
320
|
+
#* zcosg , zsing , zcosgl , zsingl , zcosh , zsinh , zcoshl , zsinhl ,
|
321
|
+
#* zcosi , zsini , zcosil , zsinil ,
|
322
|
+
#* zx -
|
323
|
+
#* zy -
|
324
|
+
#*
|
325
|
+
#* coupling :
|
326
|
+
#* none.
|
327
|
+
#*
|
328
|
+
#* references :
|
329
|
+
#* hoots, roehrich, norad spacetrack report #3 1980
|
330
|
+
#* hoots, norad spacetrack report #6 1986
|
331
|
+
#* hoots, schumacher and glover 2004
|
332
|
+
#* vallado, crawford, hujsak, kelso 2006
|
333
|
+
#----------------------------------------------------------------------------*/
|
334
|
+
|
335
|
+
def self.dscom(epoch, ep, argpp, tc, inclp, nodep, np, rec)
|
336
|
+
#/* -------------------------- constants ------------------------- */
|
337
|
+
zes = 0.01675
|
338
|
+
zel = 0.05490
|
339
|
+
c1ss = 2.9864797e-6
|
340
|
+
c1l = 4.7968065e-7
|
341
|
+
zsinis = 0.39785416
|
342
|
+
zcosis = 0.91744867
|
343
|
+
zcosgs = 0.1945905
|
344
|
+
zsings = -0.98088458
|
345
|
+
|
346
|
+
#/* --------------------- local variables ------------------------ */
|
347
|
+
#int lsflg
|
348
|
+
#double a1, a2, a3, a4, a5, a6, a7,
|
349
|
+
# a8, a9, a10, betasq, cc, ctem, stem,
|
350
|
+
# x1, x2, x3, x4, x5, x6, x7,
|
351
|
+
# x8, xnodce, xnoi, zcosg, zcosgl, zcosh, zcoshl,
|
352
|
+
# zcosi, zcosil, zsing, zsingl, zsinh, zsinhl, zsini,
|
353
|
+
# zsinil, zx, zy
|
354
|
+
|
355
|
+
rec.nm = np
|
356
|
+
rec.em = ep
|
357
|
+
rec.snodm = Math.sin(nodep)
|
358
|
+
rec.cnodm = Math.cos(nodep)
|
359
|
+
rec.sinomm = Math.sin(argpp)
|
360
|
+
rec.cosomm = Math.cos(argpp)
|
361
|
+
rec.sinim = Math.sin(inclp)
|
362
|
+
rec.cosim = Math.cos(inclp)
|
363
|
+
rec.emsq = rec.em * rec.em
|
364
|
+
betasq = 1.0 - rec.emsq
|
365
|
+
rec.rtemsq = Math.sqrt(betasq)
|
366
|
+
|
367
|
+
#/* ----------------- initialize lunar solar terms --------------- */
|
368
|
+
rec.peo = 0.0
|
369
|
+
rec.pinco = 0.0
|
370
|
+
rec.plo = 0.0
|
371
|
+
rec.pgho = 0.0
|
372
|
+
rec.pho = 0.0
|
373
|
+
rec.day = epoch + 18261.5 + tc / 1440.0
|
374
|
+
xnodce = fmod(4.5236020 - 9.2422029e-4 * rec.day, TWOPI)
|
375
|
+
stem = Math.sin(xnodce)
|
376
|
+
ctem = Math.cos(xnodce)
|
377
|
+
zcosil = 0.91375164 - 0.03568096 * ctem
|
378
|
+
zsinil = Math.sqrt(1.0 - zcosil * zcosil)
|
379
|
+
zsinhl = 0.089683511 * stem / zsinil
|
380
|
+
zcoshl = Math.sqrt(1.0 - zsinhl * zsinhl)
|
381
|
+
rec.gam = 5.8351514 + 0.0019443680 * rec.day
|
382
|
+
zx = 0.39785416 * stem / zsinil
|
383
|
+
zy = zcoshl * ctem + 0.91744867 * zsinhl * stem
|
384
|
+
zx = Math.atan2(zx, zy)
|
385
|
+
zx = rec.gam + zx - xnodce
|
386
|
+
zcosgl = Math.cos(zx)
|
387
|
+
zsingl = Math.sin(zx)
|
388
|
+
|
389
|
+
#/* ------------------------- do solar terms --------------------- */
|
390
|
+
zcosg = zcosgs
|
391
|
+
zsing = zsings
|
392
|
+
zcosi = zcosis
|
393
|
+
zsini = zsinis
|
394
|
+
zcosh = rec.cnodm
|
395
|
+
zsinh = rec.snodm
|
396
|
+
cc = c1ss
|
397
|
+
xnoi = 1.0 / rec.nm
|
398
|
+
|
399
|
+
for lsflg in 1..3
|
400
|
+
a1 = zcosg * zcosh + zsing * zcosi * zsinh
|
401
|
+
a3 = -zsing * zcosh + zcosg * zcosi * zsinh
|
402
|
+
a7 = -zcosg * zsinh + zsing * zcosi * zcosh
|
403
|
+
a8 = zsing * zsini
|
404
|
+
a9 = zsing * zsinh + zcosg * zcosi * zcosh
|
405
|
+
a10 = zcosg * zsini
|
406
|
+
a2 = rec.cosim * a7 + rec.sinim * a8
|
407
|
+
a4 = rec.cosim * a9 + rec.sinim * a10
|
408
|
+
a5 = -rec.sinim * a7 + rec.cosim * a8
|
409
|
+
a6 = -rec.sinim * a9 + rec.cosim * a10
|
410
|
+
|
411
|
+
x1 = a1 * rec.cosomm + a2 * rec.sinomm
|
412
|
+
x2 = a3 * rec.cosomm + a4 * rec.sinomm
|
413
|
+
x3 = -a1 * rec.sinomm + a2 * rec.cosomm
|
414
|
+
x4 = -a3 * rec.sinomm + a4 * rec.cosomm
|
415
|
+
x5 = a5 * rec.sinomm
|
416
|
+
x6 = a6 * rec.sinomm
|
417
|
+
x7 = a5 * rec.cosomm
|
418
|
+
x8 = a6 * rec.cosomm
|
419
|
+
|
420
|
+
rec.z31 = 12.0 * x1 * x1 - 3.0 * x3 * x3
|
421
|
+
rec.z32 = 24.0 * x1 * x2 - 6.0 * x3 * x4
|
422
|
+
rec.z33 = 12.0 * x2 * x2 - 3.0 * x4 * x4
|
423
|
+
rec.z1 = 3.0 * (a1 * a1 + a2 * a2) + rec.z31 * rec.emsq
|
424
|
+
rec.z2 = 6.0 * (a1 * a3 + a2 * a4) + rec.z32 * rec.emsq
|
425
|
+
rec.z3 = 3.0 * (a3 * a3 + a4 * a4) + rec.z33 * rec.emsq
|
426
|
+
rec.z11 = -6.0 * a1 * a5 + rec.emsq * (-24.0 * x1 * x7 - 6.0 * x3 * x5)
|
427
|
+
rec.z12 = (-6.0 * (a1 * a6 + a3 * a5) + rec.emsq *
|
428
|
+
(-24.0 * (x2 * x7 + x1 * x8) - 6.0 * (x3 * x6 + x4 * x5)))
|
429
|
+
rec.z13 = -6.0 * a3 * a6 + rec.emsq * (-24.0 * x2 * x8 - 6.0 * x4 * x6)
|
430
|
+
rec.z21 = 6.0 * a2 * a5 + rec.emsq * (24.0 * x1 * x5 - 6.0 * x3 * x7)
|
431
|
+
rec.z22 = (6.0 * (a4 * a5 + a2 * a6) + rec.emsq *
|
432
|
+
(24.0 * (x2 * x5 + x1 * x6) - 6.0 * (x4 * x7 + x3 * x8)))
|
433
|
+
rec.z23 = 6.0 * a4 * a6 + rec.emsq * (24.0 * x2 * x6 - 6.0 * x4 * x8)
|
434
|
+
rec.z1 = rec.z1 + rec.z1 + betasq * rec.z31
|
435
|
+
rec.z2 = rec.z2 + rec.z2 + betasq * rec.z32
|
436
|
+
rec.z3 = rec.z3 + rec.z3 + betasq * rec.z33
|
437
|
+
rec.s3 = cc * xnoi
|
438
|
+
rec.s2 = -0.5 * rec.s3 / rec.rtemsq
|
439
|
+
rec.s4 = rec.s3 * rec.rtemsq
|
440
|
+
rec.s1 = -15.0 * rec.em * rec.s4
|
441
|
+
rec.s5 = x1 * x3 + x2 * x4
|
442
|
+
rec.s6 = x2 * x3 + x1 * x4
|
443
|
+
rec.s7 = x2 * x4 - x1 * x3
|
444
|
+
|
445
|
+
#/* ----------------------- do lunar terms ------------------- */
|
446
|
+
if lsflg == 1
|
447
|
+
rec.ss1 = rec.s1
|
448
|
+
rec.ss2 = rec.s2
|
449
|
+
rec.ss3 = rec.s3
|
450
|
+
rec.ss4 = rec.s4
|
451
|
+
rec.ss5 = rec.s5
|
452
|
+
rec.ss6 = rec.s6
|
453
|
+
rec.ss7 = rec.s7
|
454
|
+
rec.sz1 = rec.z1
|
455
|
+
rec.sz2 = rec.z2
|
456
|
+
rec.sz3 = rec.z3
|
457
|
+
rec.sz11 = rec.z11
|
458
|
+
rec.sz12 = rec.z12
|
459
|
+
rec.sz13 = rec.z13
|
460
|
+
rec.sz21 = rec.z21
|
461
|
+
rec.sz22 = rec.z22
|
462
|
+
rec.sz23 = rec.z23
|
463
|
+
rec.sz31 = rec.z31
|
464
|
+
rec.sz32 = rec.z32
|
465
|
+
rec.sz33 = rec.z33
|
466
|
+
zcosg = zcosgl
|
467
|
+
zsing = zsingl
|
468
|
+
zcosi = zcosil
|
469
|
+
zsini = zsinil
|
470
|
+
zcosh = zcoshl * rec.cnodm + zsinhl * rec.snodm
|
471
|
+
zsinh = rec.snodm * zcoshl - rec.cnodm * zsinhl
|
472
|
+
cc = c1l
|
473
|
+
end
|
474
|
+
#end lsflg == 1
|
475
|
+
end
|
476
|
+
# end for loop
|
477
|
+
|
478
|
+
rec.zmol = fmod(4.7199672 + 0.22997150 * rec.day - rec.gam, TWOPI)
|
479
|
+
rec.zmos = fmod(6.2565837 + 0.017201977 * rec.day, TWOPI)
|
480
|
+
|
481
|
+
#/* ------------------------ do solar terms ---------------------- */
|
482
|
+
rec.se2 = 2.0 * rec.ss1 * rec.ss6
|
483
|
+
rec.se3 = 2.0 * rec.ss1 * rec.ss7
|
484
|
+
rec.si2 = 2.0 * rec.ss2 * rec.sz12
|
485
|
+
rec.si3 = 2.0 * rec.ss2 * (rec.sz13 - rec.sz11)
|
486
|
+
rec.sl2 = -2.0 * rec.ss3 * rec.sz2
|
487
|
+
rec.sl3 = -2.0 * rec.ss3 * (rec.sz3 - rec.sz1)
|
488
|
+
rec.sl4 = -2.0 * rec.ss3 * (-21.0 - 9.0 * rec.emsq) * zes
|
489
|
+
rec.sgh2 = 2.0 * rec.ss4 * rec.sz32
|
490
|
+
rec.sgh3 = 2.0 * rec.ss4 * (rec.sz33 - rec.sz31)
|
491
|
+
rec.sgh4 = -18.0 * rec.ss4 * zes
|
492
|
+
rec.sh2 = -2.0 * rec.ss2 * rec.sz22
|
493
|
+
rec.sh3 = -2.0 * rec.ss2 * (rec.sz23 - rec.sz21)
|
494
|
+
|
495
|
+
#/* ------------------------ do lunar terms ---------------------- */
|
496
|
+
rec.ee2 = 2.0 * rec.s1 * rec.s6
|
497
|
+
rec.e3 = 2.0 * rec.s1 * rec.s7
|
498
|
+
rec.xi2 = 2.0 * rec.s2 * rec.z12
|
499
|
+
rec.xi3 = 2.0 * rec.s2 * (rec.z13 - rec.z11)
|
500
|
+
rec.xl2 = -2.0 * rec.s3 * rec.z2
|
501
|
+
rec.xl3 = -2.0 * rec.s3 * (rec.z3 - rec.z1)
|
502
|
+
rec.xl4 = -2.0 * rec.s3 * (-21.0 - 9.0 * rec.emsq) * zel
|
503
|
+
rec.xgh2 = 2.0 * rec.s4 * rec.z32
|
504
|
+
rec.xgh3 = 2.0 * rec.s4 * (rec.z33 - rec.z31)
|
505
|
+
rec.xgh4 = -18.0 * rec.s4 * zel
|
506
|
+
rec.xh2 = -2.0 * rec.s2 * rec.z22
|
507
|
+
rec.xh3 = -2.0 * rec.s2 * (rec.z23 - rec.z21)
|
508
|
+
|
509
|
+
#} // dscom
|
510
|
+
end
|
511
|
+
|
512
|
+
#/*-----------------------------------------------------------------------------
|
513
|
+
#*
|
514
|
+
#* procedure dsinit
|
515
|
+
#*
|
516
|
+
#* this procedure provides deep space contributions to mean motion dot due
|
517
|
+
#* to geopotential resonance with half day and one day orbits.
|
518
|
+
#* この手順は、半日および一日の軌道との重力共鳴による平均運動ドットへの深宇宙寄与を提供します。
|
519
|
+
#*
|
520
|
+
#* author : david vallado 719-573-2600 28 jun 2005
|
521
|
+
#*
|
522
|
+
#* inputs :
|
523
|
+
#* xke - reciprocal of tumin
|
524
|
+
#* cosim, sinim-
|
525
|
+
#* emsq - eccentricity squared
|
526
|
+
#* argpo - argument of perigee
|
527
|
+
#* s1, s2, s3, s4, s5 -
|
528
|
+
#* ss1, ss2, ss3, ss4, ss5 -
|
529
|
+
#* sz1, sz3, sz11, sz13, sz21, sz23, sz31, sz33 -
|
530
|
+
#* t - time
|
531
|
+
#* tc -
|
532
|
+
#* gsto - greenwich sidereal time rad
|
533
|
+
#* mo - mean anomaly
|
534
|
+
#* mdot - mean anomaly dot (rate)
|
535
|
+
#* no - mean motion
|
536
|
+
#* nodeo - right ascension of ascending node
|
537
|
+
#* nodedot - right ascension of ascending node dot (rate)
|
538
|
+
#* xpidot -
|
539
|
+
#* z1, z3, z11, z13, z21, z23, z31, z33 -
|
540
|
+
#* eccm - eccentricity
|
541
|
+
#* argpm - argument of perigee
|
542
|
+
#* inclm - inclination
|
543
|
+
#* mm - mean anomaly
|
544
|
+
#* xn - mean motion
|
545
|
+
#* nodem - right ascension of ascending node
|
546
|
+
#*
|
547
|
+
#* outputs :
|
548
|
+
#* em - eccentricity
|
549
|
+
#* argpm - argument of perigee
|
550
|
+
#* inclm - inclination
|
551
|
+
#* mm - mean anomaly
|
552
|
+
#* nm - mean motion
|
553
|
+
#* nodem - right ascension of ascending node
|
554
|
+
#* irez - flag for resonance 0-none, 1-one day, 2-half day
|
555
|
+
#* atime -
|
556
|
+
#* d2201, d2211, d3210, d3222, d4410, d4422, d5220, d5232, d5421, d5433 -
|
557
|
+
#* dedt -
|
558
|
+
#* didt -
|
559
|
+
#* dmdt -
|
560
|
+
#* dndt -
|
561
|
+
#* dnodt -
|
562
|
+
#* domdt -
|
563
|
+
#* del1, del2, del3 -
|
564
|
+
#* ses , sghl , sghs , sgs , shl , shs , sis , sls
|
565
|
+
#* theta -
|
566
|
+
#* xfact -
|
567
|
+
#* xlamo -
|
568
|
+
#* xli -
|
569
|
+
#* xni
|
570
|
+
#*
|
571
|
+
#* locals :
|
572
|
+
#* ainv2 -
|
573
|
+
#* aonv -
|
574
|
+
#* cosisq -
|
575
|
+
#* eoc -
|
576
|
+
#* f220, f221, f311, f321, f322, f330, f441, f442, f522, f523, f542, f543 -
|
577
|
+
#* g200, g201, g211, g300, g310, g322, g410, g422, g520, g521, g532, g533 -
|
578
|
+
#* sini2 -
|
579
|
+
#* temp -
|
580
|
+
#* temp1 -
|
581
|
+
#* theta -
|
582
|
+
#* xno2 -
|
583
|
+
#*
|
584
|
+
#* coupling :
|
585
|
+
#* getgravconst- no longer used
|
586
|
+
#*
|
587
|
+
#* references :
|
588
|
+
#* hoots, roehrich, norad spacetrack report #3 1980
|
589
|
+
#* hoots, norad spacetrack report #6 1986
|
590
|
+
#* hoots, schumacher and glover 2004
|
591
|
+
#* vallado, crawford, hujsak, kelso 2006
|
592
|
+
#----------------------------------------------------------------------------*/
|
593
|
+
def self.dsinit(tc, xpidot, rec)
|
594
|
+
#/* --------------------- local variables ------------------------ */
|
595
|
+
|
596
|
+
#double ainv2, aonv = 0.0, cosisq, eoc, f220, f221, f311,
|
597
|
+
# f321, f322, f330, f441, f442, f522, f523,
|
598
|
+
# f542, f543, g200, g201, g211, g300, g310,
|
599
|
+
# g322, g410, g422, g520, g521, g532, g533,
|
600
|
+
# ses, sgs, sghl, sghs, shs, shll, sis,
|
601
|
+
# sini2, sls, temp, temp1, theta, xno2, q22,
|
602
|
+
# q31, q33, root22, root44, root54, rptim, root32,
|
603
|
+
# root52, x2o3, znl, emo, zns, emsqo
|
604
|
+
|
605
|
+
q22 = 1.7891679e-6
|
606
|
+
q31 = 2.1460748e-6
|
607
|
+
q33 = 2.2123015e-7
|
608
|
+
root22 = 1.7891679e-6
|
609
|
+
root44 = 7.3636953e-9
|
610
|
+
root54 = 2.1765803e-9
|
611
|
+
rptim = 4.37526908801129966e-3 #// this equates to 7.29211514668855e-5 rad/sec
|
612
|
+
root32 = 3.7393792e-7
|
613
|
+
root52 = 1.1428639e-7
|
614
|
+
x2o3 = 2.0 / 3.0
|
615
|
+
znl = 1.5835218e-4
|
616
|
+
zns = 1.19459e-5
|
617
|
+
|
618
|
+
#// sgp4fix identify constants and allow alternate values
|
619
|
+
#// just xke is used here so pass it in rather than have multiple calls
|
620
|
+
#// getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 )
|
621
|
+
|
622
|
+
#/* -------------------- deep space initialization ------------ */
|
623
|
+
rec.irez = 0
|
624
|
+
if ((rec.nm < 0.0052359877) and (rec.nm > 0.0034906585))
|
625
|
+
rec.irez = 1
|
626
|
+
end
|
627
|
+
if ((rec.nm >= 8.26e-3) and (rec.nm <= 9.24e-3) and (rec.em >= 0.5))
|
628
|
+
rec.irez = 2
|
629
|
+
end
|
630
|
+
|
631
|
+
#/* ------------------------ do solar terms ------------------- */
|
632
|
+
ses = rec.ss1 * zns * rec.ss5
|
633
|
+
sis = rec.ss2 * zns * (rec.sz11 + rec.sz13)
|
634
|
+
sls = -zns * rec.ss3 * (rec.sz1 + rec.sz3 - 14.0 - 6.0 * rec.emsq)
|
635
|
+
sghs = rec.ss4 * zns * (rec.sz31 + rec.sz33 - 6.0)
|
636
|
+
shs = -zns * rec.ss2 * (rec.sz21 + rec.sz23)
|
637
|
+
#// sgp4fix for 180 deg incl
|
638
|
+
if ((rec.inclm < 5.2359877e-2) or (rec.inclm > PI - 5.2359877e-2))
|
639
|
+
shs = 0.0
|
640
|
+
end
|
641
|
+
if (rec.sinim != 0.0)
|
642
|
+
shs = shs / rec.sinim
|
643
|
+
end
|
644
|
+
sgs = sghs - rec.cosim * shs
|
645
|
+
|
646
|
+
#/* ------------------------- do lunar terms ------------------ */
|
647
|
+
rec.dedt = ses + rec.s1 * znl * rec.s5
|
648
|
+
rec.didt = sis + rec.s2 * znl * (rec.z11 + rec.z13)
|
649
|
+
rec.dmdt = sls - znl * rec.s3 * (rec.z1 + rec.z3 - 14.0 - 6.0 * rec.emsq)
|
650
|
+
sghl = rec.s4 * znl * (rec.z31 + rec.z33 - 6.0)
|
651
|
+
shll = -znl * rec.s2 * (rec.z21 + rec.z23)
|
652
|
+
#// sgp4fix for 180 deg incl
|
653
|
+
if ((rec.inclm < 5.2359877e-2) or (rec.inclm > PI - 5.2359877e-2))
|
654
|
+
shll = 0.0
|
655
|
+
end
|
656
|
+
rec.domdt = sgs + sghl
|
657
|
+
rec.dnodt = shs
|
658
|
+
if (rec.sinim != 0.0)
|
659
|
+
rec.domdt = rec.domdt - rec.cosim / rec.sinim * shll
|
660
|
+
rec.dnodt = rec.dnodt + shll / rec.sinim
|
661
|
+
end
|
662
|
+
|
663
|
+
#/* ----------- calculate deep space resonance effects -------- */
|
664
|
+
rec.dndt = 0.0
|
665
|
+
theta = fmod(rec.gsto + tc * rptim, TWOPI)
|
666
|
+
rec.em = rec.em + rec.dedt * rec.t
|
667
|
+
rec.inclm = rec.inclm + rec.didt * rec.t
|
668
|
+
rec.argpm = rec.argpm + rec.domdt * rec.t
|
669
|
+
rec.nodem = rec.nodem + rec.dnodt * rec.t
|
670
|
+
rec.mm = rec.mm + rec.dmdt * rec.t
|
671
|
+
#// sgp4fix for negative inclinations
|
672
|
+
#// the following if statement should be commented out
|
673
|
+
#//if (inclm < 0.0)
|
674
|
+
#// {
|
675
|
+
#// inclm = -inclm
|
676
|
+
#// argpm = argpm - pi
|
677
|
+
#// nodem = nodem + pi
|
678
|
+
#// }
|
679
|
+
|
680
|
+
#/* -------------- initialize the resonance terms ------------- */
|
681
|
+
if (rec.irez != 0)
|
682
|
+
aonv = (rec.nm / rec.xke) ** x2o3
|
683
|
+
|
684
|
+
#/* ---------- geopotential resonance for 12 hour orbits ------ */
|
685
|
+
if (rec.irez == 2)
|
686
|
+
cosisq = rec.cosim * rec.cosim
|
687
|
+
emo = rec.em
|
688
|
+
rec.em = rec.ecco
|
689
|
+
emsqo = rec.emsq
|
690
|
+
rec.emsq = rec.eccsq
|
691
|
+
eoc = rec.em * rec.emsq
|
692
|
+
g201 = -0.306 - (rec.em - 0.64) * 0.440
|
693
|
+
|
694
|
+
if (rec.em <= 0.65)
|
695
|
+
g211 = 3.616 - 13.2470 * rec.em + 16.2900 * rec.emsq
|
696
|
+
g310 = -19.302 + 117.3900 * rec.em - 228.4190 * rec.emsq + 156.5910 * eoc
|
697
|
+
g322 = -18.9068 + 109.7927 * rec.em - 214.6334 * rec.emsq + 146.5816 * eoc
|
698
|
+
g410 = -41.122 + 242.6940 * rec.em - 471.0940 * rec.emsq + 313.9530 * eoc
|
699
|
+
g422 = -146.407 + 841.8800 * rec.em - 1629.014 * rec.emsq + 1083.4350 * eoc
|
700
|
+
g520 = -532.114 + 3017.977 * rec.em - 5740.032 * rec.emsq + 3708.2760 * eoc
|
701
|
+
else
|
702
|
+
g211 = -72.099 + 331.819 * rec.em - 508.738 * rec.emsq + 266.724 * eoc
|
703
|
+
g310 = -346.844 + 1582.851 * rec.em - 2415.925 * rec.emsq + 1246.113 * eoc
|
704
|
+
g322 = -342.585 + 1554.908 * rec.em - 2366.899 * rec.emsq + 1215.972 * eoc
|
705
|
+
g410 = -1052.797 + 4758.686 * rec.em - 7193.992 * rec.emsq + 3651.957 * eoc
|
706
|
+
g422 = -3581.690 + 16178.110 * rec.em - 24462.770 * rec.emsq + 12422.520 * eoc
|
707
|
+
if (rec.em > 0.715)
|
708
|
+
g520 = -5149.66 + 29936.92 * rec.em - 54087.36 * rec.emsq + 31324.56 * eoc
|
709
|
+
else
|
710
|
+
g520 = 1464.74 - 4664.75 * rec.em + 3763.64 * rec.emsq
|
711
|
+
end
|
712
|
+
end
|
713
|
+
|
714
|
+
if (rec.em < 0.7)
|
715
|
+
g533 = -919.22770 + 4988.6100 * rec.em - 9064.7700 * rec.emsq + 5542.21 * eoc
|
716
|
+
g521 = -822.71072 + 4568.6173 * rec.em - 8491.4146 * rec.emsq + 5337.524 * eoc
|
717
|
+
g532 = -853.66600 + 4690.2500 * rec.em - 8624.7700 * rec.emsq + 5341.4 * eoc
|
718
|
+
else
|
719
|
+
g533 = -37995.780 + 161616.52 * rec.em - 229838.20 * rec.emsq + 109377.94 * eoc
|
720
|
+
g521 = -51752.104 + 218913.95 * rec.em - 309468.16 * rec.emsq + 146349.42 * eoc
|
721
|
+
g532 = -40023.880 + 170470.89 * rec.em - 242699.48 * rec.emsq + 115605.82 * eoc
|
722
|
+
end
|
723
|
+
|
724
|
+
sini2 = rec.sinim * rec.sinim
|
725
|
+
f220 = 0.75 * (1.0 + 2.0 * rec.cosim + cosisq)
|
726
|
+
f221 = 1.5 * sini2
|
727
|
+
f321 = 1.875 * rec.sinim * (1.0 - 2.0 * rec.cosim - 3.0 * cosisq)
|
728
|
+
f322 = -1.875 * rec.sinim * (1.0 + 2.0 * rec.cosim - 3.0 * cosisq)
|
729
|
+
f441 = 35.0 * sini2 * f220
|
730
|
+
f442 = 39.3750 * sini2 * sini2
|
731
|
+
f522 = (9.84375 * rec.sinim * (sini2 * (1.0 - 2.0 * rec.cosim - 5.0 * cosisq) +
|
732
|
+
0.33333333 * (-2.0 + 4.0 * rec.cosim + 6.0 * cosisq)))
|
733
|
+
f523 = (rec.sinim * (4.92187512 * sini2 * (-2.0 - 4.0 * rec.cosim +
|
734
|
+
10.0 * cosisq) + 6.56250012 * (1.0 + 2.0 * rec.cosim - 3.0 * cosisq)))
|
735
|
+
f542 = (29.53125 * rec.sinim * (2.0 - 8.0 * rec.cosim + cosisq *
|
736
|
+
(-12.0 + 8.0 * rec.cosim + 10.0 * cosisq)))
|
737
|
+
f543 = (29.53125 * rec.sinim * (-2.0 - 8.0 * rec.cosim + cosisq *
|
738
|
+
(12.0 + 8.0 * rec.cosim - 10.0 * cosisq)))
|
739
|
+
xno2 = rec.nm * rec.nm
|
740
|
+
ainv2 = aonv * aonv
|
741
|
+
temp1 = 3.0 * xno2 * ainv2
|
742
|
+
temp = temp1 * root22
|
743
|
+
rec.d2201 = temp * f220 * g201
|
744
|
+
rec.d2211 = temp * f221 * g211
|
745
|
+
temp1 = temp1 * aonv
|
746
|
+
temp = temp1 * root32
|
747
|
+
rec.d3210 = temp * f321 * g310
|
748
|
+
rec.d3222 = temp * f322 * g322
|
749
|
+
temp1 = temp1 * aonv
|
750
|
+
temp = 2.0 * temp1 * root44
|
751
|
+
rec.d4410 = temp * f441 * g410
|
752
|
+
rec.d4422 = temp * f442 * g422
|
753
|
+
temp1 = temp1 * aonv
|
754
|
+
temp = temp1 * root52
|
755
|
+
rec.d5220 = temp * f522 * g520
|
756
|
+
rec.d5232 = temp * f523 * g532
|
757
|
+
temp = 2.0 * temp1 * root54
|
758
|
+
rec.d5421 = temp * f542 * g521
|
759
|
+
rec.d5433 = temp * f543 * g533
|
760
|
+
rec.xlamo = fmod(rec.mo + rec.nodeo + rec.nodeo - theta - theta, TWOPI)
|
761
|
+
rec.xfact = rec.mdot + rec.dmdt + 2.0 * (rec.nodedot + rec.dnodt - rptim) - rec.no_unkozai
|
762
|
+
rec.em = emo
|
763
|
+
rec.emsq = emsqo
|
764
|
+
end
|
765
|
+
#}
|
766
|
+
|
767
|
+
#/* ---------------- synchronous resonance terms -------------- */
|
768
|
+
if (rec.irez == 1)
|
769
|
+
g200 = 1.0 + rec.emsq * (-2.5 + 0.8125 * rec.emsq)
|
770
|
+
g310 = 1.0 + 2.0 * rec.emsq
|
771
|
+
g300 = 1.0 + rec.emsq * (-6.0 + 6.60937 * rec.emsq)
|
772
|
+
f220 = 0.75 * (1.0 + rec.cosim) * (1.0 + rec.cosim)
|
773
|
+
f311 = 0.9375 * rec.sinim * rec.sinim * (1.0 + 3.0 * rec.cosim) - 0.75 * (1.0 + rec.cosim)
|
774
|
+
f330 = 1.0 + rec.cosim
|
775
|
+
f330 = 1.875 * f330 * f330 * f330
|
776
|
+
rec.del1 = 3.0 * rec.nm * rec.nm * aonv * aonv
|
777
|
+
rec.del2 = 2.0 * rec.del1 * f220 * g200 * q22
|
778
|
+
rec.del3 = 3.0 * rec.del1 * f330 * g300 * q33 * aonv
|
779
|
+
rec.del1 = rec.del1 * f311 * g310 * q31 * aonv
|
780
|
+
rec.xlamo = fmod(rec.mo + rec.nodeo + rec.argpo - theta, TWOPI)
|
781
|
+
rec.xfact = rec.mdot + xpidot - rptim + rec.dmdt + rec.domdt + rec.dnodt - rec.no_unkozai
|
782
|
+
end
|
783
|
+
|
784
|
+
#/* ------------ for sgp4, initialize the integrator ---------- */
|
785
|
+
rec.xli = rec.xlamo
|
786
|
+
rec.xni = rec.no_unkozai
|
787
|
+
rec.atime = 0.0
|
788
|
+
rec.nm = rec.no_unkozai + rec.dndt
|
789
|
+
end
|
790
|
+
end
|
791
|
+
#} // dsinit
|
792
|
+
|
793
|
+
#/*-----------------------------------------------------------------------------
|
794
|
+
#*
|
795
|
+
#* procedure dspace
|
796
|
+
#*
|
797
|
+
#* this procedure provides deep space contributions to mean elements for
|
798
|
+
#* perturbing third body. these effects have been averaged over one
|
799
|
+
#* revolution of the sun and moon. for earth resonance effects, the
|
800
|
+
#* effects have been averaged over no revolutions of the satellite.
|
801
|
+
#* (mean motion)
|
802
|
+
#* この手順は、摂動する第三体の平均要素に対する深宇宙寄与を提供します。
|
803
|
+
#* これらの効果は、太陽と月の1回の公転にわたって平均化されています。
|
804
|
+
#* 地球の共鳴効果については、衛星の公転数にわたって効果が平均化されています。
|
805
|
+
#* (平均運動)
|
806
|
+
#*
|
807
|
+
#* author : david vallado 719-573-2600 28 jun 2005
|
808
|
+
#*
|
809
|
+
#* inputs :
|
810
|
+
#* d2201, d2211, d3210, d3222, d4410, d4422, d5220, d5232, d5421, d5433 -
|
811
|
+
#* dedt -
|
812
|
+
#* del1, del2, del3 -
|
813
|
+
#* didt -
|
814
|
+
#* dmdt -
|
815
|
+
#* dnodt -
|
816
|
+
#* domdt -
|
817
|
+
#* irez - flag for resonance 0-none, 1-one day, 2-half day
|
818
|
+
#* argpo - argument of perigee
|
819
|
+
#* argpdot - argument of perigee dot (rate)
|
820
|
+
#* t - time
|
821
|
+
#* tc -
|
822
|
+
#* gsto - gst
|
823
|
+
#* xfact -
|
824
|
+
#* xlamo -
|
825
|
+
#* no - mean motion
|
826
|
+
#* atime -
|
827
|
+
#* em - eccentricity
|
828
|
+
#* ft -
|
829
|
+
#* argpm - argument of perigee
|
830
|
+
#* inclm - inclination
|
831
|
+
#* xli -
|
832
|
+
#* mm - mean anomaly
|
833
|
+
#* xni - mean motion
|
834
|
+
#* nodem - right ascension of ascending node
|
835
|
+
#*
|
836
|
+
#* outputs :
|
837
|
+
#* atime -
|
838
|
+
#* em - eccentricity
|
839
|
+
#* argpm - argument of perigee
|
840
|
+
#* inclm - inclination
|
841
|
+
#* xli -
|
842
|
+
#* mm - mean anomaly
|
843
|
+
#* xni -
|
844
|
+
#* nodem - right ascension of ascending node
|
845
|
+
#* dndt -
|
846
|
+
#* nm - mean motion
|
847
|
+
#*
|
848
|
+
#* locals :
|
849
|
+
#* delt -
|
850
|
+
#* ft -
|
851
|
+
#* theta -
|
852
|
+
#* x2li -
|
853
|
+
#* x2omi -
|
854
|
+
#* xl -
|
855
|
+
#* xldot -
|
856
|
+
#* xnddt -
|
857
|
+
#* xndt -
|
858
|
+
#* xomi -
|
859
|
+
#*
|
860
|
+
#* coupling :
|
861
|
+
#* none -
|
862
|
+
#*
|
863
|
+
#* references :
|
864
|
+
#* hoots, roehrich, norad spacetrack report #3 1980
|
865
|
+
#* hoots, norad spacetrack report #6 1986
|
866
|
+
#* hoots, schumacher and glover 2004
|
867
|
+
#* vallado, crawford, hujsak, kelso 2006
|
868
|
+
#----------------------------------------------------------------------------*/
|
869
|
+
|
870
|
+
def self.dspace(tc, rec)
|
871
|
+
#int iretn
|
872
|
+
#double delt, ft, theta, x2li, x2omi, xl, xldot, xnddt, xndt, xomi, g22, g32,
|
873
|
+
# g44, g52, g54, fasx2, fasx4, fasx6, rptim, step2, stepn, stepp
|
874
|
+
|
875
|
+
xndt = 0
|
876
|
+
xnddt = 0
|
877
|
+
xldot = 0
|
878
|
+
|
879
|
+
fasx2 = 0.13130908
|
880
|
+
fasx4 = 2.8843198
|
881
|
+
fasx6 = 0.37448087
|
882
|
+
g22 = 5.7686396
|
883
|
+
g32 = 0.95240898
|
884
|
+
g44 = 1.8014998
|
885
|
+
g52 = 1.0508330
|
886
|
+
g54 = 4.4108898
|
887
|
+
rptim = 4.37526908801129966e-3 #// this equates to 7.29211514668855e-5 rad/sec
|
888
|
+
stepp = 720.0
|
889
|
+
stepn = -720.0
|
890
|
+
step2 = 259200.0
|
891
|
+
|
892
|
+
#/* ----------- calculate deep space resonance effects ----------- */
|
893
|
+
rec.dndt = 0.0
|
894
|
+
theta = fmod(rec.gsto + tc * rptim, TWOPI)
|
895
|
+
rec.em = rec.em + rec.dedt * rec.t
|
896
|
+
|
897
|
+
rec.inclm = rec.inclm + rec.didt * rec.t
|
898
|
+
rec.argpm = rec.argpm + rec.domdt * rec.t
|
899
|
+
rec.nodem = rec.nodem + rec.dnodt * rec.t
|
900
|
+
rec.mm = rec.mm + rec.dmdt * rec.t
|
901
|
+
|
902
|
+
#// sgp4fix for negative inclinations
|
903
|
+
#// the following if statement should be commented out
|
904
|
+
#// if (inclm < 0.0)
|
905
|
+
#// {
|
906
|
+
#// inclm = -inclm
|
907
|
+
#// argpm = argpm - pi
|
908
|
+
#// nodem = nodem + pi
|
909
|
+
#// }
|
910
|
+
|
911
|
+
#/* - update resonances : numerical (euler-maclaurin) integration - */
|
912
|
+
#/* ------------------------- epoch restart ---------------------- */
|
913
|
+
#// sgp4fix for propagator problems
|
914
|
+
#// the following integration works for negative time steps and periods
|
915
|
+
#// the specific changes are unknown because the original code was so convoluted
|
916
|
+
|
917
|
+
#// sgp4fix take out atime = 0.0 and fix for faster operation
|
918
|
+
ft = 0.0
|
919
|
+
if (rec.irez != 0)
|
920
|
+
#// sgp4fix streamline check
|
921
|
+
if ((rec.atime == 0.0) or (rec.t * rec.atime <= 0.0) or ((rec.t).abs < (rec.atime).abs))
|
922
|
+
rec.atime = 0.0
|
923
|
+
rec.xni = rec.no_unkozai
|
924
|
+
rec.xli = rec.xlamo
|
925
|
+
end
|
926
|
+
#// sgp4fix move check outside loop
|
927
|
+
if (rec.t > 0.0)
|
928
|
+
delt = stepp
|
929
|
+
else
|
930
|
+
delt = stepn
|
931
|
+
end
|
932
|
+
|
933
|
+
iretn = 381 #// added for do loop
|
934
|
+
while (iretn == 381)
|
935
|
+
#/* ------------------- dot terms calculated ------------- */
|
936
|
+
#/* ----------- near - synchronous resonance terms ------- */
|
937
|
+
if (rec.irez != 2)
|
938
|
+
xndt = (rec.del1 * Math.sin(rec.xli - fasx2) + rec.del2 * Math.sin(2.0 * (rec.xli - fasx4)) +
|
939
|
+
rec.del3 * Math.sin(3.0 * (rec.xli - fasx6)))
|
940
|
+
xldot = rec.xni + rec.xfact
|
941
|
+
xnddt = (rec.del1 * Math.cos(rec.xli - fasx2) +
|
942
|
+
2.0 * rec.del2 * Math.cos(2.0 * (rec.xli - fasx4)) +
|
943
|
+
3.0 * rec.del3 * Math.cos(3.0 * (rec.xli - fasx6)))
|
944
|
+
xnddt = xnddt * xldot
|
945
|
+
else
|
946
|
+
#/* --------- near - half-day resonance terms -------- */
|
947
|
+
xomi = rec.argpo + rec.argpdot * rec.atime
|
948
|
+
x2omi = xomi + xomi
|
949
|
+
x2li = rec.xli + rec.xli
|
950
|
+
xndt = (rec.d2201 * Math.sin(x2omi + rec.xli - g22) + rec.d2211 * Math.sin(rec.xli - g22) +
|
951
|
+
rec.d3210 * Math.sin(xomi + rec.xli - g32) + rec.d3222 * Math.sin(-xomi + rec.xli - g32) +
|
952
|
+
rec.d4410 * Math.sin(x2omi + x2li - g44) + rec.d4422 * Math.sin(x2li - g44) +
|
953
|
+
rec.d5220 * Math.sin(xomi + rec.xli - g52) + rec.d5232 * Math.sin(-xomi + rec.xli - g52) +
|
954
|
+
rec.d5421 * Math.sin(xomi + x2li - g54) + rec.d5433 * Math.sin(-xomi + x2li - g54))
|
955
|
+
xldot = rec.xni + rec.xfact
|
956
|
+
xnddt = (rec.d2201 * Math.cos(x2omi + rec.xli - g22) + rec.d2211 * Math.cos(rec.xli - g22) +
|
957
|
+
rec.d3210 * Math.cos(xomi + rec.xli - g32) + rec.d3222 * Math.cos(-xomi + rec.xli - g32) +
|
958
|
+
rec.d5220 * Math.cos(xomi + rec.xli - g52) + rec.d5232 * Math.cos(-xomi + rec.xli - g52) +
|
959
|
+
2.0 * (rec.d4410 * Math.cos(x2omi + x2li - g44) +
|
960
|
+
rec.d4422 * Math.cos(x2li - g44) + rec.d5421 * Math.cos(xomi + x2li - g54) +
|
961
|
+
rec.d5433 * Math.cos(-xomi + x2li - g54)))
|
962
|
+
xnddt = xnddt * xldot
|
963
|
+
end
|
964
|
+
|
965
|
+
#/* ----------------------- integrator ------------------- */
|
966
|
+
#// sgp4fix move end checks to end of routine
|
967
|
+
if ((rec.t - rec.atime).abs >= stepp)
|
968
|
+
iretn = 381
|
969
|
+
else #// exit here
|
970
|
+
ft = rec.t - rec.atime
|
971
|
+
iretn = 0
|
972
|
+
end
|
973
|
+
|
974
|
+
if (iretn == 381)
|
975
|
+
rec.xli = rec.xli + xldot * delt + xndt * step2
|
976
|
+
rec.xni = rec.xni + xndt * delt + xnddt * step2
|
977
|
+
rec.atime = rec.atime + delt
|
978
|
+
end
|
979
|
+
end
|
980
|
+
#} #// while iretn = 381
|
981
|
+
|
982
|
+
rec.nm = rec.xni + xndt * ft + xnddt * ft * ft * 0.5
|
983
|
+
xl = rec.xli + xldot * ft + xndt * ft * ft * 0.5
|
984
|
+
if (rec.irez != 1)
|
985
|
+
rec.mm = xl - 2.0 * rec.nodem + 2.0 * theta
|
986
|
+
rec.dndt = rec.nm - rec.no_unkozai
|
987
|
+
else
|
988
|
+
rec.mm = xl - rec.nodem - rec.argpm + theta
|
989
|
+
rec.dndt = rec.nm - rec.no_unkozai
|
990
|
+
end
|
991
|
+
rec.nm = rec.no_unkozai + rec.dndt
|
992
|
+
end
|
993
|
+
end
|
994
|
+
#} // dsspace
|
995
|
+
|
996
|
+
#/*-----------------------------------------------------------------------------
|
997
|
+
#*
|
998
|
+
#* procedure initl
|
999
|
+
#*
|
1000
|
+
#* this procedure initializes the spg4 propagator. all the initialization is
|
1001
|
+
#* consolidated here instead of having multiple loops inside other routines.
|
1002
|
+
#* この手順はspg4プロパゲータを初期化します。すべての初期化は他のルーチン内に複数のループを持つ代わりにここに統合されています。
|
1003
|
+
#*
|
1004
|
+
#* author : david vallado 719-573-2600 28 jun 2005
|
1005
|
+
#*
|
1006
|
+
#* inputs :
|
1007
|
+
#* satn - satellite number - not needed, placed in satrec
|
1008
|
+
#* xke - reciprocal of tumin
|
1009
|
+
#* j2 - j2 zonal harmonic
|
1010
|
+
#* ecco - eccentricity 0.0 - 1.0
|
1011
|
+
#* epoch - epoch time in days from jan 0, 1950. 0 hr
|
1012
|
+
#* inclo - inclination of satellite
|
1013
|
+
#* no - mean motion of satellite
|
1014
|
+
#*
|
1015
|
+
#* outputs :
|
1016
|
+
#* ainv - 1.0 / a
|
1017
|
+
#* ao - semi major axis
|
1018
|
+
#* con41 -
|
1019
|
+
#* con42 - 1.0 - 5.0 cos(i)
|
1020
|
+
#* cosio - cosine of inclination
|
1021
|
+
#* cosio2 - cosio squared
|
1022
|
+
#* eccsq - eccentricity squared
|
1023
|
+
#* method - flag for deep space 'd', 'n'
|
1024
|
+
#* omeosq - 1.0 - ecco * ecco
|
1025
|
+
#* posq - semi-parameter squared
|
1026
|
+
#* rp - radius of perigee
|
1027
|
+
#* rteosq - square root of (1.0 - ecco*ecco)
|
1028
|
+
#* sinio - sine of inclination
|
1029
|
+
#* gsto - gst at time of observation rad
|
1030
|
+
#* no - mean motion of satellite
|
1031
|
+
#*
|
1032
|
+
#* locals :
|
1033
|
+
#* ak -
|
1034
|
+
#* d1 -
|
1035
|
+
#* del -
|
1036
|
+
#* adel -
|
1037
|
+
#* po -
|
1038
|
+
#*
|
1039
|
+
#* coupling :
|
1040
|
+
#* getgravconst- no longer used
|
1041
|
+
#* gstime - find greenwich sidereal time from the julian date
|
1042
|
+
#*
|
1043
|
+
#* references :
|
1044
|
+
#* hoots, roehrich, norad spacetrack report #3 1980
|
1045
|
+
#* hoots, norad spacetrack report #6 1986
|
1046
|
+
#* hoots, schumacher and glover 2004
|
1047
|
+
#* vallado, crawford, hujsak, kelso 2006
|
1048
|
+
#----------------------------------------------------------------------------*/
|
1049
|
+
|
1050
|
+
def self.initl(epoch, rec)
|
1051
|
+
#/* --------------------- local variables ------------------------ */
|
1052
|
+
#double ak, d1, del, adel, po, x2o3
|
1053
|
+
|
1054
|
+
#// sgp4fix use old way of finding gst
|
1055
|
+
#double ds70
|
1056
|
+
#double ts70, tfrac, c1, thgr70, fk5r, c1p2p
|
1057
|
+
|
1058
|
+
#/* ----------------------- earth constants ---------------------- */
|
1059
|
+
#// sgp4fix identify constants and allow alternate values
|
1060
|
+
#// only xke and j2 are used here so pass them in directly
|
1061
|
+
#// getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 )
|
1062
|
+
x2o3 = 2.0 / 3.0
|
1063
|
+
|
1064
|
+
#/* ------------- calculate auxillary epoch quantities ---------- */
|
1065
|
+
rec.eccsq = rec.ecco * rec.ecco
|
1066
|
+
rec.omeosq = 1.0 - rec.eccsq
|
1067
|
+
rec.rteosq = Math.sqrt(rec.omeosq)
|
1068
|
+
rec.cosio = Math.cos(rec.inclo)
|
1069
|
+
rec.cosio2 = rec.cosio * rec.cosio
|
1070
|
+
|
1071
|
+
#/* ------------------ un-kozai the mean motion ----------------- */
|
1072
|
+
ak = (rec.xke / rec.no_kozai) ** x2o3
|
1073
|
+
d1 = 0.75 * rec.j2 * (3.0 * rec.cosio2 - 1.0) / (rec.rteosq * rec.omeosq)
|
1074
|
+
ddel = d1 / (ak * ak)
|
1075
|
+
# del is a keyword in python
|
1076
|
+
adel = ak * (1.0 - ddel * ddel - ddel * (1.0 / 3.0 + 134.0 * ddel * ddel / 81.0))
|
1077
|
+
ddel = d1 / (adel * adel)
|
1078
|
+
rec.no_unkozai = rec.no_kozai / (1.0 + ddel)
|
1079
|
+
|
1080
|
+
#puts "koz = #{rec.no_kozai}"
|
1081
|
+
#puts "unkoz = #{rec.no_unkozai}"
|
1082
|
+
|
1083
|
+
rec.ao = (rec.xke / (rec.no_unkozai)) ** x2o3
|
1084
|
+
rec.sinio = Math.sin(rec.inclo)
|
1085
|
+
po = rec.ao * rec.omeosq
|
1086
|
+
rec.con42 = 1.0 - 5.0 * rec.cosio2
|
1087
|
+
rec.con41 = -rec.con42 - rec.cosio2 - rec.cosio2
|
1088
|
+
rec.ainv = 1.0 / rec.ao
|
1089
|
+
rec.posq = po * po
|
1090
|
+
rec.rp = rec.ao * (1.0 - rec.ecco)
|
1091
|
+
rec.method = "n"
|
1092
|
+
|
1093
|
+
#// sgp4fix modern approach to finding sidereal time
|
1094
|
+
#// if (opsmode == 'a')
|
1095
|
+
#// {
|
1096
|
+
#// sgp4fix use old way of finding gst
|
1097
|
+
#// count integer number of days from 0 jan 1970
|
1098
|
+
ts70 = epoch - 7305.0
|
1099
|
+
ds70 = (ts70 + 1.0e-8).floor
|
1100
|
+
tfrac = ts70 - ds70
|
1101
|
+
#// find greenwich location at epoch
|
1102
|
+
c1 = 1.72027916940703639e-2
|
1103
|
+
thgr70 = 1.7321343856509374
|
1104
|
+
fk5r = 5.07551419432269442e-15
|
1105
|
+
c1p2p = c1 + TWOPI
|
1106
|
+
gsto1 = fmod(thgr70 + c1 * ds70 + c1p2p * tfrac + ts70 * ts70 * fk5r, TWOPI)
|
1107
|
+
if (gsto1 < 0.0)
|
1108
|
+
gsto1 = gsto1 + TWOPI
|
1109
|
+
end
|
1110
|
+
#// }
|
1111
|
+
#// else
|
1112
|
+
rec.gsto = gstime(epoch + 2433281.5)
|
1113
|
+
end
|
1114
|
+
#} // initl
|
1115
|
+
|
1116
|
+
#/*-----------------------------------------------------------------------------
|
1117
|
+
#*
|
1118
|
+
#* procedure sgp4init
|
1119
|
+
#*
|
1120
|
+
#* this procedure initializes variables for sgp4.
|
1121
|
+
#*
|
1122
|
+
#* author : david vallado 719-573-2600 28 jun 2005
|
1123
|
+
#*
|
1124
|
+
#* inputs :
|
1125
|
+
#* opsmode - mode of operation afspc or improved 'a', 'i'
|
1126
|
+
#* whichconst - which set of constants to use 72, 84
|
1127
|
+
#* satn - satellite number
|
1128
|
+
#* bstar - sgp4 type drag coefficient kg/m2er
|
1129
|
+
#* ecco - eccentricity
|
1130
|
+
#* epoch - epoch time in days from jan 0, 1950. 0 hr
|
1131
|
+
#* argpo - argument of perigee (output if ds)
|
1132
|
+
#* inclo - inclination
|
1133
|
+
#* mo - mean anomaly (output if ds)
|
1134
|
+
#* no - mean motion
|
1135
|
+
#* nodeo - right ascension of ascending node
|
1136
|
+
#*
|
1137
|
+
#* outputs :
|
1138
|
+
#* satrec - common values for subsequent calls
|
1139
|
+
#* return code - non-zero on error.
|
1140
|
+
#* 1 - mean elements, ecc >= 1.0 or ecc < -0.001 or a < 0.95 er
|
1141
|
+
#* 2 - mean motion less than 0.0
|
1142
|
+
#* 3 - pert elements, ecc < 0.0 or ecc > 1.0
|
1143
|
+
#* 4 - semi-latus rectum < 0.0
|
1144
|
+
#* 5 - epoch elements are sub-orbital
|
1145
|
+
#* 6 - satellite has decayed
|
1146
|
+
#*
|
1147
|
+
#* locals :
|
1148
|
+
#* cnodm , snodm , cosim , sinim , cosomm , sinomm
|
1149
|
+
#* cc1sq , cc2 , cc3
|
1150
|
+
#* coef , coef1
|
1151
|
+
#* cosio4 -
|
1152
|
+
#* day -
|
1153
|
+
#* dndt -
|
1154
|
+
#* em - eccentricity
|
1155
|
+
#* emsq - eccentricity squared
|
1156
|
+
#* eeta -
|
1157
|
+
#* etasq -
|
1158
|
+
#* gam -
|
1159
|
+
#* argpm - argument of perigee
|
1160
|
+
#* nodem -
|
1161
|
+
#* inclm - inclination
|
1162
|
+
#* mm - mean anomaly
|
1163
|
+
#* nm - mean motion
|
1164
|
+
#* perige - perigee
|
1165
|
+
#* pinvsq -
|
1166
|
+
#* psisq -
|
1167
|
+
#* qzms24 -
|
1168
|
+
#* rtemsq -
|
1169
|
+
#* s1, s2, s3, s4, s5, s6, s7 -
|
1170
|
+
#* sfour -
|
1171
|
+
#* ss1, ss2, ss3, ss4, ss5, ss6, ss7 -
|
1172
|
+
#* sz1, sz2, sz3
|
1173
|
+
#* sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33 -
|
1174
|
+
#* tc -
|
1175
|
+
#* temp -
|
1176
|
+
#* temp1, temp2, temp3 -
|
1177
|
+
#* tsi -
|
1178
|
+
#* xpidot -
|
1179
|
+
#* xhdot1 -
|
1180
|
+
#* z1, z2, z3 -
|
1181
|
+
#* z11, z12, z13, z21, z22, z23, z31, z32, z33 -
|
1182
|
+
#*
|
1183
|
+
#* coupling :
|
1184
|
+
#* getgravconst-
|
1185
|
+
#* initl -
|
1186
|
+
#* dscom -
|
1187
|
+
#* dpper -
|
1188
|
+
#* dsinit -
|
1189
|
+
#* sgp4 -
|
1190
|
+
#*
|
1191
|
+
#* references :
|
1192
|
+
#* hoots, roehrich, norad spacetrack report #3 1980
|
1193
|
+
#* hoots, norad spacetrack report #6 1986
|
1194
|
+
#* hoots, schumacher and glover 2004
|
1195
|
+
#* vallado, crawford, hujsak, kelso 2006
|
1196
|
+
#----------------------------------------------------------------------------*/
|
1197
|
+
|
1198
|
+
def self.sgp4init(opsmode, satrec)
|
1199
|
+
#/* --------------------- local variables ------------------------ */
|
1200
|
+
|
1201
|
+
#double cc1sq,
|
1202
|
+
# cc2, cc3, coef, coef1, cosio4,
|
1203
|
+
# eeta, etasq, perige, pinvsq, psisq, qzms24,
|
1204
|
+
# sfour,tc, temp, temp1, temp2, temp3, tsi, xpidot,
|
1205
|
+
# xhdot1,qzms2t, ss, x2o3, r[], v[],
|
1206
|
+
# delmotemp, qzms2ttemp, qzms24temp
|
1207
|
+
|
1208
|
+
epoch = (satrec.jdsatepoch + satrec.jdsatepochF) - 2433281.5
|
1209
|
+
|
1210
|
+
#/* ------------------------ initialization --------------------- */
|
1211
|
+
#// sgp4fix divisor for divide by zero check on inclination
|
1212
|
+
#// the old check used 1.0 + cos(pi-1.0e-9), but then compared it to
|
1213
|
+
#// 1.5 e-12, so the threshold was changed to 1.5e-12 for consistency
|
1214
|
+
temp4 = 1.5e-12
|
1215
|
+
|
1216
|
+
#/* ----------- set all near earth variables to zero ------------ */
|
1217
|
+
satrec.isimp = 0
|
1218
|
+
satrec.method = "n"
|
1219
|
+
satrec.aycof = 0.0
|
1220
|
+
satrec.con41 = 0.0
|
1221
|
+
satrec.cc1 = 0.0
|
1222
|
+
satrec.cc4 = 0.0
|
1223
|
+
satrec.cc5 = 0.0
|
1224
|
+
satrec.d2 = 0.0
|
1225
|
+
satrec.d3 = 0.0
|
1226
|
+
satrec.d4 = 0.0
|
1227
|
+
satrec.delmo = 0.0
|
1228
|
+
satrec.eta = 0.0
|
1229
|
+
satrec.argpdot = 0.0
|
1230
|
+
satrec.omgcof = 0.0
|
1231
|
+
satrec.sinmao = 0.0
|
1232
|
+
satrec.t = 0.0
|
1233
|
+
satrec.t2cof = 0.0
|
1234
|
+
satrec.t3cof = 0.0
|
1235
|
+
satrec.t4cof = 0.0
|
1236
|
+
satrec.t5cof = 0.0
|
1237
|
+
satrec.x1mth2 = 0.0
|
1238
|
+
satrec.x7thm1 = 0.0
|
1239
|
+
satrec.mdot = 0.0
|
1240
|
+
satrec.nodedot = 0.0
|
1241
|
+
satrec.xlcof = 0.0
|
1242
|
+
satrec.xmcof = 0.0
|
1243
|
+
satrec.nodecf = 0.0
|
1244
|
+
|
1245
|
+
#/* ----------- set all deep space variables to zero ------------ */
|
1246
|
+
satrec.irez = 0
|
1247
|
+
satrec.d2201 = 0.0
|
1248
|
+
satrec.d2211 = 0.0
|
1249
|
+
satrec.d3210 = 0.0
|
1250
|
+
satrec.d3222 = 0.0
|
1251
|
+
satrec.d4410 = 0.0
|
1252
|
+
satrec.d4422 = 0.0
|
1253
|
+
satrec.d5220 = 0.0
|
1254
|
+
satrec.d5232 = 0.0
|
1255
|
+
satrec.d5421 = 0.0
|
1256
|
+
satrec.d5433 = 0.0
|
1257
|
+
satrec.dedt = 0.0
|
1258
|
+
satrec.del1 = 0.0
|
1259
|
+
satrec.del2 = 0.0
|
1260
|
+
satrec.del3 = 0.0
|
1261
|
+
satrec.didt = 0.0
|
1262
|
+
satrec.dmdt = 0.0
|
1263
|
+
satrec.dnodt = 0.0
|
1264
|
+
satrec.domdt = 0.0
|
1265
|
+
satrec.e3 = 0.0
|
1266
|
+
satrec.ee2 = 0.0
|
1267
|
+
satrec.peo = 0.0
|
1268
|
+
satrec.pgho = 0.0
|
1269
|
+
satrec.pho = 0.0
|
1270
|
+
satrec.pinco = 0.0
|
1271
|
+
satrec.plo = 0.0
|
1272
|
+
satrec.se2 = 0.0
|
1273
|
+
satrec.se3 = 0.0
|
1274
|
+
satrec.sgh2 = 0.0
|
1275
|
+
satrec.sgh3 = 0.0
|
1276
|
+
satrec.sgh4 = 0.0
|
1277
|
+
satrec.sh2 = 0.0
|
1278
|
+
satrec.sh3 = 0.0
|
1279
|
+
satrec.si2 = 0.0
|
1280
|
+
satrec.si3 = 0.0
|
1281
|
+
satrec.sl2 = 0.0
|
1282
|
+
satrec.sl3 = 0.0
|
1283
|
+
satrec.sl4 = 0.0
|
1284
|
+
satrec.gsto = 0.0
|
1285
|
+
satrec.xfact = 0.0
|
1286
|
+
satrec.xgh2 = 0.0
|
1287
|
+
satrec.xgh3 = 0.0
|
1288
|
+
satrec.xgh4 = 0.0
|
1289
|
+
satrec.xh2 = 0.0
|
1290
|
+
satrec.xh3 = 0.0
|
1291
|
+
satrec.xi2 = 0.0
|
1292
|
+
satrec.xi3 = 0.0
|
1293
|
+
satrec.xl2 = 0.0
|
1294
|
+
satrec.xl3 = 0.0
|
1295
|
+
satrec.xl4 = 0.0
|
1296
|
+
satrec.xlamo = 0.0
|
1297
|
+
satrec.zmol = 0.0
|
1298
|
+
satrec.zmos = 0.0
|
1299
|
+
satrec.atime = 0.0
|
1300
|
+
satrec.xli = 0.0
|
1301
|
+
satrec.xni = 0.0
|
1302
|
+
|
1303
|
+
#/* ------------------------ earth constants ----------------------- */
|
1304
|
+
#// sgp4fix identify constants and allow alternate values
|
1305
|
+
#// this is now the only call for the constants
|
1306
|
+
getgravconst(satrec.whichconst, satrec)
|
1307
|
+
|
1308
|
+
#//-------------------------------------------------------------------------
|
1309
|
+
|
1310
|
+
satrec.error = 0
|
1311
|
+
satrec.operationmode = opsmode
|
1312
|
+
|
1313
|
+
#// single averaged mean elements
|
1314
|
+
satrec.am = satrec.em = satrec.im = satrec.Om = satrec.mm = satrec.nm = 0.0
|
1315
|
+
|
1316
|
+
#/* ------------------------ earth constants ----------------------- */
|
1317
|
+
#// sgp4fix identify constants and allow alternate values no longer needed
|
1318
|
+
#// getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 )
|
1319
|
+
ss = 78.0 / satrec.radiusearthkm + 1.0
|
1320
|
+
#// sgp4fix use multiply for speed instead of pow
|
1321
|
+
qzms2ttemp = (120.0 - 78.0) / satrec.radiusearthkm
|
1322
|
+
qzms2t = qzms2ttemp * qzms2ttemp * qzms2ttemp * qzms2ttemp
|
1323
|
+
x2o3 = 2.0 / 3.0
|
1324
|
+
|
1325
|
+
satrec.init = "y"
|
1326
|
+
satrec.t = 0.0
|
1327
|
+
|
1328
|
+
#// sgp4fix remove satn as it is not needed in initl
|
1329
|
+
|
1330
|
+
initl(epoch, satrec)
|
1331
|
+
|
1332
|
+
satrec.a = (satrec.no_unkozai * satrec.tumin) ** (-2.0 / 3.0)
|
1333
|
+
satrec.alta = satrec.a * (1.0 + satrec.ecco) - 1.0
|
1334
|
+
satrec.altp = satrec.a * (1.0 - satrec.ecco) - 1.0
|
1335
|
+
satrec.error = 0
|
1336
|
+
|
1337
|
+
#// sgp4fix remove this check as it is unnecessary
|
1338
|
+
#// the mrt check in sgp4 handles decaying satellite cases even if the starting
|
1339
|
+
#// condition is below the surface of te earth
|
1340
|
+
#// if (rp < 1.0)
|
1341
|
+
#// {
|
1342
|
+
#// satrec.error = 5
|
1343
|
+
#// }
|
1344
|
+
|
1345
|
+
if ((satrec.omeosq >= 0.0) or (satrec.no_unkozai >= 0.0))
|
1346
|
+
satrec.isimp = 0
|
1347
|
+
if (satrec.rp < (220.0 / satrec.radiusearthkm + 1.0))
|
1348
|
+
satrec.isimp = 1
|
1349
|
+
end
|
1350
|
+
sfour = ss
|
1351
|
+
qzms24 = qzms2t
|
1352
|
+
perige = (satrec.rp - 1.0) * satrec.radiusearthkm
|
1353
|
+
|
1354
|
+
#/* - for perigees below 156 km, s and qoms2t are altered - */
|
1355
|
+
if (perige < 156.0)
|
1356
|
+
sfour = perige - 78.0
|
1357
|
+
if (perige < 98.0)
|
1358
|
+
sfour = 20.0
|
1359
|
+
end
|
1360
|
+
#// sgp4fix use multiply for speed instead of pow
|
1361
|
+
qzms24temp = (120.0 - sfour) / satrec.radiusearthkm
|
1362
|
+
qzms24 = qzms24temp * qzms24temp * qzms24temp * qzms24temp
|
1363
|
+
sfour = sfour / satrec.radiusearthkm + 1.0
|
1364
|
+
end
|
1365
|
+
|
1366
|
+
pinvsq = 1.0 / satrec.posq
|
1367
|
+
|
1368
|
+
tsi = 1.0 / (satrec.ao - sfour)
|
1369
|
+
satrec.eta = satrec.ao * satrec.ecco * tsi
|
1370
|
+
etasq = satrec.eta * satrec.eta
|
1371
|
+
eeta = satrec.ecco * satrec.eta
|
1372
|
+
psisq = (1.0 - etasq).abs
|
1373
|
+
coef = qzms24 * (tsi ** 4.0)
|
1374
|
+
coef1 = coef / (psisq ** 3.5)
|
1375
|
+
cc2 = (coef1 * satrec.no_unkozai * (satrec.ao * (1.0 + 1.5 * etasq + eeta *
|
1376
|
+
(4.0 + etasq)) + 0.375 * satrec.j2 * tsi / psisq * satrec.con41 *
|
1377
|
+
(8.0 + 3.0 * etasq * (8.0 + etasq))))
|
1378
|
+
satrec.cc1 = satrec.bstar * cc2
|
1379
|
+
cc3 = 0.0
|
1380
|
+
if (satrec.ecco > 1.0e-4)
|
1381
|
+
cc3 = -2.0 * coef * tsi * satrec.j3oj2 * satrec.no_unkozai * satrec.sinio / satrec.ecco
|
1382
|
+
end
|
1383
|
+
satrec.x1mth2 = 1.0 - satrec.cosio2
|
1384
|
+
satrec.cc4 = (2.0 * satrec.no_unkozai * coef1 * satrec.ao * satrec.omeosq *
|
1385
|
+
(satrec.eta * (2.0 + 0.5 * etasq) + satrec.ecco *
|
1386
|
+
(0.5 + 2.0 * etasq) - satrec.j2 * tsi / (satrec.ao * psisq) *
|
1387
|
+
(-3.0 * satrec.con41 * (1.0 - 2.0 * eeta + etasq *
|
1388
|
+
(1.5 - 0.5 * eeta)) + 0.75 * satrec.x1mth2 *
|
1389
|
+
(2.0 * etasq - eeta * (1.0 + etasq)) * Math.cos(2.0 * satrec.argpo))))
|
1390
|
+
satrec.cc5 = (2.0 * coef1 * satrec.ao * satrec.omeosq * (1.0 + 2.75 *
|
1391
|
+
(etasq + eeta) + eeta * etasq))
|
1392
|
+
cosio4 = satrec.cosio2 * satrec.cosio2
|
1393
|
+
temp1 = 1.5 * satrec.j2 * pinvsq * satrec.no_unkozai
|
1394
|
+
temp2 = 0.5 * temp1 * satrec.j2 * pinvsq
|
1395
|
+
temp3 = -0.46875 * satrec.j4 * pinvsq * pinvsq * satrec.no_unkozai
|
1396
|
+
satrec.mdot = (satrec.no_unkozai + 0.5 * temp1 * satrec.rteosq * satrec.con41 + 0.0625 *
|
1397
|
+
temp2 * satrec.rteosq * (13.0 - 78.0 * satrec.cosio2 + 137.0 * cosio4))
|
1398
|
+
satrec.argpdot = (-0.5 * temp1 * satrec.con42 + 0.0625 * temp2 *
|
1399
|
+
(7.0 - 114.0 * satrec.cosio2 + 395.0 * cosio4) +
|
1400
|
+
temp3 * (3.0 - 36.0 * satrec.cosio2 + 49.0 * cosio4))
|
1401
|
+
xhdot1 = -temp1 * satrec.cosio
|
1402
|
+
satrec.nodedot = (xhdot1 + (0.5 * temp2 * (4.0 - 19.0 * satrec.cosio2) +
|
1403
|
+
2.0 * temp3 * (3.0 - 7.0 * satrec.cosio2)) * satrec.cosio)
|
1404
|
+
xpidot = satrec.argpdot + satrec.nodedot
|
1405
|
+
satrec.omgcof = satrec.bstar * cc3 * Math.cos(satrec.argpo)
|
1406
|
+
satrec.xmcof = 0.0
|
1407
|
+
if (satrec.ecco > 1.0e-4)
|
1408
|
+
satrec.xmcof = -x2o3 * coef * satrec.bstar / eeta
|
1409
|
+
end
|
1410
|
+
satrec.nodecf = 3.5 * satrec.omeosq * xhdot1 * satrec.cc1
|
1411
|
+
satrec.t2cof = 1.5 * satrec.cc1
|
1412
|
+
#// sgp4fix for divide by zero with xinco = 180 deg
|
1413
|
+
if ((satrec.cosio + 1.0).abs > 1.5e-12)
|
1414
|
+
satrec.xlcof = -0.25 * satrec.j3oj2 * satrec.sinio * (3.0 + 5.0 * satrec.cosio) / (1.0 + satrec.cosio)
|
1415
|
+
else
|
1416
|
+
satrec.xlcof = -0.25 * satrec.j3oj2 * satrec.sinio * (3.0 + 5.0 * satrec.cosio) / temp4
|
1417
|
+
end
|
1418
|
+
satrec.aycof = -0.5 * satrec.j3oj2 * satrec.sinio
|
1419
|
+
#// sgp4fix use multiply for speed instead of pow
|
1420
|
+
delmotemp = 1.0 + satrec.eta * Math.cos(satrec.mo)
|
1421
|
+
satrec.delmo = delmotemp * delmotemp * delmotemp
|
1422
|
+
satrec.sinmao = Math.sin(satrec.mo)
|
1423
|
+
satrec.x7thm1 = 7.0 * satrec.cosio2 - 1.0
|
1424
|
+
|
1425
|
+
#/* --------------- deep space initialization ------------- */
|
1426
|
+
if ((2 * PI / satrec.no_unkozai) >= 225.0)
|
1427
|
+
satrec.method = "d"
|
1428
|
+
satrec.isimp = 1
|
1429
|
+
tc = 0.0
|
1430
|
+
satrec.inclm = satrec.inclo
|
1431
|
+
|
1432
|
+
dscom(epoch, satrec.ecco, satrec.argpo, tc, satrec.inclo, satrec.nodeo, satrec.no_unkozai, satrec)
|
1433
|
+
|
1434
|
+
satrec.ep = satrec.ecco
|
1435
|
+
satrec.inclp = satrec.inclo
|
1436
|
+
satrec.nodep = satrec.nodeo
|
1437
|
+
satrec.argpp = satrec.argpo
|
1438
|
+
satrec.mp = satrec.mo
|
1439
|
+
|
1440
|
+
dpper(satrec.e3, satrec.ee2, satrec.peo, satrec.pgho,
|
1441
|
+
satrec.pho, satrec.pinco, satrec.plo, satrec.se2,
|
1442
|
+
satrec.se3, satrec.sgh2, satrec.sgh3, satrec.sgh4,
|
1443
|
+
satrec.sh2, satrec.sh3, satrec.si2, satrec.si3,
|
1444
|
+
satrec.sl2, satrec.sl3, satrec.sl4, satrec.t,
|
1445
|
+
satrec.xgh2, satrec.xgh3, satrec.xgh4, satrec.xh2,
|
1446
|
+
satrec.xh3, satrec.xi2, satrec.xi3, satrec.xl2,
|
1447
|
+
satrec.xl3, satrec.xl4, satrec.zmol, satrec.zmos, satrec.init, satrec,
|
1448
|
+
satrec.operationmode)
|
1449
|
+
|
1450
|
+
satrec.ecco = satrec.ep
|
1451
|
+
satrec.inclo = satrec.inclp
|
1452
|
+
satrec.nodeo = satrec.nodep
|
1453
|
+
satrec.argpo = satrec.argpp
|
1454
|
+
satrec.mo = satrec.mp
|
1455
|
+
|
1456
|
+
satrec.argpm = 0.0
|
1457
|
+
satrec.nodem = 0.0
|
1458
|
+
satrec.mm = 0.0
|
1459
|
+
|
1460
|
+
dsinit(tc, xpidot, satrec)
|
1461
|
+
end
|
1462
|
+
#}
|
1463
|
+
|
1464
|
+
#/* ----------- set variables if not deep space ----------- */
|
1465
|
+
if (satrec.isimp != 1)
|
1466
|
+
cc1sq = satrec.cc1 * satrec.cc1
|
1467
|
+
satrec.d2 = 4.0 * satrec.ao * tsi * cc1sq
|
1468
|
+
temp = satrec.d2 * tsi * satrec.cc1 / 3.0
|
1469
|
+
satrec.d3 = (17.0 * satrec.ao + sfour) * temp
|
1470
|
+
satrec.d4 = 0.5 * temp * satrec.ao * tsi * (221.0 * satrec.ao + 31.0 * sfour) * satrec.cc1
|
1471
|
+
satrec.t3cof = satrec.d2 + 2.0 * cc1sq
|
1472
|
+
satrec.t4cof = 0.25 * (3.0 * satrec.d3 + satrec.cc1 * (12.0 * satrec.d2 + 10.0 * cc1sq))
|
1473
|
+
satrec.t5cof = (0.2 * (3.0 * satrec.d4 +
|
1474
|
+
12.0 * satrec.cc1 * satrec.d3 +
|
1475
|
+
6.0 * satrec.d2 * satrec.d2 +
|
1476
|
+
15.0 * cc1sq * (2.0 * satrec.d2 + cc1sq)))
|
1477
|
+
end
|
1478
|
+
end
|
1479
|
+
#} // if omeosq = 0 ...
|
1480
|
+
|
1481
|
+
#/* finally propogate to zero epoch to initialize all others. */
|
1482
|
+
#/ sgp4fix take out check to let satellites process until they are actually below earth surface
|
1483
|
+
#/ if(satrec.error == 0)
|
1484
|
+
|
1485
|
+
r = [0, 0, 0]
|
1486
|
+
v = [0, 0, 0]
|
1487
|
+
|
1488
|
+
sgp4(satrec, 0.0, r, v)
|
1489
|
+
|
1490
|
+
satrec.init = "n"
|
1491
|
+
|
1492
|
+
#/sgp4fix return boolean. satrec.error contains any error codes
|
1493
|
+
return true
|
1494
|
+
end
|
1495
|
+
# // sgp4init
|
1496
|
+
|
1497
|
+
#/*-----------------------------------------------------------------------------
|
1498
|
+
#*
|
1499
|
+
#* procedure sgp4
|
1500
|
+
#*
|
1501
|
+
#* this procedure is the sgp4 prediction model from space command. this is an
|
1502
|
+
#* updated and combined version of sgp4 and sdp4, which were originally
|
1503
|
+
#* published separately in spacetrack report #3. this version follows the
|
1504
|
+
#* methodology from the aiaa paper (2006) describing the history and
|
1505
|
+
#* development of the code.
|
1506
|
+
#* この手順は、スペースコマンドからのsgp4予測モデルです。これは、元々
|
1507
|
+
#* spacetrack report #3で別々に公開されたsgp4とsdp4の更新および統合バージョンです。
|
1508
|
+
#* このバージョンは、コードの歴史と開発を説明するaiaa論文(2006)の方法論に従っています。
|
1509
|
+
#*
|
1510
|
+
#* author : david vallado 719-573-2600 28 jun 2005
|
1511
|
+
#*
|
1512
|
+
#* inputs :
|
1513
|
+
#* satrec - initialised structure from sgp4init() call.
|
1514
|
+
#* tsince - time since epoch (minutes)
|
1515
|
+
#*
|
1516
|
+
#* outputs :
|
1517
|
+
#* r - position vector km
|
1518
|
+
#* v - velocity km/sec
|
1519
|
+
#* return code - non-zero on error.
|
1520
|
+
#* 1 - mean elements, ecc >= 1.0 or ecc < -0.001 or a < 0.95 er
|
1521
|
+
#* 2 - mean motion less than 0.0
|
1522
|
+
#* 3 - pert elements, ecc < 0.0 or ecc > 1.0
|
1523
|
+
#* 4 - semi-latus rectum < 0.0
|
1524
|
+
#* 5 - epoch elements are sub-orbital
|
1525
|
+
#* 6 - satellite has decayed
|
1526
|
+
#*
|
1527
|
+
#* locals :
|
1528
|
+
#* am -
|
1529
|
+
#* axnl, aynl -
|
1530
|
+
#* betal -
|
1531
|
+
#* cosim , sinim , cosomm , sinomm , cnod , snod , cos2u ,
|
1532
|
+
#* sin2u , coseo1 , sineo1 , cosi , sini , cosip , sinip ,
|
1533
|
+
#* cosisq , cossu , sinsu , cosu , sinu
|
1534
|
+
#* delm -
|
1535
|
+
#* delomg -
|
1536
|
+
#* dndt -
|
1537
|
+
#* eccm -
|
1538
|
+
#* emsq -
|
1539
|
+
#* ecose -
|
1540
|
+
#* el2 -
|
1541
|
+
#* eo1 -
|
1542
|
+
#* eccp -
|
1543
|
+
#* esine -
|
1544
|
+
#* argpm -
|
1545
|
+
#* argpp -
|
1546
|
+
#* omgadf -c
|
1547
|
+
#* pl -
|
1548
|
+
#* r -
|
1549
|
+
#* rtemsq -
|
1550
|
+
#* rdotl -
|
1551
|
+
#* rl -
|
1552
|
+
#* rvdot -
|
1553
|
+
#* rvdotl -
|
1554
|
+
#* su -
|
1555
|
+
#* t2 , t3 , t4 , tc
|
1556
|
+
#* tem5, temp , temp1 , temp2 , tempa , tempe , templ
|
1557
|
+
#* u , ux , uy , uz , vx , vy , vz
|
1558
|
+
#* inclm - inclination
|
1559
|
+
#* mm - mean anomaly
|
1560
|
+
#* nm - mean motion
|
1561
|
+
#* nodem - right asc of ascending node
|
1562
|
+
#* xinc -
|
1563
|
+
#* xincp -
|
1564
|
+
#* xl -
|
1565
|
+
#* xlm -
|
1566
|
+
#* mp -
|
1567
|
+
#* xmdf -
|
1568
|
+
#* xmx -
|
1569
|
+
#* xmy -
|
1570
|
+
#* nodedf -
|
1571
|
+
#* xnode -
|
1572
|
+
#* nodep -
|
1573
|
+
#* np -
|
1574
|
+
#*
|
1575
|
+
#* coupling :
|
1576
|
+
#* getgravconst- no longer used. Variables are conatined within satrec
|
1577
|
+
#* dpper
|
1578
|
+
#* dpspace
|
1579
|
+
#*
|
1580
|
+
#* references :
|
1581
|
+
#* hoots, roehrich, norad spacetrack report #3 1980
|
1582
|
+
#* hoots, norad spacetrack report #6 1986
|
1583
|
+
#* hoots, schumacher and glover 2004
|
1584
|
+
#* vallado, crawford, hujsak, kelso 2006
|
1585
|
+
#----------------------------------------------------------------------------*/
|
1586
|
+
|
1587
|
+
def self.sgp4(satrec, tsince, r, v)
|
1588
|
+
|
1589
|
+
#double axnl, aynl, betal, cnod,
|
1590
|
+
# cos2u, coseo1, cosi, cosip, cosisq, cossu, cosu,
|
1591
|
+
# delm, delomg, ecose, el2, eo1,
|
1592
|
+
# esine, argpdf, pl, mrt = 0.0,
|
1593
|
+
# mvt, rdotl, rl, rvdot, rvdotl,
|
1594
|
+
# sin2u, sineo1, sini, sinip, sinsu, sinu,
|
1595
|
+
# snod, su, t2, t3, t4, tem5, temp,
|
1596
|
+
# temp1, temp2, tempa, tempe, templ, u, ux,
|
1597
|
+
# uy, uz, vx, vy, vz,
|
1598
|
+
# xinc, xincp, xl, xlm,
|
1599
|
+
# xmdf, xmx, xmy, nodedf, xnode, tc,
|
1600
|
+
# x2o3, vkmpersec, delmtemp
|
1601
|
+
|
1602
|
+
#int ktr
|
1603
|
+
|
1604
|
+
#/* ------------------ set mathematical constants --------------- */
|
1605
|
+
#// sgp4fix divisor for divide by zero check on inclination
|
1606
|
+
#// the old check used 1.0 + cos(pi-1.0e-9), but then compared it to
|
1607
|
+
#// 1.5 e-12, so the threshold was changed to 1.5e-12 for consistency
|
1608
|
+
temp4 = 1.5e-12
|
1609
|
+
x2o3 = 2.0 / 3.0
|
1610
|
+
#// sgp4fix identify constants and allow alternate values
|
1611
|
+
#// getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 )
|
1612
|
+
vkmpersec = satrec.radiusearthkm * satrec.xke / 60.0
|
1613
|
+
|
1614
|
+
#/* --------------------- clear sgp4 error flag ----------------- */
|
1615
|
+
satrec.t = tsince
|
1616
|
+
satrec.error = 0
|
1617
|
+
|
1618
|
+
#/* ------- update for secular gravity and atmospheric drag ----- */
|
1619
|
+
xmdf = satrec.mo + satrec.mdot * satrec.t
|
1620
|
+
argpdf = satrec.argpo + satrec.argpdot * satrec.t
|
1621
|
+
nodedf = satrec.nodeo + satrec.nodedot * satrec.t
|
1622
|
+
satrec.argpm = argpdf
|
1623
|
+
satrec.mm = xmdf
|
1624
|
+
t2 = satrec.t * satrec.t
|
1625
|
+
satrec.nodem = nodedf + satrec.nodecf * t2
|
1626
|
+
tempa = 1.0 - satrec.cc1 * satrec.t
|
1627
|
+
tempe = satrec.bstar * satrec.cc4 * satrec.t
|
1628
|
+
templ = satrec.t2cof * t2
|
1629
|
+
|
1630
|
+
delomg = 0
|
1631
|
+
delmtemp = 0
|
1632
|
+
delm = 0
|
1633
|
+
temp = 0
|
1634
|
+
t3 = 0
|
1635
|
+
t4 = 0
|
1636
|
+
mrt = 0
|
1637
|
+
|
1638
|
+
if (satrec.isimp != 1)
|
1639
|
+
delomg = satrec.omgcof * satrec.t
|
1640
|
+
delmtemp = 1.0 + satrec.eta * Math.cos(xmdf)
|
1641
|
+
delm = satrec.xmcof * (delmtemp * delmtemp * delmtemp - satrec.delmo)
|
1642
|
+
temp = delomg + delm
|
1643
|
+
satrec.mm = xmdf + temp
|
1644
|
+
satrec.argpm = argpdf - temp
|
1645
|
+
t3 = t2 * satrec.t
|
1646
|
+
t4 = t3 * satrec.t
|
1647
|
+
tempa = tempa - satrec.d2 * t2 - satrec.d3 * t3 - satrec.d4 * t4
|
1648
|
+
tempe = tempe + satrec.bstar * satrec.cc5 * (Math.sin(satrec.mm) - satrec.sinmao)
|
1649
|
+
templ = templ + satrec.t3cof * t3 + t4 * (satrec.t4cof + satrec.t * satrec.t5cof)
|
1650
|
+
end
|
1651
|
+
|
1652
|
+
tc = 0
|
1653
|
+
satrec.nm = satrec.no_unkozai
|
1654
|
+
satrec.em = satrec.ecco
|
1655
|
+
satrec.inclm = satrec.inclo
|
1656
|
+
if (satrec.method == "d")
|
1657
|
+
tc = satrec.t
|
1658
|
+
dspace(tc, satrec)
|
1659
|
+
end
|
1660
|
+
|
1661
|
+
if (satrec.nm <= 0.0)
|
1662
|
+
satrec.error = 2
|
1663
|
+
return false
|
1664
|
+
end
|
1665
|
+
|
1666
|
+
#puts "nm,xke,tempa = #{satrec.nm} #{satrec.xke} #{tempa}"
|
1667
|
+
satrec.am = ((satrec.xke / satrec.nm) ** x2o3) * tempa * tempa
|
1668
|
+
satrec.nm = satrec.xke / (satrec.am ** 1.5)
|
1669
|
+
satrec.em = satrec.em - tempe
|
1670
|
+
#puts "am,nm,em = #{satrec.am} #{satrec.nm} #{satrec.em}"
|
1671
|
+
if ((satrec.em >= 1.0) or (satrec.em < -0.001))
|
1672
|
+
satrec.error = 1
|
1673
|
+
return false
|
1674
|
+
end
|
1675
|
+
|
1676
|
+
if (satrec.em < 1.0e-6)
|
1677
|
+
satrec.em = 1.0e-6
|
1678
|
+
end
|
1679
|
+
|
1680
|
+
satrec.mm = satrec.mm + satrec.no_unkozai * templ
|
1681
|
+
xlm = satrec.mm + satrec.argpm + satrec.nodem
|
1682
|
+
satrec.emsq = satrec.em * satrec.em
|
1683
|
+
temp = 1.0 - satrec.emsq
|
1684
|
+
|
1685
|
+
satrec.nodem = fmod(satrec.nodem, TWOPI)
|
1686
|
+
satrec.argpm = fmod(satrec.argpm, TWOPI)
|
1687
|
+
xlm = fmod(xlm, TWOPI)
|
1688
|
+
satrec.mm = fmod(xlm - satrec.argpm - satrec.nodem, TWOPI)
|
1689
|
+
|
1690
|
+
satrec.am = satrec.am
|
1691
|
+
satrec.em = satrec.em
|
1692
|
+
satrec.im = satrec.inclm
|
1693
|
+
satrec.Om = satrec.nodem
|
1694
|
+
satrec.om = satrec.argpm
|
1695
|
+
satrec.mm = satrec.mm
|
1696
|
+
satrec.nm = satrec.nm
|
1697
|
+
|
1698
|
+
# ----------------- compute extra mean quantities -------------
|
1699
|
+
satrec.sinim = Math.sin(satrec.inclm)
|
1700
|
+
satrec.cosim = Math.cos(satrec.inclm)
|
1701
|
+
|
1702
|
+
# -------------------- add lunar-solar periodics --------------
|
1703
|
+
satrec.ep = satrec.em
|
1704
|
+
xincp = satrec.inclm
|
1705
|
+
satrec.inclp = satrec.inclm
|
1706
|
+
satrec.argpp = satrec.argpm
|
1707
|
+
satrec.nodep = satrec.nodem
|
1708
|
+
satrec.mp = satrec.mm
|
1709
|
+
sinip = satrec.sinim
|
1710
|
+
cosip = satrec.cosim
|
1711
|
+
|
1712
|
+
if (satrec.method == "d")
|
1713
|
+
dpper(satrec.e3, satrec.ee2, satrec.peo, satrec.pgho,
|
1714
|
+
satrec.pho, satrec.pinco, satrec.plo, satrec.se2,
|
1715
|
+
satrec.se3, satrec.sgh2, satrec.sgh3, satrec.sgh4,
|
1716
|
+
satrec.sh2, satrec.sh3, satrec.si2, satrec.si3,
|
1717
|
+
satrec.sl2, satrec.sl3, satrec.sl4, satrec.t,
|
1718
|
+
satrec.xgh2, satrec.xgh3, satrec.xgh4, satrec.xh2,
|
1719
|
+
satrec.xh3, satrec.xi2, satrec.xi3, satrec.xl2,
|
1720
|
+
satrec.xl3, satrec.xl4, satrec.zmol, satrec.zmos,
|
1721
|
+
"n", satrec, satrec.operationmode)
|
1722
|
+
|
1723
|
+
xincp = satrec.inclp
|
1724
|
+
if (xincp < 0.0)
|
1725
|
+
xincp = -xincp
|
1726
|
+
satrec.nodep = satrec.nodep + PI
|
1727
|
+
satrec.argpp = satrec.argpp - PI
|
1728
|
+
end
|
1729
|
+
|
1730
|
+
if ((satrec.ep < 0.0) or (satrec.ep > 1.0))
|
1731
|
+
satrec.error = 3
|
1732
|
+
#// sgp4fix add return
|
1733
|
+
return false
|
1734
|
+
end
|
1735
|
+
end
|
1736
|
+
#} // if method = d
|
1737
|
+
|
1738
|
+
#/* -------------------- long period periodics ------------------ */
|
1739
|
+
if (satrec.method == "d")
|
1740
|
+
sinip = Math.sin(xincp)
|
1741
|
+
cosip = Math.cos(xincp)
|
1742
|
+
satrec.aycof = -0.5 * satrec.j3oj2 * sinip
|
1743
|
+
#// sgp4fix for divide by zero for xincp = 180 deg
|
1744
|
+
if ((cosip + 1.0).abs > 1.5e-12)
|
1745
|
+
satrec.xlcof = -0.25 * satrec.j3oj2 * sinip * (3.0 + 5.0 * cosip) / (1.0 + cosip)
|
1746
|
+
else
|
1747
|
+
satrec.xlcof = -0.25 * satrec.j3oj2 * sinip * (3.0 + 5.0 * cosip) / temp4
|
1748
|
+
end
|
1749
|
+
end
|
1750
|
+
|
1751
|
+
axnl = satrec.ep * Math.cos(satrec.argpp)
|
1752
|
+
temp = 1.0 / (satrec.am * (1.0 - satrec.ep * satrec.ep))
|
1753
|
+
aynl = satrec.ep * Math.sin(satrec.argpp) + temp * satrec.aycof
|
1754
|
+
xl = satrec.mp + satrec.argpp + satrec.nodep + temp * satrec.xlcof * axnl
|
1755
|
+
|
1756
|
+
#/* --------------------- solve kepler's equation --------------- */
|
1757
|
+
u = fmod(xl - satrec.nodep, TWOPI)
|
1758
|
+
eo1 = u
|
1759
|
+
tem5 = 9999.9
|
1760
|
+
ktr = 1
|
1761
|
+
sineo1 = 0
|
1762
|
+
coseo1 = 0
|
1763
|
+
#// sgp4fix for kepler iteration
|
1764
|
+
#// the following iteration needs better limits on corrections
|
1765
|
+
while ((tem5.abs >= 1.0e-12) and (ktr <= 10))
|
1766
|
+
sineo1 = Math.sin(eo1)
|
1767
|
+
coseo1 = Math.cos(eo1)
|
1768
|
+
tem5 = 1.0 - coseo1 * axnl - sineo1 * aynl
|
1769
|
+
tem5 = (u - aynl * coseo1 + axnl * sineo1 - eo1) / tem5
|
1770
|
+
if (tem5.abs >= 0.95)
|
1771
|
+
if (tem5 > 0)
|
1772
|
+
tem5 = 0.95
|
1773
|
+
else
|
1774
|
+
tem5 = -0.95
|
1775
|
+
end
|
1776
|
+
#tem5 = tem5 > 0.0 ? 0.95 : -0.95
|
1777
|
+
end
|
1778
|
+
eo1 = eo1 + tem5
|
1779
|
+
ktr = ktr + 1
|
1780
|
+
end
|
1781
|
+
|
1782
|
+
#/* ------------- short period preliminary quantities ----------- */
|
1783
|
+
ecose = axnl * coseo1 + aynl * sineo1
|
1784
|
+
esine = axnl * sineo1 - aynl * coseo1
|
1785
|
+
el2 = axnl * axnl + aynl * aynl
|
1786
|
+
pl = satrec.am * (1.0 - el2)
|
1787
|
+
if (pl < 0.0)
|
1788
|
+
satrec.error = 4
|
1789
|
+
#// sgp4fix add return
|
1790
|
+
return false
|
1791
|
+
else
|
1792
|
+
rl = satrec.am * (1.0 - ecose)
|
1793
|
+
rdotl = Math.sqrt(satrec.am) * esine / rl
|
1794
|
+
rvdotl = Math.sqrt(pl) / rl
|
1795
|
+
betal = Math.sqrt(1.0 - el2)
|
1796
|
+
temp = esine / (1.0 + betal)
|
1797
|
+
sinu = satrec.am / rl * (sineo1 - aynl - axnl * temp)
|
1798
|
+
cosu = satrec.am / rl * (coseo1 - axnl + aynl * temp)
|
1799
|
+
su = Math.atan2(sinu, cosu)
|
1800
|
+
sin2u = (cosu + cosu) * sinu
|
1801
|
+
cos2u = 1.0 - 2.0 * sinu * sinu
|
1802
|
+
temp = 1.0 / pl
|
1803
|
+
temp1 = 0.5 * satrec.j2 * temp
|
1804
|
+
temp2 = temp1 * temp
|
1805
|
+
|
1806
|
+
#/* -------------- update for short period periodics ------------ */
|
1807
|
+
if (satrec.method == "d")
|
1808
|
+
cosisq = cosip * cosip
|
1809
|
+
satrec.con41 = 3.0 * cosisq - 1.0
|
1810
|
+
satrec.x1mth2 = 1.0 - cosisq
|
1811
|
+
satrec.x7thm1 = 7.0 * cosisq - 1.0
|
1812
|
+
end
|
1813
|
+
|
1814
|
+
mrt = rl * (1.0 - 1.5 * temp2 * betal * satrec.con41) + 0.5 * temp1 * satrec.x1mth2 * cos2u
|
1815
|
+
su = su - 0.25 * temp2 * satrec.x7thm1 * sin2u
|
1816
|
+
xnode = satrec.nodep + 1.5 * temp2 * cosip * sin2u
|
1817
|
+
xinc = xincp + 1.5 * temp2 * cosip * sinip * cos2u
|
1818
|
+
mvt = rdotl - satrec.nm * temp1 * satrec.x1mth2 * sin2u / satrec.xke
|
1819
|
+
rvdot = rvdotl + satrec.nm * temp1 * (satrec.x1mth2 * cos2u + 1.5 * satrec.con41) / satrec.xke
|
1820
|
+
|
1821
|
+
#/* --------------------- orientation vectors ------------------- */
|
1822
|
+
sinsu = Math.sin(su)
|
1823
|
+
cossu = Math.cos(su)
|
1824
|
+
snod = Math.sin(xnode)
|
1825
|
+
cnod = Math.cos(xnode)
|
1826
|
+
sini = Math.sin(xinc)
|
1827
|
+
cosi = Math.cos(xinc)
|
1828
|
+
xmx = -snod * cosi
|
1829
|
+
xmy = cnod * cosi
|
1830
|
+
ux = xmx * sinsu + cnod * cossu
|
1831
|
+
uy = xmy * sinsu + snod * cossu
|
1832
|
+
uz = sini * sinsu
|
1833
|
+
vx = xmx * cossu - cnod * sinsu
|
1834
|
+
vy = xmy * cossu - snod * sinsu
|
1835
|
+
vz = sini * cossu
|
1836
|
+
|
1837
|
+
#/* --------- position and velocity (in km and km/sec) ---------- */
|
1838
|
+
r[0] = (mrt * ux) * satrec.radiusearthkm
|
1839
|
+
r[1] = (mrt * uy) * satrec.radiusearthkm
|
1840
|
+
r[2] = (mrt * uz) * satrec.radiusearthkm
|
1841
|
+
v[0] = (mvt * ux + rvdot * vx) * vkmpersec
|
1842
|
+
v[1] = (mvt * uy + rvdot * vy) * vkmpersec
|
1843
|
+
v[2] = (mvt * uz + rvdot * vz) * vkmpersec
|
1844
|
+
end
|
1845
|
+
#} // if pl > 0
|
1846
|
+
|
1847
|
+
#// sgp4fix for decaying satellites
|
1848
|
+
if (mrt < 1.0)
|
1849
|
+
satrec.error = 6
|
1850
|
+
return false
|
1851
|
+
end
|
1852
|
+
|
1853
|
+
return true
|
1854
|
+
end
|
1855
|
+
#} // sgp4
|
1856
|
+
|
1857
|
+
#/* -----------------------------------------------------------------------------
|
1858
|
+
#*
|
1859
|
+
#* function getgravconst
|
1860
|
+
#*
|
1861
|
+
#* this function gets constants for the propagator. note that mu is identified to
|
1862
|
+
#* facilitiate comparisons with newer models. the common useage is WGS72.
|
1863
|
+
#* この関数はプロパゲータのための定数を取得します。muは新しいモデルとの比較を容易にするために識別されています。
|
1864
|
+
#* 一般的な使用法はWGS72です。
|
1865
|
+
#*
|
1866
|
+
#* author : david vallado 719-573-2600 21 jul 2006
|
1867
|
+
#*
|
1868
|
+
#* inputs :
|
1869
|
+
#* whichconst - which set of constants to use wgs72old, wgs72, wgs84
|
1870
|
+
#*
|
1871
|
+
#* outputs :
|
1872
|
+
#* tumin - minutes in one time unit
|
1873
|
+
#* mu - earth gravitational parameter
|
1874
|
+
#* radiusearthkm - radius of the earth in km
|
1875
|
+
#* xke - reciprocal of tumin
|
1876
|
+
#* j2, j3, j4 - un-normalized zonal harmonic values
|
1877
|
+
#* j3oj2 - j3 divided by j2
|
1878
|
+
#*
|
1879
|
+
#* locals :
|
1880
|
+
#*
|
1881
|
+
#* coupling :
|
1882
|
+
#* none
|
1883
|
+
#*
|
1884
|
+
#* references :
|
1885
|
+
#* norad spacetrack report #3
|
1886
|
+
#* vallado, crawford, hujsak, kelso 2006
|
1887
|
+
#--------------------------------------------------------------------------- */
|
1888
|
+
|
1889
|
+
def self.getgravconst(whichconst, rec)
|
1890
|
+
rec.whichconst = whichconst
|
1891
|
+
|
1892
|
+
#// -- wgs-72 low precision str#3 constants --
|
1893
|
+
if whichconst == WGS72old
|
1894
|
+
rec.mu = 398600.79964 #// in km3 / s2
|
1895
|
+
rec.radiusearthkm = 6378.135 # // km
|
1896
|
+
rec.xke = 0.0743669161 # // reciprocal of tumin
|
1897
|
+
rec.tumin = 1.0 / rec.xke
|
1898
|
+
rec.j2 = 0.001082616
|
1899
|
+
rec.j3 = -0.00000253881
|
1900
|
+
rec.j4 = -0.00000165597
|
1901
|
+
rec.j3oj2 = rec.j3 / rec.j2
|
1902
|
+
#// ------------ WGS-72 constants ------------
|
1903
|
+
elsif whichconst == WGS72
|
1904
|
+
rec.mu = 398600.8 #// in km3 / s2
|
1905
|
+
rec.radiusearthkm = 6378.135 # // km
|
1906
|
+
rec.xke = 60.0 / Math.sqrt(rec.radiusearthkm * rec.radiusearthkm * rec.radiusearthkm / rec.mu)
|
1907
|
+
rec.tumin = 1.0 / rec.xke
|
1908
|
+
rec.j2 = 0.001082616
|
1909
|
+
rec.j3 = -0.00000253881
|
1910
|
+
rec.j4 = -0.00000165597
|
1911
|
+
rec.j3oj2 = rec.j3 / rec.j2
|
1912
|
+
else # WGS84
|
1913
|
+
#// ------------ WGS-84 constants ------------
|
1914
|
+
rec.mu = 398600.44188 # // in km3 / s2
|
1915
|
+
rec.radiusearthkm = 6378.137 # // km
|
1916
|
+
rec.xke = 60.0 / Math.sqrt(rec.radiusearthkm * rec.radiusearthkm * rec.radiusearthkm / rec.mu)
|
1917
|
+
rec.tumin = 1.0 / rec.xke
|
1918
|
+
rec.j2 = 0.00108262998905
|
1919
|
+
rec.j3 = -0.00000253215306
|
1920
|
+
rec.j4 = -0.00000161098761
|
1921
|
+
rec.j3oj2 = rec.j3 / rec.j2
|
1922
|
+
end
|
1923
|
+
end
|
1924
|
+
#} // getgravconst
|
1925
|
+
|
1926
|
+
def self.fmod(numer, denom)
|
1927
|
+
#return numer%denom
|
1928
|
+
tquot = (numer / denom).floor
|
1929
|
+
return numer - tquot * denom
|
1930
|
+
end
|
1931
|
+
|
1932
|
+
#/* -----------------------------------------------------------------------------
|
1933
|
+
#*
|
1934
|
+
#* function gstime
|
1935
|
+
#*
|
1936
|
+
#* this function finds the greenwich sidereal time.
|
1937
|
+
#*
|
1938
|
+
#* author : david vallado 719-573-2600 1 mar 2001
|
1939
|
+
#*
|
1940
|
+
#* inputs description range / units
|
1941
|
+
#* jdut1 - julian date in ut1 days from 4713 bc
|
1942
|
+
#*
|
1943
|
+
#* outputs :
|
1944
|
+
#* gstime - greenwich sidereal time 0 to 2pi rad
|
1945
|
+
#*
|
1946
|
+
#* locals :
|
1947
|
+
#* temp - temporary variable for doubles rad
|
1948
|
+
#* tut1 - julian centuries from the
|
1949
|
+
#* jan 1, 2000 12 h epoch (ut1)
|
1950
|
+
#*
|
1951
|
+
#* coupling :
|
1952
|
+
#* none
|
1953
|
+
#*
|
1954
|
+
#* references :
|
1955
|
+
#* vallado 2013, 187, eq 3-45
|
1956
|
+
#* --------------------------------------------------------------------------- */
|
1957
|
+
|
1958
|
+
def self.gstime(jdut1)
|
1959
|
+
tut1 = (jdut1 - 2451545.0) / 36525.0
|
1960
|
+
temp = (-6.2e-6 * tut1 * tut1 * tut1 + 0.093104 * tut1 * tut1 +
|
1961
|
+
(876600.0 * 3600 + 8640184.812866) * tut1 + 67310.54841) #// sec
|
1962
|
+
temp = fmod(temp * DEG2RAD / 240.0, TWOPI) #//360/86400 = 1/240, to deg, to rad
|
1963
|
+
|
1964
|
+
#// ------------------------ check quadrants ---------------------
|
1965
|
+
if temp < 0.0
|
1966
|
+
temp += TWOPI
|
1967
|
+
end
|
1968
|
+
|
1969
|
+
return temp
|
1970
|
+
end
|
1971
|
+
#} // gstime
|
1972
|
+
|
1973
|
+
#/* -----------------------------------------------------------------------------
|
1974
|
+
#*
|
1975
|
+
#* procedure jday
|
1976
|
+
#*
|
1977
|
+
#* this procedure finds the julian date given the year, month, day, and time.
|
1978
|
+
#* the julian date is defined by each elapsed day since noon, jan 1, 4713 bc.
|
1979
|
+
#*
|
1980
|
+
#* algorithm : calculate the answer in one step for efficiency
|
1981
|
+
#*
|
1982
|
+
#* author : david vallado 719-573-2600 1 mar 2001
|
1983
|
+
#*
|
1984
|
+
#* inputs description range / units
|
1985
|
+
#* year - year 1900 .. 2100
|
1986
|
+
#* mon - month 1 .. 12
|
1987
|
+
#* day - day 1 .. 28,29,30,31
|
1988
|
+
#* hr - universal time hour 0 .. 23
|
1989
|
+
#* min - universal time min 0 .. 59
|
1990
|
+
#* sec - universal time sec 0.0 .. 59.999
|
1991
|
+
#*
|
1992
|
+
#* outputs :
|
1993
|
+
#* jd - julian date days from 4713 bc
|
1994
|
+
#* jdfrac - julian date fraction into day days from 4713 bc
|
1995
|
+
#*
|
1996
|
+
#* locals :
|
1997
|
+
#* none.
|
1998
|
+
#*
|
1999
|
+
#* coupling :
|
2000
|
+
#* none.
|
2001
|
+
#*
|
2002
|
+
#* references :
|
2003
|
+
#* vallado 2013, 183, alg 14, ex 3-4
|
2004
|
+
#* --------------------------------------------------------------------------- */
|
2005
|
+
|
2006
|
+
def self.jday(year, mon, day, hr, minute, sec)
|
2007
|
+
jd = 0
|
2008
|
+
jdFrac = 0
|
2009
|
+
|
2010
|
+
t1 = ((7 * (year + ((mon + 9) / 12.0).floor)) * 0.25).floor
|
2011
|
+
t2 = (275 * mon / 9.0).floor
|
2012
|
+
|
2013
|
+
jd = (367.0 * year - t1 + t2 + day + 1721013.5) # // use - 678987.0 to go to mjd directly
|
2014
|
+
|
2015
|
+
jdFrac = (sec + minute * 60.0 + hr * 3600.0) / 86400.0
|
2016
|
+
|
2017
|
+
#// check that the day and fractional day are correct
|
2018
|
+
if (jdFrac.abs > 1.0)
|
2019
|
+
dtt = jdFrac.floor
|
2020
|
+
jd = jd + dtt
|
2021
|
+
jdFrac = jdFrac - dtt
|
2022
|
+
end
|
2023
|
+
|
2024
|
+
return [jd, jdFrac]
|
2025
|
+
end
|
2026
|
+
end
|
2027
|
+
end
|