Skip to content

Commit

Permalink
fix: 🐛 fix calculation of doppler factor
Browse files Browse the repository at this point in the history
  • Loading branch information
thkruz committed Jan 14, 2024
1 parent 7f2b8ac commit 4a0ef1e
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 83 deletions.
12 changes: 12 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@
"color": "terminal.ansiBlue"
}
},
{
"label": "Clean Dist Folder",
"command": "npm run clean",
"type": "shell",
"args": [],
"isBackground": true,
"problemMatcher": [],
"icon": {
"id": "trash",
"color": "terminal.ansiYellow"
}
},
{
"label": "Test with Jest",
"command": "npm test",
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"module": "dist/main.js",
"description": "Orbital Object Toolkit. A modern typed replacement for satellite.js including SGP4 propagation, TLE parsing, Sun and Moon calculations, and more.",
"scripts": {
"build": "node ./scripts/cleanup.mjs && npx tsc -p tsconfig.build.json -m esnext",
"build": "npm run clean && npx tsc -p tsconfig.build.json -m esnext",
"clean": "node ./scripts/cleanup.mjs",
"lint": "npx eslint src",
"lint:fix": "npx eslint src --fix",
"test": "jest",
Expand Down Expand Up @@ -50,4 +51,4 @@
"typescript": "^4.9.5"
},
"homepage": "https://github.com/thkruz/ootk-core"
}
}
5 changes: 5 additions & 0 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ export const ttasec2rad = (asec2rad / 10000.0) as Radians;
*/
export const masec2rad = (asec2rad / 1000.0) as Radians;

/**
* The angular velocity of the Earth in radians per second.
*/
export const angularVelocityOfEarth = 7.292115e-5;

/**
* Astronomical unit in kilometers.
*/
Expand Down
32 changes: 12 additions & 20 deletions src/utils/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
/* eslint-disable func-style */
import { AngularDiameterMethod } from '../enums/AngularDiameterMethod';
import { AngularDistanceMethod } from '../enums/AngularDistanceMethod';
import { DifferentiableFunction, EciVec3, Radians, SpaceObjectType } from '../types/types';
import { DifferentiableFunction, EcfVec3, Kilometers, Radians, SpaceObjectType } from '../types/types';
import { angularVelocityOfEarth, cKmPerSec } from './constants';

