ootk-core
Version:
Orbital Object Toolkit. A modern typed replacement for satellite.js including SGP4 propagation, TLE parsing, Sun and Moon calculations, and more.
198 lines • 8.41 kB
JavaScript
/**
* @author Theodore Kruczek.
* @license MIT
* @copyright (c) 2022-2025 Theodore Kruczek 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.
*/
import { angularDiameter, AngularDiameterMethod, asec2rad, DataHandler, DEG2RAD, earthGravityParam, evalPoly, RAD2DEG, secondsPerDay, secondsPerSiderealDay, TAU, ttasec2rad, Vector3D, } from '../main.js';
// / Earth metrics and operations.
export class Earth {
constructor() {
// disable constructor
}
// / Earth gravitational parameter _(km²/s³)_.
static mu = earthGravityParam;
// / Earth equatorial radius.
static radiusEquator = 6378.1363;
// / Earth coefficient of flattening _(unitless)_.
static flattening = 1.0 / 298.257223563;
// / Earth polar radius.
static radiusPolar = (Earth.radiusEquator * (1.0 - Earth.flattening));
// / Earth mean radius.
static radiusMean = ((2.0 * Earth.radiusEquator + Earth.radiusPolar) / 3.0);
// / Earth eccentricity squared _(unitless)_.
static eccentricitySquared = Earth.flattening * (2.0 - Earth.flattening);
// / Earth J2 effect coefficient _(unitless)_.
static j2 = 1.08262668355315e-3;
// / Earth J3 effect coefficient _(unitless)_.
static j3 = -2.53265648533224e-6;
// / Earth J4 effect coefficient _(unitless)_.
static j4 = -1.619621591367e-6;
// / Earth J5 effect coefficient _(unitless)_.
static j5 = -2.27296082868698e-7;
// / Earth J6 effect coefficient _(unitless)_.
static j6 = 5.40681239107085e-7;
// / Earth rotation vector _(rad/s)_.
static rotation = new Vector3D(0, 0, 7.292115146706979e-5);
// / Calculate mean motion _(rad/s)_ from a given [semimajorAxis] _(km)_.
static smaToMeanMotion(semimajorAxis) {
return Math.sqrt(Earth.mu / (semimajorAxis * semimajorAxis * semimajorAxis));
}
/**
* Converts revolutions per day to semi-major axis.
* @param rpd - The number of revolutions per day.
* @returns The semi-major axis value.
*/
static revsPerDayToSma(rpd) {
return Earth.mu ** (1 / 3) / ((TAU * rpd) / secondsPerDay) ** (2 / 3);
}
// / Calculate Earth [PrecessionAngles] at a given UTC [epoch].
static precession(epoch) {
const t = epoch.toTT().toJulianCenturies();
const zeta = evalPoly(t, Earth.zetaPoly_);
const theta = evalPoly(t, Earth.thetaPoly_);
const zed = evalPoly(t, Earth.zedPoly_);
return { zeta: zeta, theta: theta, zed: zed };
}
// / Calculate Earth [NutationAngles] for a given UTC [epoch].
static nutation(epoch) {
const t = epoch.toTT().toJulianCenturies();
const moonAnom = evalPoly(t, Earth.moonAnomPoly_);
const sunAnom = evalPoly(t, Earth.sunAnomPoly_);
const moonLat = evalPoly(t, Earth.moonLatPoly_);
const sunElong = evalPoly(t, Earth.sunElongPoly_);
const moonRaan = evalPoly(t, Earth.moonRaanPoly_);
let deltaPsi = 0.0;
let deltaEpsilon = 0.0;
const dh = DataHandler.getInstance();
for (let i = 0; i < 4; i++) {
const [a1, a2, a3, a4, a5, ai, bi, ci, di] = dh.getIau1980Coeffs(i);
const arg = a1 * moonAnom + a2 * sunAnom + a3 * moonLat + a4 * sunElong + a5 * moonRaan;
const sinC = ai + bi * t;
const cosC = ci + di * t;
deltaPsi += sinC * Math.sin(arg);
deltaEpsilon += cosC * Math.cos(arg);
}
deltaPsi *= ttasec2rad;
deltaEpsilon *= ttasec2rad;
const meanEpsilon = evalPoly(t, Earth.meanEpsilonPoly_);
const epsilon = meanEpsilon + deltaEpsilon;
const eqEq = deltaPsi * Math.cos(meanEpsilon) +
0.00264 * asec2rad * Math.sin(moonRaan) +
0.000063 * asec2rad * Math.sin(2.0 * moonRaan);
const gast = epoch.gmstAngle() + eqEq;
return {
dPsi: deltaPsi,
dEps: deltaEpsilon,
mEps: meanEpsilon,
eps: epsilon,
eqEq: eqEq,
gast: gast,
};
}
// / Convert a [semimajorAxis] _(km)_ to an eastward drift rate _(rad/day)_.
static smaToDrift(semimajorAxis) {
const t = (TAU * Math.sqrt(semimajorAxis ** 3 / Earth.mu)) / secondsPerSiderealDay;
return (1.0 - t) * TAU;
}
// / Convert a [semimajorAxis] _(km)_ to an eastward drift rate _(°/day)_.
static smaToDriftDegrees(semimajorAxis) {
return Earth.smaToDrift(semimajorAxis) * RAD2DEG;
}
// / Convert an eastward [driftRate] _(rad/day)_ to a semimajor-axis _(km)_.
static driftToSemimajorAxis(driftRate) {
const t = (-driftRate / TAU + 1) * secondsPerSiderealDay;
return ((Earth.mu * t * t) / (4 * Math.PI * Math.PI)) ** (1 / 3);
}
// / Convert an eastward [driftRate] _(°/day)_ to a semimajor-axis _(km)_.
static driftDegreesToSma(driftRate) {
return Earth.driftToSemimajorAxis(DEG2RAD * driftRate);
}
/**
* Calculates the diameter of the Earth based on the satellite position.
* @param satPos The position of the satellite.
* @returns The diameter of the Earth.
*/
static diameter(satPos) {
return angularDiameter(Earth.radiusEquator * 2, satPos.magnitude(), AngularDiameterMethod.Sphere);
}
// / Earth precession `zeta` polynomial coefficients.
static zetaPoly_ = Float64Array.from([
0.017998 * asec2rad,
0.30188 * asec2rad,
2306.2181 * asec2rad,
0.0,
]);
// / Earth precession `theta` polynomial coefficients.
static thetaPoly_ = Float64Array.from([
-0.041833 * asec2rad,
-0.42665 * asec2rad,
2004.3109 * asec2rad,
0.0,
]);
// / Earth precession `zed` polynomial coefficients.
static zedPoly_ = Float64Array.from([
0.018203 * asec2rad,
1.09468 * asec2rad,
2306.2181 * asec2rad,
0,
]);
static moonAnomPoly_ = Float64Array.from([
1.4343e-5 * DEG2RAD,
0.0088553 * DEG2RAD,
(1325.0 * 360.0 + 198.8675605) * DEG2RAD,
134.96340251 * DEG2RAD,
]);
// / Earth nutation Sun anomaly polynomial coefficients.
static sunAnomPoly_ = Float64Array.from([
3.8e-8 * DEG2RAD,
-0.0001537 * DEG2RAD,
(99.0 * 360.0 + 359.0502911) * DEG2RAD,
357.52910918 * DEG2RAD,
]);
// / Earth nutation Moon latitude polynomial coefficients.
static moonLatPoly_ = Float64Array.from([
-2.88e-7 * DEG2RAD,
-0.003542 * DEG2RAD,
(1342.0 * 360.0 + 82.0174577) * DEG2RAD,
93.27209062 * DEG2RAD,
]);
// / Earth nutation Sun elongation polynomial coefficients.
static sunElongPoly_ = Float64Array.from([
1.831e-6 * DEG2RAD,
-0.0017696 * DEG2RAD,
(1236.0 * 360.0 + 307.1114469) * DEG2RAD,
297.85019547 * DEG2RAD,
]);
// / Earth nutation Moon right-ascension polynomial coefficients.
static moonRaanPoly_ = Float64Array.from([
2.139e-6 * DEG2RAD,
0.0020756 * DEG2RAD,
-(5.0 * 360.0 + 134.1361851) * DEG2RAD,
125.04455501 * DEG2RAD,
]);
// / Earth nutation mean epsilon polynomial coefficients.
static meanEpsilonPoly_ = Float64Array.from([
0.001813 * asec2rad,
-0.00059 * asec2rad,
-46.815 * asec2rad,
84381.448 * asec2rad,
]);
}
//# sourceMappingURL=Earth.js.map