@saber-usa/node-common 1.7.2 → 1.7.4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saber-usa/node-common",
3
- "version": "1.7.2",
3
+ "version": "1.7.4",
4
4
  "description": "Common node functions for Saber",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -31,6 +31,58 @@ const Earth = {
31
31
  };
32
32
 
33
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
+
34
86
  /**
35
87
  * Helper to transpose a Matrix3D
36
88
  * @param {Matrix3D} m - The matrix to transpose
@@ -21,57 +21,7 @@ const ReferenceFrame = {
21
21
  };
22
22
 
23
23
  class LaunchNominalClass {
24
- /**
25
- * Helper method to transform a vector using a Matrix3D
26
- * @param {Vector3D} vector - Vector to transform
27
- * @param {Matrix3D} matrix - Matrix to use for transformation
28
- * @return {Vector3D} Transformed vector
29
- */
30
- static transformVector(vector, matrix) {
31
- // Manual matrix-vector multiplication since pious-squid has issues
32
- const x = matrix.get(0, 0) * vector.x
33
- + matrix.get(0, 1) * vector.y + matrix.get(0, 2) * vector.z;
34
- const y = matrix.get(1, 0) * vector.x
35
- + matrix.get(1, 1) * vector.y + matrix.get(1, 2) * vector.z;
36
- const z = matrix.get(2, 0) * vector.x
37
- + matrix.get(2, 1) * vector.y + matrix.get(2, 2) * vector.z;
38
- return new Vector3D(x, y, z);
39
- }
40
-
41
- /**
42
- * Rotate a vector around an axis by an angle (Rodrigues' rotation formula)
43
- * @param {Vector3D} vector - Vector to rotate
44
- * @param {Vector3D} axis - Axis to rotate around (should be normalized)
45
- * @param {number} angleRad - Angle in radians
46
- * @return {Vector3D} Rotated vector
47
- */
48
- static rotateVector(vector, axis, angleRad) {
49
- // Ensure axis is normalized
50
- const k = axis.normalized();
51
- const v = vector;
52
- const cosTheta = Math.cos(angleRad);
53
- const sinTheta = Math.sin(angleRad);
54
-
55
- // Rodrigues' rotation formula:
56
- // v_rot = v*cos(θ) + (k × v)*sin(θ) + k*(k·v)*(1-cos(θ))
57
-
58
- // k × v (cross product)
59
- const kCrossV = new Vector3D(
60
- k.y * v.z - k.z * v.y,
61
- k.z * v.x - k.x * v.z,
62
- k.x * v.y - k.y * v.x,
63
- );
64
-
65
- // k·v (dot product)
66
- const kDotV = k.x * v.x + k.y * v.y + k.z * v.z;
67
-
68
- // Final rotation
69
- return new Vector3D(
70
- v.x * cosTheta + kCrossV.x * sinTheta + k.x * kDotV * (1 - cosTheta),
71
- v.y * cosTheta + kCrossV.y * sinTheta + k.y * kDotV * (1 - cosTheta),
72
- v.z * cosTheta + kCrossV.z * sinTheta + k.z * kDotV * (1 - cosTheta),
73
- );
74
- }
24
+
75
25
 
