Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/autonoma.ca.git
calculators/rocket/payload/Earth.js
static GRAVITY = 9.80665;
static MOLAR_MASS_AIR = 0.0289644;
- static MOLAR_MASS_DRY_AIR = 0.0289652;
- static MOLAR_MASS_WATER_VAPOUR = 0.018016;
+ static SPECIFIC_GAS_CONSTANT_DRY_AIR = 287.85;
+ static SPECIFIC_GAS_CONSTANT_WATER_VAPOUR = 461.495;
static RADIUS_EQUATOR = 6378137.0;
static RADIUS_POLAR = 6356752.0;
this.surface = temperature;
this.humidity = humidity / 100;
- }
-
- airPressure(altitude) {
- return (
- Earth.STATIC_PRESSURE *
- Math.pow(
- 1 +
- (Earth.TEMPERATURE_LAPSE_RATE / this.kelvin(this.surface)) *
- altitude,
- (-Earth.GRAVITY * Earth.MOLAR_MASS_AIR) /
- (Earth.GAS_CONSTANT * Earth.TEMPERATURE_LAPSE_RATE)
- )
- );
- }
-
- airDensity(altitude) {
- const pressure = this.airPressure(altitude);
- const kelvins = this.kelvin(this.surface);
- const psat = 0.61078 * Math.exp(
- (17.27 * (kelvins - Earth.KELVIN)) / (kelvins - 35.85)
- );
- const pressureVapour = this.humidity * psat;
- const pressureDryAir = pressure - pressureVapour;
-
- return (
- (pressureDryAir / (Earth.MOLAR_MASS_DRY_AIR * kelvins)) +
- (pressureVapour / (Earth.MOLAR_MASS_WATER_VAPOUR * kelvins))
- );
}
- kelvin(temperature) {
- return temperature + Earth.KELVIN;
+ kelvins(celsius) {
+ return celsius + Earth.KELVIN;
}
radians(degrees) {
return degrees * (Math.PI / 180);
}
radius(latitude) {
- return (
+ const result = (
Earth.RADIUS_EQUATOR *
(1 -
- ((Earth.RADIUS_EQUATOR - Earth.RADIUS_POLAR) / Earth.RADIUS_EQUATOR) *
+ ((Earth.RADIUS_EQUATOR - Earth.RADIUS_POLAR) /
+ Earth.RADIUS_EQUATOR) *
Math.pow(Math.sin(this.radians(latitude)), 2))
);
+
+ console.debug(`radius( ${latitude} ) = ${result} m`);
+
+ return result;
}
(1 + 0.0053024 * latitudeEffect - 0.0000058 * shapeEffect);
const altitudeCorrection = -3.086e-6 * altitude;
+ const result = gravityVariation + altitudeCorrection;
- return gravityVariation + altitudeCorrection;
+ console.debug(`gravity( ${latitude}, ${altitude} ) = ${result} m/s²`);
+
+ return result;
}
soundSpeed(altitude) {
const temperature = this.surface - (6 * altitude) / 1000;
- return Earth.SPEED_SOUND_0C * Math.sqrt(1 + temperature / Earth.KELVIN);
+ const result =
+ Earth.SPEED_SOUND_0C * Math.sqrt(1 + temperature / Earth.KELVIN);
+
+ console.debug(`sound( ${altitude} ) = ${result} m/s`);
+
+ return result;
}
rotationalSpeed(latitude) {
return this.radius(latitude) * (2 * Math.PI) / Earth.SIDEREAL_TIME;
}
orbitalSpeed(latitude, altitude) {
const distance = this.radius(latitude) + altitude;
- return Math.sqrt(Earth.STANDARD_GRAVITY / distance);
+ const result = Math.sqrt(Earth.STANDARD_GRAVITY / distance);
+
+ console.debug(`orbital( ${latitude}, ${altitude} ) = ${result} m / s`);
+
+ return result;
+ }
+
+ airPressure(altitude) {
+ const T0 = this.kelvins(this.surface);
+ const P0 = Earth.STATIC_PRESSURE;
+ const g = Earth.GRAVITY;
+ const M = Earth.MOLAR_MASS_AIR;
+ const R = Earth.GAS_CONSTANT;
+ const LAPSE_RATE = Earth.TEMPERATURE_LAPSE_RATE;
+ let pressure;
+
+ if (altitude <= 11000) {
+ pressure = P0 * Math.pow((1 + (LAPSE_RATE / T0) * altitude),
+ -(g * M) / (R * LAPSE_RATE));
+ } else {
+ const T1 = 216.65;
+ const P1 = P0 * Math.pow((1 + (LAPSE_RATE / T0) * 11000),
+ -(g * M) / (R * LAPSE_RATE));
+ pressure = P1 * Math.exp(-(g * M) * (altitude - 11000) /
+ (R * T1));
+ }
+
+ console.debug(`Pressure at ${altitude} meters = ${pressure} Pa`);
+ return pressure;
+ }
+
+ saturationVaporPressure(temperature) {
+ const BASE_PRESSURE = 6.1078;
+ const COEFFICIENTS = [
+ 0.99999683,
+ -0.90826951e-2,
+ 0.78736169e-4,
+ -0.61117958e-6,
+ 0.43884187e-8,
+ -0.29883885e-10,
+ 0.21874425e-12,
+ -0.17892321e-14,
+ 0.11112018e-16,
+ -0.30994571e-19
+ ];
+
+ let polynomial = 0;
+
+ for (let i = 0; i < COEFFICIENTS.length; i++) {
+ polynomial += COEFFICIENTS[i] * Math.pow(temperature, i);
+ }
+
+ return (BASE_PRESSURE / Math.pow(polynomial, 8)) * 100;
+ }
+
+ waterVaporPressure(humidity, saturationVaporPressure) {
+ return humidity * saturationVaporPressure;
+ }
+
+ dryAirPressure(totalPressure, waterVaporPressure) {
+ return totalPressure - waterVaporPressure;
+ }
+
+ airDensity(altitude) {
+ const pressure = this.airPressure(altitude);
+ const kelvins = this.kelvins(this.surface);
+
+ const saturationVapour = this.saturationVaporPressure(this.surface);
+ const waterVapour = this.waterVaporPressure(this.humidity, saturationVapour);
+ const dryAir = this.dryAirPressure(pressure, waterVapour);
+
+ let airDensity = (dryAir / (Earth.SPECIFIC_GAS_CONSTANT_DRY_AIR
+ * kelvins)) + (waterVapour /
+ (Earth.SPECIFIC_GAS_CONSTANT_WATER_VAPOUR * kelvins));
+
+ airDensity = Math.max(0, airDensity);
+
+ return airDensity;
}
}
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.dry = wet * 0.1;
this.mass = wet;
- this.targetMass = this.dry + this.payload;
- this.payload = payload;
+ this.targetMass = this.dry + payload;
this.radius = diameter / 2.0;
this.specificImpulse = specificImpulse;
flying() {
- return this.mass > this.targetMass;
+ console.assert(this.mass > 0);
+ console.assert(this.targetMass > 0);
+
+ return this.mass > this.targetMass && this.mass > this.dry;
}
below(altitude) {
+ console.assert(altitude > 0);
+
return this.altitude < altitude;
}
calculators/rocket/payload/Telemetry.js
class Telemetry {
constructor(measureName) {
- this.measureName = measureName;
this.times = [];
this.values = [];
+ this.id = measureName.toLowerCase().replace(/\s+/g, '-');
+
+ // Create a div for this telemetry plot
+ const plotContainer = document.getElementById('plots');
+ const plotDiv = document.createElement('div');
+ plotDiv.id = this.id;
+ plotContainer.appendChild(plotDiv);
}
record(time, value) {
this.times.push(time);
this.values.push(value);
}
- plot(plotName, xLabel, yLabel) {
- // TODO: Implement plotting logic using the chosen library
- const data = {
- x: this.times,
- y: this.values
- };
+ plot(plotName, yLabel) {
+ const data = this.times.map((time, index) => ({
+ time: time,
+ value: this.values[index]
+ }));
- const layout = {
- title: plotName,
- xaxis: { title: 'Time (seconds)' },
- yaxis: { title: yLabel }
- };
+ const margin = { top: 20, right: 30, bottom: 30, left: 40 },
+ width = 800 - margin.left - margin.right,
+ height = 400 - margin.top - margin.bottom;
+
+ const svg = d3.select(`#${this.id}`).append('svg')
+ .attr('width', width + margin.left + margin.right)
+ .attr('height', height + margin.top + margin.bottom)
+ .append('g')
+ .attr('transform', `translate(${margin.left},${margin.top})`);
+
+ const x = d3.scaleLinear()
+ .domain([d3.min(data, d => d.time), d3.max(data, d => d.time)])
+ .range([0, width]);
+
+ const y = d3.scaleLinear()
+ .domain([0, d3.max(data, d => d.value)])
+ .range([height, 0]);
+
+ svg.append('g')
+ .attr('transform', `translate(0,${height})`)
+ .call(d3.axisBottom(x));
+
+ svg.append('g')
+ .call(d3.axisLeft(y));
+
+ svg.append('path')
+ .datum(data)
+ .attr('fill', 'none')
+ .attr('stroke', 'steelblue')
+ .attr('stroke-width', 1.5)
+ .attr('d', d3.line()
+ .x(d => x(d.time))
+ .y(d => y(d.value))
+ );
+
+ svg.append('text')
+ .attr('x', (width / 2))
+ .attr('y', 0 - (margin.top / 2))
+ .attr('text-anchor', 'middle')
+ .style('font-size', '16px')
+ .style('text-decoration', 'underline')
+ .text(plotName);
+
+ svg.append('text')
+ .attr('x', width / 2)
+ .attr('y', height + margin.bottom)
+ .attr('text-anchor', 'middle')
+ .text('Time (seconds)');
+
+ svg.append('text')
+ .attr('transform', 'rotate(-90)')
+ .attr('y', 0 - margin.left)
+ .attr('x', 0 - (height / 2))
+ .attr('text-anchor', 'middle')
+ .text(yLabel);
}
}
calculators/rocket/payload/calculator.js
while (rocket.flying() && rocket.below(TARGET_ALTITUDE)) {
time += 0.01;
+ time = parseFloat(time.toFixed(2));
rocket.fly(time);
}
calculators/rocket/payload/index.html
<!DOCTYPE html><!DOCTYPE HTML><html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1user-scalable=yes"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="description" content="A hard sci-fi novel about automated food production, sentient machines, and surveillance societies."><link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png"><style media="screen" type="text/css">
/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}/*# sourceMappingURL=normalize.min.css.map */
- </style><link rel="stylesheet" type="text/css" media="screen" href="../../../themes/simple.css"><link rel="stylesheet" type="text/css" media="screen" href="../../../themes/form.css"><link rel="stylesheet" type="text/css" media="screen" href="../../../themes/calculator.css"><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.css"><link href="//fonts.googleapis.com/css?family=Source+Sans+Pro:200|Libre+Baskerville" rel="stylesheet"></head><body><div class="page"><header class="section header"><h1>Orbital Launch Insertion</h1></header><nav class="section menu"></nav><main class="section content"><p>
+ </style><link rel="stylesheet" type="text/css" media="screen" href="../../../themes/simple.css"><link rel="stylesheet" type="text/css" media="screen" href="../../../themes/form.css"><link rel="stylesheet" type="text/css" media="screen" href="../../../themes/calculator.css"><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.css" integrity="sha512-fHwaWebuwA7NSF5Qg/af4UeDx9XqUpYpOGgubo3yWu+b2IQR4UeQwbb42Ti7gVAjNtVoI/I9TEoYeu9omwcC6g==" crossorigin="anonymous" referrerpolicy="no-referrer"><link href="//fonts.googleapis.com/css?family=Source+Sans+Pro:200|Libre+Baskerville" rel="stylesheet"></head><body><div class="page"><header class="section header"><h1>Orbital Launch Insertion</h1></header><nav class="section menu"></nav><main class="section content"><p>
Helps determine whether a payload can be inserted into a stable orbit.
Form field values are explained in the <a href="#equations">Equations</a>
section, below.
- </p><form id="calculator"><button class="submit">Simulate</button><fieldset id="environment"><legend>Environment</legend><label for="surface_temperature">Surface temperature (℃)</label><input tabindex="1" class="variable" type="number" step="1" min="-80" value="25" id="surface_temperature" name="surface_temperature"><label for="relative_humidity">Relative humidity</label><input tabindex="2" class="variable" type="number" step="0.01" min="0" value="86.34" id="surface_temperature" name="surface_temperature"></fieldset><fieldset id="mission"><legend>Mission</legend><label for="initial_velocity">Initial velocity (Mach)</label><input tabindex="3" class="variable" type="number" step="1" min="0" value="8" id="initial_velocity" name="initial_velocity"><label for="initial_latitude">Initial latitude (°)</label><input tabindex="4" class="variable" type="number" step="any" min="0" value="1.469167" id="initial_latitude" name="initial_latitude"><label for="initial_altitude">Initial altitude (m)</label><input tabindex="5" class="variable" type="number" step="1" min="0" value="6212" id="initial_altitude" name="initial_altitude"><label for="target_altitude">Target altitude (km)</label><input tabindex="6" class="variable" type="number" step="1" min="1" value="400" id="target_altitude" name="target_altitude"></fieldset><fieldset id="rocket"><legend>Rocket</legend><label for="diameter">Diameter (m)</label><input tabindex="7" class="variable" type="number" step="any" min="0" value="0.6" id="diameter" name="diameter"><label for="wet_mass">Wet mass (kg)</label><input tabindex="8" class="variable" type="number" step="1" min="1" value="250" id="wet_mass" name="wet_mass" oninput="this.value = Math.abs(this.value)"><label for="payload">Payload mass (kg)</label><input tabindex="9" class="variable" type="number" step="1" min="1" value="25" id="payload_mass" name="payload_mass" oninput="this.value = Math.abs(this.value)"><label for="drag_coefficient">Drag coefficient</label><input tabindex="10" class="variable" type="number" step="any" min="0" value="0.219" id="drag_coefficient" name="drag_coefficient"><label for="specific_impulse">Specific impulse (s)</label><input tabindex="11" class="variable" type="number" step="1" min="1" value="1700" id="specific_impulse" name="specific_impulse"></fieldset><button class="submit">Simulate</button><fieldset id="result"><legend>Result</legend></fieldset></form><a name="equations"></a><h1>Equations</h1><p>
+ </p><form id="calculator"><button class="submit">Simulate</button><fieldset id="environment"><legend>Environment</legend><label for="surface_temperature">Surface temperature (℃)</label><input tabindex="1" class="variable" type="number" step="1" min="-80" value="25" id="surface_temperature" name="surface_temperature"><label for="relative_humidity">Relative humidity</label><input tabindex="2" class="variable" type="number" step="0.01" min="0" value="86.34" id="surface_temperature" name="surface_temperature"></fieldset><fieldset id="mission"><legend>Mission</legend><label for="initial_velocity">Initial velocity (Mach)</label><input tabindex="3" class="variable" type="number" step="1" min="0" value="8" id="initial_velocity" name="initial_velocity"><label for="initial_latitude">Initial latitude (°)</label><input tabindex="4" class="variable" type="number" step="any" min="0" value="1.469167" id="initial_latitude" name="initial_latitude"><label for="initial_altitude">Initial altitude (m)</label><input tabindex="5" class="variable" type="number" step="1" min="0" value="6212" id="initial_altitude" name="initial_altitude"><label for="target_altitude">Target altitude (km)</label><input tabindex="6" class="variable" type="number" step="1" min="1" value="400" id="target_altitude" name="target_altitude"></fieldset><fieldset id="rocket"><legend>Rocket</legend><label for="diameter">Diameter (m)</label><input tabindex="7" class="variable" type="number" step="any" min="0" value="0.6" id="diameter" name="diameter"><label for="wet_mass">Wet mass (kg)</label><input tabindex="8" class="variable" type="number" step="1" min="1" value="250" id="wet_mass" name="wet_mass" oninput="this.value = Math.abs(this.value)"><label for="payload">Payload mass (kg)</label><input tabindex="9" class="variable" type="number" step="1" min="1" value="25" id="payload_mass" name="payload_mass" oninput="this.value = Math.abs(this.value)"><label for="drag_coefficient">Drag coefficient</label><input tabindex="10" class="variable" type="number" step="any" min="0" value="0.219" id="drag_coefficient" name="drag_coefficient"><label for="specific_impulse">Specific impulse (s)</label><input tabindex="11" class="variable" type="number" step="1" min="1" value="1700" id="specific_impulse" name="specific_impulse"></fieldset><button class="submit">Simulate</button><fieldset id="result"><legend>Result</legend><div id="plots"></div></fieldset></form><a name="equations"></a><h1>Equations</h1><p>
This section describes equation inputs and outputs.
</p><h2>Cross-section area</h2><p>
$$a_h = \frac{F_{drag_h}}{m} + \frac{F_{t_h}}{m}$$
$$a_v = \frac{F_{drag_v}}{m} + g(\varphi, h) + \frac{F_{t_v}}{m}$$
- </p><div class="variables"><div class="input"><h3>Inputs</h3><dl><dt>$F_{drag_h}$</dt><dd>Horizontal drag force (N)</dd><dt>$F_{drag_v}$</dt><dd>Vertical drag force (N)</dd><dt>$F_t$</dt><dd>Total thrust force (N)</dd><dt>$m$</dt><dd>Rocket mass (kg)</dd><dt>$g(\varphi, h)$</dt><dd>Gravitational acceleration (m/s<sup>2</sup>)</dd><dt>$\varphi$</dt><dd>Latitude (degrees)</dd><dt>$h$</dt><dd>Altitude (m)</dd></dl></div><div class="output"><h3>Outputs</h3><dl><dt>$F_{t_v}$</dt><dd>Vertical thrust (N)</dd><dt>$F_{t_h}$</dt><dd>Horizontal thrust (N)</dd><dt>$a_h$</dt><dd>Horizontal acceleration (m/s<sup>2</sup>)</dd><dt>$a_v$</dt><dd>Vertical acceleration (m/s<sup>2</sup>)</dd></dl></div></div></main><footer class="section footer"></footer></div><script defer src="//code.jquery.com/jquery-1.12.4.min.js"></script><script defer type="module" src="calculator.js"></script><script src="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.js"></script><script src="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/contrib/auto-render.min.js"></script><script>
+ </p><div class="variables"><div class="input"><h3>Inputs</h3><dl><dt>$F_{drag_h}$</dt><dd>Horizontal drag force (N)</dd><dt>$F_{drag_v}$</dt><dd>Vertical drag force (N)</dd><dt>$F_t$</dt><dd>Total thrust force (N)</dd><dt>$m$</dt><dd>Rocket mass (kg)</dd><dt>$g(\varphi, h)$</dt><dd>Gravitational acceleration (m/s<sup>2</sup>)</dd><dt>$\varphi$</dt><dd>Latitude (degrees)</dd><dt>$h$</dt><dd>Altitude (m)</dd></dl></div><div class="output"><h3>Outputs</h3><dl><dt>$F_{t_v}$</dt><dd>Vertical thrust (N)</dd><dt>$F_{t_h}$</dt><dd>Horizontal thrust (N)</dd><dt>$a_h$</dt><dd>Horizontal acceleration (m/s<sup>2</sup>)</dd><dt>$a_v$</dt><dd>Vertical acceleration (m/s<sup>2</sup>)</dd></dl></div></div></main><footer class="section footer"></footer></div><script defer src="//code.jquery.com/jquery-1.12.4.min.js"></script><script defer type="module" src="calculator.js"></script><script src="//cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js" integrity="sha512-vc58qvvBdrDR4etbxMdlTt4GBQk1qjvyORR2nrsPsFPyrs+/u5c3+1Ct6upOgdZoIl7eq6k3a1UPDSNAQi/32A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.js" integrity="sha512-LQNxIMR5rXv7o+b1l8+N1EZMfhG7iFZ9HhnbJkTp4zjNr5Wvst75AqUeFDxeRUa7l5vEDyUiAip//r+EFLLCyA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/contrib/auto-render.min.js" integrity="sha512-iWiuBS5nt6r60fCz26Nd0Zqe0nbk1ZTIQbl3Kv7kYsX+yKMUFHzjaH2+AnM6vp2Xs+gNmaBAVWJjSmuPw76Efg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script>
renderMathInElement(
document.body, {
calculators/rocket/payload/launch.xsl
<link
rel="stylesheet"
- href="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.css" />
- </xsl:template>
-
- <xsl:template match="/root" mode="header">
- <h1>Orbital Launch Insertion</h1>
- </xsl:template>
-
- <xsl:template match="/root" mode="content">
- <p>
- Helps determine whether a payload can be inserted into a stable orbit.
- Form field values are explained in the <a href="#equations">Equations</a>
- section, below.
- </p>
-
- <form id="calculator">
- <button class="submit">Simulate</button>
-
- <fieldset id="environment">
- <legend>Environment</legend>
- <label for="surface_temperature">Surface temperature (&#x2103;)</label>
- <input tabindex="1"
- class="variable" type="number" step="1" min="-80" value="25"
- id="surface_temperature" name="surface_temperature" />
-
- <label for="relative_humidity">Relative humidity</label>
- <input tabindex="2"
- class="variable" type="number" step="0.01" min="0" value="86.34"
- id="surface_temperature" name="surface_temperature" />
- </fieldset>
-
- <fieldset id="mission">
- <legend>Mission</legend>
- <label for="initial_velocity">Initial velocity (Mach)</label>
- <input tabindex="3"
- class="variable" type="number" step="1" min="0" value="8"
- id="initial_velocity" name="initial_velocity" />
-
- <label for="initial_latitude">Initial latitude (&#x00b0;)</label>
- <input tabindex="4"
- class="variable" type="number" step="any" min="0" value="1.469167"
- id="initial_latitude" name="initial_latitude" />
-
- <label for="initial_altitude">Initial altitude (m)</label>
- <input tabindex="5"
- class="variable" type="number" step="1" min="0" value="6212"
- id="initial_altitude" name="initial_altitude" />
-
- <label for="target_altitude">Target altitude (km)</label>
- <input tabindex="6"
- class="variable" type="number" step="1" min="1" value="400"
- id="target_altitude" name="target_altitude" />
- </fieldset>
-
- <fieldset id="rocket">
- <legend>Rocket</legend>
- <label for="diameter">Diameter (m)</label>
- <input tabindex="7" class="variable" type="number"
- step="any" min="0" value="0.6" id="diameter" name="diameter" />
-
- <label for="wet_mass">Wet mass (kg)</label>
- <input tabindex="8"
- class="variable" type="number" step="1" min="1" value="250"
- id="wet_mass" name="wet_mass"
- oninput="this.value = Math.abs(this.value)" />
-
- <label for="payload">Payload mass (kg)</label>
- <input tabindex="9"
- class="variable" type="number" step="1" min="1" value="25"
- id="payload_mass" name="payload_mass"
- oninput="this.value = Math.abs(this.value)" />
-
- <label for="drag_coefficient">Drag coefficient</label>
- <input tabindex="10"
- class="variable" type="number" step="any" min="0" value="0.219"
- id="drag_coefficient" name="drag_coefficient" />
-
- <label for="specific_impulse">Specific impulse (s)</label>
- <input tabindex="11"
- class="variable" type="number" step="1" min="1" value="1700"
- id="specific_impulse" name="specific_impulse" />
- </fieldset>
-
- <button class="submit">Simulate</button>
-
- <fieldset id="result">
- <legend>Result</legend>
- </fieldset>
- </form>
-
- <a name="equations" />
- <h1>Equations</h1>
- <p>
- This section describes equation inputs and outputs.
- </p>
-
- <h2>Cross-section area</h2>
- <p>
- Calculates the ballistic coefficient of friction, which helps
- determine the drag force magnitude experienced by the rocket.
- </p>
- <p class="equation">
- $$A = \pi (d / 2)^2$$
- </p>
- <div class="variables">
- <div class="input">
- <h3>Input</h3>
- <dl>
- <dt>$d$</dt>
- <dd>Rocket diameter (m)</dd>
- </dl>
- </div>
- <div class="output">
- <h3>Output</h3>
- <dl>
- <dt>$A$</dt>
- <dd>Rocket's cross-section area (m<sup>2</sup>)</dd>
- </dl>
- </div>
- </div>
-
- <h2>Air pressure</h2>
- <p>
- Calculates the amount of pressure air exerts at a given altitude.
- </p>
- <p class="equation">
- $$P = P_{sea} \bigg( 1 + \frac{L}{T} h \bigg) ^ {\frac{-g_0 \cdot M}{R \cdot L}}$$
- </p>
- <div class="variables">
- <div class="input">
- <h3>Input</h3>
- <dl>
- <dt>$P_{sea}$</dt>
- <dd>Sea level pressure (101325&#160;Pa)</dd>
- <dt>$L$</dt>
- <dd>Lapse rate (-0.0065&#160;K/m)</dd>
- <dt>$T$</dt>
- <dd>Temperature (K)</dd>
- <dt>$h$</dt>
- <dd>Altitude (m)</dd>
- <dt>$g_0$</dt>
- <dd>Gravitational acceleration constant (9.80665&#160;m/s<sup>2</sup>)</dd>
- <dt>$M$</dt>
- <dd>Earth's atmospheric molar mass (0.0289644&#160;kg/mol)</dd>
- <dt>$R$</dt>
- <dd>Universal gas constant (8.31432&#160;N⋅m/mol⋅K)</dd>
- </dl>
- </div>
- <div class="output">
- <h3>Output</h3>
- <dl>
- <dt>$P$</dt>
- <dd>Air pressure (Pa)</dd>
- </dl>
- </div>
- </div>
-
- <h2>Tetens equation</h2>
- <p>
- Calculates the saturation vapour pressure of water at a given temperature.
- </p>
- <p class="equation">
- $$P_v = 0.61078 \cdot e ^ {17.27 T / (T + 237.31)}$$
- </p>
- <div class="variables">
- <div class="input">
- <h3>Inputs</h3>
- <dl>
- <dt>$T$</dt>
- <dd>Temperature (&#x2103;)</dd>
- </dl>
- </div>
- <div class="output">
- <h3>Output</h3>
- <dl>
- <dt>$P_v$</dt>
- <dd>Vapour pressure (Pa)</dd>
- </dl>
- </div>
- </div>
-
- <h2>Air density</h2>
- <p>
- Calculates the density of air at a given altitude, which helps determine
- the drag force due to air experienced by the rocket.
- </p>
- <p class="equation">
- $$\rho = \left(\frac{P_d}{R_d \cdot T}\right) + \left(\frac{P_v}{R_v \cdot T}\right)$$
- </p>
- <div class="variables">
- <div class="input">
- <h3>Inputs</h3>
- <dl>
- <dt>$P_d$</dt>
- <dd>Partial pressure of dry air (Pa)</dd>
- <dt>$P_v$</dt>
- <dd>Partial pressure of water vapor (Pa)</dd>
- <dt>$T$</dt>
- <dd>Temperature (&#x2103;)</dd>
- <dt>$R_d$</dt>
- <dd>Specific gas constant for dry air (287.058&#160;J/(kg⋅K))</dd>
- <dt>$R_v$</dt>
- <dd>Specific gas constant for water vapour (461.495&#160;J/(kg⋅K))</dd>
- </dl>
- </div>
- <div class="output">
- <h3>Output</h3>
- <dl>
- <dt>$\rho$</dt>
- <dd>Air density (kg/m<sup>3</sup>)</dd>
- </dl>
- </div>
- </div>
-
- <h2>Earth effective radius</h2>
- <p>
- Calculates Earth's radius at a given latitude, which helps determine
- the main gravitational force experienced by the rocket.
- </p>
- <p class="equation">
- $$R_f = \frac{R_e - R_{pole}}{R_e}$$
- $$R_E = R_e (1 - R_f \cdot sin^2 \varphi)$$
- </p>
- <div class="variables">
- <div class="input">
- <h3>Inputs</h3>
- <dl>
- <dt>$R_e$</dt>
- <dd>Equatorial radius (m)</dd>
- <dt>$R_{pole}$</dt>
- <dd>Polar radius (m)</dd>
- <dt>$\varphi$</dt>
- <dd>Latitude (&#x00b0;)</dd>
- </dl>
- </div>
- <div class="output">
- <h3>Outputs</h3>
- <dl>
- <dt>$R_f$</dt>
- <dd>Flattening ratio</dd>
- <dt>$R_E$</dt>
- <dd>Effective radius (m)</dd>
- </dl>
- </div>
- </div>
-
- <h2>Rotational velocity</h2>
- <p>
- Calculates the rotational speed that the rocket gains by being
- launched at a given latitude.
- </p>
- <p class="equation">
- $$\omega = R_E(\varphi) \frac{2 \pi}{T_s}$$
- </p>
- <div class="variables">
- <div class="input">
- <h3>Inputs</h3>
- <dl>
- <dt>$R_E$</dt>
- <dd>Effective radius (m)</dd>
- <dt>$\varphi$</dt>
- <dd>Latitude (&#x00b0;)</dd>
- <dt>$T_s$</dt>
- <dd>Sidereal time (86164.0905&#160;s)</dd>
- </dl>
- </div>
- <div class="output">
- <h3>Output</h3>
- <dl>
- <dt>$\omega$</dt>
- <dd>Rotational velocity (m/s)</dd>
- </dl>
- </div>
- </div>
-
- <h2>Orbital velocity</h2>
- <p>
- Calculates the necessary speed the rocket needs to reach to enter a
- stable orbit.
- </p>
- <p class="equation">
- $$v_{o} = \sqrt{\frac{G}{R_E(\varphi) + h}}$$
- </p>
- <div class="variables">
- <div class="input">
- <h3>Inputs</h3>
- <dl>
- <dt>$G$</dt>
- <dd>Standard gravitational parameter (m/s<sup>2</sup>)</dd>
- <dt>$R_E$</dt>
- <dd>Effective radius (m)</dd>
- <dt>$\varphi$</dt>
- <dd>Latitude (&#x00b0;)</dd>
- <dt>$h$</dt>
- <dd>Altitude (m)</dd>
- </dl>
- </div>
- <div class="output">
- <h3>Output</h3>
- <dl>
- <dt>$v_{o}$</dt>
- <dd>Orbital velocity (m/s)</dd>
- </dl>
- </div>
- </div>
-
- <h2>Gravity</h2>
- <p>
- Calculates the gravitational forces experienced by the rocket, which must
- be overcome to reach a stable orbit.
- </p>
- <p class="equation">
- $$g = g_0 \big[1 + 0.0053024 \cdot sin^2(\varphi) - 0.0000058 \cdot sin^2(2\varphi)\big] + \left(-3.086 \times 10^{-6} h\right)$$
- </p>
- <div class="variables">
- <div class="input">
- <h3>Inputs</h3>
- <dl>
- <dt>$g_0$</dt>
- <dd>Surface gravity (m/s<sup>2</sup>)</dd>
- <dt>$\varphi$</dt>
- <dd>Latitude (&#x00b0;)</dd>
- <dt>$h$</dt>
- <dd>Altitude (m)</dd>
- </dl>
- </div>
- <div class="output">
- <h3>Output</h3>
- <dl>
- <dt>$g$</dt>
- <dd>Gravity (m/s<sup>2</sup>)</dd>
- </dl>
- </div>
- </div>
-
- <h2>Speed of sound</h2>
- <p>
- Calculates the speed of sound given a velocity in Mach units. The
- speed of sound varies depending on altitude and temperature.
- </p>
- <p class="equation">
- $$cc = cc_s \sqrt{1 + \frac{T_s - \left(\frac{6h}{1000}\right)}{273.15}}$$
- </p>
- <div class="variables">
- <div class="input">
- <h3>Inputs</h3>
- <dl>
- <dt>$cc_s$</dt>
- <dd>Surface speed of sound (331.3&#160;m/s)</dd>
- <dt>$T_s$</dt>
- <dd>Surface temperature (&#x2103;)</dd>
- <dt>$h$</dt>
- <dd>Altitude (m)</dd>
- </dl>
- </div>
- <div class="output">
- <h3>Output</h3>
- <dl>
- <dt>$cc$</dt>
- <dd>Speed of sound (m/s)</dd>
- </dl>
- </div>
- </div>
-
- <h2>Drag force</h2>
- <p>
- Calculates the amount of drag experienced by the rocket, which must be
- overcome to reach a stable orbit.
- </p>
- <p class="equation">
- $$\rho = \rho_{air}(h)$$
- $$v_n = v_h - \omega$$
- $$v_t = \sqrt{v_n^2 + v_v^2}$$
- $$D = -\frac{1}{2} \rho \cdot C_d \cdot v_t$$
- $$\left( F_{drag_h}, F_{drag_v} \right) = \left( D \cdot v_n, D \cdot v_v \right)$$
- </p>
- <div class="variables">
- <div class="input">
- <h3>Inputs</h3>
- <dl>
- <dt>$\rho_{air}$</dt>
- <dd>Air density function (kg/m<sup>3</sup>)</dd>
- <dt>$h$</dt>
- <dd>Altitude (meters)</dd>
- <dt>$v_h$</dt>
- <dd>Horizontal velocity (m/s)</dd>
- <dt>$\omega$</dt>
- <dd>Rotational velocity (m/s)</dd>
- <dt>$v_v$</dt>
- <dd>Vertical velocity (m/s)</dd>
- <dt>$C_d$</dt>
- <dd>Ballistic coefficient</dd>
- </dl>
- </div>
- <div class="output">
- <h3>Outputs</h3>
- <dl>
- <dt>$\rho$</dt>
- <dd>Air density at altitude (kg/m<sup>3</sup>)</dd>
- <dt>$v_n$</dt>
- <dd>Net horizontal velocity (m/s)</dd>
- <dt>$v_t$</dt>
- <dd>Total speed (m/s)</dd>
- <dt>$D$</dt>
- <dd>Drag force value (N · s/m)</dd>
- <dt>$F_{drag_h}$</dt>
- <dd>Horizontal drag force (N)</dd>
- <dt>$F_{drag_v}$</dt>
- <dd>Vertical drag force (N)</dd>
- </dl>
- </div>
- </div>
-
- <h2>Acceleration</h2>
- <p>
- Calculates how quickly the rocket increases its velocity, taking both
- drag and gravitational forces into account.
- </p>
- <p class="equation">
- $$F_{t_v} = -F_{drag_v}$$
- $$F_{t_h} = \sqrt{F_t^2 - F_{t_v}^2}$$
- $$a_h = \frac{F_{drag_h}}{m} + \frac{F_{t_h}}{m}$$
- $$a_v = \frac{F_{drag_v}}{m} + g(\varphi, h) + \frac{F_{t_v}}{m}$$
- </p>
- <div class="variables">
- <div class="input">
- <h3>Inputs</h3>
- <dl>
- <dt>$F_{drag_h}$</dt>
- <dd>Horizontal drag force (N)</dd>
- <dt>$F_{drag_v}$</dt>
- <dd>Vertical drag force (N)</dd>
- <dt>$F_t$</dt>
- <dd>Total thrust force (N)</dd>
- <dt>$m$</dt>
- <dd>Rocket mass (kg)</dd>
- <dt>$g(\varphi, h)$</dt>
- <dd>Gravitational acceleration (m/s<sup>2</sup>)</dd>
- <dt>$\varphi$</dt>
- <dd>Latitude (degrees)</dd>
- <dt>$h$</dt>
- <dd>Altitude (m)</dd>
- </dl>
- </div>
- <div class="output">
- <h3>Outputs</h3>
- <dl>
- <dt>$F_{t_v}$</dt>
- <dd>Vertical thrust (N)</dd>
- <dt>$F_{t_h}$</dt>
- <dd>Horizontal thrust (N)</dd>
- <dt>$a_h$</dt>
- <dd>Horizontal acceleration (m/s<sup>2</sup>)</dd>
- <dt>$a_v$</dt>
- <dd>Vertical acceleration (m/s<sup>2</sup>)</dd>
- </dl>
- </div>
- </div>
- </xsl:template>
-
- <xsl:template name="custom-scripts">
- <script
- src="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.js" />
- <script
- src="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/contrib/auto-render.min.js" />
- <script>
+ href="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.css"
+ integrity="sha512-fHwaWebuwA7NSF5Qg/af4UeDx9XqUpYpOGgubo3yWu+b2IQR4UeQwbb42Ti7gVAjNtVoI/I9TEoYeu9omwcC6g=="
+ crossorigin="anonymous"
+ referrerpolicy="no-referrer" />
+ </xsl:template>
+
+ <xsl:template match="/root" mode="header">
+ <h1>Orbital Launch Insertion</h1>
+ </xsl:template>
+
+ <xsl:template match="/root" mode="content">
+ <p>
+ Helps determine whether a payload can be inserted into a stable orbit.
+ Form field values are explained in the <a href="#equations">Equations</a>
+ section, below.
+ </p>
+
+ <form id="calculator">
+ <button class="submit">Simulate</button>
+
+ <fieldset id="environment">
+ <legend>Environment</legend>
+ <label for="surface_temperature">Surface temperature (&#x2103;)</label>
+ <input tabindex="1"
+ class="variable" type="number" step="1" min="-80" value="25"
+ id="surface_temperature" name="surface_temperature" />
+
+ <label for="relative_humidity">Relative humidity</label>
+ <input tabindex="2"
+ class="variable" type="number" step="0.01" min="0" value="86.34"
+ id="surface_temperature" name="surface_temperature" />
+ </fieldset>
+
+ <fieldset id="mission">
+ <legend>Mission</legend>
+ <label for="initial_velocity">Initial velocity (Mach)</label>
+ <input tabindex="3"
+ class="variable" type="number" step="1" min="0" value="8"
+ id="initial_velocity" name="initial_velocity" />
+
+ <label for="initial_latitude">Initial latitude (&#x00b0;)</label>
+ <input tabindex="4"
+ class="variable" type="number" step="any" min="0" value="1.469167"
+ id="initial_latitude" name="initial_latitude" />
+
+ <label for="initial_altitude">Initial altitude (m)</label>
+ <input tabindex="5"
+ class="variable" type="number" step="1" min="0" value="6212"
+ id="initial_altitude" name="initial_altitude" />
+
+ <label for="target_altitude">Target altitude (km)</label>
+ <input tabindex="6"
+ class="variable" type="number" step="1" min="1" value="400"
+ id="target_altitude" name="target_altitude" />
+ </fieldset>
+
+ <fieldset id="rocket">
+ <legend>Rocket</legend>
+ <label for="diameter">Diameter (m)</label>
+ <input tabindex="7" class="variable" type="number"
+ step="any" min="0" value="0.6" id="diameter" name="diameter" />
+
+ <label for="wet_mass">Wet mass (kg)</label>
+ <input tabindex="8"
+ class="variable" type="number" step="1" min="1" value="250"
+ id="wet_mass" name="wet_mass"
+ oninput="this.value = Math.abs(this.value)" />
+
+ <label for="payload">Payload mass (kg)</label>
+ <input tabindex="9"
+ class="variable" type="number" step="1" min="1" value="25"
+ id="payload_mass" name="payload_mass"
+ oninput="this.value = Math.abs(this.value)" />
+
+ <label for="drag_coefficient">Drag coefficient</label>
+ <input tabindex="10"
+ class="variable" type="number" step="any" min="0" value="0.219"
+ id="drag_coefficient" name="drag_coefficient" />
+
+ <label for="specific_impulse">Specific impulse (s)</label>
+ <input tabindex="11"
+ class="variable" type="number" step="1" min="1" value="1700"
+ id="specific_impulse" name="specific_impulse" />
+ </fieldset>
+
+ <button class="submit">Simulate</button>
+
+ <fieldset id="result">
+ <legend>Result</legend>
+ <div id="plots">
+ </div>
+ </fieldset>
+ </form>
+
+ <a name="equations" />
+ <h1>Equations</h1>
+ <p>
+ This section describes equation inputs and outputs.
+ </p>
+
+ <h2>Cross-section area</h2>
+ <p>
+ Calculates the ballistic coefficient of friction, which helps
+ determine the drag force magnitude experienced by the rocket.
+ </p>
+ <p class="equation">
+ $$A = \pi (d / 2)^2$$
+ </p>
+ <div class="variables">
+ <div class="input">
+ <h3>Input</h3>
+ <dl>
+ <dt>$d$</dt>
+ <dd>Rocket diameter (m)</dd>
+ </dl>
+ </div>
+ <div class="output">
+ <h3>Output</h3>
+ <dl>
+ <dt>$A$</dt>
+ <dd>Rocket's cross-section area (m<sup>2</sup>)</dd>
+ </dl>
+ </div>
+ </div>
+
+ <h2>Air pressure</h2>
+ <p>
+ Calculates the amount of pressure air exerts at a given altitude.
+ </p>
+ <p class="equation">
+ $$P = P_{sea} \bigg( 1 + \frac{L}{T} h \bigg) ^ {\frac{-g_0 \cdot M}{R \cdot L}}$$
+ </p>
+ <div class="variables">
+ <div class="input">
+ <h3>Input</h3>
+ <dl>
+ <dt>$P_{sea}$</dt>
+ <dd>Sea level pressure (101325&#160;Pa)</dd>
+ <dt>$L$</dt>
+ <dd>Lapse rate (-0.0065&#160;K/m)</dd>
+ <dt>$T$</dt>
+ <dd>Temperature (K)</dd>
+ <dt>$h$</dt>
+ <dd>Altitude (m)</dd>
+ <dt>$g_0$</dt>
+ <dd>Gravitational acceleration constant (9.80665&#160;m/s<sup>2</sup>)</dd>
+ <dt>$M$</dt>
+ <dd>Earth's atmospheric molar mass (0.0289644&#160;kg/mol)</dd>
+ <dt>$R$</dt>
+ <dd>Universal gas constant (8.31432&#160;N⋅m/mol⋅K)</dd>
+ </dl>
+ </div>
+ <div class="output">
+ <h3>Output</h3>
+ <dl>
+ <dt>$P$</dt>
+ <dd>Air pressure (Pa)</dd>
+ </dl>
+ </div>
+ </div>
+
+ <h2>Tetens equation</h2>
+ <p>
+ Calculates the saturation vapour pressure of water at a given temperature.
+ </p>
+ <p class="equation">
+ $$P_v = 0.61078 \cdot e ^ {17.27 T / (T + 237.31)}$$
+ </p>
+ <div class="variables">
+ <div class="input">
+ <h3>Inputs</h3>
+ <dl>
+ <dt>$T$</dt>
+ <dd>Temperature (&#x2103;)</dd>
+ </dl>
+ </div>
+ <div class="output">
+ <h3>Output</h3>
+ <dl>
+ <dt>$P_v$</dt>
+ <dd>Vapour pressure (Pa)</dd>
+ </dl>
+ </div>
+ </div>
+
+ <h2>Air density</h2>
+ <p>
+ Calculates the density of air at a given altitude, which helps determine
+ the drag force due to air experienced by the rocket.
+ </p>
+ <p class="equation">
+ $$\rho = \left(\frac{P_d}{R_d \cdot T}\right) + \left(\frac{P_v}{R_v \cdot T}\right)$$
+ </p>
+ <div class="variables">
+ <div class="input">
+ <h3>Inputs</h3>
+ <dl>
+ <dt>$P_d$</dt>
+ <dd>Partial pressure of dry air (Pa)</dd>
+ <dt>$P_v$</dt>
+ <dd>Partial pressure of water vapor (Pa)</dd>
+ <dt>$T$</dt>
+ <dd>Temperature (&#x2103;)</dd>
+ <dt>$R_d$</dt>
+ <dd>Specific gas constant for dry air (287.058&#160;J/(kg⋅K))</dd>
+ <dt>$R_v$</dt>
+ <dd>Specific gas constant for water vapour (461.495&#160;J/(kg⋅K))</dd>
+ </dl>
+ </div>
+ <div class="output">
+ <h3>Output</h3>
+ <dl>
+ <dt>$\rho$</dt>
+ <dd>Air density (kg/m<sup>3</sup>)</dd>
+ </dl>
+ </div>
+ </div>
+
+ <h2>Earth effective radius</h2>
+ <p>
+ Calculates Earth's radius at a given latitude, which helps determine
+ the main gravitational force experienced by the rocket.
+ </p>
+ <p class="equation">
+ $$R_f = \frac{R_e - R_{pole}}{R_e}$$
+ $$R_E = R_e (1 - R_f \cdot sin^2 \varphi)$$
+ </p>
+ <div class="variables">
+ <div class="input">
+ <h3>Inputs</h3>
+ <dl>
+ <dt>$R_e$</dt>
+ <dd>Equatorial radius (m)</dd>
+ <dt>$R_{pole}$</dt>
+ <dd>Polar radius (m)</dd>
+ <dt>$\varphi$</dt>
+ <dd>Latitude (&#x00b0;)</dd>
+ </dl>
+ </div>
+ <div class="output">
+ <h3>Outputs</h3>
+ <dl>
+ <dt>$R_f$</dt>
+ <dd>Flattening ratio</dd>
+ <dt>$R_E$</dt>
+ <dd>Effective radius (m)</dd>
+ </dl>
+ </div>
+ </div>
+
+ <h2>Rotational velocity</h2>
+ <p>
+ Calculates the rotational speed that the rocket gains by being
+ launched at a given latitude.
+ </p>
+ <p class="equation">
+ $$\omega = R_E(\varphi) \frac{2 \pi}{T_s}$$
+ </p>
+ <div class="variables">
+ <div class="input">
+ <h3>Inputs</h3>
+ <dl>
+ <dt>$R_E$</dt>
+ <dd>Effective radius (m)</dd>
+ <dt>$\varphi$</dt>
+ <dd>Latitude (&#x00b0;)</dd>
+ <dt>$T_s$</dt>
+ <dd>Sidereal time (86164.0905&#160;s)</dd>
+ </dl>
+ </div>
+ <div class="output">
+ <h3>Output</h3>
+ <dl>
+ <dt>$\omega$</dt>
+ <dd>Rotational velocity (m/s)</dd>
+ </dl>
+ </div>
+ </div>
+
+ <h2>Orbital velocity</h2>
+ <p>
+ Calculates the necessary speed the rocket needs to reach to enter a
+ stable orbit.
+ </p>
+ <p class="equation">
+ $$v_{o} = \sqrt{\frac{G}{R_E(\varphi) + h}}$$
+ </p>
+ <div class="variables">
+ <div class="input">
+ <h3>Inputs</h3>
+ <dl>
+ <dt>$G$</dt>
+ <dd>Standard gravitational parameter (m/s<sup>2</sup>)</dd>
+ <dt>$R_E$</dt>
+ <dd>Effective radius (m)</dd>
+ <dt>$\varphi$</dt>
+ <dd>Latitude (&#x00b0;)</dd>
+ <dt>$h$</dt>
+ <dd>Altitude (m)</dd>
+ </dl>
+ </div>
+ <div class="output">
+ <h3>Output</h3>
+ <dl>
+ <dt>$v_{o}$</dt>
+ <dd>Orbital velocity (m/s)</dd>
+ </dl>
+ </div>
+ </div>
+
+ <h2>Gravity</h2>
+ <p>
+ Calculates the gravitational forces experienced by the rocket, which must
+ be overcome to reach a stable orbit.
+ </p>
+ <p class="equation">
+ $$g = g_0 \big[1 + 0.0053024 \cdot sin^2(\varphi) - 0.0000058 \cdot sin^2(2\varphi)\big] + \left(-3.086 \times 10^{-6} h\right)$$
+ </p>
+ <div class="variables">
+ <div class="input">
+ <h3>Inputs</h3>
+ <dl>
+ <dt>$g_0$</dt>
+ <dd>Surface gravity (m/s<sup>2</sup>)</dd>
+ <dt>$\varphi$</dt>
+ <dd>Latitude (&#x00b0;)</dd>
+ <dt>$h$</dt>
+ <dd>Altitude (m)</dd>
+ </dl>
+ </div>
+ <div class="output">
+ <h3>Output</h3>
+ <dl>
+ <dt>$g$</dt>
+ <dd>Gravity (m/s<sup>2</sup>)</dd>
+ </dl>
+ </div>
+ </div>
+
+ <h2>Speed of sound</h2>
+ <p>
+ Calculates the speed of sound given a velocity in Mach units. The
+ speed of sound varies depending on altitude and temperature.
+ </p>
+ <p class="equation">
+ $$cc = cc_s \sqrt{1 + \frac{T_s - \left(\frac{6h}{1000}\right)}{273.15}}$$
+ </p>
+ <div class="variables">
+ <div class="input">
+ <h3>Inputs</h3>
+ <dl>
+ <dt>$cc_s$</dt>
+ <dd>Surface speed of sound (331.3&#160;m/s)</dd>
+ <dt>$T_s$</dt>
+ <dd>Surface temperature (&#x2103;)</dd>
+ <dt>$h$</dt>
+ <dd>Altitude (m)</dd>
+ </dl>
+ </div>
+ <div class="output">
+ <h3>Output</h3>
+ <dl>
+ <dt>$cc$</dt>
+ <dd>Speed of sound (m/s)</dd>
+ </dl>
+ </div>
+ </div>
+
+ <h2>Drag force</h2>
+ <p>
+ Calculates the amount of drag experienced by the rocket, which must be
+ overcome to reach a stable orbit.
+ </p>
+ <p class="equation">
+ $$\rho = \rho_{air}(h)$$
+ $$v_n = v_h - \omega$$
+ $$v_t = \sqrt{v_n^2 + v_v^2}$$
+ $$D = -\frac{1}{2} \rho \cdot C_d \cdot v_t$$
+ $$\left( F_{drag_h}, F_{drag_v} \right) = \left( D \cdot v_n, D \cdot v_v \right)$$
+ </p>
+ <div class="variables">
+ <div class="input">
+ <h3>Inputs</h3>
+ <dl>
+ <dt>$\rho_{air}$</dt>
+ <dd>Air density function (kg/m<sup>3</sup>)</dd>
+ <dt>$h$</dt>
+ <dd>Altitude (meters)</dd>
+ <dt>$v_h$</dt>
+ <dd>Horizontal velocity (m/s)</dd>
+ <dt>$\omega$</dt>
+ <dd>Rotational velocity (m/s)</dd>
+ <dt>$v_v$</dt>
+ <dd>Vertical velocity (m/s)</dd>
+ <dt>$C_d$</dt>
+ <dd>Ballistic coefficient</dd>
+ </dl>
+ </div>
+ <div class="output">
+ <h3>Outputs</h3>
+ <dl>
+ <dt>$\rho$</dt>
+ <dd>Air density at altitude (kg/m<sup>3</sup>)</dd>
+ <dt>$v_n$</dt>
+ <dd>Net horizontal velocity (m/s)</dd>
+ <dt>$v_t$</dt>
+ <dd>Total speed (m/s)</dd>
+ <dt>$D$</dt>
+ <dd>Drag force value (N · s/m)</dd>
+ <dt>$F_{drag_h}$</dt>
+ <dd>Horizontal drag force (N)</dd>
+ <dt>$F_{drag_v}$</dt>
+ <dd>Vertical drag force (N)</dd>
+ </dl>
+ </div>
+ </div>
+
+ <h2>Acceleration</h2>
+ <p>
+ Calculates how quickly the rocket increases its velocity, taking both
+ drag and gravitational forces into account.
+ </p>
+ <p class="equation">
+ $$F_{t_v} = -F_{drag_v}$$
+ $$F_{t_h} = \sqrt{F_t^2 - F_{t_v}^2}$$
+ $$a_h = \frac{F_{drag_h}}{m} + \frac{F_{t_h}}{m}$$
+ $$a_v = \frac{F_{drag_v}}{m} + g(\varphi, h) + \frac{F_{t_v}}{m}$$
+ </p>
+ <div class="variables">
+ <div class="input">
+ <h3>Inputs</h3>
+ <dl>
+ <dt>$F_{drag_h}$</dt>
+ <dd>Horizontal drag force (N)</dd>
+ <dt>$F_{drag_v}$</dt>
+ <dd>Vertical drag force (N)</dd>
+ <dt>$F_t$</dt>
+ <dd>Total thrust force (N)</dd>
+ <dt>$m$</dt>
+ <dd>Rocket mass (kg)</dd>
+ <dt>$g(\varphi, h)$</dt>
+ <dd>Gravitational acceleration (m/s<sup>2</sup>)</dd>
+ <dt>$\varphi$</dt>
+ <dd>Latitude (degrees)</dd>
+ <dt>$h$</dt>
+ <dd>Altitude (m)</dd>
+ </dl>
+ </div>
+ <div class="output">
+ <h3>Outputs</h3>
+ <dl>
+ <dt>$F_{t_v}$</dt>
+ <dd>Vertical thrust (N)</dd>
+ <dt>$F_{t_h}$</dt>
+ <dd>Horizontal thrust (N)</dd>
+ <dt>$a_h$</dt>
+ <dd>Horizontal acceleration (m/s<sup>2</sup>)</dd>
+ <dt>$a_v$</dt>
+ <dd>Vertical acceleration (m/s<sup>2</sup>)</dd>
+ </dl>
+ </div>
+ </div>
+ </xsl:template>
+
+ <xsl:template name="custom-scripts">
+ <script
+ src="//cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js"
+ integrity="sha512-vc58qvvBdrDR4etbxMdlTt4GBQk1qjvyORR2nrsPsFPyrs+/u5c3+1Ct6upOgdZoIl7eq6k3a1UPDSNAQi/32A=="
+ crossorigin="anonymous"
+ referrerpolicy="no-referrer"
+ />
+ <script
+ src="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.js"
+ integrity="sha512-LQNxIMR5rXv7o+b1l8+N1EZMfhG7iFZ9HhnbJkTp4zjNr5Wvst75AqUeFDxeRUa7l5vEDyUiAip//r+EFLLCyA=="
+ crossorigin="anonymous"
+ referrerpolicy="no-referrer" />
+ <script
+ src="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/contrib/auto-render.min.js"
+ integrity="sha512-iWiuBS5nt6r60fCz26Nd0Zqe0nbk1ZTIQbl3Kv7kYsX+yKMUFHzjaH2+AnM6vp2Xs+gNmaBAVWJjSmuPw76Efg=="
+ crossorigin="anonymous"
+ referrerpolicy="no-referrer" />
+ <script>
renderMathInElement(
document.body, {

Revises atmospheric calculations

Author djarvis <email>
Date 2024-11-28 12:21:36 GMT-0800
Commit 64b1de946d706972b3b37d3e81c161ac3c40b098
Parent eb90e1d
Delta 665 lines added, 520 lines removed, 145-line increase