diff --git a/boot/default.ks b/boot/default.ks index f5869d3..ad008fb 100755 --- a/boot/default.ks +++ b/boot/default.ks @@ -1,6 +1,8 @@ +@LAZYGLOBAL OFF. + CLEARSCREEN. print "=================== BOOTING ===================". -wait until SHIP:UNPACKED. +wait until SHIP:LOADED and SHIP:UNPACKED. if HOMECONNECTION:ISCONNECTED { update_scripts(). diff --git a/launch.ks b/launch.ks index 377fd8e..901d72b 100755 --- a/launch.ks +++ b/launch.ks @@ -1,6 +1,11 @@ -run once util. -run once vectors. -run once node. +@LAZYGLOBAL OFF. + +run once "lib/equations". +run once "lib/node". +run once "lib/rocket". +run once "lib/util". +run once "lib/vectors". +run once "lib/warp". function launch { @@ -51,12 +56,9 @@ function launch { // LAUNCH - - // Can't use flameout or MAXTHRUSTAT on the initial staging, since the rocket may be held down by a launch tower - until STAGE:SOLIDFUEL + STAGE:LIQUIDFUEL <> 0 stage_when_ready(). - - // Auto-stage when any of the engines flameout or if there are no active engines (e.g. when we have an intermediate stage for decouplers before activating the next engine) - when any_flameout() or SHIP:MAXTHRUSTAT(0) = 0 then { + + // Enable auto-staging + when should_stage() then { stage_when_ready(). return true. // preserve trigger } @@ -83,9 +85,7 @@ function launch { print "--- CIRCULARIZE ---". print "Waiting for ship to leave the atmosphere..". - set KUNIVERSE:TIMEWARP:RATE to 4. wait until SHIP:DYNAMICPRESSURE = 0. // don't create maneuver node until we are out of the atmosphere - otherwise the apoapsis altitude and eta will change due to drag - KUNIVERSE:TIMEWARP:CANCELWARP(). print "Deploying solar panels". PANELS ON. diff --git a/lib/equations.ks b/lib/equations.ks new file mode 100644 index 0000000..ea846cf --- /dev/null +++ b/lib/equations.ks @@ -0,0 +1,10 @@ +@LAZYGLOBAL OFF. + +function orbital_velocity { + // Calculate the required velocity to acheive orbit at the provided altitude. + // https://en.wikipedia.org/wiki/Orbital_speed#Mean_orbital_speed + // http://www.orbiterwiki.org/wiki/Front_Cover_Equations + parameter altitude. + + return SQRT(BODY:MU / (BODY:RADIUS + altitude)). // BODY:MU = CONSTANT:G * BODY:MASS +} diff --git a/node.ks b/lib/node.ks similarity index 62% rename from node.ks rename to lib/node.ks index f051c5f..a343df3 100755 --- a/node.ks +++ b/lib/node.ks @@ -1,10 +1,16 @@ -run once util. +@LAZYGLOBAL OFF. + +run once "lib/rocket". +run once "lib/warp". function estimated_burn_duration { - // Calculate estimated burn duration for a maneuver node - // https://en.wikipedia.org/wiki/Tsiolkovsky_rocket_equation - // https://space.stackexchange.com/questions/27375/how-do-i-calculate-a-rockets-burn-time-from-required-velocity + // + // Calculate estimated burn duration for a maneuver node. + // Based on: + // https://en.wikipedia.org/wiki/Tsiolkovsky_rocket_equation + // https://space.stackexchange.com/questions/27375/how-do-i-calculate-a-rockets-burn-time-from-required-velocity + // parameter node is NEXTNODE. local exhaust_velocity is isp_sum() * (CONSTANT:G * KERBIN:MASS). @@ -13,8 +19,10 @@ function estimated_burn_duration { function execute_node { + // + // Execute given maneuver node (the next one by default). + // parameter node is NEXTNODE. - parameter precision is 0.05. // m/s delta-v local burn_duration is estimated_burn_duration(node). @@ -24,14 +32,12 @@ function execute_node { print "Aligning ship with burn vector..". SAS OFF. lock STEERING to node:DELTAV. - wait until VANG(SHIP:FACING:VECTOR, node:DELTAV) < 0.1. + wait until VANG(SHIP:FACING:VECTOR, node:DELTAV) < 0.5. print "Initializing warp". - unlock_control(). warp_for(MAX(0, node:ETA - (burn_duration/2) - 5)). // warp until 5s before node print "Approaching". - lock STEERING to node:DELTAV. wait until node:ETA <= CEILING(burn_duration/2). // CEILING instead of ROUND, since we'd rather start the burn too soon to have time for perfecting the burn print "Burn!". @@ -41,7 +47,12 @@ function execute_node { wait until estimated_burn_duration(node) <= 1. lock THROTTLE to MAX(0.01, estimated_burn_duration(node)). // ensure we always finish by burning with at least 1% power - wait until node:DELTAV:MAG < precision. + // The burn vector will start to drift once we have very little left to burn. Therefore, take a "snapshot" of the burn vector as it is right now, and lock steering to it, instead of the dynamic vector + local dv0 is node:DELTAV. + lock STEERING to dv0. + + // Stop the burn once the "snapshot" vector dv0 and current burn vector start facing opposite directions + wait until VDOT(dv0, node:DELTAV) < 0. set THROTTLE to 0.0. print "=== MANEUVER NODE EXECUTED ===". diff --git a/lib/rocket.ks b/lib/rocket.ks new file mode 100755 index 0000000..61eea22 --- /dev/null +++ b/lib/rocket.ks @@ -0,0 +1,62 @@ +@LAZYGLOBAL OFF. + +function any_flameout { + // + // Return true if any of our engines are starved for fuel. Primarily used to determine the need for staging. + // + local engines_list is list(). + list ENGINES in engines_list. + for engine in engines_list { + if engine:IGNITION and engine:FLAMEOUT { + return true. + } + } + return false. +} + + +function should_stage { + // + // Return true if the rocket needs to stage. + // + return SHIP:STATUS = "PRELAUNCH" // e.g. still attached to launch tower + or any_flameout() // any engine starved for fuel + or SHIP:MAXTHRUSTAT(0) = 0. // no active engines (e.g. when we have an intermediate stage for decouplers before activating the next engine) +} + + +function stage_when_ready { + // + // Stage when ready. Blocks until staging has been initiated. + // + wait until STAGE:READY. + print "STAGING". + STAGE. +} + + +function isp_sum { + // + // Return the sum of vacuum ISP for enabled engines. + // + local sum is 0. + local engines_list is list(). + list ENGINES in engines_list. + for engine in engines_list { + if engine:IGNITION { + set sum to sum + engine:VACUUMISP. + } + } + return sum. +} + + +function unlock_control { + // + // Ensure that the throttle is 0 and that the player is not locked out of control. + // + set SHIP:CONTROL:PILOTMAINTHROTTLE to 0. + set SHIP:CONTROL:NEUTRALIZE to true. + unlock STEERING. + unlock THROTTLE. +} diff --git a/lib/util.ks b/lib/util.ks new file mode 100755 index 0000000..27df7bc --- /dev/null +++ b/lib/util.ks @@ -0,0 +1,8 @@ +@LAZYGLOBAL OFF. + +function round_towards_zero { + parameter n. + + if n < 0 return CEILING(n). + return FLOOR(n). +} diff --git a/vectors.ks b/lib/vectors.ks similarity index 99% rename from vectors.ks rename to lib/vectors.ks index 57533b0..5906ca8 100755 --- a/vectors.ks +++ b/lib/vectors.ks @@ -1,3 +1,5 @@ +@LAZYGLOBAL OFF. + // Define actual_prograde, which automatically switches from SHIP:SRFPROGRADE to SHIP:PROGRADE local function set_actual_prograde { if NAVMODE = "SURFACE" { diff --git a/lib/warp.ks b/lib/warp.ks new file mode 100755 index 0000000..c21920b --- /dev/null +++ b/lib/warp.ks @@ -0,0 +1,13 @@ +@LAZYGLOBAL OFF. + +function warp_to { + parameter timestamp. + + KUNIVERSE:TIMEWARP:WARPTO(timestamp). // TODO: improve. + wait until TIME:SECONDS >= timestamp. // TODO +} + +function warp_for { + parameter seconds. + return warp_to(TIME:SECONDS + seconds). +} diff --git a/util.ks b/util.ks deleted file mode 100755 index 1004eb2..0000000 --- a/util.ks +++ /dev/null @@ -1,79 +0,0 @@ -function warp_to { - parameter timestamp. - - KUNIVERSE:TIMEWARP:WARPTO(timestamp). // TODO: improve. - // wait until TIME >= timestamp. // TODO -} - -function warp_for { - parameter seconds. - return warp_to(TIME:SECONDS + seconds). -} - - -function stage_when_ready { - wait until STAGE:READY. - print "STAGING". - STAGE. -} - - -function isp_sum { - local sum is 0. - list ENGINES in engines_list. - for engine in engines_list { - if engine:STAGE = STAGE:NUMBER set sum to sum + engine:VACUUMISP. - } - return sum. -} - - -function any_flameout { - list ENGINES in engines_list. - for engine in engines_list { - if engine:FLAMEOUT return true. - } - return false. -} - - -function round_towards_zero { - parameter n. - - if n < 0 return CEILING(n). - return FLOOR(n). -} - - -function orbital_velocity { - // Calculate the required velocity to acheive orbit at the provided altitude. - // https://en.wikipedia.org/wiki/Orbital_speed#Mean_orbital_speed - // http://www.orbiterwiki.org/wiki/Front_Cover_Equations - parameter altitude. - - return SQRT(BODY:MU / (BODY:RADIUS + altitude)). // BODY:MU = CONSTANT:G * BODY:MASS -} - - - -function unlock_control { - // Ensure that the throttle will be 0 when execution stops - set SHIP:CONTROL:PILOTMAINTHROTTLE to 0. - - // Ensure that the player is not locked out of control. - set SHIP:CONTROL:NEUTRALIZE to true. - unlock STEERING. - unlock THROTTLE. -} - - -function disable_engine_gimbal { - // Disable engine gimbal when engine is off - on (THROTTLE = 0) { - list ENGINES in engines_list. - for engine in engines_list { - if engine:HASGIMBAL set engine:GIMBAL:LOCK to (not THROTTLE). - } - return true. // preserve trigger - } -} diff --git a/various.ks b/various.ks new file mode 100644 index 0000000..aeebb16 --- /dev/null +++ b/various.ks @@ -0,0 +1,14 @@ +@LAZYGLOBAL OFF. + +function disable_engine_gimbal { + // + // Disable engine gimbal when engine is off. + // + on (THROTTLE = 0) { + list ENGINES in engines_list. + for engine in engines_list { + if engine:HASGIMBAL set engine:GIMBAL:LOCK to (not THROTTLE). + } + return true. // preserve trigger + } +}