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.
@@ -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