Skip to content

Commit

Permalink
feat(ootk-transforms): added Transforms and Utils modules
Browse files Browse the repository at this point in the history
  • Loading branch information
thkruz committed Jan 13, 2021
1 parent 13ef127 commit 122ed43
Show file tree
Hide file tree
Showing 16 changed files with 616 additions and 67 deletions.
8 changes: 7 additions & 1 deletion scripts/jest-std.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@
"verbose": true,
"silent": true,
"rootDir": "../",
"testPathIgnorePatterns": ["/node_modules/", "/test/performance/"]
"testPathIgnorePatterns": ["/node_modules/", "/test/performance/"],
"moduleNameMapper": {
"@lib(.*)$": "<rootDir>/lib/$1",
"@dist(.*)$": "<rootDir>/dist/$1",
"@src(.*)$": "<rootDir>/src/$1",
"@test(.*)$": "<rootDir>/test/$1"
}
}
127 changes: 68 additions & 59 deletions src/ootk-transforms.es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* with satellites and other orbital objects.
*
* @file The Transforms module contains a collection of conversions not contained
* in the original SGP4 library such as ECI to ECF and ECF to RAE. This almost
* entirely based on the functions in satellite.js
* in the original SGP4 library such as ECI to ECF and ECF to RAE. This was based
* on some of the functions in satellite.js.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand All @@ -29,45 +29,14 @@
const PI = Math.PI;
const TAU = PI * 2; //https://tauday.com/tau-manifesto

type vec3K = {
x: number;
y: number;
z: number;
};