/**
* Calculates the factorial of a given number.
Expand Down Expand Up @@ -630,33 +631,24 @@ export const spaceObjType2Str = (spaceObjType: SpaceObjectType): string =>
* @param velocity - The velocity vector of the source.
* @returns The calculated Doppler factor.
*/
export const dopplerFactor = (location: EciVec3, position: EciVec3, velocity: EciVec3): number => {
const mfactor = 7.292115e-5;
const c = 299792.458; // Speed of light in km/s

const range = <EciVec3>{
export const dopplerFactor = (
location: EcfVec3<Kilometers>,
position: EcfVec3<Kilometers>,
velocity: EcfVec3<Kilometers>,
): number => {
const range = <EcfVec3>{
x: position.x - location.x,
y: position.y - location.y,
z: position.z - location.z,
};
const distance = Math.sqrt(range.x ** 2 + range.y ** 2 + range.z ** 2);

const rangeVel = <EciVec3>{
x: velocity.x + mfactor * location.y,
y: velocity.y - mfactor * location.x,
const rangeVel = <EcfVec3>{
x: velocity.x + angularVelocityOfEarth * location.y,
y: velocity.y - angularVelocityOfEarth * location.x,
z: velocity.z,
};

const rangeRate = (range.x * rangeVel.x + range.y * rangeVel.y + range.z * rangeVel.z) / distance;
let dopplerFactor = 0;

if (rangeRate < 0) {
dopplerFactor = 1 + (rangeRate / c) * sign(rangeRate);
}

if (rangeRate >= 0) {
dopplerFactor = 1 - (rangeRate / c) * sign(rangeRate);
}
const dopplerFactor = 1 - rangeRate / cKmPerSec;

return dopplerFactor;
};
Expand Down
5 changes: 5 additions & 0 deletions test/utils/__snapshots__/utils.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Doppler factor calculates earth rotation the same as before #1 1`] = `1.000001479636888`;

exports[`Doppler factor calculates earth rotation the same as before #2 1`] = `1`;
142 changes: 81 additions & 61 deletions test/utils/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,96 +1,116 @@
import { EciVec3, Kilometers, linearDistance, Vec3 } from '../../src/main';
import { EcfVec3, Kilometers, linearDistance, RADIUS_OF_EARTH, Vec3 } from '../../src/main';
import { dopplerFactor, getDayOfYear } from '../../src/utils/functions';

const numDigits = 8;

const earthRadius = 6378.137;
const sincos45deg = Math.sqrt(2) / 2;

describe('Doppler factor', () => {
it('without observer movement', () => {
it('works without observer movement and object moving away', () => {
// North Pole
const observerEci = {
const observerEcf = {
x: 0,
y: 0,
z: earthRadius,
} as EciVec3;
const positionEci = {
z: RADIUS_OF_EARTH,
} as EcfVec3;
const positionEcf = {
x: 0,
y: 0,
z: earthRadius + 500,
} as EciVec3;
// Escape velocity
const velocityEci = {
x: 7.91,
z: RADIUS_OF_EARTH + 500,
} as EcfVec3;
const velocityEcf = {
x: 0,
y: 0,
z: 0,
} as EciVec3;
const dopFactor = dopplerFactor(observerEci, positionEci, velocityEci);
z: 1,
} as EcfVec3;
const dopFactor = dopplerFactor(observerEcf, positionEcf, velocityEcf);

expect(dopFactor).toBeCloseTo(1, numDigits);
expect(dopFactor).toBeLessThan(1);
});

it('movement of observer is not affected', () => {
const observerEci = {
x: earthRadius,
it('works without observer movement and object moving towards', () => {
// North Pole
const observerEcf = {
x: 0,
y: 0,
z: 0,
} as EciVec3;
const positionEci = {
x: earthRadius + 500,
z: RADIUS_OF_EARTH,
} as EcfVec3;
const positionEcf = {
x: 0,
y: 0,
z: 0,
} as EciVec3;
const velocityEci = {
z: RADIUS_OF_EARTH + 500,
} as EcfVec3;
const velocityEcf = {
x: 0,
y: 7.91,
z: 0,
} as EciVec3;
const dopFactor = dopplerFactor(observerEci, positionEci, velocityEci);
y: 0,
z: -1,
} as EcfVec3;
const dopFactor = dopplerFactor(observerEcf, positionEcf, velocityEcf);

expect(dopFactor).toBeCloseTo(1, numDigits);
expect(dopFactor).toBeGreaterThan(1);
});

it('special case', () => {
const observerEci = {
x: earthRadius,
it('calculates earth rotation the same as before #1', () => {
const observerEcf = {
x: RADIUS_OF_EARTH,
y: 0,
z: 0,
} as EciVec3;
const positionEci = {
x: (earthRadius + 500) * sincos45deg, // z*sin(45)
y: (earthRadius + 500) * sincos45deg, // z*cos(45)
} as EcfVec3;
const positionEcf = {
x: (RADIUS_OF_EARTH + 500) * sincos45deg, // z*sin(45)
y: (RADIUS_OF_EARTH + 500) * sincos45deg, // z*cos(45)
z: 0,
} as EciVec3;
const velocityEci = {
x: 7.91 * sincos45deg,
y: 7.91 * sincos45deg,
} as EcfVec3;
const velocityEcf = {
x: 0,
y: 0,
z: 0,
} as EciVec3;
const dopFactor = dopplerFactor(observerEci, positionEci, velocityEci);
} as EcfVec3;
const dopFactor = dopplerFactor(observerEcf, positionEcf, velocityEcf);

expect(dopFactor).toBeCloseTo(0.9999892152210788, numDigits);
expect(dopFactor).toMatchSnapshot();
});

test('if negative range rate works', () => {
const observerEci = {
x: earthRadius,
it('works without observer movement and a stationary object', () => {
// North Pole
const observerEcf = {
x: 0,
y: 0,
z: RADIUS_OF_EARTH,
} as EcfVec3;
const positionEcf = {
x: 0,
y: 0,
z: RADIUS_OF_EARTH + 500,
} as EcfVec3;
const velocityEcf = {
x: 0,
y: 0,
z: 0,
} as EciVec3;
const positionEci = {
x: (earthRadius + 500) * sincos45deg, // z*sin(45)
y: (earthRadius + 500) * sincos45deg, // z*cos(45)
} as EcfVec3;
const dopFactor = dopplerFactor(observerEcf, positionEcf, velocityEcf);

expect(dopFactor).toEqual(1);
});

it('calculates earth rotation the same as before #2', () => {
// North Pole
const observerEcf = {
x: RADIUS_OF_EARTH,
y: 0,
z: 0,
} as EciVec3;
const velocityEci = {
x: -7.91 * sincos45deg,
y: -7.91 * sincos45deg,
} as EcfVec3;
const positionEcf = {
x: RADIUS_OF_EARTH + 500,
y: 0,
z: 0,
} as EciVec3;
const dopFactor = dopplerFactor(observerEci, positionEci, velocityEci);
} as EcfVec3;
const velocityEcf = {
x: 0,
y: 0,
z: 1,
} as EcfVec3;
const dopFactor = dopplerFactor(observerEcf, positionEcf, velocityEcf);

expect(dopFactor).toBeCloseTo(1.000013747277977, numDigits);
expect(dopFactor).toMatchSnapshot();
});
});

Expand Down

0 comments on commit 4a0ef1e

Please sign in to comment.