fixed burn time calculations for multi stage burns

This commit is contained in:
2026-04-19 21:52:07 -04:00
parent 9a4ae5e472
commit 7431ab7946
13 changed files with 221 additions and 155 deletions
+2 -7
View File
@@ -1,9 +1,4 @@
import("library/lib_vessel_utils").
import("library/lib_ascent"). import("library/lib_ascent").
import("library/lib_orbits").
WaitForEngineStart(). WaitForEngineStart().
@@ -11,9 +6,9 @@ CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Open Terminal").
set profile to 1.2. set profile to 1.2.
set turn_start to 1000. set turn_start to 1000.
set target_orbit to 100000. set target_orbit to 150000.
Ascent(target_orbit, turn_start, profile). Ascent(target_orbit, turn_start, profile, 0).
print "Orbit Achieved, Releasing Controls". print "Orbit Achieved, Releasing Controls".
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Close Terminal"). CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Close Terminal").
+6
View File
@@ -0,0 +1,6 @@
wait until ship:unpacked.
clearscreen.
copyPath("0:/defaults", "").
run "defaults".
import("faris3").
+6
View File
@@ -0,0 +1,6 @@
wait until ship:unpacked.
clearscreen.
copyPath("0:/defaults", "").
run "defaults".
import("itsuki").
+6
View File
@@ -0,0 +1,6 @@
wait until ship:unpacked.
clearscreen.
copyPath("0:/defaults", "").
run "defaults".
import("koyuki").
+6
View File
@@ -0,0 +1,6 @@
wait until ship:unpacked.
clearscreen.
copyPath("0:/defaults", "").
run "defaults".
import("tests").
+1 -4
View File
@@ -1,8 +1,6 @@
import("library/lib_vessel_utils").
import("library/lib_ascent"). import("library/lib_ascent").
import("library/lib_orbits").
WaitForEngineStart(). WaitForEngineStart().
@@ -12,9 +10,8 @@ set profile to 1.2.
set turn_start to 1000. set turn_start to 1000.
set target_orbit to 100000. set target_orbit to 100000.
Ascent(target_orbit, turn_start, profile). Ascent(target_orbit, turn_start, profile, 1).
print "Orbit Achieved, Releasing Controls". print "Orbit Achieved, Releasing Controls".
print "Circ DV" + CalculateCircularizationDV().
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Close Terminal"). CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Close Terminal").
SHUTDOWN. SHUTDOWN.
+39
View File
@@ -0,0 +1,39 @@
import("library/lib_ascent").
WaitForEngineStart().
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Open Terminal").
set profile to 1.2.
set turn_start to 1000.
set target_orbit to 100000.
Ascent(target_orbit, turn_start, profile, 1).
wait 3.
lock steering to retrograde.
wait 10.
lock throttle to 1.
wait until ship:deltav:current <= 0.
wait 0.01.
stage.
set kuniverse:timewarp:rate to 10.
wait until kuniverse:timewarp:rate = 0.
lock steering to srfRetrograde.
wait until surfaceSpeed < 1000.
unlock steering.
set kuniverse:timewarp:rate to 5.
wait until ship:status = "LANDED" or ship:status = "SPLASHED".
SET V0 TO GETVOICE(0).
V0:PLAY( NOTE(400, 2.5) ).
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Close Terminal").
SHUTDOWN.
+19
View File
@@ -0,0 +1,19 @@
import("library/lib_vessel_utils").
import("library/lib_ascent").
import("library/lib_orbits").
WaitForEngineStart().
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Open Terminal").
set profile to 1.2.
set turn_start to 1000.
set target_orbit to 120000.
Ascent(target_orbit, turn_start, profile, 0, 73).
print "Orbit Achieved, Releasing Controls".
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Close Terminal").
SHUTDOWN.
+17
View File
@@ -0,0 +1,17 @@
import("library/lib_ascent").
WaitForEngineStart().
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Open Terminal").
set profile to 1.2.
set turn_start to 1000.
set target_orbit to 130000.
Ascent(target_orbit, turn_start, profile, 0).
print "Orbit Achieved, Releasing Controls".
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Close Terminal").
SHUTDOWN.
+41 -17
View File
@@ -5,16 +5,23 @@ import("library/lib_orbits").
declare function Ascent{ declare function Ascent{
parameter targetOrbit is 100. parameter targetOrbit is 100000.
parameter vericalAscent is 1000. parameter vericalAscent is 1000.
parameter ascentProfile is 1.2. parameter ascentProfile is 1.2.
parameter circ is 1.
parameter inc is 0.
print "Params (" + targetOrbit + ", " + vericalAscent + ", " + ascentProfile + ", " + circ + ", " + inc + ")".
print "Vertical Climb to " + vericalAscent. print "Vertical Climb to " + vericalAscent.
set tgtPitch to 90. set tgtPitch to 90.
set isDone to false.
lock throttle to 1. lock throttle to 1.
lock steering to heading(90, tgtPitch, 270). local head to 90 + inc.
lock steering to heading(head, tgtPitch, 270).
local lock asccent_prog to Map(apoapsis, 0, targetOrbit, 0.0, 1.0). local lock asccent_prog to Map(apoapsis, 0, targetOrbit, 0.0, 1.0).
@@ -25,17 +32,21 @@ declare function Ascent{
local lock tgtPitch to (1 - ease) * 90. local lock tgtPitch to (1 - ease) * 90.
when periapsis < targetOrbit then { when periapsis < targetOrbit then {
print "P: " + round(asccent_prog, 2) + " T:" + round(ease, 2) + " Pitch: " + round(tgtPitch, 2) + " " at(0, 2). print "P: " + round(asccent_prog, 2) + " T:" + round(ease, 2) + " Pitch: " + round(tgtPitch, 2) + " " at(0, 3).
print "Ap: " + round(apoapsis, 2) + " Pe:" + round(periapsis, 2) + " Alt: " + round(altitude, 2) + " " at(0, 3). print "Ap: " + round(apoapsis, 2) + " Pe:" + round(periapsis, 2) + " Alt: " + round(altitude, 2) + " " at(0, 4).
wait 0.1. wait 0.1.
preserve. if not isDone{
preserve.
}
} }
//Auto Staging //Auto Staging
when periapsis < targetOrbit then{ when periapsis < targetOrbit then{
AutoStage(). AutoStage().
wait 0.01. wait 0.01.
preserve. if not isDone{
preserve.
}
} }
wait until apoapsis >= targetOrbit. wait until apoapsis >= targetOrbit.
@@ -44,44 +55,57 @@ declare function Ascent{
lock tgtPitch to 0. lock tgtPitch to 0.
unlock steering. unlock steering.
if circ = 1 {
CircularizeBrute(targetOrbit, head).
}else if circ = 2{
Circularize(targetOrbit, head).
}
CircularizeBrute(targetOrbit). set isDone to true.
unlock steering. unlock steering.
unlock throttle. unlock throttle.
wait until throttle = 0.
} }
local function Circularize{ local function Circularize{
parameter targetOrbit. parameter targetOrbit.
parameter head.
lock throttle to 0. lock throttle to 0.
lock steering to heading(90, 0, 270). lock steering to heading(head, 0, 270).
local warpTime is eta:apoapsis. local warpTime is eta:apoapsis.
local burnDv is CalculateCircularizationDV(). local burnDv is CalculateCircularizationDV(targetOrbit, orbit:semimajoraxis).
local burnDuration is CalculateMultiStageBurnDuration(burnDv). local burnDuration is CalculateMultiStageBurnDuration(burnDv).
print "Warping to Circularization. " + round(burnDv) + "m/s. T: " + round(burnDuration, 2) + "s" at(0, 4). local remDv is ship:deltav:current - burnDv.
set warpTime to warpTime - burnDuration. print "Warping to Circularization. " + round(burnDv) + "m/s. T: " + round(burnDuration, 2) + "s" at(0, 5).
print "Final Dv expected: " + remDv + "m/s".
set warpTime to warpTime - burnDuration /2.
if warpTime > 0 { if warpTime > 0 {
wait until throttle = 0. wait until throttle = 0.
wait 0.01. //Wait for accelleration to stop wait 0.01. //Wait for accelleration to stop
warpTo(time:seconds + warpTime). set warpmode to "physics".
warpTo(time:seconds + warpTime - 3).
wait until eta:apoapsis >= burnDuration /2.
} }
wait until eta:apoapsis <= burnDuration.
lock throttle to 1. lock throttle to 1.
// wait burnDuration.
wait until periapsis >= targetOrbit. wait until periapsis >= targetOrbit.
lock throttle to 0. lock throttle to 0.
wait 0.01.
} }
local function CircularizeBrute{ local function CircularizeBrute{
parameter targetOrbit. parameter targetOrbit.
parameter head.
lock throttle to 1. lock throttle to 1.
lock steering to heading(90, 0, 270). lock steering to heading(head, 0, 270).
wait until periapsis >= targetOrbit. wait until periapsis >= targetOrbit.
lock throttle to 0. lock throttle to 0.
} }
+10 -72
View File
@@ -5,84 +5,22 @@ declare function CreateDeorbit{
parameter offsetX is 0.0. parameter offsetX is 0.0.
parameter offsetZ is 0.0. parameter offsetZ is 0.0.
local tol to 100.
lock steering to retrograde.
local lock align to vDot(ship:facing:vector, retrograde:vector).
wait until align > 0.95.
print align.
if dv > 0 {
set dv to dv * -1.
}
local tr to ADDONS:TR.
if not tr:AVAILABLE {
print "Trajectoris is not available".
return.
}
tr:settarget(target).
local deorbit to NODE(time:seconds + 200, 0, 0, dv).
until not hasNode{
remove nextNode.
wait 0.001.
}
add deorbit.
wait until tr:hasimpact.
local ipos to tr:impactpos.
local lock offset to (ipos:ALTITUDEPOSITION(0) - target:ALTITUDEPOSITION(0)).
local lock xDist to offset:x.
local lock zDist to ipos:lat - target:lat.
local dt is 60.
when xDist < 500000 then{
set dt to 30.
}
when xDist < 100000 then{
set dt to 5.
}
when xDist < 10000 then{
set dt to 1.
}
when xDist < 5000 then{
set dt to 0.5.
}
until xDist < offsetX + tol {
remove nextNode.
wait 0.001.
set deorbit:eta to deorbit:eta + dt.
add deorbit.
wait until tr:hasimpact.
set ipos to tr:impactpos.
wait 0.001.
}
until abs(zDist) < offsetZ + tol{
remove nextNode.
wait 0.001.
if zDist > 0 {
set deorbit:normal to deorbit:normal - 0.1.
} else{
set deorbit:normal to deorbit:normal + 0.1.
}
add deorbit.
wait until tr:hasimpact.
set ipos to tr:impactpos.
}
unlock steering.
} }
declare function CalculateCircularizationDV{ declare function CalculateCircularizationDV{
parameter ap is 0.
parameter sma is 0.
local mu is body:mu. local mu is body:mu.
if ap = 0 {
set ap to apoapsis.
}
if sma = 0 {
set sma to orbit:semimajoraxis.
}
local apR is apoapsis + body:radius. local apR is ap + body:radius.
local circVel is sqrt(mu / apR). local circVel is sqrt(mu / apR).
local apVel is sqrt(mu * ((2 / apR) - (1 / orbit:semimajoraxis))). local apVel is sqrt(mu * ((2 / apR) - (1 / sma))).
return circVel - apVel. return circVel - apVel.
} }
+45 -52
View File
@@ -16,8 +16,8 @@ declare function GetDragDir{
} }
declare function AnyEngineActive{ declare function AnyEngineActive{
list engines in allEngines. list engines in egs.
for eng in allEngines{ for eng in egs{
if eng:ignition { if eng:ignition {
return true. return true.
} }
@@ -26,11 +26,11 @@ declare function AnyEngineActive{
} }
declare function GetIsp{ declare function GetIsp{
LIST ENGINES IN allEngines. LIST ENGINES IN egs.
declare local totalThrust is ship:maxThrust. declare local totalThrust is ship:maxThrust.
local sum is 0. local sum is 0.
local weights is 0. local weights is 0.
for eng in allEngines{ for eng in egs{
if eng:IGNITION and not eng:flameout{ if eng:IGNITION and not eng:flameout{
local w is eng:AVAILABLETHRUST / totalThrust. local w is eng:AVAILABLETHRUST / totalThrust.
local ispW is eng:isp * w. local ispW is eng:isp * w.
@@ -42,15 +42,18 @@ declare function GetIsp{
} }
declare function GetIspForStage{ declare function GetIspForStage{
parameter engineState. parameter engineStage.
parameter pressure is 0. parameter pressure is 0.
LIST ENGINES IN allEngines. LIST ENGINES IN egs.
local totalThrust is GetThrustOfStage(engineState). local totalThrust is GetThrustOfStage(engineStage, pressure).
if totalThrust = 0{
return 0.
}
local sum is 0. local sum is 0.
local weights is 0. local weights is 0.
for eng in allEngines{ for eng in egs{
if eng:stage = engineState { if eng:stage = engineStage {
local w is eng:POSSIBLETHRUST / totalThrust. local w is eng:POSSIBLETHRUSTAT(pressure) / totalThrust.
local ispW is eng:ispat(pressure) * w. local ispW is eng:ispat(pressure) * w.
set sum to sum + ispW. set sum to sum + ispW.
set weights to weights + w. set weights to weights + w.
@@ -60,9 +63,9 @@ declare function GetIspForStage{
} }
declare function GetMaxMassFlow{ declare function GetMaxMassFlow{
LIST ENGINES IN allEngines. LIST ENGINES IN egs.
local sum is 0. local sum is 0.
for eng in allEngines{ for eng in egs{
if eng:IGNITION and not eng:flameout{ if eng:IGNITION and not eng:flameout{
set sum to sum + eng:maxmassflow. set sum to sum + eng:maxmassflow.
} }
@@ -70,6 +73,18 @@ declare function GetMaxMassFlow{
return sum. return sum.
} }
declare function GetMaxMassFlowForStage{
parameter engineStage.
LIST ENGINES IN egs.
local sum is 0.
for eng in egs{
if eng:stage = engineStage {
set sum to sum + eng:maxmassflow.
}
}
return sum.
}
@@ -86,9 +101,12 @@ declare function CalculateBurnDuration
parameter initialMass. parameter initialMass.
parameter massFlow. parameter massFlow.
if burnIsp = 0 {
return 0.
}
set dv to abs(dv). set dv to abs(dv).
local exp is -dv / (burnIsp * constant:g0). local exp is -dv / (burnIsp * constant:g0).
local massRatio is ApproximateExp(-exp). local massRatio is constant:e ^ (-exp).
local finalMass is initialMass / massRatio. local finalMass is initialMass / massRatio.
local fuelUsed is initialMass - finalMass. local fuelUsed is initialMass - finalMass.
@@ -151,67 +169,43 @@ declare function CalculateTimeToImpact{
function CalculateMultiStageBurnDuration{ function CalculateMultiStageBurnDuration{
parameter dv. parameter dv.
if ship:deltav:current >= dv { if ship:STAGEDELTAV(ship:stagenum):current >= dv {
print "one stage" at (0, 5). return CalculateBurnDuration(dv, GetIsp(), ship:mass, GetMaxMassFlow()).
return GetBurnTime(dv, ship:maxthrust, ship:mass).
}else{ }else{
print "multi stage" at (0, 5).
local burnTime is 0. local burnTime is 0.
local remDv is dv. local remDv is dv.
from {local s is ship:stagenum. } until s = 0 step { set s to s-1.} do { from {local s is ship:stagenum. } until s = -1 step { set s to s-1.} do {
if remDv <= 0 { if remDv <= 0 {
return burnTime. return burnTime.
} }
local cdv is ship:stagedeltav(s):current. local cdv is ship:stagedeltav(s):current.
local cmass is GetMassOfStage(s). local cmass is GetMassOfStage(s).
local cthrust is GetThrustOfStage(s). local cflow is GetMaxMassFlowForStage(s).
local cisp is GetIspForStage(s). local cisp is GetIspForStage(s).
local sdv is 0.
print cdv.
if cdv >= remDv { if cdv >= remDv {
set burnTime to burnTime + GetBurnTime(remDv, cmass, cthrust, cisp). set sdv to remDv.
}else{ }else{
set burnTime to burnTime + GetBurnTime(cdv, cmass, cthrust, cisp). set sdv to cdv.
} }
set burnTime to burnTime + CalculateBurnDuration(sdv, cisp, cmass, cflow).
set remDv to remDv - cdv. set remDv to remDv - cdv.
} }
return burnTime. return burnTime.
} }
} }
// Burn time from rocket equation
function GetBurnTime {
parameter deltaV.
parameter stagethrust is 0.
parameter stagemass is 0.
parameter isp is 0.
if deltaV:typename() = "Vector" {
set deltaV to deltaV:mag.
}
if isp = 0 {
set isp to GetIsp().
}
if stagethrust = 0 {
set stagethrust to ship:thrust.
}
if stagemass = 0 {
set stagemass to ship:mass.
}
local burnTime is -1.
if stagethrust <> 0 {
set burnTime to stagemass * (1 - CONSTANT:E ^ (-deltaV / isp)) / (stagethrust / isp).
}
return burnTime.
}
function GetThrustOfStage { function GetThrustOfStage {
parameter st. parameter st.
parameter pressure is 0.
local totalThrust is 0. local totalThrust is 0.
LIST ENGINES IN allEngines. LIST ENGINES IN egs.
for eng in allEngines{ for eng in egs{
if eng:stage = st { if eng:stage = st {
set totalThrust to totalThrust + eng:POSSIBLETHRUST. set totalThrust to totalThrust + eng:POSSIBLETHRUSTAT(pressure).
} }
} }
return totalThrust. return totalThrust.
@@ -219,12 +213,11 @@ function GetThrustOfStage {
function GetMassOfStage { function GetMassOfStage {
parameter st. parameter st.
local total is 0. local total is 0.
LIST PARTS IN allP. LIST PARTS IN allP.
for p in allP { for p in allP {
if p:stage <= st { if p:stage <= st and p:DECOUPLEDIN < st {
set total to total + p:mass. set total to total + p:mass.
} }
} }
+23 -3
View File
@@ -1,6 +1,26 @@
run "library/lib_vessel_utils". import("library/lib_vessel_utils").
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Open Terminal"). CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Open Terminal").
print "impact " + CalculateTimeToImpact(300, 500, 9.8). print "Waiting for Engine start".
print "Burn Duration" + CalculateBurnDuration(300, 350, 5000, 3000). WaitForEngineStart().
function printStatge {
parameter s is ship:stagenum.
local curDv is ship:STAGEDELTAV(s):current.
local isp is GetIspForStage(s).
local smass is GetMassOfStage(s).
local flow is GetMaxMassFlowForStage(s).
local thrust is GetThrustOfStage(s).
print "------ Stage: " + s + " ------".
print "Thrust: " + thrust + "kN Mass: " + round(smass, 3) + "t".
print "DV: " + round(curDv, 2) + "m/s ISP: " + round(isp, 2) + "s Flow: " + round(flow, 4) + "Mg/s".
print "Burn Duration: " + round(CalculateBurnDuration(curDv, isp, smass, flow), 2).
}
// printStatge(ship:stagenum).
// printStatge(ship:stagenum - 1).
print "Total Burn Time: " + CalculateMultiStageBurnDuration(ship:deltav:current).