@saber-usa/node-common 1.7.2 → 1.7.3
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.
- package/README.md +41 -41
- package/package.json +51 -51
- package/src/FrameConverter.js +1120 -1068
- package/src/LLA.js +179 -179
- package/src/LaunchNominalClass.js +774 -824
- package/src/NodeVector3D.js +71 -71
- package/src/OrbitUtils.js +490 -490
- package/src/PropagateUtils.js +100 -100
- package/src/ShadowGEOCalculator.js +203 -203
- package/src/TimeConverter.js +309 -309
- package/src/astro.js +3214 -3214
- package/src/ballisticPropagator.js +1037 -1037
- package/src/checkNetwork.cjs +20 -20
- package/src/constants.js +30 -30
- package/src/fixDate.js +62 -62
- package/src/index.js +47 -47
- package/src/launchNominal.js +208 -208
- package/src/loggerFactory.cjs +98 -98
- package/src/s3.js +59 -59
- package/src/transform.js +35 -35
- package/src/udl.js +116 -116
- package/src/utils.js +406 -406
package/src/FrameConverter.js
CHANGED
|
@@ -1,1068 +1,1120 @@
|
|
|
1
|
-
// FrameConverter.js - Port from C# FrameConverter.cs
|
|
2
|
-
import {Matrix3D, Vector3D} from "pious-squid";
|
|
3
|
-
import {LLA} from "./LLA.js";
|
|
4
|
-
import {TimeConverter, RaDec} from "./TimeConverter.js";
|
|
5
|
-
import {norm, cross} from "mathjs";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// Enums (assuming these exist elsewhere)
|
|
9
|
-
const ReferenceFrame = {
|
|
10
|
-
J2000: "J2000",
|
|
11
|
-
TEME: "TEME",
|
|
12
|
-
GCRF: "GCRF",
|
|
13
|
-
ITRF: "ITRF",
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
// Constants (assuming these exist elsewhere)
|
|
17
|
-
const Constants = {
|
|
18
|
-
TwoPi: 2 * Math.PI,
|
|
19
|
-
RadToDeg: 180 / Math.PI,
|
|
20
|
-
DegToRad: Math.PI / 180,
|
|
21
|
-
ArcsecToRad: Math.PI / (180 * 3600),
|
|
22
|
-
SecondToRad: Math.PI / (180 * 3600),
|
|
23
|
-
SecPerSolarDay: 86400,
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
// Earth constants (assuming these exist elsewhere)
|
|
27
|
-
const Earth = {
|
|
28
|
-
EquatorialRadiusKm: 6378.137,
|
|
29
|
-
EccentricityWgs84: 0.0818191908426,
|
|
30
|
-
SpinRateRadSec: 7.2921159e-5,
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
class FrameConverter {
|
|
34
|
-
/**
|
|
35
|
-
* Helper to
|
|
36
|
-
* @param {
|
|
37
|
-
* @
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
),
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
*
|
|
88
|
-
* @
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
* @
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
return
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
* @param {
|
|
376
|
-
* @param {
|
|
377
|
-
* @
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
*
|
|
395
|
-
*
|
|
396
|
-
*
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
*
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
*
|
|
487
|
-
* @
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
const
|
|
492
|
-
const
|
|
493
|
-
const
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
const
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
const
|
|
545
|
-
const
|
|
546
|
-
const
|
|
547
|
-
|
|
548
|
-
return new Matrix3D(
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
);
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
/**
|
|
556
|
-
* Convert
|
|
557
|
-
*
|
|
558
|
-
* @return {Matrix3D} The transformation matrix from
|
|
559
|
-
*/
|
|
560
|
-
static
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
const
|
|
592
|
-
|
|
593
|
-
const
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
const
|
|
597
|
-
const
|
|
598
|
-
const
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
const
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
const
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
const
|
|
644
|
-
|
|
645
|
-
const
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
const
|
|
674
|
-
|
|
675
|
-
const
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
const
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
* This
|
|
704
|
-
* Vallado Fundamentals
|
|
705
|
-
* @param {number}
|
|
706
|
-
* @return {Matrix3D} The transformation matrix from J2000 to ITRF
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
//
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
);
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
const
|
|
800
|
-
const
|
|
801
|
-
|
|
802
|
-
const
|
|
803
|
-
const
|
|
804
|
-
const
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
//
|
|
810
|
-
//
|
|
811
|
-
//
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
new Vector3D(
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
*
|
|
862
|
-
*
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
);
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
const
|
|
923
|
-
|
|
924
|
-
const
|
|
925
|
-
const
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
//
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
)
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
[
|
|
1011
|
-
[
|
|
1012
|
-
[0,
|
|
1013
|
-
[
|
|
1014
|
-
[
|
|
1015
|
-
[
|
|
1016
|
-
[0,
|
|
1017
|
-
[
|
|
1018
|
-
[
|
|
1019
|
-
[
|
|
1020
|
-
[1, 0,
|
|
1021
|
-
[
|
|
1022
|
-
[1, 0,
|
|
1023
|
-
[
|
|
1024
|
-
[0,
|
|
1025
|
-
[-
|
|
1026
|
-
[
|
|
1027
|
-
[
|
|
1028
|
-
[
|
|
1029
|
-
[
|
|
1030
|
-
[
|
|
1031
|
-
[
|
|
1032
|
-
[
|
|
1033
|
-
[
|
|
1034
|
-
[0,
|
|
1035
|
-
[0,
|
|
1036
|
-
[1, 0,
|
|
1037
|
-
[
|
|
1038
|
-
[
|
|
1039
|
-
[1, 0, 0,
|
|
1040
|
-
[
|
|
1041
|
-
[0, 0, 2,
|
|
1042
|
-
[0, 0,
|
|
1043
|
-
[
|
|
1044
|
-
[
|
|
1045
|
-
[
|
|
1046
|
-
[0,
|
|
1047
|
-
[0, 0,
|
|
1048
|
-
[
|
|
1049
|
-
[
|
|
1050
|
-
[
|
|
1051
|
-
[
|
|
1052
|
-
[
|
|
1053
|
-
[
|
|
1054
|
-
[
|
|
1055
|
-
[
|
|
1056
|
-
[
|
|
1057
|
-
[2, 0,
|
|
1058
|
-
[
|
|
1059
|
-
[
|
|
1060
|
-
[
|
|
1061
|
-
[
|
|
1062
|
-
[
|
|
1063
|
-
[
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1
|
+
// FrameConverter.js - Port from C# FrameConverter.cs
|
|
2
|
+
import {Matrix3D, Vector3D} from "pious-squid";
|
|
3
|
+
import {LLA} from "./LLA.js";
|
|
4
|
+
import {TimeConverter, RaDec} from "./TimeConverter.js";
|
|
5
|
+
import {norm, cross} from "mathjs";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
// Enums (assuming these exist elsewhere)
|
|
9
|
+
const ReferenceFrame = {
|
|
10
|
+
J2000: "J2000",
|
|
11
|
+
TEME: "TEME",
|
|
12
|
+
GCRF: "GCRF",
|
|
13
|
+
ITRF: "ITRF",
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// Constants (assuming these exist elsewhere)
|
|
17
|
+
const Constants = {
|
|
18
|
+
TwoPi: 2 * Math.PI,
|
|
19
|
+
RadToDeg: 180 / Math.PI,
|
|
20
|
+
DegToRad: Math.PI / 180,
|
|
21
|
+
ArcsecToRad: Math.PI / (180 * 3600),
|
|
22
|
+
SecondToRad: Math.PI / (180 * 3600),
|
|
23
|
+
SecPerSolarDay: 86400,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// Earth constants (assuming these exist elsewhere)
|
|
27
|
+
const Earth = {
|
|
28
|
+
EquatorialRadiusKm: 6378.137,
|
|
29
|
+
EccentricityWgs84: 0.0818191908426,
|
|
30
|
+
SpinRateRadSec: 7.2921159e-5,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
class FrameConverter {
|
|
34
|
+
/**
|
|
35
|
+
* Helper method to transform a vector using a Matrix3D
|
|
36
|
+
* @param {Vector3D} vector - Vector to transform
|
|
37
|
+
* @param {Matrix3D} matrix - Matrix to use for transformation
|
|
38
|
+
* @return {Vector3D} Transformed vector
|
|
39
|
+
*/
|
|
40
|
+
static transformVector(vector, matrix) {
|
|
41
|
+
// Manual matrix-vector multiplication since pious-squid has issues
|
|
42
|
+
const x = matrix.get(0, 0) * vector.x
|
|
43
|
+
+ matrix.get(0, 1) * vector.y + matrix.get(0, 2) * vector.z;
|
|
44
|
+
const y = matrix.get(1, 0) * vector.x
|
|
45
|
+
+ matrix.get(1, 1) * vector.y + matrix.get(1, 2) * vector.z;
|
|
46
|
+
const z = matrix.get(2, 0) * vector.x
|
|
47
|
+
+ matrix.get(2, 1) * vector.y + matrix.get(2, 2) * vector.z;
|
|
48
|
+
return new Vector3D(x, y, z);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Rotate a vector around an axis by an angle (Rodrigues' rotation formula)
|
|
53
|
+
* @param {Vector3D} vector - Vector to rotate
|
|
54
|
+
* @param {Vector3D} axis - Axis to rotate around (should be normalized)
|
|
55
|
+
* @param {number} angleRad - Angle in radians
|
|
56
|
+
* @return {Vector3D} Rotated vector
|
|
57
|
+
*/
|
|
58
|
+
static rotateVector(vector, axis, angleRad) {
|
|
59
|
+
// Ensure axis is normalized
|
|
60
|
+
const k = axis.normalized();
|
|
61
|
+
const v = vector;
|
|
62
|
+
const cosTheta = Math.cos(angleRad);
|
|
63
|
+
const sinTheta = Math.sin(angleRad);
|
|
64
|
+
|
|
65
|
+
// Rodrigues' rotation formula:
|
|
66
|
+
// v_rot = v*cos(θ) + (k × v)*sin(θ) + k*(k·v)*(1-cos(θ))
|
|
67
|
+
|
|
68
|
+
// k × v (cross product)
|
|
69
|
+
const kCrossV = new Vector3D(
|
|
70
|
+
k.y * v.z - k.z * v.y,
|
|
71
|
+
k.z * v.x - k.x * v.z,
|
|
72
|
+
k.x * v.y - k.y * v.x,
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// k·v (dot product)
|
|
76
|
+
const kDotV = k.x * v.x + k.y * v.y + k.z * v.z;
|
|
77
|
+
|
|
78
|
+
// Final rotation
|
|
79
|
+
return new Vector3D(
|
|
80
|
+
v.x * cosTheta + kCrossV.x * sinTheta + k.x * kDotV * (1 - cosTheta),
|
|
81
|
+
v.y * cosTheta + kCrossV.y * sinTheta + k.y * kDotV * (1 - cosTheta),
|
|
82
|
+
v.z * cosTheta + kCrossV.z * sinTheta + k.z * kDotV * (1 - cosTheta),
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Helper to transpose a Matrix3D
|
|
88
|
+
* @param {Matrix3D} m - The matrix to transpose
|
|
89
|
+
* @return {Matrix3D} The transposed matrix
|
|
90
|
+
*/
|
|
91
|
+
static transposeMatrix(m) {
|
|
92
|
+
return new Matrix3D(
|
|
93
|
+
m.get(0, 0), m.get(1, 0), m.get(2, 0),
|
|
94
|
+
m.get(0, 1), m.get(1, 1), m.get(2, 1),
|
|
95
|
+
m.get(0, 2), m.get(1, 2), m.get(2, 2),
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Helper to invert a 3x3 matrix
|
|
101
|
+
* @param {Matrix3D} m - The matrix to invert
|
|
102
|
+
* @return {Matrix3D} The inverted matrix
|
|
103
|
+
*/
|
|
104
|
+
static invertMatrix(m) {
|
|
105
|
+
const a = m.get(0, 0); const b = m.get(0, 1); const c = m.get(0, 2);
|
|
106
|
+
const d = m.get(1, 0); const e = m.get(1, 1); const f = m.get(1, 2);
|
|
107
|
+
const g = m.get(2, 0); const h = m.get(2, 1); const i = m.get(2, 2);
|
|
108
|
+
|
|
109
|
+
const det = a * (e * i - f * h) - b * (d * i - f * g) + c * (d * h - e * g);
|
|
110
|
+
|
|
111
|
+
if (Math.abs(det) < 1e-10) {
|
|
112
|
+
throw new Error("Matrix is not invertible");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const invDet = 1 / det;
|
|
116
|
+
|
|
117
|
+
return new Matrix3D(
|
|
118
|
+
new Vector3D(
|
|
119
|
+
(e * i - f * h) * invDet,
|
|
120
|
+
(c * h - b * i) * invDet,
|
|
121
|
+
(b * f - c * e) * invDet,
|
|
122
|
+
),
|
|
123
|
+
new Vector3D(
|
|
124
|
+
(f * g - d * i) * invDet,
|
|
125
|
+
(a * i - c * g) * invDet,
|
|
126
|
+
(c * d - a * f) * invDet,
|
|
127
|
+
),
|
|
128
|
+
new Vector3D(
|
|
129
|
+
(d * h - e * g) * invDet,
|
|
130
|
+
(b * g - a * h) * invDet,
|
|
131
|
+
(a * e - b * d) * invDet,
|
|
132
|
+
),
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Helper to multiply two matrices
|
|
138
|
+
* @param {Matrix3D} m1 - The first matrix
|
|
139
|
+
* @param {Matrix3D} m2 - The second matrix
|
|
140
|
+
* @return {Matrix3D} The product of the two matrices
|
|
141
|
+
*/
|
|
142
|
+
static multiplyMatrices(m1, m2) {
|
|
143
|
+
// for (let i = 0; i < 3; i++) {
|
|
144
|
+
// for (let j = 0; j < 3; j++) {
|
|
145
|
+
// let sum = 0;
|
|
146
|
+
// for (let k = 0; k < 3; k++) {
|
|
147
|
+
// sum += m1.get(i, k) * m2.get(k, j);
|
|
148
|
+
// }
|
|
149
|
+
// // Matrix3D doesn't have a set method, so we need to create a new one
|
|
150
|
+
// // This is a limitation - we'll work around it
|
|
151
|
+
// }
|
|
152
|
+
// }
|
|
153
|
+
// Create new matrix with computed values
|
|
154
|
+
return new Matrix3D(
|
|
155
|
+
new Vector3D(
|
|
156
|
+
m1.get(0, 0) * m2.get(0, 0)
|
|
157
|
+
+ m1.get(0, 1) * m2.get(1, 0) + m1.get(0, 2) * m2.get(2, 0),
|
|
158
|
+
m1.get(0, 0) * m2.get(0, 1)
|
|
159
|
+
+ m1.get(0, 1) * m2.get(1, 1) + m1.get(0, 2) * m2.get(2, 1),
|
|
160
|
+
m1.get(0, 0) * m2.get(0, 2)
|
|
161
|
+
+ m1.get(0, 1) * m2.get(1, 2) + m1.get(0, 2) * m2.get(2, 2)),
|
|
162
|
+
new Vector3D(
|
|
163
|
+
m1.get(1, 0) * m2.get(0, 0)
|
|
164
|
+
+ m1.get(1, 1) * m2.get(1, 0) + m1.get(1, 2) * m2.get(2, 0),
|
|
165
|
+
m1.get(1, 0) * m2.get(0, 1)
|
|
166
|
+
+ m1.get(1, 1) * m2.get(1, 1) + m1.get(1, 2) * m2.get(2, 1),
|
|
167
|
+
m1.get(1, 0) * m2.get(0, 2)
|
|
168
|
+
+ m1.get(1, 1) * m2.get(1, 2) + m1.get(1, 2) * m2.get(2, 2)),
|
|
169
|
+
new Vector3D(
|
|
170
|
+
m1.get(2, 0) * m2.get(0, 0)
|
|
171
|
+
+ m1.get(2, 1) * m2.get(1, 0) + m1.get(2, 2) * m2.get(2, 0),
|
|
172
|
+
m1.get(2, 0) * m2.get(0, 1)
|
|
173
|
+
+ m1.get(2, 1) * m2.get(1, 1) + m1.get(2, 2) * m2.get(2, 1),
|
|
174
|
+
m1.get(2, 0) * m2.get(0, 2)
|
|
175
|
+
+ m1.get(2, 1) * m2.get(1, 2) + m1.get(2, 2) * m2.get(2, 2)),
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Get transform from a frame to a destination frame at a given time.
|
|
181
|
+
* Apply this to a position vector using: vec3d.TransformBy(matrix)
|
|
182
|
+
* @param {string} from - Source reference frame
|
|
183
|
+
* @param {string} to - Destination reference frame
|
|
184
|
+
* @param {Date} utc - UTC time for the transformation
|
|
185
|
+
* @return {Matrix3D} The transformation matrix
|
|
186
|
+
*/
|
|
187
|
+
static getTransform(from, to, utc) {
|
|
188
|
+
switch (from) {
|
|
189
|
+
case ReferenceFrame.J2000:
|
|
190
|
+
switch (to) {
|
|
191
|
+
case ReferenceFrame.J2000:
|
|
192
|
+
break;
|
|
193
|
+
case ReferenceFrame.TEME:
|
|
194
|
+
return this.j2000ToTEME(utc);
|
|
195
|
+
case ReferenceFrame.GCRF:
|
|
196
|
+
return this.j2000ToGCRF();
|
|
197
|
+
case ReferenceFrame.ITRF:
|
|
198
|
+
return this.j2000ToITRF(utc);
|
|
199
|
+
default:
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
break;
|
|
203
|
+
case ReferenceFrame.TEME:
|
|
204
|
+
switch (to) {
|
|
205
|
+
case ReferenceFrame.J2000:
|
|
206
|
+
return this.temeToJ2000(utc);
|
|
207
|
+
case ReferenceFrame.TEME:
|
|
208
|
+
break;
|
|
209
|
+
case ReferenceFrame.GCRF:
|
|
210
|
+
return this.multiplyMatrices(this.j2000ToGCRF(), this.temeToJ2000(utc));
|
|
211
|
+
case ReferenceFrame.ITRF:
|
|
212
|
+
return this.multiplyMatrices(this.j2000ToITRF(utc), this.temeToJ2000(utc));
|
|
213
|
+
default:
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
break;
|
|
217
|
+
case ReferenceFrame.GCRF:
|
|
218
|
+
switch (to) {
|
|
219
|
+
case ReferenceFrame.J2000:
|
|
220
|
+
return this.gcrfToJ2000();
|
|
221
|
+
case ReferenceFrame.TEME:
|
|
222
|
+
return this.multiplyMatrices(this.j2000ToTEME(utc), this.gcrfToJ2000());
|
|
223
|
+
case ReferenceFrame.GCRF:
|
|
224
|
+
break;
|
|
225
|
+
case ReferenceFrame.ITRF:
|
|
226
|
+
return this.multiplyMatrices(this.j2000ToITRF(utc), this.gcrfToJ2000());
|
|
227
|
+
default:
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
break;
|
|
231
|
+
case ReferenceFrame.ITRF:
|
|
232
|
+
switch (to) {
|
|
233
|
+
case ReferenceFrame.J2000:
|
|
234
|
+
return this.itrfToJ2000(utc);
|
|
235
|
+
case ReferenceFrame.TEME:
|
|
236
|
+
return this.multiplyMatrices(this.j2000ToTEME(utc), this.itrfToJ2000(utc));
|
|
237
|
+
case ReferenceFrame.GCRF:
|
|
238
|
+
return this.multiplyMatrices(this.j2000ToGCRF(), this.itrfToJ2000(utc));
|
|
239
|
+
case ReferenceFrame.ITRF:
|
|
240
|
+
break;
|
|
241
|
+
default:
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
break;
|
|
245
|
+
default:
|
|
246
|
+
break; // TODO: custom frame xforms, RIC, etc
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Return identity matrix
|
|
250
|
+
return new Matrix3D(
|
|
251
|
+
new Vector3D(1, 0, 0),
|
|
252
|
+
new Vector3D(0, 1, 0),
|
|
253
|
+
new Vector3D(0, 0, 1),
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Convert from ITRF/ECEF to azimuth, elevation, range.
|
|
259
|
+
* Optional velocity component will yield AzElRange rates, however this will slow down the computation.
|
|
260
|
+
* @param {LLA} site - Ground site in LLA
|
|
261
|
+
* @param {Vector3D} r - Position vector in ECEF frame
|
|
262
|
+
* @param {Vector3D} [v=null] - Velocity vector in ECEF frame
|
|
263
|
+
* @param {number} [planetRadius=Earth.EquatorialRadiusKm] - Planet radius
|
|
264
|
+
* @param {number} [planetEccentricity=Earth.EccentricityWgs84] - Planet eccentricity
|
|
265
|
+
* @return {AzElRange} Azimuth, elevation, and range
|
|
266
|
+
*/
|
|
267
|
+
static itrfToAzElRange(site, r, v = null,
|
|
268
|
+
planetRadius = Earth.EquatorialRadiusKm, planetEccentricity = Earth.EccentricityWgs84) {
|
|
269
|
+
// Transform
|
|
270
|
+
const ecef2sez = this.ecefToSEZ(site);
|
|
271
|
+
|
|
272
|
+
// To SEZ
|
|
273
|
+
const siteEcef = this.llaToECEF(site, planetRadius, planetEccentricity);
|
|
274
|
+
const rhoEcef = r.subtract(siteEcef);
|
|
275
|
+
const rhoDotEcef = v === null ? new Vector3D(0, 0, 0) : v;
|
|
276
|
+
const rhoSez = ecef2sez.multiplyVector3D(rhoEcef);
|
|
277
|
+
const rhoDotSez = ecef2sez.multiplyVector3D(rhoDotEcef);
|
|
278
|
+
|
|
279
|
+
// AER
|
|
280
|
+
const rho = rhoSez.magnitude();
|
|
281
|
+
let sinBeta; let cosBeta;
|
|
282
|
+
const el = Math.asin(rhoSez.z / rho);
|
|
283
|
+
|
|
284
|
+
if (el * Constants.RadToDeg !== 90 || v === null) {
|
|
285
|
+
sinBeta = rhoSez.y / Math.sqrt(Math.pow(rhoSez.x, 2) + Math.pow(rhoSez.y, 2));
|
|
286
|
+
cosBeta = -rhoSez.x / Math.sqrt(Math.pow(rhoSez.x, 2) + Math.pow(rhoSez.y, 2));
|
|
287
|
+
} else { // use rates
|
|
288
|
+
sinBeta = rhoDotSez.y / Math.sqrt(Math.pow(rhoDotSez.x, 2) + Math.pow(rhoDotSez.y, 2));
|
|
289
|
+
cosBeta = -rhoDotSez.x / Math.sqrt(Math.pow(rhoDotSez.x, 2) + Math.pow(rhoDotSez.y, 2));
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
let az = Math.atan2(sinBeta, cosBeta);
|
|
293
|
+
// Wrap to [0, 2π]
|
|
294
|
+
while (az < 0) az += Constants.TwoPi;
|
|
295
|
+
while (az >= Constants.TwoPi) az -= Constants.TwoPi;
|
|
296
|
+
|
|
297
|
+
// Rates
|
|
298
|
+
if (v !== null) {
|
|
299
|
+
const rhoDot = rhoSez.dot(rhoDotSez) / rho;
|
|
300
|
+
const azDot = (
|
|
301
|
+
rhoDotSez.x * rhoSez.y - rhoDotSez.y * rhoSez.x) / (
|
|
302
|
+
Math.pow(rhoSez.x, 2) + Math.pow(rhoSez.y, 2));
|
|
303
|
+
const elDot = (rhoDotSez.z - rhoDot * Math.sin(el)) / Math.sqrt(
|
|
304
|
+
Math.pow(rhoSez.x, 2) + Math.pow(rhoSez.y, 2));
|
|
305
|
+
|
|
306
|
+
return {
|
|
307
|
+
azimuth: az,
|
|
308
|
+
elevation: el,
|
|
309
|
+
range: rho,
|
|
310
|
+
azimuthDot: azDot,
|
|
311
|
+
elevationDot: elDot,
|
|
312
|
+
rangeDot: rhoDot,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return {
|
|
317
|
+
azimuth: az,
|
|
318
|
+
elevation: el,
|
|
319
|
+
range: rho,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Convert from azimuth, elevation, and range to ITRF/ECEF.
|
|
325
|
+
* Will return velocity if AzElRange rates are not zero.
|
|
326
|
+
* @param {AzElRange} aer - Azimuth, elevation, and range
|
|
327
|
+
* @param {LLA} site - Ground site in LLA
|
|
328
|
+
* @param {number} [planetRadius=Earth.EquatorialRadiusKm] - Planet radius
|
|
329
|
+
* @param {number} [planetEccentricity=Earth.EccentricityWgs84] - Planet eccentricity
|
|
330
|
+
* @return {Object} Position and velocity in ECEF
|
|
331
|
+
*/
|
|
332
|
+
static azElRangeToITRF(aer, site, planetRadius = Earth.EquatorialRadiusKm,
|
|
333
|
+
planetEccentricity = Earth.EccentricityWgs84) {
|
|
334
|
+
const Ce = planetRadius / Math.sqrt(
|
|
335
|
+
1 - Math.pow(planetEccentricity, 2)
|
|
336
|
+
* Math.pow(Math.sin(site.Latitude.Radians), 2));
|
|
337
|
+
|
|
338
|
+
const Se = Ce * (1 - Math.pow(planetEccentricity, 2));
|
|
339
|
+
const rd = (Ce + site.AltitudeKm) * Math.cos(site.Latitude.Radians);
|
|
340
|
+
const rK = (Se + site.AltitudeKm) * Math.sin(site.Latitude.Radians);
|
|
341
|
+
|
|
342
|
+
const rSiteEcef = new Vector3D(
|
|
343
|
+
rd * Math.cos(site.Longitude.Radians),
|
|
344
|
+
rd * Math.sin(site.Longitude.Radians),
|
|
345
|
+
rK);
|
|
346
|
+
|
|
347
|
+
const rho = aer.RangeKm;
|
|
348
|
+
const drho = aer.RangeRatePerSec || 0;
|
|
349
|
+
const daz = aer.AzimuthRatePerSec ? aer.AzimuthRatePerSec.Radians : 0;
|
|
350
|
+
const del = aer.ElevationRatePerSec ? aer.ElevationRatePerSec.Radians : 0;
|
|
351
|
+
const saz = Math.sin(aer.Azimuth.Radians);
|
|
352
|
+
const caz = Math.cos(aer.Azimuth.Radians);
|
|
353
|
+
const sel = Math.sin(aer.Elevation.Radians);
|
|
354
|
+
const cel = Math.cos(aer.Elevation.Radians);
|
|
355
|
+
|
|
356
|
+
const rhoSez = new Vector3D(-rho * cel * caz, rho * cel * saz, rho * sel);
|
|
357
|
+
const rhoDotSez = new Vector3D(
|
|
358
|
+
-drho * cel * caz + rho * sel * caz * del + rho * cel * saz * daz,
|
|
359
|
+
drho * cel * saz - rho * sel * saz * del + rho * cel * caz * daz,
|
|
360
|
+
drho * sel + rho * cel * del);
|
|
361
|
+
|
|
362
|
+
const s2e = this.sezToECEF(site);
|
|
363
|
+
|
|
364
|
+
const rhoEcef = s2e.multiplyVector3D(rhoSez);
|
|
365
|
+
const rhoDotEcef = s2e.multiplyVector3D(rhoDotSez);
|
|
366
|
+
const rEcef = rhoEcef.add(rSiteEcef);
|
|
367
|
+
const vEcef = rhoDotEcef;
|
|
368
|
+
|
|
369
|
+
return {Position: rEcef, Velocity: vEcef};
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Convert position and velocity in J2000 to Azimuth, elevation, and range and each of their rates.
|
|
374
|
+
* @param {LLA} site - Ground site in LLA
|
|
375
|
+
* @param {Date} utc - UTC time
|
|
376
|
+
* @param {Vector3D} r - Position vector in J2000
|
|
377
|
+
* @param {Vector3D} [v=null] - Velocity vector in J2000
|
|
378
|
+
* @return {AzElRange} Azimuth, elevation, and range and their rates
|
|
379
|
+
*/
|
|
380
|
+
static J2000ToAzElRange(site, utc, r, v = null) {
|
|
381
|
+
// Transform
|
|
382
|
+
const j2k2itrf = this.j2000ToITRF(utc);
|
|
383
|
+
|
|
384
|
+
// SEZ vectors
|
|
385
|
+
const rEcef = j2k2itrf.multiplyVector3D(r);
|
|
386
|
+
const vEcef = v === null ? new Vector3D(0, 0, 0) : j2k2itrf.multiplyVector3D(v);
|
|
387
|
+
|
|
388
|
+
return this.itrfToAzElRange(site, rEcef, v === null ? v : vEcef);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Convert Az, El, Range to J2000 position and velocity.
|
|
393
|
+
* @param {AzElRange} aer - Azimuth, elevation, and range
|
|
394
|
+
* @param {LLA} site - Ground site in LLA
|
|
395
|
+
* @param {Date} utc - UTC time
|
|
396
|
+
* @return {Object} Position and velocity in J2000
|
|
397
|
+
*/
|
|
398
|
+
static AzElRangeToJ2000(aer, site, utc) {
|
|
399
|
+
const {Position: rEcef, Velocity: vEcef} = this.azElRangeToITRF(aer, site);
|
|
400
|
+
|
|
401
|
+
return this.itrfToJ2000(utc, rEcef, vEcef === null ? new Vector3D(0, 0, 0) : vEcef);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Converts a TEME position vector from an SGP4 propagation to Lat, Lon, Alt.
|
|
406
|
+
* @param {Vector3D} r - Position vector in TEME
|
|
407
|
+
* @param {Date} utc - UTC time
|
|
408
|
+
* @return {LLA} Latitude, longitude, and altitude
|
|
409
|
+
*/
|
|
410
|
+
static TEMEToLLA(r, utc) {
|
|
411
|
+
return this.j2000ToLLA(this.temeToJ2000(utc).multiplyVector3D(r), utc);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Convert Lat, Lon, Alt to a TEME position vector.
|
|
416
|
+
* @param {LLA} lla - Latitude, longitude, and altitude
|
|
417
|
+
* @param {Date} utc - UTC time
|
|
418
|
+
* @return {Vector3D} Position vector in TEME
|
|
419
|
+
*/
|
|
420
|
+
static LLAToTEME(lla, utc) {
|
|
421
|
+
return this.j2000ToTEME(utc).multiplyVector3D(this.llaToJ2000(lla, utc));
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Converts a J2000 position vector to Lat, Lon, Alt.
|
|
426
|
+
* J2000 is the default reference frame of the UDL and many other applications.
|
|
427
|
+
* @param {Vector3D} r - Position vector in J2000
|
|
428
|
+
* @param {Date} utc - UTC time
|
|
429
|
+
* @return {LLA} Latitude, longitude, and altitude
|
|
430
|
+
*/
|
|
431
|
+
static j2000ToLLA(r, utc) {
|
|
432
|
+
return this.ecefToLLA(this.j2000ToITRF(utc).multiplyVector3D(r));
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Converts Lat, Lon, Alt to J2000 position vector.
|
|
437
|
+
* @param {LLA} lla - Latitude, longitude, and altitude
|
|
438
|
+
* @param {Date} utc - UTC time
|
|
439
|
+
* @return {Vector3D} Position vector in J2000
|
|
440
|
+
*/
|
|
441
|
+
static llaToJ2000(lla, utc) {
|
|
442
|
+
return this.itrfToJ2000(utc).multiplyVector3D(this.llaToECEF(lla));
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Convert ECEF coordinates to Lat, Lon, Alt.
|
|
447
|
+
* ECEF includes ITRF and WGS frames.
|
|
448
|
+
* Vallado Fundamentals, p. 172
|
|
449
|
+
* @param {Vector3D} r The vector r must be in ITRF frame (see j2000ToITRF()).
|
|
450
|
+
* @param {number} planetRadKm
|
|
451
|
+
* @param {number} planetEcc
|
|
452
|
+
* @param {number} tol
|
|
453
|
+
* @return {LLA} Latitude, longitude, and altitude
|
|
454
|
+
*/
|
|
455
|
+
static ecefToLLA(r, planetRadKm = Earth.EquatorialRadiusKm,
|
|
456
|
+
planetEcc = Earth.EccentricityWgs84, tol = 1e-6) {
|
|
457
|
+
const rdels = Math.sqrt(Math.pow(r.x, 2) + Math.pow(r.y, 2));
|
|
458
|
+
const lambda = Math.acos(r.x / rdels) * Math.sign(Math.asin(r.y / rdels));
|
|
459
|
+
let phigd = Math.atan2(r.z, rdels);
|
|
460
|
+
const rdel = rdels;
|
|
461
|
+
const phigdOld = phigd;
|
|
462
|
+
let C;
|
|
463
|
+
|
|
464
|
+
let iter = 0;
|
|
465
|
+
|
|
466
|
+
do {
|
|
467
|
+
C = planetRadKm / Math.sqrt(1 - Math.pow(planetEcc, 2) * Math.pow(Math.sin(phigd), 2));
|
|
468
|
+
phigd = Math.atan2(r.z + C * Math.pow(planetEcc, 2) * Math.sin(phigd), rdel);
|
|
469
|
+
iter++;
|
|
470
|
+
} while (phigd - phigdOld > tol && iter < 10);
|
|
471
|
+
|
|
472
|
+
const nearPoles = r.angle(new Vector3D(0, 0, 1)) * Constants.RadToDeg < 1
|
|
473
|
+
|| r.angle(new Vector3D(0, 0, -1)) * Constants.RadToDeg < 1;
|
|
474
|
+
const S = C * (1 - Math.pow(planetEcc, 2));
|
|
475
|
+
const hEllip = nearPoles ? r.z / Math.sin(phigd) - S : rdel / Math.cos(phigd) - C;
|
|
476
|
+
|
|
477
|
+
return new LLA(phigd * Constants.RadToDeg, lambda * Constants.RadToDeg, hEllip);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Convert Lat, Lon, Alt to ECEF position.
|
|
482
|
+
* ECEF includes ITRF and WGS frames.
|
|
483
|
+
* Vallado Fundamentals, p. 144
|
|
484
|
+
* @param {LLA} lla - Latitude, longitude, and altitude
|
|
485
|
+
* @param {number} [planetRad=Earth.EquatorialRadiusKm] - Planet radius
|
|
486
|
+
* @param {number} [planetEcc=Earth.EccentricityWgs84] - Planet eccentricity
|
|
487
|
+
* @return {Vector3D} Position vector in ECEF
|
|
488
|
+
*/
|
|
489
|
+
static llaToECEF(lla, planetRad = Earth.EquatorialRadiusKm,
|
|
490
|
+
planetEcc = Earth.EccentricityWgs84) {
|
|
491
|
+
const phigd = lla.Latitude.Radians;
|
|
492
|
+
const lamba = lla.Longitude.Radians;
|
|
493
|
+
const h = lla.AltitudeKm;
|
|
494
|
+
|
|
495
|
+
const C = planetRad / Math.sqrt(1
|
|
496
|
+
- Math.pow(planetEcc, 2) * Math.pow(Math.sin(phigd), 2));
|
|
497
|
+
const S = planetRad * (1
|
|
498
|
+
- Math.pow(planetEcc, 2)) / Math.sqrt(1
|
|
499
|
+
- Math.pow(planetEcc, 2) * Math.pow(Math.sin(phigd), 2));
|
|
500
|
+
|
|
501
|
+
return new Vector3D(
|
|
502
|
+
(C + h) * Math.cos(phigd) * Math.cos(lamba),
|
|
503
|
+
(C + h) * Math.cos(phigd) * Math.sin(lamba),
|
|
504
|
+
(S + h) * Math.sin(phigd));
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Converts Azimuth and Elevation (Topocentric Coordinates) to Right Ascension
|
|
509
|
+
* and Declination (Spherical Coordinates) at a given time.
|
|
510
|
+
* @param {Date} utc - The UTC time
|
|
511
|
+
* @param {Site} site - The observer's location
|
|
512
|
+
* @param {AzEl} azel - The azimuth and elevation angles
|
|
513
|
+
* @return {RaDec} The right ascension and declination
|
|
514
|
+
*/
|
|
515
|
+
static AzElToRaDec(utc, site, azel) {
|
|
516
|
+
const t = new TimeConverter(utc);
|
|
517
|
+
const latRads = site.Latitude.Radians;
|
|
518
|
+
const azRads = azel.Azimuth.Radians;
|
|
519
|
+
const elRads = azel.Elevation.Radians;
|
|
520
|
+
|
|
521
|
+
const dec = Math.asin(Math.sin(elRads) * Math.sin(latRads)
|
|
522
|
+
+ Math.cos(elRads) * Math.cos(latRads) * Math.cos(azRads));
|
|
523
|
+
|
|
524
|
+
// Get local siderial time from longitude
|
|
525
|
+
const {lmst} = TimeConverter.getLMST(site.Longitude.Degrees, t.JulianUT1);
|
|
526
|
+
|
|
527
|
+
// Get local hour angle, the angle between the zenith and north polar distance of the object
|
|
528
|
+
const H = Math.atan2(
|
|
529
|
+
-Math.sin(azRads) * Math.cos(elRads) * Math.cos(latRads),
|
|
530
|
+
Math.sin(elRads) - Math.sin(latRads) * Math.sin(dec));
|
|
531
|
+
|
|
532
|
+
const ra = (lmst - H) % Constants.TwoPi;
|
|
533
|
+
|
|
534
|
+
return new RaDec(ra * Constants.RadToDeg, dec * Constants.RadToDeg);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Convert ECEF to SEZ frame for a given ground site.
|
|
539
|
+
* @param {Site} site - The observer's location
|
|
540
|
+
* @return {Matrix3D} The transformation matrix from ECEF to SEZ
|
|
541
|
+
*/
|
|
542
|
+
static ecefToSEZ(site) {
|
|
543
|
+
const sinLat = Math.sin(site.Latitude.Radians);
|
|
544
|
+
const cosLat = Math.cos(site.Latitude.Radians);
|
|
545
|
+
const sinLon = Math.sin(site.Longitude.Radians);
|
|
546
|
+
const cosLon = Math.cos(site.Longitude.Radians);
|
|
547
|
+
|
|
548
|
+
return new Matrix3D(
|
|
549
|
+
sinLat * cosLon, sinLat * sinLon, -cosLat,
|
|
550
|
+
-sinLon, cosLon, 0,
|
|
551
|
+
cosLat * cosLon, cosLat * sinLon, sinLat,
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Convert SEZ to ECEF frame for a given ground site.
|
|
557
|
+
* @param {Site} site - The observer's location
|
|
558
|
+
* @return {Matrix3D} The transformation matrix from SEZ to ECEF
|
|
559
|
+
*/
|
|
560
|
+
static sezToECEF(site) {
|
|
561
|
+
// SEZ to ECEF is the transpose of ECEF to SEZ for orthogonal matrices
|
|
562
|
+
const sinLat = Math.sin(site.Latitude.Radians);
|
|
563
|
+
const cosLat = Math.cos(site.Latitude.Radians);
|
|
564
|
+
const sinLon = Math.sin(site.Longitude.Radians);
|
|
565
|
+
const cosLon = Math.cos(site.Longitude.Radians);
|
|
566
|
+
|
|
567
|
+
// This is the transpose of ecefToSEZ matrix
|
|
568
|
+
return new Matrix3D(
|
|
569
|
+
new Vector3D(sinLat * cosLon, -sinLon, cosLat * cosLon),
|
|
570
|
+
new Vector3D(sinLat * sinLon, cosLon, cosLat * sinLon),
|
|
571
|
+
new Vector3D(-cosLat, 0, sinLat),
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Convert GCRF to J2000 (frame bias).
|
|
577
|
+
* @return {Matrix3D} The transformation matrix from GCRF to J2000
|
|
578
|
+
*/
|
|
579
|
+
static gcrfToJ2000() {
|
|
580
|
+
// https://github.com/skyfielders/python-skyfield/blob/master/skyfield/framelib.py
|
|
581
|
+
// 'xi0', 'eta0', and 'da0' are ICRS frame biases in arcseconds taken
|
|
582
|
+
// from IERS (2003) Conventions, Chapter 5.
|
|
583
|
+
const xi0 = -0.0166170 * Constants.ArcsecToRad;
|
|
584
|
+
const eta0 = -0.0068192 * Constants.ArcsecToRad;
|
|
585
|
+
const da0 = -0.01460 * Constants.ArcsecToRad;
|
|
586
|
+
|
|
587
|
+
// Compute elements of rotation matrix.
|
|
588
|
+
const yx = -da0;
|
|
589
|
+
const zx = xi0;
|
|
590
|
+
const xy = da0;
|
|
591
|
+
const zy = eta0;
|
|
592
|
+
const xz = -xi0;
|
|
593
|
+
const yz = -eta0;
|
|
594
|
+
|
|
595
|
+
// Include second-order corrections to diagonal elements.
|
|
596
|
+
const xx = 1 - 0.5 * (yx * yx + zx * zx);
|
|
597
|
+
const yy = 1 - 0.5 * (yx * yx + zy * zy);
|
|
598
|
+
const zz = 1 - 0.5 * (zy * zy + zx * zx);
|
|
599
|
+
|
|
600
|
+
return new Matrix3D(
|
|
601
|
+
xx, xy, xz,
|
|
602
|
+
yx, yy, yz,
|
|
603
|
+
zx, zy, zz,
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Convert J2000 to GCRF (inverse frame bias).
|
|
609
|
+
* Vallado Fundamentals
|
|
610
|
+
* @return {Matrix3D} The transformation matrix from J2000 to GCRF
|
|
611
|
+
*/
|
|
612
|
+
static j2000ToGCRF() {
|
|
613
|
+
return this.invertMatrix(this.gcrfToJ2000());
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Convert ITRF to J2000 using IAU-1980 FK5 reduction. This only works for position vectors, not velocity.
|
|
618
|
+
* Vallado Fundamentals
|
|
619
|
+
* @param {number} utc - Julian centuries of TT
|
|
620
|
+
* @return {Matrix3D} The transformation matrix from ITRF to J2000
|
|
621
|
+
*/
|
|
622
|
+
static itrfToJ2000(utc) {
|
|
623
|
+
const t = new TimeConverter(utc);
|
|
624
|
+
|
|
625
|
+
const prc = this.precessionFk5(t.JulianCenturiesTT);
|
|
626
|
+
const {nut, nutLon, raan, meanObliq} = this.nutationFk5(t.JulianCenturiesTT);
|
|
627
|
+
const sid = this.siderealFk5(t.JulianUT1, nutLon, meanObliq, raan, 2);
|
|
628
|
+
const pol = this.polarMotionFk5(TimeConverter.XP * Constants.SecondToRad,
|
|
629
|
+
TimeConverter.YP * Constants.SecondToRad);
|
|
630
|
+
|
|
631
|
+
return this.multiplyMatrices(this.multiplyMatrices(
|
|
632
|
+
this.multiplyMatrices(prc, nut), sid), pol);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* ITRF to J2000 with velocity component.
|
|
637
|
+
* @param {Date} utc - UTC time
|
|
638
|
+
* @param {Vector3D} r - Position vector in ITRF
|
|
639
|
+
* @param {Vector3D} v - Velocity vector in ITRF
|
|
640
|
+
* @return {Object} Position and velocity in J2000
|
|
641
|
+
*/
|
|
642
|
+
static itrfToJ2000WithVelocity(utc, r, v) {
|
|
643
|
+
const t = new TimeConverter(utc);
|
|
644
|
+
|
|
645
|
+
const omega = new Vector3D(0, 0, Earth.SpinRateRadSec * (1
|
|
646
|
+
- TimeConverter.LOD / Constants.SecPerSolarDay));
|
|
647
|
+
|
|
648
|
+
const prc = this.precessionFk5(t.JulianCenturiesTT);
|
|
649
|
+
const {nut, raan} = this.nutationFk5(t.JulianCenturiesTT);
|
|
650
|
+
const sid = this.siderealFk5(t.JulianUT1, nut.nutLon, nut.meanObliq, raan, 2);
|
|
651
|
+
const pol = this.polarMotionFk5(TimeConverter.XP * Constants.SecondToRad,
|
|
652
|
+
TimeConverter.YP * Constants.SecondToRad);
|
|
653
|
+
const temp = this.multiplyMatrices(prc, nut);
|
|
654
|
+
const trans = this.multiplyMatrices(temp, sid);
|
|
655
|
+
|
|
656
|
+
const rpef = pol.multiplyVector3D(r);
|
|
657
|
+
const vpef = pol.multiplyVector3D(v);
|
|
658
|
+
const crossr = omega.cross(rpef);
|
|
659
|
+
const reci = trans.multiplyVector3D(rpef);
|
|
660
|
+
const veci = trans.multiplyVector3D(vpef.add(crossr));
|
|
661
|
+
|
|
662
|
+
return {Position: reci, Velocity: veci};
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* J2000 to ITRF with velocity component.
|
|
667
|
+
* @param {Date} utc - UTC time
|
|
668
|
+
* @param {Vector3D} r - Position vector in J2000
|
|
669
|
+
* @param {Vector3D} v - Velocity vector in J2000
|
|
670
|
+
* @return {Object} Position and velocity in ITRF
|
|
671
|
+
*/
|
|
672
|
+
static j2000ToITRFWithVelocity(utc, r, v) {
|
|
673
|
+
const t = new TimeConverter(utc);
|
|
674
|
+
|
|
675
|
+
const omega = new Vector3D(0, 0, Earth.SpinRateRadSec * (1
|
|
676
|
+
- TimeConverter.LOD / Constants.SecPerSolarDay));
|
|
677
|
+
|
|
678
|
+
let prc = this.precessionFk5(t.JulianCenturiesTT);
|
|
679
|
+
const {nut, raan} = this.nutationFk5(t.JulianCenturiesTT);
|
|
680
|
+
let sid = this.siderealFk5(t.JulianUT1, nut.nutLon, nut.meanObliq, raan, 2);
|
|
681
|
+
let pol = this.polarMotionFk5(TimeConverter.XP * Constants.SecondToRad,
|
|
682
|
+
TimeConverter.YP * Constants.SecondToRad);
|
|
683
|
+
|
|
684
|
+
prc = this.transposeMatrix(prc);
|
|
685
|
+
const nutTranspose = this.transposeMatrix(nut.matrix);
|
|
686
|
+
sid = this.transposeMatrix(sid);
|
|
687
|
+
pol = this.transposeMatrix(pol);
|
|
688
|
+
|
|
689
|
+
const temp = this.multiplyMatrices(sid, nutTranspose);
|
|
690
|
+
const trans = this.multiplyMatrices(temp, prc);
|
|
691
|
+
|
|
692
|
+
const rpef = trans.multiplyVector3D(r);
|
|
693
|
+
const recef = pol.multiplyVector3D(rpef);
|
|
694
|
+
const tempvec1 = trans.multiplyVector3D(v);
|
|
695
|
+
const crossr = omega.cross(rpef);
|
|
696
|
+
const vpef = tempvec1.subtract(crossr);
|
|
697
|
+
const vecef = pol.multiplyVector3D(vpef);
|
|
698
|
+
|
|
699
|
+
return {Position: recef, Velocity: vecef};
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* Convert J2000 to ITRF using IAU-1980 FK5 reduction. This only works for position vectors, not velocity.
|
|
704
|
+
* Vallado Fundamentals
|
|
705
|
+
* @param {number} utc - Julian centuries of TT
|
|
706
|
+
* @return {Matrix3D} The transformation matrix from J2000 to ITRF
|
|
707
|
+
*/
|
|
708
|
+
static j2000ToITRF(utc) {
|
|
709
|
+
return this.invertMatrix(this.itrfToJ2000(utc));
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Convert TEME to J2000 at some UTC time.
|
|
714
|
+
* Vallado Fundamentals
|
|
715
|
+
* @param {Date} utc - UTC time
|
|
716
|
+
* @return {Matrix3D} The transformation matrix from TEME to J2000
|
|
717
|
+
*/
|
|
718
|
+
static temeToJ2000(utc) {
|
|
719
|
+
const t = new TimeConverter(utc);
|
|
720
|
+
const ttt = t.JulianCenturiesTT;
|
|
721
|
+
|
|
722
|
+
let eqeTemp = Matrix3D.zeros();
|
|
723
|
+
let eqeg;
|
|
724
|
+
|
|
725
|
+
const prec = this.precessionFk5(ttt);
|
|
726
|
+
// const { nut } = this.nutationFk5(ttt);
|
|
727
|
+
const nut = this.nutationFk5(ttt);
|
|
728
|
+
|
|
729
|
+
// Rotate teme through just geometric terms
|
|
730
|
+
eqeg = nut.nutLon * Math.cos(nut.meanObliq);
|
|
731
|
+
eqeg %= Constants.TwoPi;
|
|
732
|
+
|
|
733
|
+
eqeTemp = new Matrix3D(new Vector3D(Math.cos(eqeg), Math.sin(eqeg), 0),
|
|
734
|
+
new Vector3D(-Math.sin(eqeg), Math.cos(eqeg), 0), new Vector3D(0, 0, 1));
|
|
735
|
+
|
|
736
|
+
const eqe = new Matrix3D(eqeTemp);
|
|
737
|
+
const eqep = eqe.matrix[0].transpose();
|
|
738
|
+
const temp = this.multiplyMatrices(nut.nut, eqep);
|
|
739
|
+
const returnMat = this.multiplyMatrices(prec, temp);
|
|
740
|
+
return returnMat;
|
|
741
|
+
// return prec.multiply(temp);
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Convert J2000 to TEME at some UTC time.
|
|
746
|
+
* @param {Date} utc - UTC time
|
|
747
|
+
* @return {Matrix3D} The transformation matrix from J2000 to TEME
|
|
748
|
+
*/
|
|
749
|
+
static j2000ToTEME(utc) {
|
|
750
|
+
return this.invertMatrix(this.temeToJ2000(utc));
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Get nutation transformation according to FK5.
|
|
755
|
+
* This matrix is also TOD to MOD.
|
|
756
|
+
* Vallado Fundamentals
|
|
757
|
+
* @param {number} ttt - Julian centuries of TT
|
|
758
|
+
* @return {Matrix3D} The transformation matrix from J2000 to ITRF
|
|
759
|
+
*
|
|
760
|
+
*/
|
|
761
|
+
static nutationFk5(ttt) {
|
|
762
|
+
// Compute the mean obliquity of the ecliptic
|
|
763
|
+
let me1980 = ((0.001813 * ttt - 0.00059) * ttt - 46.8150) * ttt + 84381.448;
|
|
764
|
+
me1980 = me1980 / 3600 % 360;
|
|
765
|
+
me1980 *= Constants.DegToRad;
|
|
766
|
+
|
|
767
|
+
// Evaluate the Delaunay parameters associated with the Moon and the Sun in the interval [0,2π]°
|
|
768
|
+
const oo3600 = 1 / 3600;
|
|
769
|
+
let Mm = ((0.064 * ttt + 31.310) * ttt + 1717915922.6330) * ttt * oo3600 + 134.96298139;
|
|
770
|
+
let Ms = (((-0.012) * ttt - 0.577) * ttt + 129596581.2240) * ttt * oo3600 + 357.52772333;
|
|
771
|
+
let uMm = ((0.011 * ttt - 13.257) * ttt + 1739527263.1370) * ttt * oo3600 + 93.27191028;
|
|
772
|
+
let Ds = ((0.019 * ttt - 6.891) * ttt + 1602961601.3280) * ttt * oo3600 + 297.85036306;
|
|
773
|
+
let Omegam = ((0.008 * ttt + 7.455) * ttt - 6962890.5390) * ttt * oo3600 + 125.04452222;
|
|
774
|
+
|
|
775
|
+
Mm = Mm % 360 * Constants.DegToRad;
|
|
776
|
+
Ms = Ms % 360 * Constants.DegToRad;
|
|
777
|
+
uMm = uMm % 360 * Constants.DegToRad;
|
|
778
|
+
Ds = Ds % 360 * Constants.DegToRad;
|
|
779
|
+
Omegam = Omegam % 360 * Constants.DegToRad;
|
|
780
|
+
|
|
781
|
+
// Compute nutation in longitude and in obliquity
|
|
782
|
+
let dPsi1980 = 0;
|
|
783
|
+
let dEp1980 = 0;
|
|
784
|
+
|
|
785
|
+
// Compute the nutation in the longitude and in obliquity
|
|
786
|
+
for (const row of this.NUT_COEFF) {
|
|
787
|
+
const ap = row[0] * Mm + row[1] * Ms + row[2] * uMm + row[3] * Ds + row[4] * Omegam;
|
|
788
|
+
dPsi1980 += (row[5] + row[6] * ttt) * Math.sin(ap);
|
|
789
|
+
dEp1980 += (row[7] + row[8] * ttt) * Math.cos(ap);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
// The nutation coefficients lead to angles with unit 0.0001. Hence, we must convert to [rad]
|
|
793
|
+
dPsi1980 *= 0.0001 / 3600 * Constants.DegToRad;
|
|
794
|
+
dEp1980 *= 0.0001 / 3600 * Constants.DegToRad;
|
|
795
|
+
|
|
796
|
+
const meanObliq = me1980;
|
|
797
|
+
const nutObliq = dEp1980;
|
|
798
|
+
const nutLon = dPsi1980;
|
|
799
|
+
const raan = Omegam;
|
|
800
|
+
const trueObliq = meanObliq + nutObliq;
|
|
801
|
+
|
|
802
|
+
const cospsi = Math.cos(nutLon);
|
|
803
|
+
const sinpsi = Math.sin(nutLon);
|
|
804
|
+
const coseps = Math.cos(meanObliq);
|
|
805
|
+
const sineps = Math.sin(meanObliq);
|
|
806
|
+
const costrueeps = Math.cos(trueObliq);
|
|
807
|
+
const sintrueeps = Math.sin(trueObliq);
|
|
808
|
+
|
|
809
|
+
// const nut = new Matrix3D(
|
|
810
|
+
// cospsi, costrueeps * sinpsi, sintrueeps * sinpsi,
|
|
811
|
+
// -coseps * sinpsi, costrueeps * coseps * cospsi + sintrueeps * sineps, sintrueeps * coseps * cospsi - sineps * costrueeps,
|
|
812
|
+
// -sineps * sinpsi, costrueeps * sineps * cospsi - sintrueeps * coseps, sintrueeps * sineps * cospsi + costrueeps * coseps
|
|
813
|
+
// );
|
|
814
|
+
|
|
815
|
+
const nut = new Matrix3D(
|
|
816
|
+
new Vector3D(cospsi, costrueeps * sinpsi, sintrueeps * sinpsi),
|
|
817
|
+
new Vector3D(-coseps * sinpsi, costrueeps * coseps * cospsi + sintrueeps * sineps,
|
|
818
|
+
sintrueeps * coseps * cospsi - sineps * costrueeps),
|
|
819
|
+
new Vector3D(-sineps * sinpsi, costrueeps * sineps * cospsi - sintrueeps * coseps,
|
|
820
|
+
sintrueeps * sineps * cospsi + costrueeps * coseps),
|
|
821
|
+
);
|
|
822
|
+
|
|
823
|
+
return {
|
|
824
|
+
nut,
|
|
825
|
+
meanObliq,
|
|
826
|
+
nutObliq,
|
|
827
|
+
nutLon,
|
|
828
|
+
trueObliq,
|
|
829
|
+
raan,
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Get precession transformation based on FK5.
|
|
835
|
+
* This matrix is also MOD to GCRF.
|
|
836
|
+
* Vallado Fundamentals
|
|
837
|
+
* @param {number} ttt - Julian centuries of TT
|
|
838
|
+
* @return {Matrix3D} Precession transformation matrix
|
|
839
|
+
*/
|
|
840
|
+
static precessionFk5(ttt) {
|
|
841
|
+
const convrt = Math.PI / (180 * 3600); // " to rad
|
|
842
|
+
|
|
843
|
+
let zeta = ((0.017998 * ttt + 0.30188) * ttt + 2306.2181) * ttt; // "
|
|
844
|
+
let theta = ((-0.041833 * ttt - 0.42665) * ttt + 2004.3109) * ttt;
|
|
845
|
+
let z = ((0.018203 * ttt + 1.09468) * ttt + 2306.2181) * ttt;
|
|
846
|
+
|
|
847
|
+
zeta *= convrt;
|
|
848
|
+
theta *= convrt;
|
|
849
|
+
z *= convrt;
|
|
850
|
+
|
|
851
|
+
const coszeta = Math.cos(zeta);
|
|
852
|
+
const sinzeta = Math.sin(zeta);
|
|
853
|
+
const costheta = Math.cos(theta);
|
|
854
|
+
const sintheta = Math.sin(theta);
|
|
855
|
+
const cosz = Math.cos(z);
|
|
856
|
+
const sinz = Math.sin(z);
|
|
857
|
+
|
|
858
|
+
// // Form matrix mod to gcrf
|
|
859
|
+
// return new Matrix3D(
|
|
860
|
+
// coszeta * costheta * cosz - sinzeta * sinz, coszeta * costheta * sinz + sinzeta * cosz, coszeta * sintheta,
|
|
861
|
+
// -sinzeta * costheta * cosz - coszeta * sinz, -sinzeta * costheta * sinz + coszeta * cosz, -sinzeta * sintheta,
|
|
862
|
+
// -sintheta * cosz, -sintheta * sinz, costheta
|
|
863
|
+
// );
|
|
864
|
+
|
|
865
|
+
return new Matrix3D(
|
|
866
|
+
new Vector3D(coszeta * costheta * cosz - sinzeta * sinz,
|
|
867
|
+
coszeta * costheta * sinz + sinzeta * cosz, coszeta * sintheta),
|
|
868
|
+
new Vector3D(-sinzeta * costheta * cosz - coszeta * sinz,
|
|
869
|
+
-sinzeta * costheta * sinz + coszeta * cosz, -sinzeta * sintheta),
|
|
870
|
+
new Vector3D(-sintheta * cosz, -sintheta * sinz, costheta));
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* Get transformation matrix associated with sidereal time.
|
|
875
|
+
* Thie matrix is also PEF/GTOD to TOD.
|
|
876
|
+
* Vallado Fundamentals
|
|
877
|
+
* @param {number} jdut1 - Julian date of UT1
|
|
878
|
+
* @param {number} deltapsi - Nutation in longitude (rad)
|
|
879
|
+
* @param {number} meaneps - Mean obliquity (rad)
|
|
880
|
+
* @param {number} raan - Right ascension of ascending node (rad)
|
|
881
|
+
* @param {number} eqeterms - Equatorial terms (rad)
|
|
882
|
+
* @return {Matrix3D} Sidereal transformation matrix
|
|
883
|
+
*/
|
|
884
|
+
static siderealFk5(jdut1, deltapsi, meaneps, raan, eqeterms) {
|
|
885
|
+
// FK5 approach
|
|
886
|
+
const gmst = TimeConverter.getGMST(jdut1).Radians;
|
|
887
|
+
|
|
888
|
+
// Find mean ast
|
|
889
|
+
let ast = (jdut1 > 2450449.5) && (eqeterms > 0)
|
|
890
|
+
? gmst + deltapsi * Math.cos(meaneps)
|
|
891
|
+
+ 0.00264 * Constants.SecondToRad * Math.sin(raan)
|
|
892
|
+
+ 0.000063 * Constants.SecondToRad * Math.sin(2 * raan)
|
|
893
|
+
: gmst + deltapsi * Math.cos(meaneps);
|
|
894
|
+
|
|
895
|
+
ast %= 2.0 * Math.PI;
|
|
896
|
+
|
|
897
|
+
const sinast = Math.sin(ast);
|
|
898
|
+
const cosast = Math.cos(ast);
|
|
899
|
+
|
|
900
|
+
// return new Matrix3D(
|
|
901
|
+
// cosast, -sinast, 0,
|
|
902
|
+
// sinast, cosast, 0,
|
|
903
|
+
// 0, 0, 1
|
|
904
|
+
// );
|
|
905
|
+
|
|
906
|
+
return new Matrix3D(
|
|
907
|
+
new Vector3D(cosast, -sinast, 0), new Vector3D(sinast, cosast, 0),
|
|
908
|
+
new Vector3D(0, 0, 1),
|
|
909
|
+
);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
/**
|
|
913
|
+
* Get transformation associated with polar motion of Earth.
|
|
914
|
+
* This matrix is also ITRF to PEF/GTOD.
|
|
915
|
+
* xp and yp are the polar motion coefficients (rad).
|
|
916
|
+
* Vallado Fundamentals
|
|
917
|
+
* @param {number} xp - Polar motion coefficient in x (rad)
|
|
918
|
+
* @param {number} yp - Polar motion coefficient in y (rad)
|
|
919
|
+
* @return {Matrix3D} Polar motion transformation matrix
|
|
920
|
+
*/
|
|
921
|
+
static polarMotionFk5(xp, yp) {
|
|
922
|
+
const cosxp = Math.cos(xp);
|
|
923
|
+
const sinxp = Math.sin(xp);
|
|
924
|
+
const cosyp = Math.cos(yp);
|
|
925
|
+
const sinyp = Math.sin(yp);
|
|
926
|
+
|
|
927
|
+
// // FK5 approach
|
|
928
|
+
// return new Matrix3D(
|
|
929
|
+
// cosxp, 0, -sinxp,
|
|
930
|
+
// sinxp * sinyp, cosyp, cosxp * sinyp,
|
|
931
|
+
// sinxp * cosyp, -sinyp, cosxp * cosyp
|
|
932
|
+
// );
|
|
933
|
+
|
|
934
|
+
return new Matrix3D(
|
|
935
|
+
new Vector3D(cosxp, 0, -sinxp),
|
|
936
|
+
new Vector3D(sinxp * sinyp, cosyp, cosxp * sinyp),
|
|
937
|
+
new Vector3D(sinxp * cosyp, -sinyp, cosxp * cosyp),
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
/**
|
|
942
|
+
* Check if a frame is inertially defined.
|
|
943
|
+
* @param {ReferenceFrame} frame - The reference frame to check
|
|
944
|
+
* @param {boolean} throwError - Whether to throw an error if the frame is non-inertial
|
|
945
|
+
* @return {boolean} True if the frame is inertial, false otherwise
|
|
946
|
+
*/
|
|
947
|
+
static CheckIfInertial(frame, throwError = false) {
|
|
948
|
+
if (frame === ReferenceFrame.ITRF) {
|
|
949
|
+
if (throwError) {
|
|
950
|
+
throw new Error(
|
|
951
|
+
"Cannot use a non-inertial frame for this method."
|
|
952
|
+
+ " Try converting to an ECI frame.");
|
|
953
|
+
}
|
|
954
|
+
return false;
|
|
955
|
+
}
|
|
956
|
+
return true;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
static perifocalToInertial(keplerianElements) {
|
|
960
|
+
const cosi = Math.cos(keplerianElements.inclination);
|
|
961
|
+
const sini = Math.sin(keplerianElements.inclination);
|
|
962
|
+
const cosRaan = Math.cos(keplerianElements.raan);
|
|
963
|
+
const sinRaan = Math.sin(keplerianElements.raan);
|
|
964
|
+
const cosw = Math.cos(keplerianElements.argOfPeriapsis);
|
|
965
|
+
const sinw = Math.sin(keplerianElements.argOfPeriapsis);
|
|
966
|
+
|
|
967
|
+
// The matrix elements
|
|
968
|
+
const r11 = cosRaan * cosw - sinRaan * sinw * cosi;
|
|
969
|
+
const r12 = -cosRaan * sinw - sinRaan * cosw * cosi;
|
|
970
|
+
const r13 = sinRaan * sini;
|
|
971
|
+
|
|
972
|
+
const r21 = sinRaan * cosw + cosRaan * sinw * cosi;
|
|
973
|
+
const r22 = -sinRaan * sinw + cosRaan * cosw * cosi;
|
|
974
|
+
const r23 = -cosRaan * sini;
|
|
975
|
+
|
|
976
|
+
const r31 = sinw * sini;
|
|
977
|
+
const r32 = cosw * sini;
|
|
978
|
+
const r33 = cosi;
|
|
979
|
+
|
|
980
|
+
// Packing
|
|
981
|
+
return new Matrix3D(
|
|
982
|
+
new Vector3D(r11, r12, r13),
|
|
983
|
+
new Vector3D(r21, r22, r23),
|
|
984
|
+
new Vector3D(r31, r32, r33),
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
static eciToRtn(r, v) {
|
|
989
|
+
const rTemp = [r.x, r.y, r.z];
|
|
990
|
+
const vTemp = [v.x, v.y, v.z];
|
|
991
|
+
const rHat = rTemp.map((component) => component / norm(rTemp));
|
|
992
|
+
const vHat = vTemp.map((component) => component / norm(vTemp));
|
|
993
|
+
const nHat = cross(rHat, vHat).map((component) => component / norm(cross(rHat, vHat)));
|
|
994
|
+
const tHat = cross(nHat, rHat).map((component) => component / norm(cross(nHat, rHat)));
|
|
995
|
+
|
|
996
|
+
return new Matrix3D(
|
|
997
|
+
new Vector3D(rHat[0], rHat[1], rHat[2]),
|
|
998
|
+
new Vector3D(tHat[0], tHat[1], tHat[2]),
|
|
999
|
+
new Vector3D(nHat[0], nHat[1], nHat[2]),
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
static rtnToEci(r, v) {
|
|
1004
|
+
const eciToRtn = this.eciToRtn(r, v);
|
|
1005
|
+
return this.invertMatrix(eciToRtn);
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
// 1980 IAU Theory of Nutation Coefficients
|
|
1009
|
+
static NUT_COEFF = [
|
|
1010
|
+
[0, 0, 0, 0, 1, -171996.0, -174.2, 92025.0, 8.9],
|
|
1011
|
+
[0, 0, 2, -2, 2, -13187.0, -1.6, 5736.0, -3.1],
|
|
1012
|
+
[0, 0, 2, 0, 2, -2274.0, -0.2, 977.0, -0.5],
|
|
1013
|
+
[0, 0, 0, 0, 2, 2062.0, 0.2, -895.0, 0.5],
|
|
1014
|
+
[0, 1, 0, 0, 0, 1426.0, -3.4, 54.0, -0.1],
|
|
1015
|
+
[1, 0, 0, 0, 0, 712.0, 0.1, -7.0, 0.0],
|
|
1016
|
+
[0, 1, 2, -2, 2, -517.0, 1.2, 224.0, -0.6],
|
|
1017
|
+
[0, 0, 2, 0, 1, -386.0, -0.4, 200.0, 0.0],
|
|
1018
|
+
[1, 0, 2, 0, 2, -301.0, 0.0, 129.0, -0.1],
|
|
1019
|
+
[0, -1, 2, -2, 2, 217.0, -0.5, -95.0, 0.3],
|
|
1020
|
+
[1, 0, 0, -2, 0, -158.0, 0.0, -1.0, 0.0],
|
|
1021
|
+
[0, 0, 2, -2, 1, 129.0, 0.1, -70.0, 0.0],
|
|
1022
|
+
[-1, 0, 2, 0, 2, 123.0, 0.0, -53.0, 0.0],
|
|
1023
|
+
[1, 0, 0, 0, 1, 63.0, 0.1, -33.0, 0.0],
|
|
1024
|
+
[0, 0, 0, 2, 0, 63.0, 0.0, -2.0, 0.0],
|
|
1025
|
+
[-1, 0, 2, 2, 2, -59.0, 0.0, 26.0, 0.0],
|
|
1026
|
+
[-1, 0, 0, 0, 1, -58.0, -0.1, 32.0, 0.0],
|
|
1027
|
+
[1, 0, 2, 0, 1, -51.0, 0.0, 27.0, 0.0],
|
|
1028
|
+
[2, 0, 0, -2, 0, 48.0, 0.0, 1.0, 0.0],
|
|
1029
|
+
[-2, 0, 2, 0, 1, 46.0, 0.0, -24.0, 0.0],
|
|
1030
|
+
[0, 0, 2, 2, 2, -38.0, 0.0, 16.0, 0.0],
|
|
1031
|
+
[2, 0, 2, 0, 2, -31.0, 0.0, 13.0, 0.0],
|
|
1032
|
+
[2, 0, 0, 0, 0, 29.0, 0.0, -1.0, 0.0],
|
|
1033
|
+
[1, 0, 2, -2, 2, 29.0, 0.0, -12.0, 0.0],
|
|
1034
|
+
[0, 0, 2, 0, 0, 26.0, 0.0, -1.0, 0.0],
|
|
1035
|
+
[0, 0, 2, -2, 0, -22.0, 0.0, 0.0, 0.0],
|
|
1036
|
+
[-1, 0, 2, 0, 1, 21.0, 0.0, -10.0, 0.0],
|
|
1037
|
+
[0, 2, 0, 0, 0, 17.0, -0.1, 0.0, 0.0],
|
|
1038
|
+
[0, 2, 2, -2, 2, -16.0, 0.1, 7.0, 0.0],
|
|
1039
|
+
[-1, 0, 0, 2, 1, 16.0, 0.0, -8.0, 0.0],
|
|
1040
|
+
[0, 1, 0, 0, 1, -15.0, 0.0, 9.0, 0.0],
|
|
1041
|
+
[1, 0, 0, -2, 1, -13.0, 0.0, 7.0, 0.0],
|
|
1042
|
+
[0, -1, 0, 0, 1, -12.0, 0.0, 6.0, 0.0],
|
|
1043
|
+
[2, 0, -2, 0, 0, 11.0, 0.0, 0.0, 0.0],
|
|
1044
|
+
[-1, 0, 2, 2, 1, -10.0, 0.0, 5.0, 0.0],
|
|
1045
|
+
[1, 0, 2, 2, 2, -8.0, 0.0, 3.0, 0.0],
|
|
1046
|
+
[0, -1, 2, 0, 2, -7.0, 0.0, 3.0, 0.0],
|
|
1047
|
+
[0, 0, 2, 2, 1, -7.0, 0.0, 3.0, 0.0],
|
|
1048
|
+
[1, 1, 0, -2, 0, -7.0, 0.0, 0.0, 0.0],
|
|
1049
|
+
[0, 1, 2, 0, 2, 7.0, 0.0, -3.0, 0.0],
|
|
1050
|
+
[-2, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0],
|
|
1051
|
+
[0, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0],
|
|
1052
|
+
[2, 0, 2, -2, 2, 6.0, 0.0, -3.0, 0.0],
|
|
1053
|
+
[1, 0, 0, 2, 0, 6.0, 0.0, 0.0, 0.0],
|
|
1054
|
+
[1, 0, 2, -2, 1, 6.0, 0.0, -3.0, 0.0],
|
|
1055
|
+
[0, 0, 0, -2, 1, -5.0, 0.0, 3.0, 0.0],
|
|
1056
|
+
[0, -1, 2, -2, 1, -5.0, 0.0, 3.0, 0.0],
|
|
1057
|
+
[2, 0, 2, 0, 1, -5.0, 0.0, 3.0, 0.0],
|
|
1058
|
+
[1, -1, 0, 0, 0, 5.0, 0.0, 0.0, 0.0],
|
|
1059
|
+
[1, 0, 0, -1, 0, -4.0, 0.0, 0.0, 0.0],
|
|
1060
|
+
[0, 0, 0, 1, 0, -4.0, 0.0, 0.0, 0.0],
|
|
1061
|
+
[0, 1, 0, -2, 0, -4.0, 0.0, 0.0, 0.0],
|
|
1062
|
+
[1, 0, -2, 0, 0, 4.0, 0.0, 0.0, 0.0],
|
|
1063
|
+
[2, 0, 0, -2, 1, 4.0, 0.0, -2.0, 0.0],
|
|
1064
|
+
[0, 1, 2, -2, 1, 4.0, 0.0, -2.0, 0.0],
|
|
1065
|
+
[1, 1, 0, 0, 0, -3.0, 0.0, 0.0, 0.0],
|
|
1066
|
+
[1, -1, 0, -1, 0, -3.0, 0.0, 0.0, 0.0],
|
|
1067
|
+
[-1, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0],
|
|
1068
|
+
[0, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0],
|
|
1069
|
+
[1, -1, 2, 0, 2, -3.0, 0.0, 1.0, 0.0],
|
|
1070
|
+
[3, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0],
|
|
1071
|
+
[-2, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0],
|
|
1072
|
+
[1, 0, 2, 0, 0, 3.0, 0.0, 0.0, 0.0],
|
|
1073
|
+
[-1, 0, 2, 4, 2, -2.0, 0.0, 1.0, 0.0],
|
|
1074
|
+
[1, 0, 0, 0, 2, -2.0, 0.0, 1.0, 0.0],
|
|
1075
|
+
[-1, 0, 2, -2, 1, -2.0, 0.0, 1.0, 0.0],
|
|
1076
|
+
[0, -2, 2, -2, 1, -2.0, 0.0, 1.0, 0.0],
|
|
1077
|
+
[-2, 0, 0, 0, 1, -2.0, 0.0, 1.0, 0.0],
|
|
1078
|
+
[2, 0, 0, 0, 1, 2.0, 0.0, -1.0, 0.0],
|
|
1079
|
+
[3, 0, 0, 0, 0, 2.0, 0.0, 0.0, 0.0],
|
|
1080
|
+
[1, 1, 2, 0, 2, 2.0, 0.0, -1.0, 0.0],
|
|
1081
|
+
[0, 0, 2, 1, 2, 2.0, 0.0, -1.0, 0.0],
|
|
1082
|
+
[1, 0, 0, 2, 1, -1.0, 0.0, 0.0, 0.0],
|
|
1083
|
+
[1, 0, 2, 2, 1, -1.0, 0.0, 1.0, 0.0],
|
|
1084
|
+
[1, 1, 0, -2, 1, -1.0, 0.0, 0.0, 0.0],
|
|
1085
|
+
[0, 1, 0, 2, 0, -1.0, 0.0, 0.0, 0.0],
|
|
1086
|
+
[0, 1, 2, -2, 0, -1.0, 0.0, 0.0, 0.0],
|
|
1087
|
+
[0, 1, -2, 2, 0, -1.0, 0.0, 0.0, 0.0],
|
|
1088
|
+
[1, 0, -2, 2, 0, -1.0, 0.0, 0.0, 0.0],
|
|
1089
|
+
[1, 0, -2, -2, 0, -1.0, 0.0, 0.0, 0.0],
|
|
1090
|
+
[1, 0, 2, -2, 0, -1.0, 0.0, 0.0, 0.0],
|
|
1091
|
+
[1, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0],
|
|
1092
|
+
[2, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0],
|
|
1093
|
+
[0, 0, 2, 4, 2, -1.0, 0.0, 0.0, 0.0],
|
|
1094
|
+
[0, 0, 2, -1, 2, -1.0, 0.0, 0.0, 0.0],
|
|
1095
|
+
[-2, 0, 2, 4, 2, -1.0, 0.0, 1.0, 0.0],
|
|
1096
|
+
[2, 0, 2, 2, 2, -1.0, 0.0, 0.0, 0.0],
|
|
1097
|
+
[0, -1, 2, 0, 1, -1.0, 0.0, 0.0, 0.0],
|
|
1098
|
+
[0, 0, -2, 0, 1, -1.0, 0.0, 0.0, 0.0],
|
|
1099
|
+
[0, 0, 4, -2, 2, 1.0, 0.0, 0.0, 0.0],
|
|
1100
|
+
[0, 1, 0, 0, 2, 1.0, 0.0, 0.0, 0.0],
|
|
1101
|
+
[1, 1, 2, -2, 2, 1.0, 0.0, -1.0, 0.0],
|
|
1102
|
+
[3, 0, 2, -2, 2, 1.0, 0.0, 0.0, 0.0],
|
|
1103
|
+
[-2, 0, 2, 2, 2, 1.0, 0.0, -1.0, 0.0],
|
|
1104
|
+
[-1, 0, 0, 0, 2, 1.0, 0.0, -1.0, 0.0],
|
|
1105
|
+
[0, 0, -2, 2, 1, 1.0, 0.0, 0.0, 0.0],
|
|
1106
|
+
[0, 1, 2, 0, 1, 1.0, 0.0, 0.0, 0.0],
|
|
1107
|
+
[-1, 0, 4, 0, 2, 1.0, 0.0, 0.0, 0.0],
|
|
1108
|
+
[2, 1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0],
|
|
1109
|
+
[2, 0, 0, 2, 0, 1.0, 0.0, 0.0, 0.0],
|
|
1110
|
+
[2, 0, 2, -2, 1, 1.0, 0.0, -1.0, 0.0],
|
|
1111
|
+
[2, 0, -2, 0, 1, 1.0, 0.0, 0.0, 0.0],
|
|
1112
|
+
[1, -1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0],
|
|
1113
|
+
[-1, 0, 0, 1, 1, 1.0, 0.0, 0.0, 0.0],
|
|
1114
|
+
[-1, -1, 0, 2, 1, 1.0, 0.0, 0.0, 0.0],
|
|
1115
|
+
[0, 1, 0, 1, 0, 1.0, 0.0, 0.0, 0.0],
|
|
1116
|
+
];
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
export {FrameConverter, ReferenceFrame};
|
|
1120
|
+
export const EarthParams = Earth;
|