ootk
Version:
Orbital Object Toolkit including Multiple Propagators, Initial Orbit Determination, and Maneuver Calculations.
97 lines (81 loc) • 3.39 kB
text/typescript
/**
* @author @thkruz Theodore Kruczek
* @license AGPL-3.0-or-later
* @copyright (c) 2025 Kruczek Labs LLC
*
* Orbital Object ToolKit is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* Orbital Object ToolKit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with
* Orbital Object ToolKit. If not, see <http://www.gnu.org/licenses/>.
*/
import { EpochUTC, Seconds, Vector3D } from '../main.js';
import { StateInterpolator } from '../interpolator/StateInterpolator.js';
import { ChebyshevCoefficients } from './../interpolator/ChebyshevCoefficients.js';
import { ChebyshevInterpolator } from './../interpolator/ChebyshevInterpolator.js';
// / Ephemeris compressor.
export class ChebyshevCompressor {
// / Create a new [ChebyshevCompressor] object from an [Interpolator].
constructor(private readonly interpolator_: StateInterpolator) {
// Do nothing.
}
// / Return the cosine of π times [x].
private static _cosPi(x: number): number {
return Math.cos(Math.PI * x);
}
private _fitCoefficient(j: number, n: number, a: number, b: number): Vector3D {
let sumX = 0.0;
let sumY = 0.0;
let sumZ = 0.0;
const h = 0.5;
for (let i = 0; i < n; i++) {
const x = ChebyshevCompressor._cosPi((i + h) / n);
const seconds = x * (h * (b - a)) + h * (b + a) as Seconds;
const state = this.interpolator_.interpolate(new EpochUTC(seconds))!;
const fx = state.position.x;
const fy = state.position.y;
const fz = state.position.z;
const nFac = ChebyshevCompressor._cosPi((j * (i + h)) / n);
sumX += fx * nFac;
sumY += fy * nFac;
sumZ += fz * nFac;
}
return new Vector3D(sumX * (2 / n), sumY * (2 / n), sumZ * (2 / n));
}
private _fitWindow(coeffs: number, a: Seconds, b: Seconds): ChebyshevCoefficients {
const cx = new Float64Array();
const cy = new Float64Array();
const cz = new Float64Array();
for (let j = 0; j < coeffs; j++) {
const result = this._fitCoefficient(j, coeffs, a, b);
cx[j] = result.x;
cy[j] = result.y;
cz[j] = result.z;
}
return new ChebyshevCoefficients(a, b, cx, cy, cz);
}
/**
* Compress this object's interpolater, using the provided coefficients
* per revolution [cpr].
* @param cpr Coefficients per revolution.
* @returns A new [ChebyshevInterpolator] object.
*/
compress(cpr = 21): ChebyshevInterpolator {
const { start, end } = this.interpolator_.window();
const period = this.interpolator_.interpolate(start)!.period;
const coefficients: ChebyshevCoefficients[] = [];
let current = start;
while (current < end) {
const step = Math.min(period, end.posix - current.posix) as Seconds;
const segment = current.roll(step);
coefficients.push(this._fitWindow(cpr, current.posix, segment.posix));
current = segment;
}
return new ChebyshevInterpolator(coefficients);
}
}