@saber-usa/node-common 1.7.16 → 1.7.17
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 +22 -1
- package/package.json +9 -9
- package/src/FrameConverter.js +116 -139
- package/src/LLA.js +1 -1
- package/src/LaunchNominalClass.js +10 -24
- package/src/NodeVector3D.js +2 -2
- package/src/OrbitUtils.js +23 -42
- package/src/ShadowGEOCalculator.js +2 -2
- package/src/TimeConverter.js +11 -9
- package/src/astro.js +170 -164
- package/src/ballisticPropagator.js +34 -40
- package/src/checkNetwork.cjs +21 -21
- package/src/constants.js +2 -2
- package/src/fixDate.js +1 -1
- package/src/index.js +1 -1
- package/src/launchNominal.js +13 -13
- package/src/loggerFactory.cjs +122 -99
- package/src/s3.js +3 -3
- package/src/udl.js +1 -1
- package/src/utils.js +2 -2
package/src/OrbitUtils.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import {MU} from "./constants.js";
|
|
2
|
-
import {cross, norm} from "mathjs";
|
|
2
|
+
import {cross, dot, norm} from "mathjs";
|
|
3
3
|
import {wrapHalfRevUnsigned, wrapOneRevUnsigned} from "./utils.js";
|
|
4
4
|
|
|
5
5
|
const EARTH_MU_KM = MU / 1e9;
|
|
6
|
+
const cross3 = (a, b) => cross(a, b);
|
|
7
|
+
const dot3 = (a, b) => dot(a, b);
|
|
6
8
|
|
|
7
9
|
class OrbitUtils {
|
|
8
|
-
constructor() {
|
|
9
|
-
// Prevent instantiation
|
|
10
|
-
}
|
|
11
10
|
/**
|
|
12
11
|
* Get inclination based on azimuth and latitude.
|
|
13
12
|
* @param {number} azimuthRad - Azimuth in radians
|
|
@@ -176,12 +175,12 @@ class OrbitUtils {
|
|
|
176
175
|
r1 = (c - a) * (fb - fc);
|
|
177
176
|
q = (c - b) * (fa - fc);
|
|
178
177
|
p = (c - b) * q - (c - a) * r1;
|
|
179
|
-
q = 2
|
|
180
|
-
if (q > 0
|
|
178
|
+
q = 2 * (q - r1);
|
|
179
|
+
if (q > 0) {p = -p;}
|
|
181
180
|
q = Math.abs(q);
|
|
182
|
-
min1 = 3
|
|
181
|
+
min1 = 3 * q * Math.abs(xm);
|
|
183
182
|
min2 = Math.abs(e * q);
|
|
184
|
-
if (2
|
|
183
|
+
if (2 * p < Math.min(min1, min2)) {
|
|
185
184
|
e = d;
|
|
186
185
|
d = p / q;
|
|
187
186
|
} else {
|
|
@@ -285,21 +284,8 @@ class OrbitUtils {
|
|
|
285
284
|
throw new Error("Mu must be greater than 1e-30.");
|
|
286
285
|
}
|
|
287
286
|
|
|
288
|
-
// Helper functions
|
|
289
|
-
function cross(a, b) {
|
|
290
|
-
return [
|
|
291
|
-
a[1] * b[2] - a[2] * b[1],
|
|
292
|
-
a[2] * b[0] - a[0] * b[2],
|
|
293
|
-
a[0] * b[1] - a[1] * b[0],
|
|
294
|
-
];
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
function dot(a, b) {
|
|
298
|
-
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
299
|
-
}
|
|
300
|
-
|
|
301
287
|
function norm(v) {
|
|
302
|
-
return Math.
|
|
288
|
+
return Math.hypot(v[0], v[1], v[2]);
|
|
303
289
|
}
|
|
304
290
|
|
|
305
291
|
function clamp(value, min, max) {
|
|
@@ -307,8 +293,8 @@ class OrbitUtils {
|
|
|
307
293
|
}
|
|
308
294
|
|
|
309
295
|
// Calculate basic vectors
|
|
310
|
-
const h =
|
|
311
|
-
const n =
|
|
296
|
+
const h = cross3(r, v);
|
|
297
|
+
const n = cross3([0, 0, 1], h);
|
|
312
298
|
|
|
313
299
|
const rLength = norm(r);
|
|
314
300
|
const vLength = norm(v);
|
|
@@ -319,7 +305,7 @@ class OrbitUtils {
|
|
|
319
305
|
// Eccentricity vector calculation (corrected formula)
|
|
320
306
|
const vLengthSq = vLength * vLength;
|
|
321
307
|
const muOverR = mu / rLength;
|
|
322
|
-
const rvDot =
|
|
308
|
+
const rvDot = dot3(r, v);
|
|
323
309
|
|
|
324
310
|
const e = [
|
|
325
311
|
(1 / mu) * ((vLengthSq - muOverR) * r[0] - rvDot * v[0]),
|
|
@@ -332,7 +318,7 @@ class OrbitUtils {
|
|
|
332
318
|
if (zeta === 0) {throw new Error("Zeta cannot be zero.");}
|
|
333
319
|
|
|
334
320
|
const eLength = norm(e);
|
|
335
|
-
if (Math.abs(1
|
|
321
|
+
if (Math.abs(1 - eLength) <= tol) {
|
|
336
322
|
throw new Error("Parabolic orbit conversion is not supported.");
|
|
337
323
|
}
|
|
338
324
|
|
|
@@ -363,7 +349,7 @@ class OrbitUtils {
|
|
|
363
349
|
|
|
364
350
|
// CASE 1: Non-circular, Inclined Orbit
|
|
365
351
|
if (eLength >= 1e-11 && i >= 1e-11 && i <= Math.PI - 1e-11) {
|
|
366
|
-
if (nLength === 0
|
|
352
|
+
if (nLength === 0) {
|
|
367
353
|
throw new Error("Cannot convert from Cartesian to Keplerian "
|
|
368
354
|
+ "- line-of-nodes vector is a zero vector.");
|
|
369
355
|
}
|
|
@@ -371,47 +357,42 @@ class OrbitUtils {
|
|
|
371
357
|
raan = Math.acos(n[0] / nLength);
|
|
372
358
|
if (n[1] < 0) {raan = 2 * Math.PI - raan;}
|
|
373
359
|
|
|
374
|
-
w = Math.acos(
|
|
360
|
+
w = Math.acos(dot3(n, e) / (nLength * eLength));
|
|
375
361
|
if (e[2] < 0) {w = 2 * Math.PI - w;}
|
|
376
362
|
|
|
377
|
-
f = Math.acos(clamp(
|
|
363
|
+
f = Math.acos(clamp(dot3(e, r) / (eLength * rLength), -1, 1));
|
|
378
364
|
if (rvDot < 0) {f = 2 * Math.PI - f;}
|
|
379
365
|
} else if (eLength >= 1e-11 && (i < 1e-11 || i > Math.PI - 1e-11)) { // CASE 2: Non-circular, Equatorial Orbit
|
|
380
|
-
if (eLength === 0
|
|
366
|
+
if (eLength === 0) {
|
|
381
367
|
throw new Error(`Cannot convert from Cartesian to Keplerian
|
|
382
368
|
- eccentricity is zero.`);
|
|
383
369
|
}
|
|
384
|
-
raan = 0;
|
|
385
370
|
w = Math.acos(e[0] / eLength);
|
|
386
371
|
if (e[1] < 0) {w = 2 * Math.PI - w;}
|
|
387
372
|
|
|
388
373
|
// For GMT-4446 fix (LOJ: 2014.03.21)
|
|
389
|
-
if (i > Math.PI - 1e-11) {w *= -1
|
|
390
|
-
if (w < 0
|
|
374
|
+
if (i > Math.PI - 1e-11) {w *= -1;}
|
|
375
|
+
if (w < 0) {w += 2 * Math.PI;}
|
|
391
376
|
|
|
392
|
-
f = Math.acos(clamp(
|
|
377
|
+
f = Math.acos(clamp(dot3(e, r) / (eLength * rLength), -1, 1));
|
|
393
378
|
if (rvDot < 0) {f = 2 * Math.PI - f;}
|
|
394
379
|
} else if (eLength < 1e-11 && i >= 1e-11 && i <= Math.PI - 1e-11) { // CASE 3: Circular, Inclined Orbit
|
|
395
|
-
if (nLength === 0
|
|
380
|
+
if (nLength === 0) {
|
|
396
381
|
throw new Error("Cannot convert from Cartesian to Keplerian "
|
|
397
382
|
+ "- line-of-nodes vector is a zero vector.");
|
|
398
383
|
}
|
|
399
384
|
raan = Math.acos(n[0] / nLength);
|
|
400
385
|
if (n[1] < 0) {raan = 2 * Math.PI - raan;}
|
|
401
386
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
f = Math.acos(clamp(dot(n, r) / (nLength * rLength), -1, 1));
|
|
387
|
+
f = Math.acos(clamp(dot3(n, r) / (nLength * rLength), -1, 1));
|
|
405
388
|
if (r[2] < 0) {f = 2 * Math.PI - f;}
|
|
406
389
|
} else if (eLength < 1e-11 && (i < 1e-11 || i > Math.PI - 1e-11)) { // CASE 4: Circular, Equatorial Orbit
|
|
407
|
-
raan = 0;
|
|
408
|
-
w = 0;
|
|
409
390
|
f = Math.acos(clamp(r[0] / rLength, -1, 1));
|
|
410
391
|
if (r[1] < 0) {f = 2 * Math.PI - f;}
|
|
411
392
|
|
|
412
393
|
// For GMT-4446 fix (LOJ: 2014.03.21)
|
|
413
|
-
if (i > Math.PI - 1e-11) {f *= -1
|
|
414
|
-
if (f < 0
|
|
394
|
+
if (i > Math.PI - 1e-11) {f *= -1;}
|
|
395
|
+
if (f < 0) {f += 2 * Math.PI;}
|
|
415
396
|
}
|
|
416
397
|
|
|
417
398
|
// Calculate additional orbital parameters
|
|
@@ -140,7 +140,7 @@ class ShadowGEOCalculator {
|
|
|
140
140
|
|
|
141
141
|
// Project shadow center onto the GEO belt
|
|
142
142
|
const shadowAxisEq = [shadowAxis[0], shadowAxis[1], 0];
|
|
143
|
-
const shadowAxisNorm = Math.
|
|
143
|
+
const shadowAxisNorm = Math.hypot(shadowAxisEq[0], shadowAxisEq[1]);
|
|
144
144
|
shadowAxisEq[0] /= shadowAxisNorm;
|
|
145
145
|
shadowAxisEq[1] /= shadowAxisNorm;
|
|
146
146
|
|
|
@@ -168,7 +168,7 @@ class ShadowGEOCalculator {
|
|
|
168
168
|
|
|
169
169
|
// Project shadow center onto the GEO belt
|
|
170
170
|
const shadowAxisEq = [shadowAxis[0], shadowAxis[1], 0];
|
|
171
|
-
const shadowAxisNorm = Math.
|
|
171
|
+
const shadowAxisNorm = Math.hypot(shadowAxisEq[0], shadowAxisEq[1]);
|
|
172
172
|
shadowAxisEq[0] /= shadowAxisNorm;
|
|
173
173
|
shadowAxisEq[1] /= shadowAxisNorm;
|
|
174
174
|
|
package/src/TimeConverter.js
CHANGED
|
@@ -62,7 +62,7 @@ class TimeConverter {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
get JulianUTC() {
|
|
65
|
-
return this._julian
|
|
65
|
+
return this._julian === null ? TimeConverter.dateTimeToJulian(this.UTC) : this._julian;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
get JulianUT1() {
|
|
@@ -242,12 +242,12 @@ class TimeConverter {
|
|
|
242
242
|
static getGMST(jdut1, wrap360 = true) {
|
|
243
243
|
const tut1 = TimeConverter.julianToCenturiesTxxx(jdut1);
|
|
244
244
|
let gmst = -6.2e-6 * tut1 * tut1 * tut1 + 0.093104 * tut1 * tut1
|
|
245
|
-
+ (876600
|
|
246
|
-
gmst = gmst * (Math.PI / 180) / 240
|
|
245
|
+
+ (876600 * 3600 + 8640184.812866) * tut1 + 67310.54841; // seconds
|
|
246
|
+
gmst = gmst * (Math.PI / 180) / 240 % (2 * Math.PI); // 360/86400 = 1/240, to deg, to rad
|
|
247
247
|
|
|
248
248
|
// Check quadrants
|
|
249
|
-
if (gmst < 0
|
|
250
|
-
gmst += 2
|
|
249
|
+
if (gmst < 0 && wrap360) {
|
|
250
|
+
gmst += 2 * Math.PI;
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
return {
|
|
@@ -269,9 +269,9 @@ class TimeConverter {
|
|
|
269
269
|
let lst = lonDeg * Math.PI / 180 + gmst;
|
|
270
270
|
|
|
271
271
|
// Check quadrants
|
|
272
|
-
lst %= 2
|
|
273
|
-
if (lst < 0
|
|
274
|
-
lst += 2
|
|
272
|
+
lst %= 2 * Math.PI;
|
|
273
|
+
if (lst < 0 && wrap360) {
|
|
274
|
+
lst += 2 * Math.PI;
|
|
275
275
|
}
|
|
276
276
|
|
|
277
277
|
return {
|
|
@@ -286,7 +286,7 @@ class TimeConverter {
|
|
|
286
286
|
* @return {number} Centuries since J2000
|
|
287
287
|
*/
|
|
288
288
|
static julianToCenturiesTxxx(julian) {
|
|
289
|
-
return (julian - 2451545
|
|
289
|
+
return (julian - 2451545) / 36525;
|
|
290
290
|
}
|
|
291
291
|
}
|
|
292
292
|
|
|
@@ -304,6 +304,8 @@ class RaDec {
|
|
|
304
304
|
Radians: decDeg * Math.PI / 180,
|
|
305
305
|
};
|
|
306
306
|
}
|
|
307
|
+
|
|
307
308
|
}
|
|
308
309
|
|
|
309
310
|
export {TimeConverter, RaDec};
|
|
311
|
+
|