@saber-usa/node-common 1.7.6 → 1.7.7-alpha.2
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 +52 -51
- package/src/FrameConverter.js +7 -6
- package/src/LaunchNominalClass.js +57 -76
- package/src/OrbitUtils.js +6 -187
- package/src/PropagateUtils.js +9 -9
- package/src/astro.js +56 -68
- package/src/ballisticPropagator.js +1 -1
- package/src/checkNetwork.cjs +20 -20
- package/src/constants.js +3 -1
- package/src/launchNominal.js +1 -1
- package/src/loggerFactory.cjs +98 -98
package/README.md
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
# Saber Common node functions
|
|
2
|
-
|
|
3
|
-
The contains common node functions used across saber applications
|
|
4
|
-
|
|
5
|
-
## Logger
|
|
6
|
-
|
|
7
|
-
The logger component is a standard logger based on [winston](https://github.com/winstonjs/winston). The logger factory
|
|
8
|
-
creates a default console logger for errors along with exception/rejection catching. By setting the `CONSOLE_LOG`
|
|
9
|
-
variable to `true` will turn on the console logger for local development. The log level is configured by the `LOG_LEVEL`
|
|
10
|
-
environment variable to one of the following levels: `emerg`, `alert`, `crit`, `error`, `warning`, `warn`, `notice`,
|
|
11
|
-
`info`, `debug` (default level is `error`). The reason using an environment variable for the level is useful when
|
|
12
|
-
deployed to the server. Changing the environment variable is easier than setting a new flag in the script execution.
|
|
13
|
-
|
|
14
|
-
### Usage
|
|
15
|
-
|
|
16
|
-
To create a new logger, just pass in options to the factory:
|
|
17
|
-
|
|
18
|
-
```javascript
|
|
19
|
-
const logger = loggerFactory(opts);
|
|
20
|
-
|
|
21
|
-
logger.debug("This is a debug message");
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
For further usage, consult [winston](https://github.com/winstonjs/winston)
|
|
25
|
-
|
|
26
|
-
### Options
|
|
27
|
-
|
|
28
|
-
- `nameSpace` help distinguish where the logger message comes from.
|
|
29
|
-
- `additionalData` Data to include with each message
|
|
30
|
-
- `level` overwrite the `LOG_LEVEL` environment level
|
|
31
|
-
|
|
32
|
-
## Transformer
|
|
33
|
-
|
|
34
|
-
A transformer for object keys is provided. This will take an object and transform the keys using a function.
|
|
35
|
-
|
|
36
|
-
## Publishing changes
|
|
37
|
-
|
|
38
|
-
1. Change the version in package.json
|
|
39
|
-
2. Run `npm publish && npm install`
|
|
40
|
-
3. Enable GPG in GIT: `git config --global commit.gpgsign true`
|
|
41
|
-
4. Run `gpg --list-keys` to get your <id>
|
|
1
|
+
# Saber Common node functions
|
|
2
|
+
|
|
3
|
+
The contains common node functions used across saber applications
|
|
4
|
+
|
|
5
|
+
## Logger
|
|
6
|
+
|
|
7
|
+
The logger component is a standard logger based on [winston](https://github.com/winstonjs/winston). The logger factory
|
|
8
|
+
creates a default console logger for errors along with exception/rejection catching. By setting the `CONSOLE_LOG`
|
|
9
|
+
variable to `true` will turn on the console logger for local development. The log level is configured by the `LOG_LEVEL`
|
|
10
|
+
environment variable to one of the following levels: `emerg`, `alert`, `crit`, `error`, `warning`, `warn`, `notice`,
|
|
11
|
+
`info`, `debug` (default level is `error`). The reason using an environment variable for the level is useful when
|
|
12
|
+
deployed to the server. Changing the environment variable is easier than setting a new flag in the script execution.
|
|
13
|
+
|
|
14
|
+
### Usage
|
|
15
|
+
|
|
16
|
+
To create a new logger, just pass in options to the factory:
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
const logger = loggerFactory(opts);
|
|
20
|
+
|
|
21
|
+
logger.debug("This is a debug message");
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
For further usage, consult [winston](https://github.com/winstonjs/winston)
|
|
25
|
+
|
|
26
|
+
### Options
|
|
27
|
+
|
|
28
|
+
- `nameSpace` help distinguish where the logger message comes from.
|
|
29
|
+
- `additionalData` Data to include with each message
|
|
30
|
+
- `level` overwrite the `LOG_LEVEL` environment level
|
|
31
|
+
|
|
32
|
+
## Transformer
|
|
33
|
+
|
|
34
|
+
A transformer for object keys is provided. This will take an object and transform the keys using a function.
|
|
35
|
+
|
|
36
|
+
## Publishing changes
|
|
37
|
+
|
|
38
|
+
1. Change the version in package.json
|
|
39
|
+
2. Run `npm publish && npm install`
|
|
40
|
+
3. Enable GPG in GIT: `git config --global commit.gpgsign true`
|
|
41
|
+
4. Run `gpg --list-keys` to get your <id>
|
|
42
42
|
5. Tell the GIT to use your key `git config user.signingkey <id>`
|
package/package.json
CHANGED
|
@@ -1,51 +1,52 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@saber-usa/node-common",
|
|
3
|
-
"version": "1.7.
|
|
4
|
-
"description": "Common node functions for Saber",
|
|
5
|
-
"main": "src/index.js",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"lint": "eslint . --ext js",
|
|
9
|
-
"lint:fix": "eslint . --ext js --fix",
|
|
10
|
-
"test": "jest --no-coverage --silent",
|
|
11
|
-
"test:unit": "jest --coverage --runInBand --no-watch",
|
|
12
|
-
"sonar": "node --experimental-vm-modules sonar-project.js"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"@babel/
|
|
34
|
-
"@babel/
|
|
35
|
-
"@
|
|
36
|
-
"
|
|
37
|
-
"eslint-
|
|
38
|
-
"jest": "
|
|
39
|
-
"jest
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@saber-usa/node-common",
|
|
3
|
+
"version": "1.7.7-alpha.2",
|
|
4
|
+
"description": "Common node functions for Saber",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"lint": "eslint . --ext js",
|
|
9
|
+
"lint:fix": "eslint . --ext js --fix",
|
|
10
|
+
"test": "jest --no-coverage --silent",
|
|
11
|
+
"test:unit": "jest --coverage --runInBand --no-watch",
|
|
12
|
+
"sonar": "node --experimental-vm-modules sonar-project.js",
|
|
13
|
+
"prepub:alpha": "npm version prerelease --preid=alpha && npm publish --tag alpha"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"src/**/*"
|
|
17
|
+
],
|
|
18
|
+
"author": "Saber USA",
|
|
19
|
+
"license": "ISC",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@aws-sdk/client-s3": "^3.666.0",
|
|
22
|
+
"date-fns": "^4.1.0",
|
|
23
|
+
"lodash": "4.17.21",
|
|
24
|
+
"mathjs": "^14.7.0",
|
|
25
|
+
"pious-squid": "^2.3.0",
|
|
26
|
+
"plotly": "^1.0.6",
|
|
27
|
+
"satellite.js": "^6.0.1",
|
|
28
|
+
"solar-calculator": "^0.3.0",
|
|
29
|
+
"three": "^0.178.0",
|
|
30
|
+
"winston": "3.3.3"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@babel/core": "7.16.0",
|
|
34
|
+
"@babel/eslint-parser": "7.16.3",
|
|
35
|
+
"@babel/plugin-transform-modules-commonjs": "7.16.0",
|
|
36
|
+
"@jest/globals": "27.4.4",
|
|
37
|
+
"eslint-config-google": "0.14.0",
|
|
38
|
+
"eslint-plugin-jest": "25.3.0",
|
|
39
|
+
"jest": "29.7.0",
|
|
40
|
+
"jest-diff": "29.7.0",
|
|
41
|
+
"nodemon": "3.1.4",
|
|
42
|
+
"sonarqube-scanner": "3.0.1"
|
|
43
|
+
},
|
|
44
|
+
"overrides": {
|
|
45
|
+
"braces": "3.0.3"
|
|
46
|
+
},
|
|
47
|
+
"babel": {
|
|
48
|
+
"plugins": [
|
|
49
|
+
"@babel/plugin-transform-modules-commonjs"
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
}
|
package/src/FrameConverter.js
CHANGED
|
@@ -3,6 +3,7 @@ import {Matrix3D, Vector3D} from "pious-squid";
|
|
|
3
3
|
import {LLA} from "./LLA.js";
|
|
4
4
|
import {TimeConverter, RaDec} from "./TimeConverter.js";
|
|
5
5
|
import {norm, cross} from "mathjs";
|
|
6
|
+
import {DEG2RAD} from "./constants.js";
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
// Enums (assuming these exist elsewhere)
|
|
@@ -957,12 +958,12 @@ class FrameConverter {
|
|
|
957
958
|
}
|
|
958
959
|
|
|
959
960
|
static perifocalToInertial(keplerianElements) {
|
|
960
|
-
const cosi = Math.cos(keplerianElements.
|
|
961
|
-
const sini = Math.sin(keplerianElements.
|
|
962
|
-
const cosRaan = Math.cos(keplerianElements.raan);
|
|
963
|
-
const sinRaan = Math.sin(keplerianElements.raan);
|
|
964
|
-
const cosw = Math.cos(keplerianElements.
|
|
965
|
-
const sinw = Math.sin(keplerianElements.
|
|
961
|
+
const cosi = Math.cos(keplerianElements.i * DEG2RAD);
|
|
962
|
+
const sini = Math.sin(keplerianElements.i * DEG2RAD);
|
|
963
|
+
const cosRaan = Math.cos(keplerianElements.raan * DEG2RAD);
|
|
964
|
+
const sinRaan = Math.sin(keplerianElements.raan * DEG2RAD);
|
|
965
|
+
const cosw = Math.cos(keplerianElements.w * DEG2RAD);
|
|
966
|
+
const sinw = Math.sin(keplerianElements.w * DEG2RAD);
|
|
966
967
|
|
|
967
968
|
// The matrix elements
|
|
968
969
|
const r11 = cosRaan * cosw - sinRaan * sinw * cosi;
|
|
@@ -5,12 +5,14 @@ import {WGS84_EARTH_EQUATORIAL_RADIUS_KM,
|
|
|
5
5
|
GRAV_CONST,
|
|
6
6
|
EARTH_MASS,
|
|
7
7
|
MU,
|
|
8
|
-
EARTH_RADIUS_KM
|
|
8
|
+
EARTH_RADIUS_KM,
|
|
9
|
+
DEG2RAD} from "./constants.js";
|
|
9
10
|
import {FrameConverter} from "./FrameConverter.js";
|
|
10
11
|
import {OrbitUtils} from "./OrbitUtils.js";
|
|
11
12
|
import {wrapOneRevUnsigned} from "./utils.js";
|
|
12
13
|
import {BallisticPropagator} from "./ballisticPropagator.js";
|
|
13
14
|
import {norm, cross, dot} from "mathjs";
|
|
15
|
+
import {cartesianToKeplerian, keplerianToCartesian} from "./astro.js";
|
|
14
16
|
|
|
15
17
|
// Reference frames enum
|
|
16
18
|
const ReferenceFrame = {
|
|
@@ -20,6 +22,8 @@ const ReferenceFrame = {
|
|
|
20
22
|
GCRF: "GCRF",
|
|
21
23
|
};
|
|
22
24
|
|
|
25
|
+
const mu = GRAV_CONST * EARTH_MASS / 1e9; // km^3/s^2
|
|
26
|
+
|
|
23
27
|
class LaunchNominalClass {
|
|
24
28
|
/** Get position at a given time in specified reference frame
|
|
25
29
|
*
|
|
@@ -54,7 +58,6 @@ class LaunchNominalClass {
|
|
|
54
58
|
let bearingRad = degreesToRadians(bearingDeg);
|
|
55
59
|
bearingRad = wrapOneRevUnsigned(bearingRad);
|
|
56
60
|
|
|
57
|
-
// const latRad = degreesToRadians(this.groundSiteLat);
|
|
58
61
|
const latRad = llaVals.Latitude.Radians;
|
|
59
62
|
const targetInclination = OrbitUtils.getInclination(bearingRad, latRad);
|
|
60
63
|
|
|
@@ -75,23 +78,7 @@ class LaunchNominalClass {
|
|
|
75
78
|
ReferenceFrame.J2000,
|
|
76
79
|
llaVals,
|
|
77
80
|
);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// const transformMatrix = FrameConverter.j2000ToTEME(orbitInsertionTime);
|
|
81
|
-
// const initialTemeState = {
|
|
82
|
-
// position: this.transformVector(
|
|
83
|
-
// new Vector3D(initialStateVector.position[0],
|
|
84
|
-
// initialStateVector.position[1], initialStateVector.position[2]),
|
|
85
|
-
// transformMatrix
|
|
86
|
-
// ),
|
|
87
|
-
// velocity: this.transformVector(
|
|
88
|
-
// new Vector3D(initialStateVector.velocity[0],
|
|
89
|
-
// initialStateVector.velocity[1], initialStateVector.velocity[2]),
|
|
90
|
-
// transformMatrix
|
|
91
|
-
// ),
|
|
92
|
-
// };
|
|
93
|
-
|
|
94
|
-
// End of something
|
|
81
|
+
|
|
95
82
|
const initialJ2000State = new J2000(
|
|
96
83
|
EpochUTC.fromDateString(orbitInsertionTime.toISOString()),
|
|
97
84
|
new Vector3D(initialStateVector.position[0],
|
|
@@ -104,11 +91,11 @@ class LaunchNominalClass {
|
|
|
104
91
|
|
|
105
92
|
let sat = {
|
|
106
93
|
stateVector: initialStateVector,
|
|
107
|
-
elements:
|
|
94
|
+
elements: cartesianToKeplerian(
|
|
108
95
|
[initialTemeState.position.x, initialTemeState.position.y,
|
|
109
96
|
initialTemeState.position.z],
|
|
110
97
|
[initialTemeState.velocity.x, initialTemeState.velocity.y,
|
|
111
|
-
initialTemeState.velocity.z]),
|
|
98
|
+
initialTemeState.velocity.z], mu),
|
|
112
99
|
epoch: orbitInsertionTime,
|
|
113
100
|
};
|
|
114
101
|
|
|
@@ -150,12 +137,12 @@ class LaunchNominalClass {
|
|
|
150
137
|
|
|
151
138
|
const temeState = propagatedJ2000State.toTEME();
|
|
152
139
|
|
|
153
|
-
// Convert to orbital elements
|
|
154
|
-
const elements =
|
|
140
|
+
// Convert to orbital elements - angles are in degrees
|
|
141
|
+
const elements = cartesianToKeplerian(
|
|
155
142
|
[temeState.position.x, temeState.position.y,
|
|
156
143
|
temeState.position.z],
|
|
157
144
|
[temeState.velocity.x, temeState.velocity.y,
|
|
158
|
-
temeState.velocity.z]);
|
|
145
|
+
temeState.velocity.z], mu);
|
|
159
146
|
|
|
160
147
|
sat = {
|
|
161
148
|
stateVector: propagated,
|
|
@@ -165,7 +152,7 @@ class LaunchNominalClass {
|
|
|
165
152
|
|
|
166
153
|
// Calculate current inclination
|
|
167
154
|
oldInclinationDelta = inclinationDelta;
|
|
168
|
-
inclinationDelta = Math.abs(
|
|
155
|
+
inclinationDelta = Math.abs((sat.elements.i)
|
|
169
156
|
- radiansToDegrees(targetInclination));
|
|
170
157
|
|
|
171
158
|
if (oldInclinationDelta < inclinationDelta) {
|
|
@@ -238,22 +225,22 @@ class LaunchNominalClass {
|
|
|
238
225
|
// Transform to elliptical orbit
|
|
239
226
|
const ellipticalElements = OrbitUtils.transformElliptical(
|
|
240
227
|
svInitial,
|
|
241
|
-
initialNominal.states[0].elements.inc,
|
|
242
|
-
initialNominal.states[0].elements.raan,
|
|
228
|
+
initialNominal.states[0].elements.inc * DEG2RAD,
|
|
229
|
+
initialNominal.states[0].elements.raan * DEG2RAD,
|
|
243
230
|
targetEcc,
|
|
244
|
-
|
|
231
|
+
targetArgOfPeriapsisDeg * DEG2RAD,
|
|
245
232
|
targetPerigeeKm + WGS84_EARTH_EQUATORIAL_RADIUS_KM,
|
|
246
233
|
);
|
|
247
234
|
|
|
248
235
|
// Convert elliptical elements to cartesian state
|
|
249
|
-
const ellipticalStateVector =
|
|
236
|
+
const ellipticalStateVector = keplerianToCartesian(ellipticalElements, mu);
|
|
250
237
|
|
|
251
|
-
const ellipticalPos = ellipticalStateVector.
|
|
252
|
-
const ellipticalVel = ellipticalStateVector.
|
|
238
|
+
const ellipticalPos = ellipticalStateVector.r;
|
|
239
|
+
const ellipticalVel = ellipticalStateVector.v;
|
|
253
240
|
|
|
254
241
|
const ellipticalState = {
|
|
255
|
-
position: new NodeVector3D(ellipticalPos
|
|
256
|
-
velocity: new NodeVector3D(ellipticalVel
|
|
242
|
+
position: new NodeVector3D(ellipticalPos.x, ellipticalPos.y, ellipticalPos.z),
|
|
243
|
+
velocity: new NodeVector3D(ellipticalVel.x, ellipticalVel.y, ellipticalVel.z),
|
|
257
244
|
epochUtc: orbitInsertionTime,
|
|
258
245
|
referenceFrame: "J2000",
|
|
259
246
|
};
|
|
@@ -266,7 +253,7 @@ class LaunchNominalClass {
|
|
|
266
253
|
const ellipNomVel = ellipticalNominal.velocity;
|
|
267
254
|
|
|
268
255
|
// Convert to orbital elements
|
|
269
|
-
const elements =
|
|
256
|
+
const elements = cartesianToKeplerian(
|
|
270
257
|
[ellipNomPos.x, ellipNomPos.y, ellipNomPos.z],
|
|
271
258
|
[ellipNomVel.x, ellipNomVel.y, ellipNomVel.z]);
|
|
272
259
|
|
|
@@ -406,7 +393,7 @@ class LaunchNominalClass {
|
|
|
406
393
|
}
|
|
407
394
|
|
|
408
395
|
static hohmannTransferWithIncZeroing(state0, targetSMA,
|
|
409
|
-
burnAtNodes = 1, mu = MU
|
|
396
|
+
burnAtNodes = 1, mu = MU) {
|
|
410
397
|
let t0 = state0.epochUtc;
|
|
411
398
|
let i = null;
|
|
412
399
|
|
|
@@ -471,8 +458,8 @@ class LaunchNominalClass {
|
|
|
471
458
|
|
|
472
459
|
const rElementConv = [state0.position.x, state0.position.y, state0.position.z];
|
|
473
460
|
const vElementConv = [state0.velocity.x, state0.velocity.y, state0.velocity.z];
|
|
474
|
-
const elements0 =
|
|
475
|
-
const incDiff = elements0.
|
|
461
|
+
const elements0 = cartesianToKeplerian(rElementConv, vElementConv, mu);
|
|
462
|
+
const incDiff = elements0.i * DEG2RAD;
|
|
476
463
|
|
|
477
464
|
const h = cross([state0.position.x, state0.position.y, state0.position.z],
|
|
478
465
|
[state0.velocity.x, state0.velocity.y, state0.velocity.z]);
|
|
@@ -538,41 +525,34 @@ class LaunchNominalClass {
|
|
|
538
525
|
}
|
|
539
526
|
|
|
540
527
|
static #getNextNodeCrossingGeoOrbit(sv) {
|
|
541
|
-
const geoElements =
|
|
542
|
-
semiMajorAxis: 35786.0 + EARTH_RADIUS_KM,
|
|
543
|
-
eccentricity: 0,
|
|
544
|
-
inclination: 0,
|
|
545
|
-
raan: 0,
|
|
546
|
-
argOfPeriapsis: 0,
|
|
547
|
-
trueAnomaly: 0,
|
|
548
|
-
};
|
|
528
|
+
const geoElements = [35786 + EARTH_RADIUS_KM, 0, 0, 0, 0, 0];
|
|
549
529
|
const geoOrbitState = {
|
|
550
|
-
state:
|
|
530
|
+
state: keplerianToCartesian(geoElements, mu),
|
|
551
531
|
epochUtc: sv.epochUtc,
|
|
552
532
|
};
|
|
553
533
|
const nextNode = this.#findMutualNodeTimes(sv, geoOrbitState);
|
|
554
534
|
return nextNode.nextNodeTime;
|
|
555
535
|
}
|
|
556
536
|
|
|
557
|
-
static #findMutualNodeTimes(sv1, sv2, muEarth = MU
|
|
537
|
+
static #findMutualNodeTimes(sv1, sv2, muEarth = MU) {
|
|
558
538
|
// Implementation for finding mutual node times between two state vectors
|
|
559
539
|
|
|
560
540
|
if (!(sv1.epochUtc === sv2.epochUtc)) {
|
|
561
541
|
return "lol what on earth";
|
|
562
542
|
}
|
|
563
543
|
|
|
564
|
-
const orbit1 =
|
|
544
|
+
const orbit1 = cartesianToKeplerian(
|
|
565
545
|
[sv1.position.x, sv1.position.y, sv1.position.z],
|
|
566
|
-
[sv1.velocity.x, sv1.velocity.y, sv1.velocity.z]);
|
|
567
|
-
const orbit2 = OrbitUtils.stateVectorToElements(
|
|
568
|
-
sv2.state.position,
|
|
569
|
-
sv2.state.velocity);
|
|
546
|
+
[sv1.velocity.x, sv1.velocity.y, sv1.velocity.z], muEarth);
|
|
570
547
|
|
|
571
|
-
const
|
|
572
|
-
|
|
548
|
+
const orbit2 = cartesianToKeplerian(
|
|
549
|
+
[sv2.state.r.x, sv2.state.r.y, sv2.state.r.z],
|
|
550
|
+
[sv2.state.v.x, sv2.state.v.y, sv2.state.v.z], muEarth);
|
|
573
551
|
|
|
574
|
-
const
|
|
575
|
-
const
|
|
552
|
+
const state1 = keplerianToCartesian(Object.values(orbit1), muEarth);
|
|
553
|
+
const state2 = keplerianToCartesian(Object.values(orbit2), muEarth);
|
|
554
|
+
const h1 = cross(Object.values(state1.r), Object.values(state1.v));
|
|
555
|
+
const h2 = cross(Object.values(state2.r), Object.values(state2.v));
|
|
576
556
|
const h1Norm = norm(h1);
|
|
577
557
|
const h2Norm = norm(h2);
|
|
578
558
|
|
|
@@ -585,7 +565,8 @@ class LaunchNominalClass {
|
|
|
585
565
|
return Math.acos(dotProduct / normsProduct);
|
|
586
566
|
}
|
|
587
567
|
|
|
588
|
-
const ascendingFirst
|
|
568
|
+
const ascendingFirst
|
|
569
|
+
= getAngleBetween2Vectors(Object.values(state1.r), h2unit) > Math.PI / 2;
|
|
589
570
|
|
|
590
571
|
const nodalLine = cross(h1unit, h2unit);
|
|
591
572
|
const nodalLineUnit = nodalLine.map((component) => component / norm(nodalLine));
|
|
@@ -600,10 +581,10 @@ class LaunchNominalClass {
|
|
|
600
581
|
|
|
601
582
|
const mutualNodeLinePerifocal = rTilde1inverse.multiplyVector3D(nodalLineUnitVector3D);
|
|
602
583
|
const slopeMutualNodalLinePerifocal = mutualNodeLinePerifocal.y / mutualNodeLinePerifocal.x;
|
|
603
|
-
const mutualNode = this.#findIntersectionEllipseLine(
|
|
584
|
+
const mutualNode = this.#findIntersectionEllipseLine(
|
|
604
585
|
slopeMutualNodalLinePerifocal,
|
|
605
|
-
orbit1.
|
|
606
|
-
orbit1.
|
|
586
|
+
orbit1.a,
|
|
587
|
+
orbit1.e);
|
|
607
588
|
|
|
608
589
|
const q1 = mutualNode.vec1;
|
|
609
590
|
const q2 = mutualNode.vec2;
|
|
@@ -614,13 +595,13 @@ class LaunchNominalClass {
|
|
|
614
595
|
return ((n % m) + m) % m;
|
|
615
596
|
}
|
|
616
597
|
|
|
617
|
-
const n0 = mod(orbit1.
|
|
598
|
+
const n0 = mod(orbit1.f * DEG2RAD, 2 * Math.PI);
|
|
618
599
|
const n1 = mod(Math.atan2(dot(q1unit, [0, 1, 0]), dot(q1unit, [1, 0, 0])), 2 * Math.PI);
|
|
619
600
|
const n2 = mod(Math.atan2(dot(q2unit, [0, 1, 0]), dot(q2unit, [1, 0, 0])), 2 * Math.PI);
|
|
620
601
|
|
|
621
|
-
const e0 = OrbitUtils.trueAnomalyToEccentricAnomaly(n0, orbit1.
|
|
622
|
-
let e1 = OrbitUtils.trueAnomalyToEccentricAnomaly(n1, orbit1.
|
|
623
|
-
let e2 = OrbitUtils.trueAnomalyToEccentricAnomaly(n2, orbit1.
|
|
602
|
+
const e0 = OrbitUtils.trueAnomalyToEccentricAnomaly(n0, orbit1.e);
|
|
603
|
+
let e1 = OrbitUtils.trueAnomalyToEccentricAnomaly(n1, orbit1.e); // only matching to 2 sig figs w astrolib
|
|
604
|
+
let e2 = OrbitUtils.trueAnomalyToEccentricAnomaly(n2, orbit1.e); // only matching to 3 sig figs w astrolib
|
|
624
605
|
|
|
625
606
|
if (e1 < 0) {
|
|
626
607
|
e1 += 2 * Math.PI;
|
|
@@ -633,13 +614,13 @@ class LaunchNominalClass {
|
|
|
633
614
|
const k1 = n1 < n0 ? 1 : 0;
|
|
634
615
|
const k2 = n2 < n0 ? 1 : 0;
|
|
635
616
|
|
|
636
|
-
const dt1 = Math.sqrt(Math.pow(orbit1.
|
|
637
|
-
* (2 * k1 * Math.PI + (e1 - orbit1.
|
|
638
|
-
- (e0 - orbit1.
|
|
617
|
+
const dt1 = Math.sqrt(Math.pow(orbit1.a, 3) / muEarth)
|
|
618
|
+
* (2 * k1 * Math.PI + (e1 - orbit1.e * Math.sin(e1))
|
|
619
|
+
- (e0 - orbit1.e * Math.sin(e0)));
|
|
639
620
|
const dt2 = Math.sqrt(
|
|
640
|
-
Math.pow(orbit1.
|
|
641
|
-
* (2 * k2 * Math.PI + (e2 - orbit1.
|
|
642
|
-
- (e0 - orbit1.
|
|
621
|
+
Math.pow(orbit1.a, 3) / muEarth)
|
|
622
|
+
* (2 * k2 * Math.PI + (e2 - orbit1.e * Math.sin(e2))
|
|
623
|
+
- (e0 - orbit1.e * Math.sin(e0)));
|
|
643
624
|
let first = null;
|
|
644
625
|
let second = null;
|
|
645
626
|
|
|
@@ -719,7 +700,7 @@ class LaunchNominalOutput {
|
|
|
719
700
|
const j2000ToTeme = FrameConverter.getTransform("J2000", "TEME", epoch);
|
|
720
701
|
const posTeme = FrameConverter.transformVector(pos, j2000ToTeme);
|
|
721
702
|
const velTeme = FrameConverter.transformVector(vel, j2000ToTeme);
|
|
722
|
-
elements =
|
|
703
|
+
elements = cartesianToKeplerian(
|
|
723
704
|
[posTeme.x, posTeme.y, posTeme.z],
|
|
724
705
|
[velTeme.x, velTeme.y, velTeme.z]);
|
|
725
706
|
}
|
|
@@ -731,12 +712,12 @@ class LaunchNominalOutput {
|
|
|
731
712
|
v: [vel.x, vel.y, vel.z],
|
|
732
713
|
},
|
|
733
714
|
elements: {
|
|
734
|
-
sma: elements.
|
|
735
|
-
ecc: elements.
|
|
736
|
-
inc: elements.
|
|
715
|
+
sma: elements.a,
|
|
716
|
+
ecc: elements.e,
|
|
717
|
+
inc: elements.i,
|
|
737
718
|
raan: elements.raan,
|
|
738
|
-
argp: elements.
|
|
739
|
-
ta: elements.
|
|
719
|
+
argp: elements.w,
|
|
720
|
+
ta: elements.f,
|
|
740
721
|
},
|
|
741
722
|
// Placeholder for tle
|
|
742
723
|
});
|