2018-07-27 17:23:38 +02:00
@LAZYGLOBAL OFF.
run once "lib/rocket".
run once "lib/warp".
2018-07-19 14:42:03 +02:00
2018-07-26 04:06:14 +02:00
function estimated_burn_duration {
2018-07-27 17:23:38 +02:00
//
// 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
//
2018-07-26 04:06:14 +02:00
parameter node is NEXTNODE.
2018-07-19 14:42:03 +02:00
2018-08-05 19:40:16 +02:00
local exhaust_velocity is isp_sum() * (CONSTANT:G * KERBIN:mass).
return ((SHIP:mass * exhaust_velocity) / SHIP:maxthrust) * (1 - CONSTANT:E^(-node:deltav:mag/exhaust_velocity)).
2018-07-26 04:06:14 +02:00
}
function execute_node {
2018-07-27 17:23:38 +02:00
//
// Execute given maneuver node (the next one by default).
//
2018-07-26 04:06:14 +02:00
parameter node is NEXTNODE.
2018-07-19 14:42:03 +02:00
2018-07-26 04:06:14 +02:00
local burn_duration is estimated_burn_duration(node).
2018-07-19 14:42:03 +02:00
2018-07-26 04:06:14 +02:00
print "=== EXECUTE MANEUVER NODE ===".
print "Estimated burn duration: " + ROUND(burn_duration, 1) + "s".
print "Aligning ship with burn vector..".
2018-08-05 19:40:16 +02:00
SAS off.
lock STEERING to node:deltav.
wait until vang(SHIP:facing:vector, node:deltav) < 0.5.
2018-07-19 14:42:03 +02:00
print "Initializing warp".
2018-08-05 19:45:56 +02:00
warp_for(max(0, node:eta - (burn_duration/2) - 5)). // warp until 5s before node
2018-07-19 14:42:03 +02:00
print "Approaching".
2018-08-05 19:45:56 +02:00
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
2018-07-19 14:42:03 +02:00
print "Burn!".
lock THROTTLE to 1.0.
2018-07-26 04:06:14 +02:00
// Decrease throttle linearly when the burn duration is less than 1 second
wait until estimated_burn_duration(node) <= 1.
2018-08-05 19:45:56 +02:00
lock THROTTLE to max(0.01, estimated_burn_duration(node)). // ensure we always finish by burning with at least 1% power
2018-07-26 04:06:14 +02:00
2018-07-27 17:23:38 +02:00
// 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
2018-08-05 19:40:16 +02:00
local dv0 is node:deltav.
2018-07-27 17:23:38 +02:00
lock STEERING to dv0.
// Stop the burn once the "snapshot" vector dv0 and current burn vector start facing opposite directions
2018-08-05 19:40:16 +02:00
wait until vdot(dv0, node:deltav) < 0.
2018-07-19 14:42:03 +02:00
set THROTTLE to 0.0.
2018-07-26 04:06:14 +02:00
print "=== MANEUVER NODE EXECUTED ===".
2018-08-05 19:40:16 +02:00
print round(node:deltav:mag, 3) + "m/s delta-v remaining".
2018-07-26 04:06:14 +02:00
unlock_control().
wait 1.
2018-07-19 14:42:03 +02:00
remove node.
}