From 4c2d701dfc25d04a3929956e0ff2d5f94466bd05 Mon Sep 17 00:00:00 2001 From: Theodore Kruczek Date: Wed, 10 Jan 2024 21:43:50 -0500 Subject: [PATCH] test: :white_check_mark: fix tests --- examples/satellite-js-migration.ts | 125 ++++++++ examples/sensor.ts | 69 ----- examples/transforms.ts | 22 ++ src/objects/Satellite.ts | 52 ++-- src/objects/Star.ts | 5 +- src/objects/index.ts | 1 + src/operations/Vector3D.ts | 7 +- src/transforms/transforms.ts | 75 ++++- test/sat/{sat.test.js => sat.test.ts} | 12 +- test/sat/sensor.test.ts | 2 +- ...oon.test.js.snap => sun-moon.test.ts.snap} | 8 +- .../{sun-moon.test.js => sun-moon.test.ts} | 42 +-- test/transforms/transforms.json | 287 ----------------- ...{transforms.test.js => transforms.test.ts} | 28 +- test/transforms/transformsData.ts | 289 ++++++++++++++++++ test/utils/{utils.test.js => utils.test.ts} | 74 +++-- 16 files changed, 616 insertions(+), 482 deletions(-) create mode 100644 examples/satellite-js-migration.ts delete mode 100644 examples/sensor.ts create mode 100644 examples/transforms.ts rename test/sat/{sat.test.js => sat.test.ts} (88%) rename test/sun-moon/__snapshots__/{sun-moon.test.js.snap => sun-moon.test.ts.snap} (92%) rename test/sun-moon/{sun-moon.test.js => sun-moon.test.ts} (82%) delete mode 100644 test/transforms/transforms.json rename test/transforms/{transforms.test.js => transforms.test.ts} (88%) create mode 100644 test/transforms/transformsData.ts rename test/utils/{utils.test.js => utils.test.ts} (70%) diff --git a/examples/satellite-js-migration.ts b/examples/satellite-js-migration.ts new file mode 100644 index 0000000..b13f50f --- /dev/null +++ b/examples/satellite-js-migration.ts @@ -0,0 +1,125 @@ +/* eslint-disable max-len */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { + calcGmst, + DEG2RAD, + Degrees, + GroundPosition, + Kilometers, + lla2eci, + Radians, + Satellite, + Sgp4, + TleLine1, + TleLine2, +} from '../src/ootk-core'; + +// Sample TLE +const tle1 = '1 25544U 98067A 19156.50900463 .00003075 00000-0 59442-4 0 9992' as TleLine1; +const tle2 = '2 25544 51.6433 59.2583 0008217 16.4489 347.6017 15.51174618173442' as TleLine2; + +// Initialize a Satellite Object +const satellite = new Satellite({ + tle1, + tle2, +}); + +// You can still propagate a satellite using time since epoch (in minutes), but it's not recommended. +const timeSinceTleEpochMinutes = 10; +const positionAndVelocity = Sgp4.propagate(satellite.satrec, timeSinceTleEpochMinutes); + +// Use a Date object instead +const positionAndVelocity2 = satellite.eci(new Date(2024, 0, 1)); +// Or use the current time +const positionAndVelocity3 = satellite.eci(); + +/* + * The position_velocity result is a key-value pair of ECI coordinates. + * These are the base results from which all other coordinates are derived. + */ +const positionEci = positionAndVelocity.position; // positionAndVelocity might be false +const velocityEci = positionAndVelocity.velocity; // typescript will error on this code + +/* + * Unlike satellite.js using the eci method will ALWAYS return a result or throw + * an error if it can't propagate the satellite. No more checking for false and trying to handle + * a combined object and boolean result. + */ +const positionEci2 = satellite.eci().position; // This is correctly typed + +// Set the Observer at 122.03 West by 36.96 North, in DEGREES (because who likes working in radians?) +const observer = new GroundPosition({ + lon: -122.0308 as Degrees, + lat: 36.9613422 as Degrees, + alt: 0.37 as Kilometers, +}); + +/** + * You can still calculate GMST if you want to, but unlike satellite.js it's not required. + */ +const { gmst, j } = calcGmst(new Date()); + +// You can get ECF, Geodetic, Look Angles, and Doppler Factor. +const positionEcf = satellite.ecf(); +const observerEcf = observer.ecf(); +const positionGd = satellite.lla(); +const lookAngles = satellite.rae(observer); +// This never worked in satellite.js, but it does now! +const dopplerFactor = satellite.dopplerFactor(observer); + +/** + * The coordinates are all stored in strongly typed key-value pairs. + * ECI and ECF are accessed by `x`, `y`, `z` properties. + * + * satellite.js generates Property 'x' does not exist on type 'boolean | { x: number; y: number; z: number; }'. + */ +const position = satellite.eci().position; +const satelliteX = position.x; // This is typed as Kilometers +const satelliteY = position.y; // to prevent you from accidentally +const satelliteZ = position.z; // mixing Meters with Kilometers. + +// Look Angles may be accessed by `azimuth`, `elevation`, `range` properties. +const azimuth = lookAngles.azimuth; // Typed as Degrees +const elevation = lookAngles.elevation; // Typed as Degrees +const rangeSat = lookAngles.range; // Typed as Kilometers + +// Geodetic coords are accessed via `longitude`, `latitude`, `height`. +const longitude = positionGd.lon; // Longitude is in Degrees +const latitude = positionGd.lat; // Latitude is in Degrees +const height = positionGd.alt; // Height is in Kilometers + +// Convert the DEGREES to RADIANS if you want. +const longitudeRad = longitude * DEG2RAD; +const latitudeRad = latitude * DEG2RAD; +/** + * In TypeScript you need to label your units. + * This will help prevent you from passing the wrong units into functions. + */ +const longitudeRad2 = (longitude * DEG2RAD) as Radians; +const latitudeRad2 = (latitude * DEG2RAD) as Radians; + +// lla2eci(positionGd, gmst); // Throws an error: Argument of type 'LlaVec3' is not assignable to parameter of type 'LlaVec3'. +lla2eci(observer.llaRad(), gmst); // This is correctly typed + +// eslint-disable-next-line no-console +console.log( + positionEci2, + positionEcf, + observerEcf, + positionGd, + lookAngles, + dopplerFactor, + satelliteX, + satelliteY, + satelliteZ, + azimuth, + elevation, + rangeSat, + longitude, + latitude, + height, + longitudeRad, + latitudeRad, + longitudeRad2, + latitudeRad2, +); diff --git a/examples/sensor.ts b/examples/sensor.ts deleted file mode 100644 index 23e39cf..0000000 --- a/examples/sensor.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* eslint-disable no-console */ -import { - calcGmst, - DEG2RAD, - Degrees, - ecf2eci, - eci2lla, - eci2rae, - Kilometers, - Satellite, - Sensor, - SensorParams, - SpaceObjectType, - TleLine1, - TleLine2, -} from '../lib/ootk-core'; - -const capeCodRadar = new Sensor({ - lat: 41.754785, - lon: -70.539151, - alt: 0.060966, - minAz: 347 as Degrees, - maxAz: 227 as Degrees, - minEl: 3 as Degrees, - maxEl: 85 as Degrees, - minRng: 0 as Kilometers, - maxRng: 5556 as Kilometers, - name: 'Cape Cod', - type: SpaceObjectType.PHASED_ARRAY_RADAR, -}); - -const testSensor = new Sensor({ - lat: 41, - lon: -71, - alt: 1, -} as SensorParams); - -const sat = new Satellite({ - tle1: '1 00005U 58002B 23361.70345217 .00000401 00000-0 53694-3 0 99999' as TleLine1, - tle2: '2 00005 34.2395 218.8683 1841681 30.7692 338.8934 10.85144797345180' as TleLine2, -}); - -const date = new Date('2023-12-31T20:51:19.934Z'); - -const ecf = { - x: 4000 as Kilometers, - y: 7000 as Kilometers, - z: 3000 as Kilometers, -}; -// const ecf2 = { x: 982.8336640053099, y: -6779.137352354403, z: 3813.7284924837254 } as EcfVec3; - -// const rae = ecf2rae(testSensor, ecf); - -const { gmst } = calcGmst(date); -const rae2 = eci2rae(date, ecf2eci(ecf, gmst), testSensor); -const lla = eci2lla(ecf2eci(ecf, gmst), gmst); - -// console.log(rae); -console.log(rae2); -console.log({ - lat: lla.lat * DEG2RAD, - lon: lla.lon * DEG2RAD, - alt: lla.alt, -}); - -// sat.propagateTo(date); - -console.log(sat.raeOpt(testSensor, date)); -console.log(sat.getJ2000(date).toITRF().toGeodetic()); diff --git a/examples/transforms.ts b/examples/transforms.ts new file mode 100644 index 0000000..8efb2be --- /dev/null +++ b/examples/transforms.ts @@ -0,0 +1,22 @@ +/* eslint-disable no-console */ +import { Degrees, ecf2rae, EcfVec3, GroundPosition, Kilometers, lla2ecf, lla2sez, RAD2DEG } from '../src/ootk-core'; + +const observer = new GroundPosition({ + name: 'ground-position', + lat: (0.7287584767123405 * RAD2DEG) as Degrees, + lon: (-1.2311404365114507 * RAD2DEG) as Degrees, + alt: 0.060966 as Kilometers, +}); + +const ecf = { + x: 1838.5578358534067, + y: -4971.972919387344, + z: 4466.101983887215, +} as EcfVec3; + +const llaRad = observer.llaRad(); + +console.log(llaRad); // Good +console.log(lla2ecf(observer)); // Good +console.log(lla2sez(llaRad, ecf)); +console.log(ecf2rae(observer, ecf)); diff --git a/src/objects/Satellite.ts b/src/objects/Satellite.ts index 00c92af..b0a54b5 100644 --- a/src/objects/Satellite.ts +++ b/src/objects/Satellite.ts @@ -1,3 +1,4 @@ +import { dopplerFactor } from './../utils/functions'; /** * @author Theodore Kruczek. * @description Orbital Object ToolKit (OOTK) is a collection of tools for working @@ -57,10 +58,9 @@ import { Vector3D } from '../operations/Vector3D'; import { Sgp4 } from '../sgp4/sgp4'; import { EpochUTC } from '../time/EpochUTC'; import { Tle } from '../tle/tle'; -import { ecf2rae, eci2ecf, eci2lla } from '../transforms'; -import { Utils } from '../utils/utils'; +import { ecf2rae, eci2ecf, eci2lla, jday } from '../transforms'; import { BaseObject } from './BaseObject'; -import { Sensor } from './Sensor'; +import { GroundPosition } from './GroundPosition'; /** * TODO: Reduce unnecessary calls to calculateTimeVariables using optional @@ -175,8 +175,8 @@ export class Satellite extends BaseObject { * * @optimized */ - az(sensor: Sensor, date: Date = this.time): Degrees { - return (this.raeOpt(sensor, date).az * RAD2DEG) as Degrees; + az(observer: GroundPosition, date: Date = this.time): Degrees { + return (this.raeOpt(observer, date).az * RAD2DEG) as Degrees; } /** @@ -185,8 +185,8 @@ export class Satellite extends BaseObject { * * @expanded */ - rae(sensor: Sensor, date: Date = this.time): RAE { - const rae = this.raeOpt(sensor, date); + rae(observer: GroundPosition, date: Date = this.time): RAE { + const rae = this.raeOpt(observer, date); const epoch = new EpochUTC(date.getTime()); return new RAE(epoch, rae.rng, (rae.az * DEG2RAD) as Radians, (rae.el * DEG2RAD) as Radians); @@ -197,10 +197,10 @@ export class Satellite extends BaseObject { * * @optimized */ - getEcf(date: Date = this.time): EcfVec3 { + ecf(date: Date = this.time): EcfVec3 { const { gmst } = Satellite.calculateTimeVariables(date); - return eci2ecf(this.getEci(date).position, gmst); + return eci2ecf(this.eci(date).position, gmst); } /** @@ -208,7 +208,7 @@ export class Satellite extends BaseObject { * * @optimized */ - getEci(date: Date = this.time): PosVel { + eci(date: Date = this.time): PosVel { const { m } = Satellite.calculateTimeVariables(date, this.satrec); const pv = Sgp4.propagate(this.satrec, m); @@ -249,8 +249,8 @@ export class Satellite extends BaseObject { * * @optimized */ - el(sensor: Sensor, date: Date = this.time): Degrees { - return (this.raeOpt(sensor, date).el * RAD2DEG) as Degrees; + el(observer: GroundPosition, date: Date = this.time): Degrees { + return (this.raeOpt(observer, date).el * RAD2DEG) as Degrees; } /** @@ -258,7 +258,7 @@ export class Satellite extends BaseObject { */ lla(date: Date = this.time): LlaVec3 { const { gmst } = Satellite.calculateTimeVariables(date, this.satrec); - const pos = this.getEci(date).position; + const pos = this.eci(date).position; return eci2lla(pos, gmst); } @@ -280,18 +280,12 @@ export class Satellite extends BaseObject { * * @optimized */ - raeOpt(sensor: Sensor, date: Date = this.time): RaeVec3 { + raeOpt(observer: GroundPosition, date: Date = this.time): RaeVec3 { const { gmst } = Satellite.calculateTimeVariables(date, this.satrec); - const eci = this.getEci(date).position; + const eci = this.eci(date).position; const ecf = eci2ecf(eci, gmst); - const lla = { - lat: (sensor.lat * DEG2RAD) as Radians, - lon: (sensor.lon * DEG2RAD) as Radians, - alt: sensor.alt, - }; - - return ecf2rae(lla, ecf); + return ecf2rae(observer, ecf); } /** @@ -299,8 +293,14 @@ export class Satellite extends BaseObject { * * @optimized */ - range(sensor: Sensor, date: Date = this.time): Kilometers { - return this.raeOpt(sensor, date).rng; + range(observer: GroundPosition, date: Date = this.time): Kilometers { + return this.raeOpt(observer, date).rng; + } + + dopplerFactor(observer: GroundPosition, date?: Date): number { + const position = this.eci(date); + + return dopplerFactor(observer.eci(date), position.position, position.velocity); } /** @@ -309,7 +309,7 @@ export class Satellite extends BaseObject { * This method changes the position and time properties of the satellite object. */ propagateTo(date: Date): this { - const pv = this.getEci(date); + const pv = this.eci(date); this.position = pv.position as EciVec3; this.time = date; @@ -328,7 +328,7 @@ export class Satellite extends BaseObject { satrec?: SatelliteRecord, ): { gmst: GreenwichMeanSiderealTime; m: number; j: number } { const j = - Utils.jday( + jday( date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate(), diff --git a/src/objects/Star.ts b/src/objects/Star.ts index f7aeee0..425b2fe 100644 --- a/src/objects/Star.ts +++ b/src/objects/Star.ts @@ -41,8 +41,7 @@ import { MILLISECONDS_TO_DAYS } from '../utils/constants'; import { Celestial } from '../body'; import { Sgp4 } from '../sgp4/sgp4'; -import { ecf2eci, rae2ecf } from '../transforms/transforms'; -import { Utils } from '../utils/utils'; +import { ecf2eci, jday, rae2ecf } from '../transforms/transforms'; import { BaseObject } from './BaseObject'; export class Star extends BaseObject { @@ -92,7 +91,7 @@ export class Star extends BaseObject { private static calculateTimeVariables_(date: Date): { gmst: GreenwichMeanSiderealTime; j: number } { const j = - Utils.jday( + jday( date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate(), diff --git a/src/objects/index.ts b/src/objects/index.ts index 21b82bd..c020960 100644 --- a/src/objects/index.ts +++ b/src/objects/index.ts @@ -1,4 +1,5 @@ export { BaseObject } from './BaseObject'; +export { GroundPosition } from './GroundPosition'; export { Satellite } from './Satellite'; export { Sensor } from './Sensor'; export { Star } from './Star'; diff --git a/src/operations/Vector3D.ts b/src/operations/Vector3D.ts index 6389299..6bb7cc9 100644 --- a/src/operations/Vector3D.ts +++ b/src/operations/Vector3D.ts @@ -1,3 +1,4 @@ +import { linearDistance } from '../ootk-core'; import { Matrix } from './Matrix'; import { Vector } from './Vector'; @@ -107,11 +108,7 @@ export class Vector3D { * Return the Euclidean distance between this and another [Vector3D]. */ distance(v: Vector3D): number { - const dx = this.x - v.x; - const dy = this.y - v.y; - const dz = this.z - v.z; - - return Math.sqrt(dx * dx + dy * dy + dz * dz); + return linearDistance(this, v); } /** diff --git a/src/transforms/transforms.ts b/src/transforms/transforms.ts index 96ff68c..d17fcc6 100644 --- a/src/transforms/transforms.ts +++ b/src/transforms/transforms.ts @@ -28,7 +28,7 @@ * DEALINGS IN THE SOFTWARE. */ -import { Earth, Sensor, Sgp4, Utils } from '../ootk-core'; +import { Earth, Sensor, Sgp4 } from '../ootk-core'; import { Degrees, EcefVec3, @@ -190,9 +190,9 @@ export function enu2rf({ x, y, z } } /** - * Calculates Geodetic Lat Lon Alt to ECF coordinates. + * Converts geodetic coordinates (longitude, latitude, altitude) to Earth-Centered Earth-Fixed (ECF) coordinates. */ -export function lla2ecf(lla: LlaVec3): EcfVec3 { +export function llaRad2ecf(lla: LlaVec3): EcfVec3 { const { lon, lat, alt } = lla; const a = 6378.137; @@ -206,12 +206,28 @@ export function lla2ecf(lla: LlaVec3): EcfVec3 const z = (normal * (1 - e2) + alt) * Math.sin(lat); return { - x: x, - y: y, - z: z, + x: x, + y: y, + z: z, }; } +/** + * Converts geodetic coordinates (longitude, latitude, altitude) to Earth-Centered Earth-Fixed (ECF) coordinates. + */ +export function lla2ecf(lla: LlaVec3): EcfVec3 { + const { lon, lat, alt } = lla; + + const lonRad = lon * DEG2RAD; + const latRad = lat * DEG2RAD; + + return llaRad2ecf({ + lon: lonRad as Radians, + lat: latRad as Radians, + alt, + }); +} + /** * Converts geodetic coordinates (latitude, longitude, altitude) to Earth-centered inertial (ECI) coordinates. * @param lla The geodetic coordinates in radians and meters. @@ -255,10 +271,10 @@ export function lla2ecef(lla: LlaVec3): EcefVec3(lla: LlaVec3, ecf: EcfVec3): SezVec3 { - const lat = lla.lat; const lon = lla.lon; + const lat = lla.lat; - const observerEcf = lla2ecf({ + const observerEcf = llaRad2ecf({ lat, lon, alt: 0, @@ -319,7 +335,7 @@ export function rae2ecf(rae: RaeVec3, lla: LlaVec3 rng: rae.rng, }; - const obsEcf = lla2ecf(llaRad); + const obsEcf = llaRad2ecf(llaRad); const sez = rae2sez(raeRad); // Some needed calculations @@ -446,13 +462,48 @@ export function uv2azel(u: Radians, v: Radians, coneHalfAngle: Radians): { az: R * @param ecf The Earth-Centered Fixed (ECF) coordinates. * @returns The Right Ascension (RA), Elevation (E), and Azimuth (A) coordinates. */ -export function ecf2rae(lla: LlaVec3, ecf: EcfVec3): RaeVec3 { +export function ecfRad2rae(lla: LlaVec3, ecf: EcfVec3): RaeVec3 { const sezCoords = lla2sez(lla, ecf); const rae = sez2rae(sezCoords); return { rng: rae.rng, az: (rae.az * RAD2DEG) as Degrees, el: (rae.el * RAD2DEG) as Degrees }; } +/** + * Converts Earth-Centered Fixed (ECF) coordinates to Right Ascension (RA), + * Elevation (E), and Azimuth (A) coordinates. + * + * @param lla The Latitude, Longitude, and Altitude (LLA) coordinates. + * @param ecf The Earth-Centered Fixed (ECF) coordinates. + * @returns The Right Ascension (RA), Elevation (E), and Azimuth (A) coordinates. + */ +export function ecf2rae(lla: LlaVec3, ecf: EcfVec3): RaeVec3 { + const { lat, lon } = lla; + const latRad = (lat * DEG2RAD) as Radians; + const lonRad = (lon * DEG2RAD) as Radians; + + return ecfRad2rae({ lat: latRad, lon: lonRad, alt: lla.alt }, ecf); +} + +export const jday = (year?: number, mon?: number, day?: number, hr?: number, minute?: number, sec?: number) => { + if (!year) { + const now = new Date(); + const jDayStart = new Date(now.getUTCFullYear(), 0, 0); + const jDayDiff = now.getDate() - jDayStart.getDate(); + + return Math.floor(jDayDiff / MILLISECONDS_TO_DAYS); + } + + return ( + 367.0 * year - + Math.floor(7 * (year + Math.floor((mon + 9) / 12.0)) * 0.25) + + Math.floor((275 * mon) / 9.0) + + day + + 1721013.5 + + ((sec / 60.0 + minute) / 60.0 + hr) / 24.0 + ); +}; + /** * Calculates the Greenwich Mean Sidereal Time (GMST) for a given date. * @@ -461,7 +512,7 @@ export function ecf2rae(lla: LlaVec3, ecf: EcfVec3 */ export function calcGmst(date: Date): { gmst: GreenwichMeanSiderealTime; j: number } { const j = - Utils.jday( + jday( date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate(), @@ -505,7 +556,7 @@ export function eci2rae(now: Date, eci: EciVec3, sensor: Sensor): Ra alt: sensor.alt, }; - const rae = ecf2rae(lla, positionEcf); + const rae = ecfRad2rae(lla, positionEcf); // Add to cache eci2raeCache.set(key, rae); diff --git a/test/sat/sat.test.js b/test/sat/sat.test.ts similarity index 88% rename from test/sat/sat.test.js rename to test/sat/sat.test.ts index 302115a..c63b32b 100644 --- a/test/sat/sat.test.js +++ b/test/sat/sat.test.ts @@ -4,13 +4,13 @@ * @since 1.2.0 */ -import { Satellite } from '../../lib/ootk-core'; +import { Satellite, TleLine1, TleLine2 } from '../../lib/ootk-core'; import { RAD2DEG } from '../../lib/utils/constants'; const dateObj = new Date(1661400000000); -const tle1 = '1 25544U 98067A 22203.46960946 .00003068 00000+0 61583-4 0 9996'; -const tle2 = '2 25544 51.6415 161.8339 0005168 35.9781 54.7009 15.50067047350657'; +const tle1 = '1 25544U 98067A 22203.46960946 .00003068 00000+0 61583-4 0 9996' as TleLine1; +const tle2 = '2 25544 51.6415 161.8339 0005168 35.9781 54.7009 15.50067047350657' as TleLine2; describe('Basic Satellite functionality', () => { it('should create a new Sat object', () => { @@ -23,7 +23,7 @@ describe('Basic Satellite functionality', () => { }); it('should allow chaining', () => { - const eci = new Satellite({ name: 'Test', tle1, tle2 }).propagateTo(dateObj).getEci().position; + const eci = new Satellite({ name: 'Test', tle1, tle2 }).propagateTo(dateObj).eci().position; expect(eci.x).toBeCloseTo(6512.640035319078); expect(eci.y).toBeCloseTo(-1545.524934684146); @@ -33,7 +33,7 @@ describe('Basic Satellite functionality', () => { it('should allow getting eci coordinates', () => { const sat = new Satellite({ name: 'Test', tle1, tle2 }); - const eci = sat.getEci(dateObj).position; + const eci = sat.eci(dateObj).position; expect(eci.x).toBeCloseTo(6512.640035319078); expect(eci.y).toBeCloseTo(-1545.524934684146); @@ -43,7 +43,7 @@ describe('Basic Satellite functionality', () => { it('should allow getting ecf coordinates', () => { const sat = new Satellite({ name: 'Test', tle1, tle2 }); - const eci = sat.getEcf(dateObj); + const eci = sat.ecf(dateObj); expect(eci.x).toBeCloseTo(4585.677469309576); expect(eci.y).toBeCloseTo(-4875.929624270418); diff --git a/test/sat/sensor.test.ts b/test/sat/sensor.test.ts index 9a940ba..fbb8d11 100644 --- a/test/sat/sensor.test.ts +++ b/test/sat/sensor.test.ts @@ -28,7 +28,7 @@ describe('Basic Sensor functionality', () => { maxRng: 100000 as Kilometers, }); - const rae = sensor.getRae(sat, dateObj); + const rae = sensor.rae(sat, dateObj); expect(rae.az).toMatchSnapshot(); expect(rae.el).toMatchSnapshot(); diff --git a/test/sun-moon/__snapshots__/sun-moon.test.js.snap b/test/sun-moon/__snapshots__/sun-moon.test.ts.snap similarity index 92% rename from test/sun-moon/__snapshots__/sun-moon.test.js.snap rename to test/sun-moon/__snapshots__/sun-moon.test.ts.snap index 19543d0..54fec88 100644 --- a/test/sun-moon/__snapshots__/sun-moon.test.js.snap +++ b/test/sun-moon/__snapshots__/sun-moon.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Sun and Moon MoonMath Unit Tests 1`] = ` +exports[`Sun and Moon Moon Unit Tests 1`] = ` Object { "angle": 2.0187380462851525, "fraction": 0.04918501150967336, @@ -41,8 +41,8 @@ Object { exports[`Sun and Moon getMoonIllumination returns fraction and angle of moons illuminated limb and phase 1`] = ` Object { - "angle": 2.0187380462851525, - "fraction": 0.04918501150967336, + "angle": 1.870981046981252, + "fraction": 0.09702945670419616, "next": Object { "date": "2022-08-27T06:46:57.840Z", "firstQuarter": Object { @@ -74,6 +74,6 @@ Object { "to": 0.966136806691289, "weight": 6.3825, }, - "phaseValue": 0.9288143180691704, + "phaseValue": 0.8991701089962825, } `; diff --git a/test/sun-moon/sun-moon.test.js b/test/sun-moon/sun-moon.test.ts similarity index 82% rename from test/sun-moon/sun-moon.test.js rename to test/sun-moon/sun-moon.test.ts index 6dcb75c..f01b961 100644 --- a/test/sun-moon/sun-moon.test.js +++ b/test/sun-moon/sun-moon.test.ts @@ -5,10 +5,10 @@ */ import { Celestial } from '../../lib/body/Celestial'; +import { Moon } from '../../lib/body/Moon'; import { Sun } from '../../lib/body/Sun'; -import { Utils } from '../../lib/ootk-core'; +import { Degrees, Meters } from '../../lib/ootk-core'; -const { MoonMath } = Utils; // Use number of milliseconds since epoch instead of local year, month, day, etc for consistency across machines const dateObj = new Date(1661400000000); @@ -17,27 +17,27 @@ describe('Sun and Moon', () => { const d = Sun.julian2date(Sun.date2jSince2000(dateObj)); const c = Sun.raDec(d); - Celestial.getStarAzEl(dateObj, 0, 0, c.ra, c.dec); - Sun.azEl(dateObj, 0, 0); + Celestial.getStarAzEl(dateObj, 0 as Degrees, 0 as Degrees, c.ra, c.dec); + Sun.azEl(dateObj, 0 as Degrees, 0 as Degrees); }); test('Local Solar Time', () => { // Use number of milliseconds since epoch instead of local year, month, day, etc for consistency across machines - const lst = Sun.getSolarTime(new Date(1658807880000), -5, -71); + const lst = Sun.getSolarTime(new Date(1658807880000), -5, -71 as Degrees); expect(lst.toUTCString()).toEqual('Tue, 26 Jul 2022 04:07:49 GMT'); }); - test('MoonMath Unit Tests', () => { - expect(MoonMath.getMoonIllumination(dateObj)).toMatchSnapshot(); + test('Moon Unit Tests', () => { + expect(Moon.getMoonIllumination(dateObj)).toMatchSnapshot(); - MoonMath.getMoonPosition(dateObj, 0, 0); - MoonMath.getMoonTimes(dateObj, 0, 0, true); - MoonMath.getMoonTimes(dateObj, -10, -10, false); + Moon.rae(dateObj, 0 as Degrees, 0 as Degrees); + Moon.getMoonTimes(dateObj, 0 as Degrees, 0 as Degrees, true); + Moon.getMoonTimes(dateObj, -10 as Degrees, -10 as Degrees, false); }); test('getMoonIllumination returns fraction and angle of moons illuminated limb and phase', () => { - const moonIllum = MoonMath.getMoonIllumination(dateObj); + const moonIllum = Moon.getMoonIllumination(dateObj); expect(moonIllum).toMatchSnapshot(); }); @@ -50,7 +50,7 @@ describe('Sun and Moon', () => { describe('Test for #6 fix', () => { test('Test for #6 fix', () => { const date = new Date('2013-03-05UTC'); - const result = (Sun.azEl(date, 50.5, 30.5).az * 180) / Math.PI; + const result = (Sun.azEl(date, 50.5 as Degrees, 30.5 as Degrees).az * 180) / Math.PI; expect(result).toBeCloseTo(36.742354609606814); }); @@ -85,7 +85,7 @@ describe('Test for variety of date/time stamps', () => { const date = new Date(testDateStrings[i]); const testDateDay = date.getDate(); - const times = Sun.getTimes(date, lat, lng); + const times = Sun.getTimes(date, lat as Degrees, lng as Degrees); expect(times.solarNoon.getDate()).toEqual(testDateDay); }); @@ -124,7 +124,7 @@ describe('Suncalc.js tests', () => { }; test('getTimes returns sun phases for the given date and location', () => { - const times = Sun.getTimes(date, lat, lon, 0, true); + const times = Sun.getTimes(date, lat as Degrees, lon as Degrees, 0 as Meters, true); // eslint-disable-next-line guard-for-in for (const i in testTimes) { @@ -133,7 +133,7 @@ describe('Suncalc.js tests', () => { }); test('getTimes adjusts sun phases when additionally given the observer height', () => { - const times = Sun.getTimes(date, lat, lon, alt, true); + const times = Sun.getTimes(date, lat as Degrees, lon as Degrees, alt as Meters, true); // eslint-disable-next-line guard-for-in for (const i in heightTestTimes) { @@ -142,14 +142,14 @@ describe('Suncalc.js tests', () => { }); test('getSunAzEl returns azimuth and altitude for the given time and location', () => { - const sunPos = Sun.azEl(date, lat, lon); + const sunPos = Sun.azEl(date, lat as Degrees, lon as Degrees); expect(sunPos.az).toBeCloseTo(0.6412750628729547); expect(sunPos.el).toBeCloseTo(-0.7000406838781611); }); test('getMoonIllumination returns fraction and angle of moons illuminated limb and phase', () => { - const moonIllum = MoonMath.getMoonIllumination(date); + const moonIllum = Moon.getMoonIllumination(date); expect(moonIllum.fraction).toBeCloseTo(0.4848068202456373); expect(moonIllum.phaseValue).toBeCloseTo(0.7548368838538762); @@ -157,7 +157,7 @@ describe('Suncalc.js tests', () => { }); test('getMoonPosition returns moon position data given time and location', () => { - const moonPos = MoonMath.getMoonPosition(date, lat, lon); + const moonPos = Moon.rae(date, lat as Degrees, lon as Degrees); expect(moonPos.az).toBeCloseTo(2.1631927013459706); expect(moonPos.el).toBeCloseTo(0.014551482243892251); @@ -165,7 +165,7 @@ describe('Suncalc.js tests', () => { }); test('getMoonTimes returns moon rise and set times', () => { - const moonTimes = MoonMath.getMoonTimes(new Date('2013-03-04UTC'), lat, lon, true); + const moonTimes = Moon.getMoonTimes(new Date('2013-03-04UTC'), lat as Degrees, lon as Degrees, true); expect(moonTimes.rise.toUTCString()).toEqual('Mon, 04 Mar 2013 23:54:29 GMT'); expect(moonTimes.set.toUTCString()).toEqual('Mon, 04 Mar 2013 07:47:58 GMT'); @@ -204,7 +204,7 @@ describe('Tests from Hypnos3', () => { }; test('southern hemisphere', () => { - const times = Sun.getTimes(date, lat, lon); + const times = Sun.getTimes(date, lat as Degrees, lon as Degrees); // eslint-disable-next-line guard-for-in for (const i in testTimes) { @@ -213,7 +213,7 @@ describe('Tests from Hypnos3', () => { }); test('getSolarTime returns the solar time', () => { - const solarTime = Sun.getSolarTime(date, -5, -71); + const solarTime = Sun.getSolarTime(date, -5, -71 as Degrees); expect(solarTime.toUTCString()).toEqual('Tue, 05 Mar 2013 00:03:33 GMT'); }); diff --git a/test/transforms/transforms.json b/test/transforms/transforms.json deleted file mode 100644 index 89cf020..0000000 --- a/test/transforms/transforms.json +++ /dev/null @@ -1,287 +0,0 @@ -{ - "validLatitudes": [ - { - "radians": 0, - "degrees": 0 - }, - { - "radians": 1.0471975511965976, - "degrees": 60 - }, - { - "radians": 1.5707963267948966, - "degrees": 90 - }, - { - "radians": -1.0471975511965976, - "degrees": -60 - }, - { - "radians": -1.5707963267948966, - "degrees": -90 - } - ], - "validLongitudes": [ - { - "radians": 0, - "degrees": 0 - }, - { - "radians": 1.0471975511965976, - "degrees": 60 - }, - { - "radians": 2.356194490192345, - "degrees": 135 - }, - { - "radians": 3.141592653589793, - "degrees": 180 - }, - { - "radians": -1.0471975511965976, - "degrees": -60 - }, - { - "radians": -2.356194490192345, - "degrees": -135 - }, - { - "radians": -3.141592653589793, - "degrees": -180 - } - ], - "validGeodeticToEcf": [ - { - "lla": { - "lon": 0, - "lat": 0, - "alt": 0 - }, - "ecf": { - "x": 6378.137, - "y": 0, - "z": 0 - } - }, - { - "lla": { - "lon": 380, - "lat": 40, - "alt": 1 - }, - "ecf": { - "x": 4224.936136182726, - "y": -564.0109140102323, - "z": 4730.161371331031 - } - }, - { - "lla": { - "lon": -400, - "lat": 80, - "alt": 2 - }, - "ecf": { - "x": 371.1876676842122, - "y": -601.2811231618838, - "z": -6319.632371290254 - } - } - ], - "validEciToGeodetic": [ - { - "eci": { - "x": 6400, - "y": 100, - "z": 0 - }, - "gmst": 0, - "lla": { - "lon": 0.015623, - "lat": 0, - "alt": 22.6442 - } - }, - { - "eci": { - "x": 5000, - "y": 45000, - "z": 0 - }, - "gmst": 10, - "lla": { - "lon": -2.256675587199412, - "lat": 0, - "alt": 38898.78869068708 - } - }, - { - "eci": { - "x": 5000, - "y": 45000, - "z": 0 - }, - "gmst": -10, - "lla": { - "lon": -1.1062315087381709, - "lat": 0, - "alt": 38898.78869068708 - } - } - ], - "validEciToEcf": [ - { - "eci": { - "x": 6400, - "y": 0, - "z": 0 - }, - "gmst": 10, - "ecf": { - "x": -5370.057786089295, - "y": 3481.7351096919665, - "z": 0 - } - }, - { - "eci": { - "x": 8000, - "y": 0, - "z": 8000 - }, - "gmst": 10, - "ecf": { - "x": -6712.572232611619, - "y": 4352.168887114958, - "z": 8000 - } - }, - { - "eci": { - "x": 8000, - "y": -4000, - "z": -8000 - }, - "gmst": -30, - "ecf": { - "x": -2718.114897270775, - "y": -8521.25879229323, - "z": -8000 - } - } - ], - "validEcfToEci": [ - { - "ecf": { - "x": 5555, - "y": 3000, - "z": 0 - }, - "gmst": 100, - "eci": { - "x": 6309.278258887361, - "y": -225.90451950165834, - "z": 0 - } - }, - { - "ecf": { - "x": 12000, - "y": 0, - "z": 9999 - }, - "gmst": 5000, - "eci": { - "x": 1856.0208741689655, - "y": -11855.597265201322, - "z": 9999 - } - }, - { - "ecf": { - "x": 54321, - "y": 12345, - "z": 12345 - }, - "gmst": 12345, - "eci": { - "x": 18321.41422594596, - "y": -52606.994276059, - "z": 12345 - } - } - ], - "validEcfToLookangles": [ - { - "lla": { - "lon": -71, - "lat": 41, - "alt": 1 - }, - "satelliteEcf": { - "x": 4000, - "y": 7000, - "z": 3000 - }, - "rae": { - "rng": 4612.7279304771755, - "az": 2.769701913047414, - "el": 0.2050152036110117 - } - } - ], - "validRae2Sez": [ - { - "rae": { - "rng": 4612.7279304771755, - "az": 2.769701913047414, - "el": 0.2050152036110117 - }, - "sez": { - "s": 4207.414029689924, - "e": 1641.0595158550045, - "z": 939.0685857776206 - } - } - ], - "validRae2Ecf": [ - { - "rae": { - "rng": 4612.7279304771755, - "az": 158.6922301314627, - "el": 11.74650590326194 - }, - "lla": { - "lon": -71, - "lat": 41, - "alt": 1 - }, - "ecf": { - "x": 4000, - "y": 7000, - "z": 3000 - } - } - ], - "invalidLatitudes": [ - { - "radians": 2.0943951023931953, - "degrees": 120 - }, - { - "radians": -2.0943951023931953, - "degrees": -120 - } - ], - "invalidLongitudes": [ - { - "radians": 4.71238898038469, - "degrees": 270 - }, - { - "radians": -4.71238898038469, - "degrees": -270 - } - ] -} \ No newline at end of file diff --git a/test/transforms/transforms.test.js b/test/transforms/transforms.test.ts similarity index 88% rename from test/transforms/transforms.test.js rename to test/transforms/transforms.test.ts index c71d4ed..6643dc7 100644 --- a/test/transforms/transforms.test.js +++ b/test/transforms/transforms.test.ts @@ -1,9 +1,5 @@ -/** - * @file Tests from js to ensure compatibility - * @since 0.2.0 - */ - import { + Degrees, ecf2eci, ecf2rae, eci2ecf, @@ -12,12 +8,12 @@ import { getDegLon, getRadLat, getRadLon, + Kilometers, lla2ecf, rae2ecf, rae2sez, } from '../../lib/ootk-core'; -import { RAD2DEG } from '../../lib/utils/constants'; -import transformData from './transforms.json'; +import { transformsData } from './transformsData'; const numDigits = 6; @@ -32,7 +28,7 @@ describe('Latitude & longitude conversions', () => { validEcfToLookangles, invalidLatitudes, invalidLongitudes, - } = transformData; + } = transformsData; validLatitudes.forEach((item) => { it(`convert valid latitude value (${item.radians} radians) to degrees`, () => { @@ -66,8 +62,8 @@ describe('Latitude & longitude conversions', () => { it('convert valid ECI coordinates to LLA', () => { const llaCoordinates = eci2lla(item.eci, item.gmst); - expect(llaCoordinates.lon).toBeCloseTo(item.lla.lon * RAD2DEG); - expect(llaCoordinates.lat).toBeCloseTo(item.lla.lat * RAD2DEG); + expect(llaCoordinates.lon).toBeCloseTo(item.lla.lon); + expect(llaCoordinates.lat).toBeCloseTo(item.lla.lat); expect(llaCoordinates.alt).toBeCloseTo(item.lla.alt); }); }); @@ -97,8 +93,8 @@ describe('Latitude & longitude conversions', () => { const raeCoordinates = ecf2rae(item.lla, item.satelliteEcf); expect(raeCoordinates.rng).toBeCloseTo(item.rae.rng, 0); - expect(raeCoordinates.az).toBeCloseTo(item.rae.az * RAD2DEG, 1); - expect(raeCoordinates.el).toBeCloseTo(item.rae.el * RAD2DEG, 1); + expect(raeCoordinates.az).toBeCloseTo(item.rae.az, 1); + expect(raeCoordinates.el).toBeCloseTo(item.rae.el, 1); }); }); @@ -123,7 +119,7 @@ describe('Latitude & longitude conversions', () => { describe('Rae2Sez', () => { it('should convert valid RAE coordinates to SEZ', () => { - const { rae, sez } = transformData.validRae2Sez[0]; + const { rae, sez } = transformsData.validRae2Sez[0]; const sezCoordinates = rae2sez(rae); expect(sezCoordinates.s).toBeCloseTo(sez.s); @@ -141,9 +137,9 @@ describe('Rae2Ecf', () => { z: 4000, }; const lla = { - lon: 0, - lat: 0, - alt: 0, + lon: 0 as Degrees, + lat: 0 as Degrees, + alt: 0 as Kilometers, }; const rae = ecf2rae(lla, ecf); diff --git a/test/transforms/transformsData.ts b/test/transforms/transformsData.ts new file mode 100644 index 0000000..643c16c --- /dev/null +++ b/test/transforms/transformsData.ts @@ -0,0 +1,289 @@ +import { Degrees, EcfVec3, EciVec3, Kilometers, RAD2DEG, Radians } from '../../lib/ootk-core'; + +export const transformsData = { + validLatitudes: [ + { + radians: 0 as Radians, + degrees: 0 as Degrees, + }, + { + radians: 1.0471975511965976 as Radians, + degrees: 60 as Degrees, + }, + { + radians: 1.5707963267948966 as Radians, + degrees: 90 as Degrees, + }, + { + radians: -1.0471975511965976 as Radians, + degrees: -60 as Degrees, + }, + { + radians: -1.5707963267948966 as Radians, + degrees: -90 as Degrees, + }, + ], + validLongitudes: [ + { + radians: 0 as Radians, + degrees: 0 as Degrees, + }, + { + radians: 1.0471975511965976 as Radians, + degrees: 60 as Degrees, + }, + { + radians: 2.356194490192345 as Radians, + degrees: 135 as Degrees, + }, + { + radians: 3.141592653589793 as Radians, + degrees: 180 as Degrees, + }, + { + radians: -1.0471975511965976 as Radians, + degrees: -60 as Degrees, + }, + { + radians: -2.356194490192345 as Radians, + degrees: -135 as Degrees, + }, + { + radians: -3.141592653589793 as Radians, + degrees: -180 as Degrees, + }, + ], + validGeodeticToEcf: [ + { + lla: { + lon: 0 as Degrees, + lat: 0 as Degrees, + alt: 0 as Kilometers, + }, + ecf: { + x: 6378.137 as Kilometers, + y: 0 as Kilometers, + z: 0 as Kilometers, + }, + }, + { + lla: { + lon: 380 as Degrees, + lat: 40 as Degrees, + alt: 1 as Kilometers, + }, + ecf: { + x: 4598.36107377528 as Kilometers, + y: 1673.6665572625757 as Kilometers, + z: 4078.628359764023 as Kilometers, + }, + }, + { + lla: { + lon: -400 as Degrees, + lat: 80 as Degrees, + alt: 2 as Kilometers, + }, + ecf: { + x: 851.4677191220125 as Kilometers, + y: -714.4662490746402 as Kilometers, + z: 6261.512576488877 as Kilometers, + }, + }, + ], + validEciToGeodetic: [ + { + eci: { + x: 6400, + y: 100, + z: 0, + } as EciVec3, + gmst: 0, + lla: { + lon: (0.015623 * RAD2DEG) as Degrees, + lat: (0 * RAD2DEG) as Degrees, + alt: 22.6442 as Kilometers, + }, + }, + { + eci: { + x: 5000, + y: 45000, + z: 0, + } as EciVec3, + gmst: 10, + lla: { + lon: (-2.256675587199412 * RAD2DEG) as Degrees, + lat: (0 * RAD2DEG) as Degrees, + alt: 38898.78869068708 as Kilometers, + }, + }, + { + eci: { + x: 5000, + y: 45000, + z: 0, + } as EciVec3, + gmst: -10, + lla: { + lon: (-1.1062315087381709 * RAD2DEG) as Degrees, + lat: (0 * RAD2DEG) as Degrees, + alt: 38898.78869068708, + }, + }, + ], + validEciToEcf: [ + { + eci: { + x: 6400, + y: 0, + z: 0, + }, + gmst: 10, + ecf: { + x: -5370.057786089295, + y: 3481.7351096919665, + z: 0, + }, + }, + { + eci: { + x: 8000, + y: 0, + z: 8000, + }, + gmst: 10, + ecf: { + x: -6712.572232611619, + y: 4352.168887114958, + z: 8000, + }, + }, + { + eci: { + x: 8000, + y: -4000, + z: -8000, + }, + gmst: -30, + ecf: { + x: -2718.114897270775, + y: -8521.25879229323, + z: -8000, + }, + }, + ], + validEcfToEci: [ + { + ecf: { + x: 5555, + y: 3000, + z: 0, + }, + gmst: 100, + eci: { + x: 6309.278258887361, + y: -225.90451950165834, + z: 0, + }, + }, + { + ecf: { + x: 12000, + y: 0, + z: 9999, + }, + gmst: 5000, + eci: { + x: 1856.0208741689655, + y: -11855.597265201322, + z: 9999, + }, + }, + { + ecf: { + x: 54321, + y: 12345, + z: 12345, + }, + gmst: 12345, + eci: { + x: 18321.41422594596, + y: -52606.994276059, + z: 12345, + }, + }, + ], + validEcfToLookangles: [ + { + lla: { + lat: (0.7287584767123405 * RAD2DEG) as Degrees, + lon: (-1.2311404365114507 * RAD2DEG) as Degrees, + alt: 0.060966 as Kilometers, + }, + satelliteEcf: { + x: 1838.5578358534067, + y: -4971.972919387344, + z: 4466.101983887215, + } as EcfVec3, + rae: { + az: 156.45929778422533 as Degrees, + el: 70.9805298041814 as Degrees, + rng: 591.9168938970199 as Kilometers, + }, + }, + ], + validRae2Sez: [ + { + rae: { + rng: 4612.7279304771755 as Kilometers, + az: 2.769701913047414 as Radians, + el: 0.2050152036110117 as Radians, + }, + sez: { + s: 4207.414029689924 as Kilometers, + e: 1641.0595158550045 as Kilometers, + z: 939.0685857776206 as Kilometers, + }, + }, + ], + validRae2Ecf: [ + { + rae: { + rng: 4612.7279304771755 as Kilometers, + az: 158.6922301314627 as Degrees, + el: 11.74650590326194 as Degrees, + }, + lla: { + lon: -71 as Degrees, + lat: 41 as Degrees, + alt: 1 as Kilometers, + }, + ecf: { + x: 4000 as Kilometers, + y: 7000 as Kilometers, + z: 3000 as Kilometers, + }, + }, + ], + invalidLatitudes: [ + { + radians: 2.0943951023931953 as Radians, + degrees: 120 as Degrees, + }, + { + radians: -2.0943951023931953 as Radians, + degrees: -120 as Degrees, + }, + ], + invalidLongitudes: [ + { + radians: 4.71238898038469 as Radians, + degrees: 270 as Degrees, + }, + { + radians: -4.71238898038469 as Radians, + degrees: -270 as Degrees, + }, + ], +}; diff --git a/test/utils/utils.test.js b/test/utils/utils.test.ts similarity index 70% rename from test/utils/utils.test.js rename to test/utils/utils.test.ts index acacd1a..e0dacb7 100644 --- a/test/utils/utils.test.js +++ b/test/utils/utils.test.ts @@ -3,8 +3,8 @@ * @since 1.0.0-alpha3 */ -import { Utils } from '../../lib/ootk-core'; // eslint-disable-line -import { getDayOfYear } from '../../lib/utils/functions'; +import { EciVec3, Kilometers, linearDistance, Utils, Vec3 } from '../../lib/ootk-core'; // eslint-disable-line +import { dopplerFactor, getDayOfYear } from '../../lib/utils/functions'; const numDigits = 8; @@ -14,86 +14,86 @@ const sincos45deg = Math.sqrt(2) / 2; describe('Doppler factor', () => { it('without observer movement', () => { // North Pole - const observerEcf = { + const observerEci = { x: 0, y: 0, z: earthRadius, - }; - const positionEcf = { + } as EciVec3; + const positionEci = { x: 0, y: 0, z: earthRadius + 500, - }; + } as EciVec3; // Escape velocity - const velocityEcf = { + const velocityEci = { x: 7.91, y: 0, z: 0, - }; - const dopFactor = Utils.dopplerFactor(observerEcf, positionEcf, velocityEcf); + } as EciVec3; + const dopFactor = dopplerFactor(observerEci, positionEci, velocityEci); expect(dopFactor).toBeCloseTo(1, numDigits); }); it('movement of observer is not affected', () => { - const observerEcf = { + const observerEci = { x: earthRadius, y: 0, z: 0, - }; - const positionEcf = { + } as EciVec3; + const positionEci = { x: earthRadius + 500, y: 0, z: 0, - }; - const velocityEcf = { + } as EciVec3; + const velocityEci = { x: 0, y: 7.91, z: 0, - }; - const dopFactor = Utils.dopplerFactor(observerEcf, positionEcf, velocityEcf); + } as EciVec3; + const dopFactor = dopplerFactor(observerEci, positionEci, velocityEci); expect(dopFactor).toBeCloseTo(1, numDigits); }); it('special case', () => { - const observerEcf = { + const observerEci = { x: earthRadius, y: 0, z: 0, - }; - const positionEcf = { + } as EciVec3; + const positionEci = { x: (earthRadius + 500) * sincos45deg, // z*sin(45) y: (earthRadius + 500) * sincos45deg, // z*cos(45) z: 0, - }; - const velocityEcf = { + } as EciVec3; + const velocityEci = { x: 7.91 * sincos45deg, y: 7.91 * sincos45deg, z: 0, - }; - const dopFactor = Utils.dopplerFactor(observerEcf, positionEcf, velocityEcf); + } as EciVec3; + const dopFactor = dopplerFactor(observerEci, positionEci, velocityEci); expect(dopFactor).toBeCloseTo(0.9999892152210788, numDigits); }); test('if negative range rate works', () => { - const observerEcf = { + const observerEci = { x: earthRadius, y: 0, z: 0, - }; - const positionEcf = { + } as EciVec3; + const positionEci = { x: (earthRadius + 500) * sincos45deg, // z*sin(45) y: (earthRadius + 500) * sincos45deg, // z*cos(45) z: 0, - }; - const velocityEcf = { + } as EciVec3; + const velocityEci = { x: -7.91 * sincos45deg, y: -7.91 * sincos45deg, z: 0, - }; - const dopFactor = Utils.dopplerFactor(observerEcf, positionEcf, velocityEcf); + } as EciVec3; + const dopFactor = dopplerFactor(observerEci, positionEci, velocityEci); expect(dopFactor).toBeCloseTo(1.000013747277977, numDigits); }); @@ -101,8 +101,18 @@ describe('Doppler factor', () => { describe('Distance function', () => { test('if distance calculation is correct', () => { - expect(Utils.distance({ x: 1000, y: 1000, z: 1000 }, { x: 1000, y: 1000, z: 1000 })).toEqual(0); - expect(Utils.distance({ x: 1000, y: 1000, z: 1000 }, { x: 1000, y: 1000, z: 1100 })).toEqual(100); + expect( + linearDistance( + { x: 1000, y: 1000, z: 1000 } as Vec3, + { x: 1000, y: 1000, z: 1000 } as Vec3, + ), + ).toEqual(0); + expect( + linearDistance( + { x: 1000, y: 1000, z: 1000 } as Vec3, + { x: 1000, y: 1000, z: 1100 } as Vec3, + ), + ).toEqual(100); }); });