Restructure. Improve node execution precision by an order of magnitude.

This commit is contained in:
Casper V. Kristensen 2018-07-27 17:23:38 +02:00
parent eb040aa911
commit a6bcb34e06
Signed by: caspervk
GPG key ID: B1156723DB3BDDA8
10 changed files with 143 additions and 100 deletions

View file

@ -1,6 +1,8 @@
@LAZYGLOBAL OFF.
CLEARSCREEN. CLEARSCREEN.
print "=================== BOOTING ===================". print "=================== BOOTING ===================".
wait until SHIP:UNPACKED. wait until SHIP:LOADED and SHIP:UNPACKED.
if HOMECONNECTION:ISCONNECTED { if HOMECONNECTION:ISCONNECTED {
update_scripts(). update_scripts().

View file

@ -1,6 +1,11 @@
run once util. @LAZYGLOBAL OFF.
run once vectors.
run once node. 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 { function launch {
@ -52,11 +57,8 @@ function launch {
// LAUNCH // LAUNCH
// Can't use flameout or MAXTHRUSTAT on the initial staging, since the rocket may be held down by a launch tower // Enable auto-staging
until STAGE:SOLIDFUEL + STAGE:LIQUIDFUEL <> 0 stage_when_ready(). when should_stage() then {
// 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 {
stage_when_ready(). stage_when_ready().
return true. // preserve trigger return true. // preserve trigger
} }
@ -83,9 +85,7 @@ function launch {
print "--- CIRCULARIZE ---". print "--- CIRCULARIZE ---".
print "Waiting for ship to leave the atmosphere..". 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 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". print "Deploying solar panels".
PANELS ON. PANELS ON.

10
lib/equations.ks Normal file
View file

@ -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
}

View file

@ -1,10 +1,16 @@
run once util. @LAZYGLOBAL OFF.
run once "lib/rocket".
run once "lib/warp".
function estimated_burn_duration { function estimated_burn_duration {
// Calculate estimated burn duration for a maneuver node //
// Calculate estimated burn duration for a maneuver node.
// Based on:
// https://en.wikipedia.org/wiki/Tsiolkovsky_rocket_equation // 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 // https://space.stackexchange.com/questions/27375/how-do-i-calculate-a-rockets-burn-time-from-required-velocity
//
parameter node is NEXTNODE. parameter node is NEXTNODE.
local exhaust_velocity is isp_sum() * (CONSTANT:G * KERBIN:MASS). local exhaust_velocity is isp_sum() * (CONSTANT:G * KERBIN:MASS).
@ -13,8 +19,10 @@ function estimated_burn_duration {
function execute_node { function execute_node {
//
// Execute given maneuver node (the next one by default).
//
parameter node is NEXTNODE. parameter node is NEXTNODE.
parameter precision is 0.05. // m/s delta-v
local burn_duration is estimated_burn_duration(node). local burn_duration is estimated_burn_duration(node).
@ -24,14 +32,12 @@ function execute_node {
print "Aligning ship with burn vector..". print "Aligning ship with burn vector..".
SAS OFF. SAS OFF.
lock STEERING to node:DELTAV. 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". print "Initializing warp".
unlock_control().
warp_for(MAX(0, node:ETA - (burn_duration/2) - 5)). // warp until 5s before node warp_for(MAX(0, node:ETA - (burn_duration/2) - 5)). // warp until 5s before node
print "Approaching". 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 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!". print "Burn!".
@ -41,7 +47,12 @@ function execute_node {
wait until estimated_burn_duration(node) <= 1. 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 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. set THROTTLE to 0.0.
print "=== MANEUVER NODE EXECUTED ===". print "=== MANEUVER NODE EXECUTED ===".

62
lib/rocket.ks Executable file
View file

@ -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.
}

8
lib/util.ks Executable file
View file

@ -0,0 +1,8 @@
@LAZYGLOBAL OFF.
function round_towards_zero {
parameter n.
if n < 0 return CEILING(n).
return FLOOR(n).
}

View file

@ -1,3 +1,5 @@
@LAZYGLOBAL OFF.
// Define actual_prograde, which automatically switches from SHIP:SRFPROGRADE to SHIP:PROGRADE // Define actual_prograde, which automatically switches from SHIP:SRFPROGRADE to SHIP:PROGRADE
local function set_actual_prograde { local function set_actual_prograde {
if NAVMODE = "SURFACE" { if NAVMODE = "SURFACE" {

13
lib/warp.ks Executable file
View file

@ -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).
}

79
util.ks
View file

@ -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
}
}

14
various.ks Normal file
View file

@ -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
}
}