0e6904da89
estimated burn duration of half of the delta-V instead of half of the estimated duration of the entire burn to account for the acceleration increasing over the course of the burn as the rocket uses fuel.
105 lines
3.8 KiB
Plaintext
105 lines
3.8 KiB
Plaintext
@LAZYGLOBAL OFF.
|
|
|
|
run once "lib/rocket".
|
|
run once "lib/warp".
|
|
|
|
|
|
function estimated_burn_duration {
|
|
//
|
|
// Calculate estimated burn duration of a vector or 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
|
|
// https://www.alternatewars.com/BBOW/Space/Rocket_Equations.htm
|
|
//
|
|
parameter burn.
|
|
parameter isp is isp_sum().
|
|
parameter thrust is SHIP:availablethrust.
|
|
|
|
if burn:istype("Node") {
|
|
set burn to burn:deltav.
|
|
}
|
|
|
|
local deltav is burn:mag.
|
|
local exhaust_velocity is isp * CONSTANT:g0.
|
|
local wet_mass is SHIP:mass.
|
|
return ((wet_mass * exhaust_velocity) / thrust) * (1 - CONSTANT:E^(-deltav/exhaust_velocity)).
|
|
}
|
|
|
|
|
|
function vector_to_node {
|
|
//
|
|
// Convert given vector to a maneuver node, optionally at the given time.
|
|
// See vector_to_node.png.
|
|
// Based on
|
|
// https://www.reddit.com/r/Kos/comments/701k7w/dmzmwwj/
|
|
//
|
|
parameter vec.
|
|
parameter time is TIME:seconds. // now
|
|
|
|
local position_at_time is positionat(SHIP, time) - BODY:POSITION. // from the body's center
|
|
|
|
local prograde_at_time is velocityat(SHIP, time):orbit.
|
|
local normal_at_time is vcrs(prograde_at_time, position_at_time). // vector cross product is a vector that is normal to the plane containing them (see image)
|
|
local radial_at_time is vcrs(normal_at_time, prograde_at_time).
|
|
|
|
// Project the given input vector onto the three components to find its magnitude at the given time
|
|
local vec_prograde_at_time is vdot(vec, prograde_at_time:normalized).
|
|
local vec_normal_at_time is vdot(vec, normal_at_time:normalized).
|
|
local vec_radial_at_time is vdot(vec, radial_at_time:normalized).
|
|
|
|
return NODE(time, vec_radial_at_time, vec_normal_at_time, vec_prograde_at_time).
|
|
}
|
|
|
|
|
|
function execute_burn {
|
|
//
|
|
// Execute given burn vector or node.
|
|
//
|
|
parameter burn. // Vector or Node
|
|
|
|
local node is burn.
|
|
if burn:istype("Vector") {
|
|
set node to vector_to_node(burn).
|
|
add node.
|
|
}
|
|
|
|
local lock burn_duration to estimated_burn_duration(node).
|
|
|
|
print "==> EXECUTING MANEUVER NODE".
|
|
print "Estimated burn duration: " + round(burn_duration, 2) + "s".
|
|
|
|
print "Aligning ship with burn vector".
|
|
SAS off.
|
|
lock STEERING to node.
|
|
wait until vang(SHIP:facing:vector, node:burnvector) <= 0.5.
|
|
|
|
// Start time is based on half of the delta-v instead of half the burn time to account for the acceleration increasing
|
|
// over the course of the burn as the rocket uses fuel, and thus the 2nd half of the burn will take less time than the first.
|
|
local burn_start_time is TIME:seconds + node:eta - estimated_burn_duration(node:deltav/2).
|
|
warp_to(burn_start_time - 3). // 3s before we need to start burn
|
|
|
|
print "Approaching maneuver node".
|
|
wait until TIME:seconds >= burn_start_time.
|
|
|
|
print "Burn!".
|
|
// Decrease throttle linearly with burn duration when under 1 second, but ensure we always finish by burning with at least 1% power at all times.
|
|
lock THROTTLE to max(0.01, min(1.0, burn_duration)).
|
|
|
|
// The burn vector will start to drift once we have very little left to burn.
|
|
// Therefore, save the burn vector as it is right now, and lock steering to it, instead of the dynamic vector
|
|
wait until burn_duration <= 1.
|
|
local dv0 is node:burnvector.
|
|
lock STEERING to dv0.
|
|
|
|
// Stop the burn once the saved vector, dv0, and current burn vector start facing opposite directions
|
|
wait until vdot(dv0, node:burnvector) < 0.
|
|
set THROTTLE to 0.0.
|
|
|
|
print "==> MANEUVER NODE EXECUTED".
|
|
print round(node:deltav:mag, 3) + "m/s delta-v remaining".
|
|
unlock_control().
|
|
wait 1.
|
|
remove node.
|
|
}
|