import("library/lib_staging"). import("library/lib_math"). import("library/lib_vessel_utils"). import("library/lib_orbits"). import("library/lib_num_to_formatted_str"). import("library/lib_gui"). declare ASCENT_STATE is "Pre-Launch". declare function Ascent{ parameter targetOrbit is 100000, vericalAscent is 1000, ascentProfile is 1.2, circ is 1, inc is 0. // local tgtOrbitSI is si_formatting(targetOrbit, "m"). local vericalAscentSI is si_formatting(vericalAscent, "m"). set tgtPitch to 90. local head to 90 + inc. lock throttle to 1. PrepareHUD(targetOrbit, vericalAscent, ascentProfile, circ, inc). when true then { RenderHUD(vericalAscentSI, tgtPitch). wait 0.01. if ASCENT_STATE <> "DONE" { preserve. } } WaitForEngineStart(). lock steering to heading(head, tgtPitch, 270). local lock asccent_prog to Map(apoapsis, 0, targetOrbit, 0.0, 1.0). SetState("Vertical Ascent"). wait until altitude > vericalAscent and asccent_prog > 0. SetState("Gravity Turn"). local lock ease to EaseOutExp(asccent_prog, ascentProfile). lock tgtPitch to (1 - ease) * 90. //Auto Staging when periapsis < targetOrbit then{ AutoStage(). wait 0.01. if ASCENT_STATE <> "DONE" { preserve. } } wait until apoapsis >= targetOrbit. lock throttle to 0. unlock tgt_pitch. lock tgtPitch to 0. unlock steering. SetState("Circularization"). if circ = 1 { CircularizeBrute(targetOrbit, head). }else if circ = 2{ Circularize(targetOrbit, head). }else if circ = 3 { lock steering to heading(head, 0, 270). CreateCircularizationNode(apoapsis). } SetState("Done"). unlock steering. unlock throttle. wait until throttle = 0. } local function Circularize{ parameter tgt, head. lock throttle to 0. lock steering to heading(head, 0, 270). local warpTime is eta:apoapsis. local burnDv is CalculateCircularizationDV(tgt, orbit:semimajoraxis). local burnDuration is CalculateMultiStageBurnDuration(burnDv). local remDv is ship:deltav:current - burnDv. 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 { wait until throttle = 0. wait 0.01. //Wait for accelleration to stop set warpmode to "physics". warpTo(time:seconds + warpTime - 3). wait until eta:apoapsis >= burnDuration /2. } lock throttle to 1. // wait burnDuration. wait until periapsis >= tgt. lock throttle to 0. wait 0.01. } local function CircularizeBrute{ parameter tgt, head. lock throttle to 1. lock steering to heading(head, 0, 270). wait until periapsis >= tgt. lock throttle to 0. } local function CreateCircularizationNode{ parameter tgt. lock throttle to 0. local c is terminal:width /2. PrepareCircNodeHUD(). local burnDvSI is " ---". local burnDurationSI is " ---". local burnDuration is 0. when true then { PrintRightAligned(2, 12, c - 4, burnDvSI). PrintRightAligned(c, 12, c - 2, burnDurationSI). if hasNode { PrintRightAligned(2, 13, c - 4, si_formatting(nextNode:deltav:mag, "m/s")). PrintRightAligned(c, 13, c - 2, time_formatting(circNode:eta - burnDuration /2, 0, 0, true, false)). } wait 0.01. if ASCENT_STATE = "Circularization" { preserve. } } wait until altitude > 80000. local burnDv is CalculateCircularizationDV(tgt, orbit:semimajoraxis). set burnDvSI to si_formatting(burnDv, "m/s"). local circNode is Node(time:seconds + eta:apoapsis, 0, 0, burnDv). add circNode. wait 0.01. lock steering to circNode:burnvector. set burnDuration to CalculateMultiStageBurnDuration(burnDv). set burnDurationSI to time_formatting(burnDuration). wait until circNode:eta <= burnDuration /2. lock throttle to 1. wait until nextNode:deltav:mag <= 10. lock throttle to 0.25. wait until NEXTNODE:deltav:mag <= 1. lock throttle to 0. unlock steering. remove nextNode. wait 0.01. wait until throttle = 0. } local function PrepareHUD{ parameter targetOrbit, vericalAscent, ascentProfile, circ, inc. clearScreen. DrawWindow(0, 0, terminal:width, terminal:height, " Air Tako OS "). print "Ascent: " + si_formatting(vericalAscent, "m") + " with a " + ascentProfile + " ascent profile." at (2, 1). print "Orbit: " + si_formatting(targetOrbit, "m") + " at " + inc + "°" at (2, 2). local circText is "None". if circ = 1 { set circText to "Brute Force". }else if circ = 2{ set circText to "Blind Calculated". }else if circ = 3 { set circText to "Manuever Node". } print "Circularization Method: " + circText at (2, 3). //Orbit Separator DrawHorizontalLineCapped(0, 4, terminal:width, "┉"). PrintCentered(0, 5, terminal:width, "Orbit"). PrepareOrbitHUD(). //Guidance Separator DrawHorizontalLineCapped(0, 10, terminal:width, "┉"). PrintCentered(0, 11, terminal:width, "Guidance - " + ASCENT_STATE). //Status Bar DrawHorizontalLineCapped(0, terminal:height - 4, terminal:width, "┉"). PrepareGuidanceHUD(). } local function PrepareOrbitHUD{ local c is terminal:width /2. print "Altitude:" at (2, 6). print "Surface Alt:" at (c, 6). //Ap print "Ap:" at (2, 7). print "ETA:" at (c, 7). //Pe print "Pe:" at (2, 8). print "ETA:" at (c, 8). //Speeds print "Air Speed:" at (2, 9). print "Orbit Speed:" at (c, 9). } local function PrepareGuidanceHUD{ local c is terminal:width /2. if ASCENT_STATE = "Pre-Launch" { print "Waiting for engine start..." at (2, 12). }else if ASCENT_STATE = "Vertical Ascent" { print "Vertical Ascent:" at (2, 12). }else if ASCENT_STATE = "Gravity Turn" { print "Target Pitch:" at (2, 12). print "Current Pitch:" at (c, 12). print "Deviation:" at (2, 13). print "AoA:" at (c, 13). }else if ASCENT_STATE = "Circularization" { }else if ASCENT_STATE = "Done" { if periapsis > 80000 { print "Orbit Achieved" at (2, 12). } else{ print "Not yet in orbit! Perform corrections manually!" at (2, 12). } } } local function PrepareCircNodeHUD{ local c is terminal:width /2. print "Delta V:" at (2, 12). print "Duration:" at (c, 12). print "Burn:" at (2, 13). print "ETA:" at (c, 13). } local function RenderHUD{ parameter veriticalAscSI. parameter tgtPitch. local c is terminal:width /2. //Orbit Section //altitude PrintRightAligned(2, 6, c - 4, si_formatting(altitude, "m")). PrintRightAligned(c, 6, c - 2, si_formatting(alt:radar, "m")). //Ap PrintRightAligned(2, 7, c - 4, si_formatting(apoapsis, "m")). if airspeed < constant:e { PrintRightAligned(c, 7, c - 2, "Inf" ). }else{ PrintRightAligned(c, 7, c - 2, time_formatting(eta:apoapsis) ). } //Pe PrintRightAligned(2, 8, c - 4, si_formatting(periapsis, "m")). PrintRightAligned(c, 8, c - 2, time_formatting(eta:periapsis)). //Speeds PrintRightAligned(2, 9, c - 4, si_formatting(airspeed, "m/s")). PrintRightAligned(c, 9, c - 2, si_formatting(ship:velocity:orbit:mag, "m/s")). if ASCENT_STATE = "Pre-Launch" { }else if ASCENT_STATE = "Vertical Ascent" { print si_formatting(altitude, "m") + " of " + veriticalAscSI at (2 + 16, 12). }else if ASCENT_STATE = "Gravity Turn" { local curPitch is 90 - VANG(ship:up:forevector, ship:facing:forevector). local aoa is vAng(ship:facing:vector, ship:velocity:surface). local dPitch is tgtPitch - curPitch. PrintRightAligned(2, 12, c - 4, round(tgtPitch, 2) + "°"). PrintRightAligned(c, 12, c - 2, round(curPitch, 2) + "°"). PrintRightAligned(2, 13, c - 4, round(dPitch, 2) + "°"). PrintRightAligned(c, 13, c - 2, round(aoa, 2) + "°"). }else if ASCENT_STATE = "Circularization" { }else if ASCENT_STATE = "Done" { } RenderStatusBar(). } local function SetState{ parameter stateText. set ASCENT_STATE to stateText. ClearArea(2, 11, terminal:width - 4, 6, " "). PrintCentered(0, 11, terminal:width, "Guidance - " + ASCENT_STATE). PrepareGuidanceHUD(). } local function RenderStatusBar{ // ClearArea(2, terminal:height - 3, terminal:width - 4, 1, " "). print "Status: " + status + " " at (2, terminal:height - 3) . PrintRightAligned(2, terminal:height - 3, terminal:width - 4, ship:NAME + " - " + ship:type). }