Restructure. Improve node execution precision by an order of magnitude.
This commit is contained in:
parent
eb040aa911
commit
a6bcb34e06
10 changed files with 143 additions and 100 deletions
|
@ -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().
|
||||
|
|
22
launch.ks
22
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.
|
||||
|
|
10
lib/equations.ks
Normal file
10
lib/equations.ks
Normal 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
|
||||
}
|
|
@ -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 ===".
|
62
lib/rocket.ks
Executable file
62
lib/rocket.ks
Executable 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
8
lib/util.ks
Executable file
|
@ -0,0 +1,8 @@
|
|||
@LAZYGLOBAL OFF.
|
||||
|
||||
function round_towards_zero {
|
||||
parameter n.
|
||||
|
||||
if n < 0 return CEILING(n).
|
||||
return FLOOR(n).
|
||||
}
|
|
@ -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" {
|
13
lib/warp.ks
Executable file
13
lib/warp.ks
Executable 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
79
util.ks
|
@ -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
14
various.ks
Normal 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
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue