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