Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/autonoma.ca.git
calculators/rocket/payload/Rocket.js
class Rocket {
- constructor(wet, payload, diameter, dragCoefficient, specificImpulse) {
- console.assert(wet >= 1);
- console.assert(payload >= 1);
- console.assert(diameter > 0);
- console.assert(dragCoefficient > 0);
- console.assert(specificImpulse > 1);
-
- this.mass = wet;
- this.targetMass = wet + payload;
- this.radius = diameter / 2.0;
- this.specificImpulse = specificImpulse;
- this.totalThrust = 0.0;
- this.targetAltitude = 0.0;
- this.massFlowRate = 0.0;
- this.vAcceleration = 0.0;
- this.hAcceleration = 0.0;
-
- const crossSectionArea = Math.PI * this.radius ** 2;
- this.ballisticCoefficient = dragCoefficient * crossSectionArea;
-
- this.flightRecorder = false;
- this.launched = false;
- this.relocated = false;
- this.world = false;
- }
+ constructor(wetMass, payloadMass) {
+ this.wetMass = wetMass;
+ this.payloadMass = payloadMass;
+ this.dryMass = this.wetMass * 0.1 + this.payloadMass;
+ this.mass = this.wetMass;
- recorder(flightRecorder) {
- this.blackBox = flightRecorder;
- this.flightRecorder = true;
+ this.azimuth = 0.0;
}
on(planet) {
this.planet = planet;
- this.world = true;
}
- translocate(latitude, altitude) {
- console.assert(!this.launched);
- console.assert(this.world);
+ fuselage(diameter, dragCoefficient, specificImpulse) {
+ const crossSectionalArea = Math.PI * (diameter / 2) ** 2;
+ this.ballisticCoefficient = dragCoefficient * crossSectionalArea;
+ this.specificImpulse = specificImpulse;
+ }
+ translocate(latitude, altitude) {
this.latitude = latitude;
this.altitude = altitude;
- this.azimuth = 0;
-
- const LOCAL_GRAVITY = this.planet.gravity(latitude, altitude);
- this.vExhaust = this.specificImpulse * LOCAL_GRAVITY;
- this.maxAcceleration = 5.0 * LOCAL_GRAVITY;
- this.rotationalSpeed = this.planet.rotationalSpeed(latitude, altitude);
- this.relocated = true;
}
-
- launch(hVelocity, vVelocity) {
- console.assert(this.world);
- console.assert(this.relocated);
- console.assert(!this.launched);
- this.launched = true;
+ apogee(targetAltitude) {
+ this.targetAltitude = targetAltitude;
+ }
- this.hVelocity = hVelocity + this.rotationalSpeed;
- this.vVelocity = vVelocity;
+ gravity() {
+ return this.planet.gravity(this.latitude, this.altitude);
+ }
- const dragForce = this.drag();
+ launch(initialVelocity) {
+ this.exhaustVelocity = this.specificImpulse * this.gravity();
+ this.maximumAcceleration = 5.0 * this.gravity();
+ this.vVelocity = initialVelocity * this.planet.soundSpeed(this.altitude);
- this.massFlowRate = Math.abs(dragForce[1]) / this.vExhaust * 1.001;
- this.totalThrust = this.vExhaust * this.massFlowRate;
+ this.hVelocity = this.planet.rotationalSpeed(this.latitude, this.altitude);
+ this.hVelocityTarget = this.planet.orbitalSpeed(this.latitude, this.targetAltitude);
+ this.massFlowRate = Math.abs(this.drag()[1]) / this.exhaustVelocity * 1.001;
}
- apogee(altitude) {
- this.hTargetVelocity = this.planet.orbitalSpeed(this.latitude, altitude);
- this.targetAltitude = altitude;
+ recorder(blackBox) {
+ this.flightRecorder = blackBox;
}
drag() {
- console.assert(this.launched);
- console.assert(this.relocated);
- console.assert(this.world);
-
const rho = this.planet.airDensity(this.altitude);
- const hVelocityNet = this.hVelocity - this.rotationalSpeed;
- const totalSpeed = Math.sqrt(hVelocityNet ** 2 + this.vVelocity ** 2);
+ const vHorNet = this.hVelocity - this.planet.rotationalSpeed(this.latitude, this.altitude);
+ const totalSpeed = Math.sqrt(vHorNet ** 2 + this.vVelocity ** 2);
const magnitude = 0.5 * rho * this.ballisticCoefficient * totalSpeed ** 2;
- const forceRatio = [-hVelocityNet / totalSpeed, -this.vVelocity / totalSpeed];
+ const ratio = [-vHorNet / totalSpeed, -this.vVelocity / totalSpeed];
- return [forceRatio[0] * magnitude, forceRatio[1] * magnitude];
+ return [ratio[0] * magnitude, ratio[1] * magnitude];
}
flying() {
- console.assert(this.mass > 0);
- console.assert(this.targetMass > 0);
- console.assert(this.targetAltitude > 0);
-
- return (
- this.mass > this.targetMass &&
- this.altitude < this.targetAltitude
- );
+ return this.mass > this.dryMass && this.altitude < this.targetAltitude;
}
fly(step) {
- console.assert(this.launched);
- console.assert(step > 0);
-
- const dragForce = this.drag();
+ const drag = this.drag();
- if (this.hVelocity < this.hTargetVelocity) {
- const magnitude = Math.sqrt(
- this.hAcceleration ** 2 + this.vAcceleration ** 2
- );
- const absDragForce = Math.abs(dragForce[1]);
+ if (this.hVelocity < this.hVelocityTarget) {
+ const accMag = Math.sqrt(this.hAcceleration ** 2 + this.vAcceleration ** 2);
+ const absDrag = Math.abs(drag[1]);
- if (magnitude > this.maxAcceleration &&
- this.vExhaust * this.massFlowRate * 0.98 > absDragForce) {
+ if (accMag > this.maximumAcceleration && this.exhaustVelocity * this.massFlowRate * 0.98 > absDrag) {
this.massFlowRate *= 0.99;
}
-
- if (this.vExhaust * this.massFlowRate < absDragForce) {
- this.massFlowRate = absDragForce / this.vExhaust * 1.1;
+ if (this.exhaustVelocity * this.massFlowRate < absDrag) {
+ this.massFlowRate = absDrag / this.exhaustVelocity * 1.1;
}
} else {
this.massFlowRate = 0.0;
}
- this.totalThrust = this.vExhaust * this.massFlowRate;
+ this.totalThrust = this.exhaustVelocity * this.massFlowRate;
const thrusting = this.totalThrust > 0;
- const vThrust = thrusting ? -dragForce[1] : 0.0;
- const hThrust = thrusting ? Math.sqrt(this.totalThrust ** 2 - vThrust ** 2) : 0.0;
+ const vThrust = thrusting ? -drag[1] : 0;
+ const hThrust = thrusting ? Math.sqrt(this.totalThrust ** 2 - vThrust ** 2) : 0;
- this.hAcceleration = dragForce[0] / this.mass + hThrust / this.mass;
- this.vAcceleration = dragForce[1] / this.mass - this.planet.gravity(this.latitude, this.altitude) + vThrust / this.mass;
+ this.hAcceleration = drag[0] / this.mass + hThrust / this.mass;
+ this.vAcceleration = drag[1] / this.mass + this.gravity() + vThrust / this.mass;
- this.hVelocity += this.hAcceleration * step;
this.vVelocity += this.vAcceleration * step;
+ this.hVelocity += this.hAcceleration * step;
- this.azimuth += this.hVelocity * step + 0.5 * this.hAcceleration * step ** 2;
this.altitude += this.vVelocity * step + 0.5 * this.vAcceleration * step ** 2;
+ this.azimuth += this.hVelocity * step + 0.5 * this.hAcceleration * step ** 2;
this.mass -= this.massFlowRate * step;
-
}
-
- stop() {}
record(time) {
- console.assert(this.flightRecorder);
-
- this.blackBox.azimuth(time, this.azimuth);
- this.blackBox.horizontalVelocity(time, this.hVelocity);
- this.blackBox.horizontalAcceleration(time, this.hAcceleration);
- this.blackBox.altitude(time, this.altitude);
- this.blackBox.verticalVelocity(time, this.vVelocity);
- this.blackBox.verticalAcceleration(time, this.vAcceleration);
- this.blackBox.thrustAcceleration(time, this.totalThrust / this.mass);
- this.blackBox.mass(time, this.mass);
+ if (this.flightRecorder) {
+ this.flightRecorder.azimuth(time, this.azimuth);
+ this.flightRecorder.horizontalVelocity(time, this.hVelocity);
+ this.flightRecorder.horizontalAcceleration(time, this.hAcceleration);
+ this.flightRecorder.altitude(time, this.altitude);
+ this.flightRecorder.verticalVelocity(time, this.vVelocity);
+ this.flightRecorder.verticalAcceleration(time, this.vAcceleration);
+ this.flightRecorder.thrustAcceleration(time, this.totalThrust / this.mass);
+ this.flightRecorder.mass(time, this.mass);
+ }
}
}
calculators/rocket/payload/calculator.js
-/**
- * The purpose of this code is to help calculate parameters required to
- * send a rocket into space using a combination of single-stage to orbit
- * and an electromagnetic accelerator.
- */
-
import Earth from './Earth.js';
-import Rocket from './Rocket.js';
import FlightRecorder from './FlightRecorder.js';
-import {$} from './Selector.js';
+import Rocket from './Rocket.js';
document.querySelectorAll('.submit').forEach(button => {
button.addEventListener('click', function (event) {
event.preventDefault();
- // Inputs
const INITIAL_VELOCITY = 8.0; // Mach
const INITIAL_LATITUDE = 1.469167; // degrees
const DRAG_COEFFICIENT = 0.29;
const SPECIFIC_IMPULSE = 1400.0; // seconds
-
- const earth = new Earth(INITIAL_LATITUDE);
-
- const SPEED_OF_SOUND = earth.soundSpeed(INITIAL_ALTITUDE);
- const INITIAL_HORIZONTAL_VELOCITY = 0;
- const INITIAL_VERTICAL_VELOCITY = INITIAL_VELOCITY * SPEED_OF_SOUND;
const blackBox = new FlightRecorder();
- const rocket = new Rocket(
- WET_MASS,
- PAYLOAD_MASS,
- ROCKET_DIAMETER,
- DRAG_COEFFICIENT,
- SPECIFIC_IMPULSE
- );
+ const rocket = new Rocket(WET_MASS, PAYLOAD_MASS);
+ const planet = new Earth(INITIAL_LATITUDE);
- rocket.on(earth);
+ rocket.on(planet);
rocket.recorder(blackBox);
+ rocket.fuselage(ROCKET_DIAMETER, DRAG_COEFFICIENT, SPECIFIC_IMPULSE);
rocket.translocate(INITIAL_LATITUDE, INITIAL_ALTITUDE);
rocket.apogee(TARGET_ALTITUDE);
- rocket.launch(INITIAL_HORIZONTAL_VELOCITY, INITIAL_VERTICAL_VELOCITY);
-
- const DELTA_TIME = 0.01;
+ rocket.launch(INITIAL_VELOCITY);
let time = 0.0;
+ const TIME_STEP = 0.01;
- do {
+ while (rocket.flying()) {
+ rocket.fly(TIME_STEP);
rocket.record(time);
- rocket.fly(DELTA_TIME);
- time = parseFloat((time + DELTA_TIME).toFixed(2));
+ time += TIME_STEP;
}
- while (rocket.flying());
- rocket.stop();
blackBox.plot();
});

Resolves issues with rocket calculations

Author djarvis <email>
Date 2024-12-03 22:50:17 GMT-0800
Commit e89468db95b3909183505f145c2ad549403bb4af
Parent 7e3fb30
Delta 66 lines added, 134 lines removed, 68-line decrease