ootk
Version:
Orbital Object Toolkit including Multiple Propagators, Initial Orbit Determination, and Maneuver Calculations.
70 lines • 2.92 kB
JavaScript
/**
* @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 { DataHandler, DEG2RAD, Earth, ITRF, J2000, Sun, Vector3D, } from '../main.js';
/**
* Harris-Priester atmospheric drag force model.
* Atmospheric density model assumes mean solar flux.
*/
export class AtmosphericDrag {
mass;
area;
dragCoeff;
cosine;
constructor(mass, area, dragCoeff, cosine) {
this.mass = mass;
this.area = area;
this.dragCoeff = dragCoeff;
this.cosine = cosine;
}
static _getHPDensity(state, n) {
const hpa = DataHandler.getInstance().getHpAtmosphere(state.height);
if (hpa === null) {
return 0.0;
}
const sunPos = Sun.positionApparent(state.epoch);
const sunVec = new J2000(state.epoch, sunPos, Vector3D.origin).toITRF().position.normalize();
const bulVec = sunVec.rotZ(-30.0 * DEG2RAD);
const cosPsi = bulVec.normalize().dot(state.position.normalize());
const c2Psi2 = 0.5 * (1.0 + cosPsi);
const cPsi2 = Math.sqrt(c2Psi2);
const cosPow = cPsi2 > 1e-12 ? c2Psi2 * cPsi2 ** (n - 2) : 0.0;
const altitude = hpa.height;
const [h0, min0, max0] = hpa.hp0;
const [h1, min1, max1] = hpa.hp1;
const dH = (h0 - altitude) / (h0 - h1);
const rhoMin = min0 * (min1 / min0) ** dH;
if (cosPow === 0) {
return rhoMin;
}
const rhoMax = max0 * (max1 / max0) ** dH;
return rhoMin + (rhoMax - rhoMin) * cosPow;
}
acceleration(state) {
const itrfState = state.toITRF();
const density = AtmosphericDrag._getHPDensity(itrfState, this.cosine);
if (density === 0) {
return Vector3D.origin;
}
const rotation = new ITRF(state.epoch, Earth.rotation, Vector3D.origin).toJ2000().position;
const vRel = state.velocity.subtract(rotation.cross(state.position))
.scale(1000.0);
const vm = vRel.magnitude();
const fScale = -0.5 * density * ((this.dragCoeff * this.area) / this.mass) * vm;
return vRel.scale(fScale / 1000.0);
}
}
//# sourceMappingURL=AtmosphericDrag.js.map