76
26
  /** Get position at a given time in specified reference frame
77
27
  *
@@ -82,7 +32,7 @@ class LaunchNominalClass {
82
32
  static getPositionJ2000(utc, posITRF) {
83
33
  const transformMatrix = FrameConverter.itrfToJ2000(utc);
84
34
 
85
- return this.transformVector(posITRF, transformMatrix);
35
+ return FrameConverter.transformVector(posITRF, transformMatrix);
86
36
  }
87
37
 
88
38
  /** Generate a circular launch nominal.
@@ -427,16 +377,16 @@ class LaunchNominalClass {
427
377
  // Cardinal directions in ITRF frame
428
378
  // South vector (1, 0, 0) in SEZ
429
379
  const southSEZ = new Vector3D(1, 0, 0);
430
- const south = this.transformVector(southSEZ, sez2ecef).normalized();
380
+ const south = FrameConverter.transformVector(southSEZ, sez2ecef).normalized();
431
381
  const north = south.scale(-1);
432
382
 
433
383
  // Zenith vector (0, 0, 1) in SEZ
434
384
  const zenithSEZ = new Vector3D(0, 0, 1);
435
- const zenith = this.transformVector(zenithSEZ, sez2ecef).normalized();
385
+ const zenith = FrameConverter.transformVector(zenithSEZ, sez2ecef).normalized();
436
386
  const nadir = zenith.scale(-1);
437
387
 
438
- const northJ2000 = this.transformVector(north, itrf2j2000).normalized();
439
- const nadirJ2000 = this.transformVector(nadir, itrf2j2000).normalized();
388
+ const northJ2000 = FrameConverter.transformVector(north, itrf2j2000).normalized();
389
+ const nadirJ2000 = FrameConverter.transformVector(nadir, itrf2j2000).normalized();
440
390
 
441
391
  // Position of site in J2000 scaled by the orbit altitude
442
392
  const siteJ2000 = this.getPositionJ2000(orbitInsertionTime, positionITRF);
@@ -446,7 +396,7 @@ class LaunchNominalClass {
446
396
  // North vector rotated by azimuth along nadir vector scaled by the velocity of a circular orbit
447
397
  const rLength = Math.sqrt(r.x * r.x + r.y * r.y + r.z * r.z);
448
398
  const velocityMagnitude = Math.sqrt(mu / rLength);
449
- const velocityDirection = this.rotateVector(northJ2000, nadirJ2000, azimuthRad);
399
+ const velocityDirection = FrameConverter.rotateVector(northJ2000, nadirJ2000, azimuthRad);
450
400
  const v = velocityDirection.scale(velocityMagnitude);
451
401
 
452
402
  return {
@@ -502,7 +452,7 @@ class LaunchNominalClass {
502
452
  };
503
453
 
504
454
  const rtnToEci = FrameConverter.rtnToEci(stateAtM1.position, stateAtM1.velocity);
505
- const dv1eci = this.transformVector(burn1.dv, rtnToEci);
455
+ const dv1eci = FrameConverter.transformVector(burn1.dv, rtnToEci);
506
456
 
507
457
  const state1 = {
508
458
  position: new NodeVector3D(
@@ -564,7 +514,7 @@ class LaunchNominalClass {
564
514
  };
565
515
 
566
516
  const rtnToEci2 = FrameConverter.rtnToEci(stateAtM2.position, stateAtM2.velocity);
567
- const dv1eci2 = this.transformVector(burn2.dv, rtnToEci2);
517
+ const dv1eci2 = FrameConverter.transformVector(burn2.dv, rtnToEci2);
568
518
 
569
519
  const state2 = {
570
520
  position: new NodeVector3D(
@@ -769,8 +719,8 @@ class LaunchNominalOutput {
769
719
 
770
720
  if (!elements) {
771
721
  const j2000ToTeme = FrameConverter.getTransform("J2000", "TEME", epoch);
772
- const posTeme = LaunchNominalClass.transformVector(pos, j2000ToTeme);
773
- const velTeme = LaunchNominalClass.transformVector(vel, j2000ToTeme);
722
+ const posTeme = FrameConverter.transformVector(pos, j2000ToTeme);
723
+ const velTeme = FrameConverter.transformVector(vel, j2000ToTeme);
774
724
  elements = OrbitUtils.stateVectorToElements(
775
725
  [posTeme.x, posTeme.y, posTeme.z],
776
726
  [velTeme.x, velTeme.y, velTeme.z]);
package/src/astro.js CHANGED
@@ -779,6 +779,7 @@ const getTRIC = (pEphem, tEphem) => {
779
779
  const isPrimaryEpoch = []; // Whether point is primary epoch
780
780
  const isTargetEpoch = []; // Whether point is target epoch
781
781
  const sources = []; // Sources
782
+ const datamodes = []; // Data modes
782
783
 
783
784
  for (let j = 0; j < pEphem.length; j++) {
784
785
  const prim = pEphem[j];
@@ -788,6 +789,7 @@ const getTRIC = (pEphem, tEphem) => {
788
789
  isPrimaryEpoch.push((!!prim.isEpoch)+""); // it can't be a boolean for some reason
789
790
  isTargetEpoch.push((!!target.isEpoch)+"");
790
791
  sources.push(prim.source + ", " + target.source);
792
+ datamodes.push(prim.datamode + ", " + target.datamode);
791
793
 
792
794
  // Calculate RIC values.
793
795
  const deltaR = {
@@ -828,6 +830,7 @@ const getTRIC = (pEphem, tEphem) => {
828
830
  isPrimaryEpoch,
829
831
  isTargetEpoch,
830
832
  sources,
833
+ datamodes,
831
834
  targetVisibility,
832
835
  primaryVisibility,
833
836
  };