Skip to content

Commit

Permalink
test: ✅ add tests for Tle
Browse files Browse the repository at this point in the history
  • Loading branch information
thkruz committed Jan 15, 2024
1 parent 0c2f59f commit 39673ba
Show file tree
Hide file tree
Showing 10 changed files with 409 additions and 26 deletions.
15 changes: 8 additions & 7 deletions src/coordinate/ClassicalElements.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Degrees, Kilometers, Radians, Seconds } from '../main';
import { Minutes, PositionVelocity, Degrees, Kilometers, Radians, Seconds } from '../main';
import { Vector3D } from '../operations/Vector3D';
import { EpochUTC } from '../time/EpochUTC';
import { earthGravityParam, RAD2DEG, sec2min, secondsPerDay, TAU } from '../utils/constants';
import { earthGravityParam, MINUTES_PER_DAY, RAD2DEG, sec2min, TAU } from '../utils/constants';
import { clamp, matchHalfPlane, newtonNu } from '../utils/functions';
import { EquinoctialElements } from './EquinoctialElements';
import { OrbitRegime } from '../enums/OrbitRegime';
import { StateVector } from './StateVector';
import { PositionVelocity } from 'src/types/types';
import { ClassicalElementsParams } from '../interfaces/ClassicalElementsParams';

