orbit-studio / src /modules /simulation /propagator.test.ts
moncefem's picture
Deploy Orbit Studio propagator
9f21d0a
Raw
History Blame Contribute Delete
1.76 kB
import { describe, expect, it } from "vitest";
import { EARTH, initialState, propagate, type PropagationRequest } from "./propagator";
const request = (): PropagationRequest => ({
altitudeKm: 500,
eccentricity: 0,
inclinationDeg: 51.6,
raanDeg: 0,
argumentOfPeriapsisDeg: 0,
trueAnomalyDeg: 0,
durationSeconds: 5_600,
sampleCount: 121,
massKg: 1_000,
areaM2: 10,
dragCoefficient: 2.2,
reflectivityCoefficient: 1.2,
forces: { gravity: true, j2: false, drag: false, moon: false, sun: false, solarRadiationPressure: false },
});
function specificEnergy(state: readonly number[]): number {
const radius = Math.hypot(state[0]!, state[1]!, state[2]!);
const speed = Math.hypot(state[3]!, state[4]!, state[5]!);
return speed ** 2 / 2 - EARTH.mu / radius;
}
describe("custom propagation", () => {
it("creates the expected circular LEO state", () => {
const state = initialState(request());
expect(Math.hypot(state[0], state[1], state[2]) - EARTH.radius).toBeCloseTo(500_000, -1);
expect(Math.hypot(state[3], state[4], state[5])).toBeGreaterThan(7_500);
});
it("keeps two-body specific energy bounded through one orbit", () => {
const samples = propagate(request());
const energies = samples.map(({ state }) => specificEnergy(state));
expect(Math.max(...energies) - Math.min(...energies)).toBeLessThan(25);
});
it("accepts third-body, drag, and radiation-pressure force configurations", () => {
const samples = propagate({ ...request(), durationSeconds: 600, sampleCount: 31, forces: { gravity: true, j2: true, drag: true, moon: true, sun: true, solarRadiationPressure: true } });
expect(samples).toHaveLength(31);
expect(samples.at(-1)?.elapsedSeconds).toBeCloseTo(600);
});
});