ootk
Version:
Orbital Object Toolkit including Multiple Propagators, Initial Orbit Determination, and Maneuver Calculations.
110 lines (97 loc) • 3.83 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 { Kilometers, KilometersPerSecond, PositionVelocity, Seconds, Vector3D } from '../main.js';
// / Chebyshev compressed ephemeris coefficients.
export class ChebyshevCoefficients {
cxd_: Float64Array;
cyd_: Float64Array;
czd_: Float64Array;
// / Create a new [ChebyshevCoefficients] object.
constructor(
public a: Seconds,
public b: Seconds,
private readonly cx_: Float64Array,
private readonly cy_: Float64Array,
private readonly cz_: Float64Array,
) {
this.cxd_ = ChebyshevCoefficients._derivative(a, b, cx_);
this.cyd_ = ChebyshevCoefficients._derivative(a, b, cy_);
this.czd_ = ChebyshevCoefficients._derivative(a, b, cz_);
}
/**
* Calculates the derivative of a polynomial represented by Chebyshev coefficients.
* @param a - The lower bound of the polynomial's domain.
* @param b - The upper bound of the polynomial's domain.
* @param c - The Chebyshev coefficients of the polynomial.
* @returns The derivative of the polynomial as an array of coefficients.
*/
private static _derivative(a: number, b: number, c: Float64Array): Float64Array {
const n = c.length;
const d = new Float64Array(n);
d[n - 1] = 0;
d[n - 2] = 2 * (n - 1) * c[n - 1];
for (let k = n - 3; k >= 0; k--) {
d[k] = d[k + 2] + 2 * (k + 1) * c[k + 1];
}
for (let k = 0; k < n; k++) {
d[k] *= 2 / (b - a);
}
return d;
}
// / Return the size _(bytes)_ of this coefficient set's cached data.
get sizeBytes(): number {
return (64 * 2 + 64 * 3 * this.cx_.length) / 8;
}
/**
* Evaluates the Chebyshev polynomial represented by the given coefficients at the specified value.
* @param c - The coefficients of the Chebyshev polynomial.
* @param t - The value at which to evaluate the polynomial _(POSIX seconds)_.
* @returns The result of evaluating the polynomial at the specified value.
*/
evaluate(c: Float64Array, t: number): number {
const n = c.length;
const x = (t - 0.5 * (this.b + this.a)) / (0.5 * (this.b - this.a));
const alpha = 2 * x;
const beta = -1;
let y1 = 0.0;
let y2 = 0.0;
for (let k = n - 1; k >= 1; k--) {
const tmp = y1;
y1 = alpha * y1 + beta * y2 + c[k];
y2 = tmp;
}
return x * y1 - y2 + 0.5 * c[0];
}
/**
* Interpolates the position and velocity at a given time (km, km/s).
* @param t - The time value to interpolate at _(POSIX seconds)_.
* @returns An object containing the interpolated position and velocity.
*/
interpolate(t: number): PositionVelocity {
const pos = new Vector3D(
this.evaluate(this.cx_, t) as Kilometers,
this.evaluate(this.cy_, t) as Kilometers,
this.evaluate(this.cz_, t) as Kilometers,
);
const vel = new Vector3D(
this.evaluate(this.cxd_, t) as KilometersPerSecond,
this.evaluate(this.cyd_, t) as KilometersPerSecond,
this.evaluate(this.czd_, t) as KilometersPerSecond,
);
return { position: pos, velocity: vel };
}
}