/**
Expand Down Expand Up @@ -97,7 +96,7 @@ export class ClassicalElements {

return new ClassicalElements({
epoch: state.epoch,
semimajorAxis: a as Kilometers,
semimajorAxis: a,
eccentricity: e,
inclination: i as Radians,
rightAscension: o as Radians,
Expand Down Expand Up @@ -181,16 +180,18 @@ export class ClassicalElements {
* Calculates the period of the orbit.
* @returns The period in seconds.
*/
get period(): Seconds {
return (TAU * Math.sqrt(this.semimajorAxis ** 3 / this.mu)) as Seconds;
get period(): Minutes {
const periodSec = (TAU * Math.sqrt(this.semimajorAxis ** 3 / this.mu)) as Seconds;

return (periodSec / 60) as Minutes;
}

/**
* Compute the number of revolutions completed per day for this orbit.
* @returns The number of revolutions per day.
*/
get revsPerDay(): number {
return secondsPerDay / this.period;
return MINUTES_PER_DAY / this.period;
}

/**
Expand Down
14 changes: 8 additions & 6 deletions src/coordinate/EquinoctialElements.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Kilometers, Radians, Seconds } from '../main';
import { EpochUTC } from '../time/EpochUTC';
import { earthGravityParam, secondsPerDay, TAU } from '../utils/constants';
import { earthGravityParam, MINUTES_PER_DAY, TAU } from '../utils/constants';
import { newtonM } from '../utils/functions';
import { ClassicalElements } from './ClassicalElements';
import { PositionVelocity } from 'src/types/types';
import { Minutes, PositionVelocity } from 'src/types/types';
import { EquinoctialElementsParams } from '../interfaces/EquinoctialElementsParams';

/**
Expand Down Expand Up @@ -135,10 +135,12 @@ export class EquinoctialElements {

/**
* Gets the period of the orbit.
* @returns The period in seconds.
* @returns The period in minutes.
*/
get period(): Seconds {
return (TAU * Math.sqrt(this.semimajorAxis ** 3 / this.mu)) as Seconds;
get period(): Minutes {
const periodSec = (TAU * Math.sqrt(this.semimajorAxis ** 3 / this.mu)) as Seconds;

return (periodSec / 60) as Minutes;
}

/**
Expand All @@ -147,7 +149,7 @@ export class EquinoctialElements {
* @returns The number of revolutions per day.
*/
get revsPerDay(): number {
return secondsPerDay / this.period;
return MINUTES_PER_DAY / this.period;
}

/**
Expand Down
34 changes: 26 additions & 8 deletions src/coordinate/TEME.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,40 @@ import { StateVector } from './StateVector';
* communication, navigation, and remote sensing.
*/
export class TEME extends StateVector {
// / Create a new [TEME] object from a [ClassicalElements] object.
static fromClassicalElements(elements: ClassicalElements): TEME {
const rv = elements.toPositionVelocity();

return new TEME(elements.epoch, rv.position, rv.velocity);
}

/**
* Gets the name of the coordinate system.
* @returns The name of the coordinate system.
*/
get name(): string {
return 'TEME';
}

/**
* Gets a value indicating whether the coordinate is inertial.
* @returns A boolean value indicating whether the coordinate is inertial.
*/
get inertial(): boolean {
return true;
}

// / Convert this to a [J2000] state vector object.
/**
* Creates a TEME (True Equator Mean Equinox) object from classical orbital
* elements.
*
* @param elements - The classical orbital elements.
* @returns A new TEME object.
*/
static fromClassicalElements(elements: ClassicalElements): TEME {
const rv = elements.toPositionVelocity();

return new TEME(elements.epoch, rv.position, rv.velocity);
}

/**
* Converts the TEME (True Equator Mean Equinox) coordinates to J2000
* coordinates.
* @returns The J2000 coordinates.
*/
toJ2000(): J2000 {
const p = Earth.precession(this.epoch);
const n = Earth.nutation(this.epoch);
Expand Down
7 changes: 5 additions & 2 deletions src/coordinate/Tle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
Line2Data,
Minutes,
SatelliteRecord,
Seconds,
StateVectorSgp4,
TleData,
TleDataFull,
Expand Down Expand Up @@ -175,8 +176,10 @@ export class Tle {
return this.semimajorAxis * (1 - this.eccentricity);
}

get period(): number {
return TAU * Math.sqrt(this.semimajorAxis ** 3 / earthGravityParam);
get period(): Minutes {
const periodSec = (TAU * Math.sqrt(this.semimajorAxis ** 3 / earthGravityParam)) as Seconds;

return (periodSec / 60) as Minutes;
}

private static parseEpoch_(epochStr: string): EpochUTC {
Expand Down
48 changes: 48 additions & 0 deletions test/coordinate/TEME.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { exampleDate } from '../lib/mockData';
import { ClassicalElements, EpochUTC, J2000, Kilometers, Radians, TEME, Vector3D } from './../../src/main';
describe('TEME', () => {
let stateVector: TEME;

beforeEach(() => {
stateVector = new J2000(
EpochUTC.fromDateTime(new Date(1705109326817)),
new Vector3D(1538.223335842895 as Kilometers, 5102.261204021967 as Kilometers, 4432.634965003577 as Kilometers),
new Vector3D(
-7.341518909379302 as Kilometers,
0.6516718453998644 as Kilometers,
1.7933882499861993 as Kilometers,
),
).toTEME();
});

// name
it('should return the name of the coordinate system', () => {
expect(stateVector.name).toMatchSnapshot();
});

// inertial
it('should return whether the coordinate system is inertial', () => {
expect(stateVector.inertial).toMatchSnapshot();
});

// fromClassicalElements
it('should create a TEME coordinate from classical orbital elements', () => {
const epoch = EpochUTC.fromDateTime(exampleDate);
const elements = new ClassicalElements({
epoch,
semimajorAxis: 6943.547853722985 as Kilometers,
eccentricity: 0.0011235968124658146,
inclination: 0.7509087232045765 as Radians,
rightAscension: 0.028239555738616327 as Radians,
argPerigee: 2.5386411901807353 as Radians,
trueAnomaly: 0.5931399364974058 as Radians,
});

expect(TEME.fromClassicalElements(elements)).toMatchSnapshot();
});

// toJ2000
it('should convert the TEME coordinates to J2000 coordinates', () => {
expect(stateVector.toJ2000()).toMatchSnapshot();
});
});
84 changes: 84 additions & 0 deletions test/coordinate/Tle.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { exampleDate } from '../lib/mockData';
import { ClassicalElements, EpochUTC, Kilometers, Radians, Tle, TleLine1, TleLine2 } from '../../src/main';

describe('Tle', () => {
let tle: Tle;

beforeEach(() => {
// Sample TLE
const tle1 = '1 56006U 23042W 24012.45049317 .00000296 00000-0 36967-4 0 9992' as TleLine1;
const tle2 = '2 56006 143.0043 13.3620 0001137 267.5965 92.4747 15.02542972 44491' as TleLine2;

tle = new Tle(tle1, tle2);
});

// toString
it('should return the TLE as a string', () => {
expect(tle.toString()).toMatchSnapshot();
});

// semiMajorAxis
it('should return the semi-major axis', () => {
expect(tle.semimajorAxis).toMatchSnapshot();
});

// eccentricity
it('should return the eccentricity', () => {
expect(tle.eccentricity).toMatchSnapshot();
});

// inclination
it('should return the inclination', () => {
expect(tle.inclination).toMatchSnapshot();
});

// inclinationDeg
it('should return the inclination in degrees', () => {
expect(tle.inclinationDegrees).toMatchSnapshot();
});

// apogee
it('should return the apogee', () => {
expect(tle.apogee).toMatchSnapshot();
});

// perigee
it('should return the perigee', () => {
expect(tle.perigee).toMatchSnapshot();
});

// period
it('should return the period', () => {
expect(tle.period).toMatchSnapshot();
});

// propagate
it('should propagate the TLE', () => {
const epoch = EpochUTC.fromDateTime(exampleDate);
const propagated = tle.propagate(epoch);

expect(propagated).toMatchSnapshot();
});

// state
it('should return the state vector', () => {
expect(tle.state).toMatchSnapshot();
});

// fromClassicalElements
it('should create a TLE from classical orbital elements', () => {
const epoch = EpochUTC.fromDateTime(exampleDate);
const elements = new ClassicalElements({
epoch,
semimajorAxis: 6943.547853722985 as Kilometers,
eccentricity: 0.0011235968124658146,
inclination: 0.7509087232045765 as Radians,
rightAscension: 0.028239555738616327 as Radians,
argPerigee: 2.5386411901807353 as Radians,
trueAnomaly: 0.5931399364974058 as Radians,
});
const tle = Tle.fromClassicalElements(elements);

expect(tle).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ exports[`ClassicalElements should calculate the orbit regime of ClassicalElement

exports[`ClassicalElements should calculate the perigee of ClassicalElements 1`] = `6935.746105487338`;

exports[`ClassicalElements should calculate the period of ClassicalElements 1`] = `5758.152068066809`;
exports[`ClassicalElements should calculate the period of ClassicalElements 1`] = `95.96920113444682`;

exports[`ClassicalElements should calculate true anomaly in degrees 1`] = `33.984415021959016`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ exports[`ClassicalElements should return the mean motion 1`] = `0.00109302064133

exports[`ClassicalElements should return the mean motion 2`] = `0.0010926340790517568`;

exports[`ClassicalElements should return the period 1`] = `5748.459882237341`;
exports[`ClassicalElements should return the period 1`] = `95.80766470395568`;

exports[`ClassicalElements should return the period 2`] = `5750.493626038512`;
exports[`ClassicalElements should return the period 2`] = `95.8415604339752`;

exports[`ClassicalElements should return the retrograde factor 1`] = `1`;

Expand Down
41 changes: 41 additions & 0 deletions test/coordinate/__snapshots__/TEME.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`TEME should convert the TEME coordinates to J2000 coordinates 1`] = `
J2000 {
"epoch": EpochUTC {
"posix": 1705109326.817,
},
"position": Vector3D {
"x": 1538.2233358428946,
"y": 5102.2612040219665,
"z": 4432.634965003576,
},
"velocity": Vector3D {
"x": -7.341518909379303,
"y": 0.6516718453998649,
"z": 1.793388249986199,
},
}
`;

exports[`TEME should create a TEME coordinate from classical orbital elements 1`] = `
TEME {
"epoch": EpochUTC {
"posix": 1705109326.817,
},
"position": Vector3D {
"x": -6935.3813042612455,
"y": -146.1261328371035,
"z": 46.43907991639276,
},
"velocity": Vector3D {
"x": 0.07740377357485445,
"y": -5.543955093986134,
"z": -5.174123893746047,
},
}
`;

exports[`TEME should return the name of the coordinate system 1`] = `"TEME"`;

exports[`TEME should return whether the coordinate system is inertial 1`] = `true`;
Loading

0 comments on commit 39673ba

Please sign in to comment.