@saber-usa/node-common 1.7.36 → 1.7.38
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/package.json +8 -7
- package/src/astro.js +54 -18
- package/src/udl.js +28 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saber-usa/node-common",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.38",
|
|
4
4
|
"description": "Common node functions for Saber",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -23,13 +23,13 @@
|
|
|
23
23
|
"author": "Saber USA",
|
|
24
24
|
"license": "ISC",
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@aws-sdk/client-s3": "^3.
|
|
26
|
+
"@aws-sdk/client-s3": "^3.1119.0",
|
|
27
27
|
"date-fns": "^4.4.0",
|
|
28
28
|
"lodash": "4.18.1",
|
|
29
29
|
"mathjs": "^15.2.0",
|
|
30
30
|
"pious-squid": "^2.3.0",
|
|
31
31
|
"plotly": "^1.0.6",
|
|
32
|
-
"satellite.js": "^7.0
|
|
32
|
+
"satellite.js": "^7.1.0",
|
|
33
33
|
"solar-calculator": "^0.3.0",
|
|
34
34
|
"three": "^0.185.1",
|
|
35
35
|
"winston": "3.19.0"
|
|
@@ -41,16 +41,17 @@
|
|
|
41
41
|
"@jest/globals": "^30.4.1",
|
|
42
42
|
"@sonar/scan": "^5.0.0",
|
|
43
43
|
"cross-env": "^10.1.0",
|
|
44
|
-
"eslint": "^10.
|
|
45
|
-
"eslint-plugin-jest": "^29.
|
|
46
|
-
"globals": "^17.
|
|
44
|
+
"eslint": "^10.9.1",
|
|
45
|
+
"eslint-plugin-jest": "^29.16.2",
|
|
46
|
+
"globals": "^17.11.0",
|
|
47
47
|
"jest": "^30.4.2",
|
|
48
48
|
"jest-diff": "^30.4.1",
|
|
49
49
|
"nodemon": "3.1.14"
|
|
50
50
|
},
|
|
51
51
|
"overrides": {
|
|
52
52
|
"braces": "3.0.3",
|
|
53
|
-
"brace-expansion": "2.1.
|
|
53
|
+
"brace-expansion": "2.1.4",
|
|
54
|
+
"js-yaml": "3.15.2",
|
|
54
55
|
"lodash": "4.18.1"
|
|
55
56
|
}
|
|
56
57
|
}
|
package/src/astro.js
CHANGED
|
@@ -40,6 +40,7 @@ import {DEG2RAD,
|
|
|
40
40
|
REGIMES,
|
|
41
41
|
GRAV_CONST,
|
|
42
42
|
EARTH_MASS,
|
|
43
|
+
MU,
|
|
43
44
|
WGS72_EARTH_EQUATORIAL_RADIUS_KM,
|
|
44
45
|
WGS84_EARTH_EQUATORIAL_RADIUS_KM,
|
|
45
46
|
MILLIS_PER_DAY,
|
|
@@ -49,6 +50,7 @@ import TLEValidator from "./tle/TLEValidator.js";
|
|
|
49
50
|
import MultiLineTLEValidator from "./tle/MultiLineTLEValidator.js";
|
|
50
51
|
import {TLE_ERRORS} from "./tle/tleErrors.js";
|
|
51
52
|
import {TleParseUtils} from "./tle/TleParseUtils.js";
|
|
53
|
+
import {OrbitUtils} from "./OrbitUtils.js";
|
|
52
54
|
|
|
53
55
|
// Solar Terminator
|
|
54
56
|
// Returns sun latitude and longitude as -180/180
|
|
@@ -310,8 +312,34 @@ const getLonAndDrift = (line1, line2, datetime) => {
|
|
|
310
312
|
};
|
|
311
313
|
|
|
312
314
|
/**
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
+
* Orbital period in minutes from semi-major axis and gravitational parameter.
|
|
316
|
+
* @param {number} aKm Semi-major axis (km)
|
|
317
|
+
* @param {number} muKm3s2 Standard gravitational parameter (km³/s²)
|
|
318
|
+
* @return {number|null} Period in minutes, or null if a ≤ 0
|
|
319
|
+
*/
|
|
320
|
+
const orbitalPeriodMinutes = (aKm, muKm3s2) => {
|
|
321
|
+
const periodSec = OrbitUtils.getPeriod(aKm, muKm3s2);
|
|
322
|
+
return periodSec === null ? null : periodSec / 60;
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Mean motion in revolutions per day from semi-major axis and gravitational parameter.
|
|
327
|
+
* @param {number} aKm Semi-major axis (km)
|
|
328
|
+
* @param {number} muKm3s2 Standard gravitational parameter (km³/s²)
|
|
329
|
+
* @return {number} Mean motion in rev/day
|
|
330
|
+
*/
|
|
331
|
+
const orbitalMeanMotionRevPerDay = (aKm, muKm3s2) => {
|
|
332
|
+
const nRadS = OrbitUtils.getMeanMotion(aKm, muKm3s2);
|
|
333
|
+
return nRadS * 86400 / (2 * Math.PI);
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Classify orbit regime using JCO v1.0.0 primary period/eccentricity cuts
|
|
338
|
+
* (Orbit_Class_Definitions_v1.0.0_11Jun2024.csv). Evaluation order matters:
|
|
339
|
+
* HEO first, then GEO family (1300–1800 min), MEO, LEO, else Undetermined.
|
|
340
|
+
*
|
|
341
|
+
* Documentation available at: https://unifieddatalibrary.com/scs/download?id=/CommunityData/JCO_DOK/JCO_JSON_Requirements/Orbit_Class_Definitions_v1.0.0_11Jun2024.xlsx
|
|
342
|
+
*
|
|
315
343
|
* @param {Object} orbit Object with keys eccentricity, inclination (deg), meanmotion (rev/day) and period (min)
|
|
316
344
|
* @return {number} the regime index
|
|
317
345
|
*/
|
|
@@ -320,34 +348,43 @@ const calcRegime = (orbit) => {
|
|
|
320
348
|
return REGIMES.Undetermined;
|
|
321
349
|
}
|
|
322
350
|
|
|
323
|
-
const {eccentricity, inclination, meanmotion, period}
|
|
351
|
+
const {eccentricity: e, inclination: i, meanmotion: n, period: T}
|
|
324
352
|
= lowerCaseObjectKeys(orbit);
|
|
325
353
|
|
|
326
|
-
if (!isDefined(
|
|
354
|
+
if (!isDefined(e)) {
|
|
327
355
|
return REGIMES.Undetermined;
|
|
328
356
|
}
|
|
329
357
|
|
|
330
|
-
if (
|
|
331
|
-
return REGIMES.
|
|
358
|
+
if (e >= 0.25) {
|
|
359
|
+
return REGIMES.Heo;
|
|
332
360
|
}
|
|
333
361
|
|
|
334
|
-
if (
|
|
335
|
-
return REGIMES.
|
|
362
|
+
if (!isDefined(T) || T <= 0) {
|
|
363
|
+
return REGIMES.Undetermined;
|
|
336
364
|
}
|
|
337
365
|
|
|
338
|
-
if (
|
|
366
|
+
if (T > 1300 && T < 1800) {
|
|
367
|
+
if (!isDefined(n) || !isDefined(i)) {
|
|
368
|
+
return REGIMES.Undetermined;
|
|
369
|
+
}
|
|
370
|
+
if (n >= 0.99 && n <= 1.01 && i <= 0.01) {
|
|
371
|
+
return REGIMES.GeoStationary;
|
|
372
|
+
}
|
|
373
|
+
if (n >= 0.99 && n <= 1.01 && i > 0.01) {
|
|
374
|
+
return REGIMES.GeoInclined;
|
|
375
|
+
}
|
|
339
376
|
return REGIMES.GeoDrifter;
|
|
340
377
|
}
|
|
341
378
|
|
|
342
|
-
if (
|
|
379
|
+
if (T > 600 && T < 900) {
|
|
343
380
|
return REGIMES.Meo;
|
|
344
381
|
}
|
|
345
382
|
|
|
346
|
-
if (
|
|
383
|
+
if (T <= 225) {
|
|
347
384
|
return REGIMES.Leo;
|
|
348
385
|
}
|
|
349
386
|
|
|
350
|
-
return
|
|
387
|
+
return REGIMES.Undetermined;
|
|
351
388
|
};
|
|
352
389
|
|
|
353
390
|
/**
|
|
@@ -1748,11 +1785,9 @@ const cartesianToElsetElements = (pv, epoch) => {
|
|
|
1748
1785
|
ArgOfPerigee: kepl.w,
|
|
1749
1786
|
};
|
|
1750
1787
|
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
elset.MeanMotion = meanMotion / (2*Math.PI) * 60 * 60 * 24; // rads/s to revs per day
|
|
1788
|
+
const muKm3s2 = MU / 1e9;
|
|
1789
|
+
elset.MeanMotion = orbitalMeanMotionRevPerDay(elset.SemiMajorAxis, muKm3s2);
|
|
1790
|
+
elset.Period = orbitalPeriodMinutes(elset.SemiMajorAxis, muKm3s2);
|
|
1756
1791
|
|
|
1757
1792
|
const trueAnomaly = kepl.f;
|
|
1758
1793
|
|
|
@@ -1763,7 +1798,6 @@ const cartesianToElsetElements = (pv, epoch) => {
|
|
|
1763
1798
|
// Compute Mean Anomaly from Eccentric Anomaly and Eccentricity
|
|
1764
1799
|
elset.MeanAnomaly = (E - (elset.Eccentricity)*Math.sin(E)) * RAD2DEG;
|
|
1765
1800
|
|
|
1766
|
-
elset.Period = 2*Math.PI/meanMotion / 60; // period in minutes
|
|
1767
1801
|
elset.Apogee = elset.SemiMajorAxis * (1 + elset.Eccentricity); // km
|
|
1768
1802
|
elset.Perigee = elset.SemiMajorAxis * (1 - elset.Eccentricity); // km
|
|
1769
1803
|
|
|
@@ -3590,6 +3624,8 @@ export {
|
|
|
3590
3624
|
} from "satellite.js";
|
|
3591
3625
|
export {
|
|
3592
3626
|
calcRegime,
|
|
3627
|
+
orbitalPeriodMinutes,
|
|
3628
|
+
orbitalMeanMotionRevPerDay,
|
|
3593
3629
|
altToRegime,
|
|
3594
3630
|
cartesianToRIC,
|
|
3595
3631
|
angleBetween3DCoords,
|
package/src/udl.js
CHANGED
|
@@ -5,11 +5,14 @@ import {
|
|
|
5
5
|
getElsetUdlFromTle,
|
|
6
6
|
getLonAndDrift,
|
|
7
7
|
getRaanPrecession,
|
|
8
|
+
orbitalMeanMotionRevPerDay,
|
|
9
|
+
orbitalPeriodMinutes,
|
|
8
10
|
raDecToAzEl,
|
|
9
11
|
azElToRaDec,
|
|
10
12
|
raDecToGeodetic,
|
|
11
13
|
estimateSlantRange,
|
|
12
14
|
} from "./astro.js";
|
|
15
|
+
import {REGIMES, MU} from "./constants.js";
|
|
13
16
|
import {lowerCaseObjectKeys, jsonArrayOrNull} from "./transform.js";
|
|
14
17
|
import {isDefined} from "./utils.js";
|
|
15
18
|
import _ from "lodash";
|
|
@@ -327,6 +330,28 @@ const getSVSatno = (udlRow) => {
|
|
|
327
330
|
return null;
|
|
328
331
|
};
|
|
329
332
|
|
|
333
|
+
const computeStateRegimeFromKeplerians = (keplerians) => {
|
|
334
|
+
const {a, e, i} = keplerians;
|
|
335
|
+
if (!isDefined(a) || a <= 0 || !isDefined(e) || e >= 1) {
|
|
336
|
+
return REGIMES.Undetermined;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const muKm3s2 = MU / 1e9;
|
|
340
|
+
const period = orbitalPeriodMinutes(a, muKm3s2);
|
|
341
|
+
const meanmotion = orbitalMeanMotionRevPerDay(a, muKm3s2);
|
|
342
|
+
|
|
343
|
+
if (period === null) {
|
|
344
|
+
return REGIMES.Undetermined;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return calcRegime({
|
|
348
|
+
eccentricity: e,
|
|
349
|
+
inclination: i,
|
|
350
|
+
meanmotion,
|
|
351
|
+
period,
|
|
352
|
+
});
|
|
353
|
+
};
|
|
354
|
+
|
|
330
355
|
const udlToNpsState = (udlRow) => {
|
|
331
356
|
const Xpos = _.get(udlRow, "xpos", null); // kilometers
|
|
332
357
|
const Ypos = _.get(udlRow, "ypos", null);
|
|
@@ -351,6 +376,8 @@ const udlToNpsState = (udlRow) => {
|
|
|
351
376
|
keplerians = cartesianToKeplerian(pos, vel);
|
|
352
377
|
}
|
|
353
378
|
|
|
379
|
+
const regime = computeStateRegimeFromKeplerians(keplerians);
|
|
380
|
+
|
|
354
381
|
const npsState = lowerCaseObjectKeys({
|
|
355
382
|
satno: getSVSatno(udlRow),
|
|
356
383
|
Epoch: fixDate(_.get(udlRow, "epoch", null)),
|
|
@@ -388,7 +415,7 @@ const udlToNpsState = (udlRow) => {
|
|
|
388
415
|
Longitude: null,
|
|
389
416
|
LonDriftDegreesPerDay: null,
|
|
390
417
|
RaanPrecessionDegreesPerDay: null,
|
|
391
|
-
Regime:
|
|
418
|
+
Regime: regime,
|
|
392
419
|
});
|
|
393
420
|
return npsState;
|
|
394
421
|
};
|