kOS/lib/launch_rocket.ks

101 lines
2.8 KiB
Plaintext
Raw Normal View History

2021-08-19 02:32:07 +00:00
RunOncePath("lib/throttle").
RunOncePath("lib/navigation").
RunOncePath("lib/navball").
2021-08-02 04:20:19 +00:00
2021-08-11 09:04:21 +00:00
// Calculate the direction to lock during ascent.
function getClampedDir {
2021-08-11 09:04:21 +00:00
parameter minPitch is 5.
2021-08-20 23:37:48 +00:00
2021-08-11 09:04:21 +00:00
// face just beneath prograde, but hold a solid eastern heading and don't
// rotate the ship
2021-08-11 09:04:21 +00:00
local newHeading is lookdirup(SHIP:SRFPROGRADE:FOREVECTOR, heading(90, 0, 270):TOPVECTOR).
if GetPitch(newHeading:FOREVECTOR) < minPitch {
set newHeading to heading(90, minPitch, 270).
}
return newHeading.
}
// Given a target (end) pitch, a target duration, and a start time,
// returns the correct current heading.
function pitchProgram {
parameter endPitch, duration, startTime.
// what percent through the duration are we?
local elapsedP is (TIME:SECONDS - startTime) / duration.
local p is endPitch * elapsedP.
return Heading(90, 90 - p, 270).
}
2021-08-02 04:20:19 +00:00
function Launch {
2021-08-20 23:37:48 +00:00
parameter apoapsisTarget is 80000.
parameter atmoTWR is 2.0.
// parameter leadAngle is 2.
2021-08-20 23:37:48 +00:00
parameter minPitch is 5.
parameter initialPitch is 20.
parameter pitchTime is 30.
2021-08-20 23:37:48 +00:00
parameter autoStage is true.
2021-08-02 04:20:19 +00:00
// Configure subsystems.
RCS off.
SAS off.
// Countdowns are cute.
print "Initiating automated launch sequence.".
from { local x is 5. } until x = 0 step { set x to x - 1. } do {
print "..." + x.
wait 0.5.
}
2021-08-06 05:36:26 +00:00
// staging logic. Stage as many times as needed until we finish ascent.
// Once Apo target is attained just drop this trigger.
2021-08-20 23:37:48 +00:00
if autoStage {
when FlameOut() or SHIP:ORBIT:APOAPSIS > apoapsisTarget then {
if SHIP:ORBIT:APOAPSIS > apoapsisTarget {
return false.
}
stage.
return true.
2021-08-06 05:36:26 +00:00
}
}
// Drag controls
when SHIP:VERTICALSPEED > 340 then {
print "Throttling for drag control.".
lock THROTTLE to ThrottleToTWR(atmoTWR).
// TODO: if we have a pressure sensor we can use it to decide when to kick the throttle up instead, neat solution for e.g. Duna and Eve.
when SHIP:ALTITUDE > 32000 then {
lock THROTTLE to 1.0.
}
}
2021-08-02 04:20:19 +00:00
print "Phase 1: Vertical Ascent.".
lock THROTTLE to 1.0.
2021-08-20 23:37:48 +00:00
lock STEERING to Heading(90,90,270).
2021-08-02 04:20:19 +00:00
stage.
wait until SHIP:VERTICALSPEED > 100.
print "Phase 2: Initial Pitch.".
local startTime is TIME:SECONDS.
lock STEERING to pitchProgram(initialPitch, pitchTime, startTime).
wait pitchTime.
2021-08-02 04:20:19 +00:00
print "Phase 3: Stable Prograde Boost.".
lock STEERING to getClampedDir(minPitch).
2021-08-20 23:37:48 +00:00
wait until SHIP:ORBIT:APOAPSIS > apoapsisTarget.
2021-08-02 04:20:19 +00:00
// TODO: A smoother approach based on target orbital velocity should be considered.
print "Phase 4: Circularization Maneuver.".
2021-08-02 04:20:19 +00:00
lock THROTTLE to 0.0.
set SHIP:CONTROL:PILOTMAINTHROTTLE to 0.
wait 0.001. // make sure these control updates get applied
add CreateCircularizationNode().
ExecNode().
print "Ascent Complete.".
2021-08-27 07:59:24 +00:00
set SHIP:CONTROL:PILOTMAINTHROTTLE to 0.
2021-08-02 04:20:19 +00:00
unlock THROTTLE.
unlock STEERING.
SAS on.
}