Files

375 lines
10 KiB
Plaintext

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{
local parameter targetOrbit is 100000,
vericalAscent is 1000,
ascentProfile is 1.2,
circ is 1,
inc is 0,
maxQ is 15.
// local tgtOrbitSI is si_formatting(targetOrbit, "m").
local vericalAscentSI is si_formatting(vericalAscent, "m").
local head to 90 + inc.
lock throttle to GetThrottle(maxQ).
lock tgtPitch to 00.
PrepareHUD(targetOrbit, vericalAscent, ascentProfile, circ, inc).
//HUD
when true then {
RenderHUD(vericalAscentSI, tgtPitch).
wait 0.01.
if ASCENT_STATE <> "Done" {
preserve.
}
}
WaitForEngineStart().
lock steering to heading(90, 90, 270).
local lock asccent_prog to Map(apoapsis, vericalAscent, targetOrbit, 0.0, 1.0).
SetState("Vertical Ascent").
wait until altitude > vericalAscent and asccent_prog > 0.
SetState("Gravity Turn").
lock ease to EaseOutExp(asccent_prog, ascentProfile).
lock tgtPitch to (1 - ease) * 90.
lock steering to heading(head, tgtPitch, 270).
//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).
}
if periapsis < 80000 {
SetState("Orbit Correction").
FixOrbitalInsertion().
}
SetState("Done").
unlock steering.
unlock throttle.
wait until throttle = 0.
}
local function GetThrottle{
local parameter maxQ.
lock curQ to ship:q * constant:ATMtokPa.
if curQ > maxQ {
return min(1, max(0.5, Map(curQ, maxQ, maxQ * 1.2, 1, 0))).
}else {
return 1.
}
}
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.
local lock aoa to vAng(heading(head, 0, 270):forevector, ship:velocity:surface).
lock steering to heading(head, -aoa, 270).
wait until periapsis >= 80000.
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(nextNode: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).
local burnStart is circNode:eta - burnDuration /2.
if burnStart > 10 {
warpTo(time:seconds + burnStart - 10).
}
wait until circNode:eta <= burnDuration /2.
lock throttle to 1.
wait until nextNode:deltav:mag <= max(20, burnDv * 0.1).
lock throttle to 0.75.
wait until NEXTNODE:deltav:mag <= max(10, burnDv * 0.05).
lock throttle to 0.4.
wait until NEXTNODE:deltav:mag <= max(1, burnDv * 0.01).
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 = "Orbit Correction" {
print "Not yet in orbit! Attempting to Correct..." at (2, 12).
}else if ASCENT_STATE = "Done" {
print "Orbit Achieved" 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 is 0.
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 curPitch - tgtPitch.
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(2, 11, terminal:width - 4, "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).
}
local function FixOrbitalInsertion{
local parameter tgtAlt.
// Ap is behind ship
if eta:apoapsis < orbit:period / 2 {
print "Performing Radial Correction..." at (2, 13).
lock steering to up.
wait until vAng(ship:facing:forevector, up:forevector) < 2.
lock throttle to 0.2.
wait until eta:apoapsis <= orbit:period / 2.
lock throttle to 0.
lock steering to prograde.
wait until vAng(ship:facing:forevector, prograde:forevector) < 2.
lock throttle to Map(periapsis, 0, tgtAlt, 1, 0.1).
wait until periapsis > tgtAlt.
lock throttle to 0.
}else{
//Ap is ahead
print "Performing Circularization Correction..." at (2, 13).
local burnDv is CalculateCircularizationDV(tgtAlt, orbit:semimajoraxis).
local burnDuration to CalculateBurnDuration(burnDv).
local circNode is Node(time:seconds + eta:apoapsis, 0, 0, burnDv).
add circNode.
wait 0.01.
lock steering to circNode:burnvector.
local burnStart is circNode:eta - burnDuration /2.
if burnStart > 10 {
warpTo(time:seconds + burnStart - 10).
}
wait until circNode:eta <= burnDuration /2.
lock throttle to 1.
wait until nextNode:deltav:mag <= max(20, burnDv * 0.1).
lock throttle to 0.75.
wait until NEXTNODE:deltav:mag <= max(10, burnDv * 0.05).
lock throttle to 0.4.
wait until NEXTNODE:deltav:mag <= max(1, burnDv * 0.01).
lock throttle to 0.
unlock steering.
remove nextNode.
wait 0.01.
wait until throttle = 0.
}
}