class Transforms {
static dopplerFactor(location: vec3K, position: vec3K, velocity: vec3K): number {
const mfactor = 7.292115e-5;
const c = 299792.458; // Speed of light in km/s

const range = {
x: position.x - location.x,
y: position.y - location.y,
z: position.z - location.z,
w: 0,
};
range.w = Math.sqrt(range.x ** 2 + range.y ** 2 + range.z ** 2);

const rangeVel = {
x: velocity.x + mfactor * location.y,
y: velocity.y - mfactor * location.x,
z: velocity.z,
};

const sign = (value) => (value >= 0 ? 1 : -1);

const rangeRate =
(range.x * rangeVel.x + range.y * rangeVel.y + range.z * rangeVel.z) / range.w;

return 1 + (rangeRate / c) * sign(rangeRate);
}

static rad2deg(radians: number): number {
return radians * 180 / PI;
return (radians * 180) / PI;
}

static deg2rad(degrees: number): number {
return degrees * PI / 180.0;
return (degrees * PI) / 180.0;
}

static getDegLat(radians: number): number {
Expand Down Expand Up @@ -213,7 +182,7 @@ class Transforms {
alt: number;
},
ecf: { x: number; y: number; z: number },
): { topS: number; topE: number; topZ: number } {
): { s: number; e: number; z: number } {
// http://www.celestrak.com/columns/v02n02/
// TS Kelso's method, except I'm using ECF frame
// and he uses ECI.
Expand All @@ -227,37 +196,32 @@ class Transforms {
const rz = ecf.z - observerEcf.z;

// top is short for topocentric
const topS =
Math.sin(lat) * Math.cos(lon) * rx +
Math.sin(lat) * Math.sin(lon) * ry -
Math.cos(lat) * rz;
const south =
Math.sin(lat) * Math.cos(lon) * rx + Math.sin(lat) * Math.sin(lon) * ry - Math.cos(lat) * rz;

const topE = -Math.sin(lon) * rx + Math.cos(lon) * ry;
const east = -Math.sin(lon) * rx + Math.cos(lon) * ry;

const topZ =
Math.cos(lat) * Math.cos(lon) * rx +
Math.cos(lat) * Math.sin(lon) * ry +
Math.sin(lat) * rz;
const zenith =
Math.cos(lat) * Math.cos(lon) * rx + Math.cos(lat) * Math.sin(lon) * ry + Math.sin(lat) * rz;

return { topS, topE, topZ };
return { s: south, e: east, z: zenith };
}

/**
* @param {Object} tc Containing SEZ coordinates
* @param {Number} tc.topS Positive horizontal vector S due south.
* @param {Number} tc.topE Positive horizontal vector E due east.
* @param {Number} tc.topZ Vector Z normal to the surface of the earth (up).
* @param {Object} sez Containing SEZ coordinates
* @param {Number} sez.s Positive horizontal vector S due south.
* @param {Number} sez.e Positive horizontal vector E due east.
* @param {Number} sez.z Vector Z normal to the surface of the earth (up).
* @returns {Object} Rng, Az, El array
*/
static sez2lla(tc: {
topS: number;
topE: number;
topZ: number;
static sez2rae(sez: {
s: number;
e: number;
z: number;
}): { rng: number; az: number; el: number } {
const { topS, topE, topZ } = tc;
const rng = Math.sqrt(topS * topS + topE * topE + topZ * topZ);
const el = Math.asin(topZ / rng);
const az = Math.atan2(-topE, topS) + PI;
const rng = Math.sqrt(sez.s * sez.s + sez.e * sez.e + sez.z * sez.z);
const el = Math.asin(sez.z / rng);
const az = Math.atan2(-sez.e, sez.s) + PI;

return {
rng, // km
Expand All @@ -275,7 +239,52 @@ class Transforms {
ecf: { x: number; y: number; z: number },
): { rng: number; az: number; el: number } {
const sezCoords = Transforms.lla2sez(lla, ecf);
return Transforms.sez2lla(sezCoords);
return Transforms.sez2rae(sezCoords);
}

static rae2sez(rae: {
rng: number;
az: number;
el: number;
}): {
s: number;
e: number;
z: number;
} {
// az,el,range to sez convertion
const south = -rae.rng * Math.cos(rae.el) * Math.cos(rae.az);
const east = rae.rng * Math.cos(rae.el) * Math.sin(rae.az);
const zenith = rae.rng * Math.sin(rae.el);

return {
s: south,
e: east,
z: zenith,
};
}

static rae2ecf(
rae: { rng: number; az: number; el: number },
lla: {
lat: number;
lon: number;
alt: number;
},
): { x: number; y: number; z: number } {
const obsEcf = Transforms.lla2ecf(lla);
const sez = Transforms.rae2sez(rae);

// some needed calculations
const slat = Math.sin(lla.lat);
const slon = Math.sin(lla.lon);
const clat = Math.cos(lla.lat);
const clon = Math.cos(lla.lon);

const x = slat * clon * sez.s + -slon * sez.e + clat * clon * sez.z + obsEcf.x;
const y = slat * slon * sez.s + clon * sez.e + clat * slon * sez.z + obsEcf.y;
const z = -clat * sez.s + slat * sez.z + obsEcf.z;

return { x: x, y: y, z: z };
}
}

Expand Down
65 changes: 65 additions & 0 deletions src/ootk-utils.es.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* @author Theodore Kruczek.
* @description Orbital Object ToolKit (OOTK) is a collection of tools for working
* with satellites and other orbital objects.
*
* @file The Utils module.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

type vec3K = {
x: number;
y: number;
z: number;
};

class Utils {
static distance(pos1: vec3K, pos2: vec3K): number {
return Math.sqrt((pos1.x - pos2.x) ** 2 + (pos1.y - pos2.y) ** 2 + (pos1.z - pos2.z) ** 2);
}

static dopplerFactor(location: vec3K, position: vec3K, velocity: vec3K): number {
const mfactor = 7.292115e-5;
const c = 299792.458; // Speed of light in km/s

const range = {
x: position.x - location.x,
y: position.y - location.y,
z: position.z - location.z,
w: 0,
};
range.w = Math.sqrt(range.x ** 2 + range.y ** 2 + range.z ** 2);

const rangeVel = {
x: velocity.x + mfactor * location.y,
y: velocity.y - mfactor * location.x,
z: velocity.z,
};

const sign = (value) => (value >= 0 ? 1 : -1);

const rangeRate =
(range.x * rangeVel.x + range.y * rangeVel.y + range.z * rangeVel.z) / range.w;

return 1 + (rangeRate / c) * sign(rangeRate);
}
}

export { Utils };
4 changes: 2 additions & 2 deletions test/legacy/ext.test.js → test/sgp4/legacy/ext.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
* @since 0.2.0
*/

import { compareVectors } from '../lib/compareVectors';
import { Sgp4 } from '../../lib/ootk-sgp4.es.js'; // eslint-disable-line
import { compareVectors } from '@test/lib/compareVectors';
import { Sgp4 } from '@lib/ootk-sgp4.es.js'; // eslint-disable-line

describe.skip('Julian date / time', () => {
let now;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @since 0.2.0
*/

import { Sgp4 } from '../../lib/ootk-sgp4.es.js'; // eslint-disable-line
import { Sgp4 } from '@lib/ootk-sgp4.es.js'; // eslint-disable-line

// wgs84 constants
const mu = 398600.8; // in km3 / s2
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion test/legacy/io.test.js → test/sgp4/legacy/io.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import badTleData from './io.json';
import { Sgp4 } from '../../lib/ootk-sgp4.es.js'; // eslint-disable-line
import { Sgp4 } from '@lib/ootk-sgp4.es.js'; // eslint-disable-line

describe('Twoline', () => {
it('twoline to satellite record', () => {
Expand Down
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions test/rsr/rsr3.test.js → test/sgp4/rsr/rsr3.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
* sgp4Data is from https://www.celestrak.com/publications/AIAA/2006-6753/AIAA-2006-6753-Rev1.pdf
* Only using the first and last state vectors for verification
*/
import { Sgp4 } from '../../lib/ootk-sgp4.es.js';
import { compareVectors } from '../lib/compareVectors';
import { Sgp4 } from '@lib/ootk-sgp4.es.js';
import { compareVectors } from '@test/lib/compareVectors';
import sgp4Data from './rsr3.json';
import sgp4FailData from './rsr3-fail.json';

Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* @since 0.2.0
*/

import { Sgp4 } from '../lib/ootk-sgp4.es.js';
import { Sgp4 } from '@lib/ootk-sgp4.es.js';
import sgp4Data from './sgp4-full-cov.json';
import sgp4FailData from './sgp4-full-cov-fail.json';

Expand Down
Loading

0 comments on commit 122ed43

Please sign in to comment.