Compare commits

..

6 Commits

12 changed files with 184 additions and 51 deletions

View File

@ -4,7 +4,6 @@ parameter debug is false.
Bootstrap(
"/boot/aircraft",
"/prog/aircraft",
List(), // no additional program files
List("/prog/aircraft"),
debug
).

View File

@ -4,7 +4,6 @@ parameter debug is false.
Bootstrap(
"/boot/helicopter",
"/prog/helicopter",
List(), // no additional program files
List("/prog/helicopter"),
debug
).

View File

@ -4,7 +4,6 @@ parameter debug is false.
Bootstrap(
"/boot/launchpad",
"/prog/launchpad",
List(),
List("/prog/launchpad"),
debug
).

View File

@ -4,7 +4,6 @@ parameter debug is false.
Bootstrap(
"/boot/rocket",
"/prog/rocket",
List(),
List("/prog/rocket"),
debug
).

View File

@ -4,12 +4,12 @@ parameter debug is false.
Bootstrap(
"/boot/satellite",
"",
List(
"/prog/execnode",
"/prog/circ",
"/prog/satdeploy",
"/prog/nodestats"
),
debug
debug,
false
).

View File

@ -4,12 +4,12 @@ parameter debug is false.
Bootstrap(
"/boot/science",
"",
List(
"/prog/circ",
"/prog/execnode",
"/prog/nodestats",
"/prog/reentry"
),
debug
debug,
false
).

View File

@ -1,20 +1,24 @@
// "bootfile" should be the path to the bootfile, so it can be deleted.
// "programs" is a List() of programs to install in the CPU root.
// "debug" will skip compiling if enabled, and only copy files.
// if "init" is true, the first program in the programs List will become the new boot file.
// pass false in here if you want CPU control from the terminal.
function Bootstrap {
parameter bootFile, init, programs, debug.
parameter bootFile, programs, debug, init is true.
local initProgram is "".
if init {
set initProgram to programs[0]:Replace("/prog", "").
}
// create a list of libraries that we need to compile
local libs is UniqueSet().
if init <> "" {
addLibs(libs, init).
}
for program in programs {
addLibs(libs, program).
}
// compile the main program files
if init <> "" {
compileFile(init, "/init", debug).
}
for program in programs {
compileFile(program, program:Replace("/prog", ""), debug).
}
@ -29,18 +33,13 @@ function Bootstrap {
// Open a terminal and run init.
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Open Terminal").
if init <> "" {
run "/init".
RunPath(initProgram).
}
// ... or delete the bootstrapping file, set init to the bootfile,
// ... or delete the bootstrapping file, configure to boot from the init program,
// and reboot.
} else {
DeletePath("1:" + bootfile).
// Set OS to boot and restart.
if init = "" {
set CORE:BOOTFILENAME to "".
} else {
set CORE:BOOTFILENAME to "/init".
}
set CORE:BOOTFILENAME to initProgram.
reboot.
}
}

View File

@ -30,14 +30,12 @@ function pitchProgram {
function Launch {
parameter apoapsisTarget is 80000.
parameter atmoTWR is 2.0.
// parameter leadAngle is 2.
parameter minPitch is 5.
parameter initialPitch is 20.
parameter pitchTime is 30.
parameter kickAngle is 20.
parameter kickTime is 30.
parameter kickStart is 100.
parameter autoStage is true.
NoFuelResources(true).
// Configure subsystems.
RCS off.
SAS off.
@ -72,17 +70,18 @@ function Launch {
}
}
print "Phase 1: Vertical Ascent.".
lock THROTTLE to 1.0.
lock STEERING to Heading(90,90,270).
NoFuelResources(true).
PreLaunchCrossfeed(false).
stage.
wait until SHIP:VERTICALSPEED > 100.
wait until SHIP:VERTICALSPEED > kickStart.
print "Phase 2: Initial Pitch.".
local startTime is TIME:SECONDS.
lock STEERING to pitchProgram(initialPitch, pitchTime, startTime).
wait pitchTime.
lock STEERING to pitchProgram(kickAngle, kickTime, startTime).
wait kickTime.
print "Phase 3: Stable Prograde Boost.".
lock STEERING to getClampedDir(minPitch).
@ -93,8 +92,8 @@ function Launch {
lock THROTTLE to 0.0.
set SHIP:CONTROL:PILOTMAINTHROTTLE to 0.
wait 0.001. // make sure these control updates get applied
add CreateCircularizationNode().
ExecNode().
insertionBurn(apoapsisTarget).
print "Ascent Complete.".
set SHIP:CONTROL:PILOTMAINTHROTTLE to 0.
@ -102,3 +101,54 @@ function Launch {
unlock STEERING.
SAS on.
}
// Calculate and perform the insertion burn for orbit.
// The reason to prefer this over CreateCircularizationNode() and ExecNode() is that the amount of RCS needed
// to vector into position during launch adjusts our orbit significantly. This gives us a "wait until" that
// serves the specific needs of launch.
// It also makes automated launches possible before maneuver nodes are unlocked.
//
// TODO: Refactor code reuse between this function and ExecNode().
//
// prerequisites:
// * Vessel is still behind the Apoapsis
// * Apoapsis is at the target height
function insertionBurn {
parameter apoapsisTarget.
// vector is prograde but only on the horizonal plane
print "Adjusting heading.".
local lock horizon is Vxcl(SHIP:UP:FOREVECTOR, SHIP:PROGRADE:FOREVECTOR).
lock STEERING to LookDirUp(horizon, SHIP:FACING:TOPVECTOR).
// calculate the deltaV to get us to the target velocity, for calculating burn start time.
local t is TIME + SHIP:ORBIT:ETA:APOAPSIS.
local Vc is sqrt(SHIP:BODY:MU/(PositionAt(SHIP, t) - SHIP:BODY:POSITION):MAG).
local dV is Vc - VelocityAt(SHIP, t):ORBIT:MAG.
if WillStage(dV) {
when FlameOut() then {
print "Flameout detected. Staging.".
stage.
}
}
// calculate the total burn time (Tb) and the burn start time (Ts)
local Tb is BurnTime(dV).
local Ts is TIME + SHIP:OBT:ETA:APOAPSIS - BurnTime(dV / 2).
// warp to the burn point
print "Waiting for burn window.".
wait until (VAng(SHIP:FACING:FOREVECTOR, STEERINGMANAGER:TARGET:FOREVECTOR) <= 0.5) OR (TIME > Ts).
if TIME < Ts - 2 {
KUNIVERSE:TIMEWARP:WarpTo(Ts:SECONDS - 2).
}
wait until SHIP:UNPACKED.
wait until TIME > Ts.
// burn until periapsis is clear
print "Circularizing orbit.".
lock THROTTLE to 1.0.
wait until SHIP:OBT:PERIAPSIS > apoapsisTarget.
lock THROTTLE to 0.0.
}

View File

@ -102,6 +102,9 @@ function BurnTime {
local lastStage is false.
// We allow a small tolerance to deal with potential floating point errors.
until totaldV <= 0.001 {
if s < 0 {
print "Ran out of fuel with " + totaldV + " dV remaining".
}
local F is stageThrust(s).
local Isp is stageISP(s).
local m is stageMass(s).

View File

@ -33,3 +33,20 @@ function NoFuelResources {
}
}
}
function PreLaunchCrossfeed {
parameter enable is true.
local eventName is "Disable Crossfeed".
if enable {
set eventName to "Enable Crossfeed".
}
for part in SHIP:PartsTagged("prelaunch") {
if part:MODULES:Find("ModuleToggleCrossfeed") = -1 {
print "Prelaunch part does not have crossfeed module. skipping.".
} else if part:GetModule("ModuleToggleCrossfeed"):ALLEVENTNAMES:Find(eventName) > -1 {
part:GetModule("ModuleToggleCrossfeed"):DoEvent(eventName).
}
}
}

View File

@ -3,11 +3,20 @@
// stages, spools up the engines, and then "releases control"
// to the main ship computer.
//
// *** CONSTRUCTION NOTES ***
// If using this script, put the annabuncheskOS-launchpad.cfg file from the patches/ directory into your GameData/
// directory. This will ensure the launchpad has a high enough fuel flow rate for the spool-up sequence.
// If your lower stage uses engine plates, be sure to attach the launch pad to one of the *engine* bottom nodes,
// not the Engine Plate's bottom node. Otherwise fuel delivery won't work.
//
// *** TAGGING REQUIREMENTS ***
// The launchpad object should have the "launchpad" tag.
// The ship's main CPU (the one with launch functionality" should be tagged "shipcpu".
// Fuel tanks with the "nofuel" tag will have *all* resources temporarily disabled during this
// sequence. The main ship computer must re-enable them after staging. NoFuelResources in lib/systems is ideal
// for this.
// Fuel tanks with the "nofuel" tag will have *all* resources temporarily disabled during the pre-launch
// sequence. The main ship computer must re-enable them after staging. NoFuelResources() in lib/systems is ideal
// for this.
// Similarly, any crossfeed-capable decouplers tagged "prelaunch" will have crossfeed ENABLED during pre-launch.
// MainCPU should, again, disable these once it stages. PreLaunchCrossfeed() in lib/systems is your friend.
RunOncePath("/lib/systems").
RunOncePath("/lib/ui").
@ -35,6 +44,7 @@ function preLaunch {
print "Beginning pre-launch sequence.".
NoFuelResources(false).
PreLaunchCrossfeed(true).
// turn on generator and fuel flow
enableLaunchpadFlow().
@ -56,7 +66,8 @@ function preLaunch {
local msg is Lex(
"command", "launch",
"angle", options["Kick Angle"]:TEXT:ToNumber(),
"time", options["Kick Time"]:TEXT:ToNumber()
"time", options["Kick Time"]:TEXT:ToNumber(),
"start", options["Kick Start"]:TEXT:ToNumber()
).
Processor("shipcpu"):CONNECTION:SendMessage(msg).
iface:Hide().
@ -76,7 +87,8 @@ MakeMenu(
List(
List("Spool-up Time", "SCALAR", "15"),
List("Kick Angle", "SCALAR", "30"),
List("Kick Time", "SCALAR", "45")
List("Kick Time", "SCALAR", "45"),
List("Kick Start", "SCALAR", "100")
),
"Execute",
preLaunch@

View File

@ -20,9 +20,9 @@ on AG9 {
// Top-level menu structure.
local iface is gui(250, 300).
set iface:X to 200.
set iface:Y to 700.
set iface:Y to 750.
local top is iface:AddVLayout().
local rows is list(MakeRow(top), MakeRow(top), MakeRow(top)).
local rows is list(MakeRow(top), MakeRow(top), MakeRow(top), MakeRow(top)).
local stk is iface:AddStack().
// Buttons and menus.
@ -95,8 +95,9 @@ MakeMenu(
MakeButton(rows[2], "Launch"),
List(
List("Target Apoapsis", "SCALAR", "80000"),
List("Initial Pitch", "SCALAR", "30"),
List("Pitch Time", "SCALAR", "45"),
List("Kick Angle", "SCALAR", "30"),
List("Kick Time", "SCALAR", "45"),
List("Kick Start", "SCALAR", "100"),
List("Atmo TWR", "SCALAR", "2.0"),
List("Minimum Pitch", "SCALAR", "5"),
List("Autostage", "BOOL", true)
@ -108,8 +109,9 @@ MakeMenu(
options["Target Apoapsis"]:TEXT:ToNumber(),
options["Atmo TWR"]:TEXT:ToNumber(),
options["Minimum Pitch"]:TEXT:ToNumber(),
options["Initial Pitch"]:TEXT:ToNumber(),
options["Pitch Time"]:TEXT:ToNumber(),
options["Kick Angle"]:TEXT:ToNumber(),
options["Kick Time"]:TEXT:ToNumber(),
options["Kick Start"]:TEXT:ToNumber(),
options["Autostage"]:PRESSED
).
}
@ -120,7 +122,9 @@ MakeMenu(
MakeButton(rows[2], "Node"),
List(
List("Node dV", "RO", "0"),
List("Node Burn Time", "RO", "0")
List("Node Burn Time", "RO", "0"),
List("Node Lead Time", "RO", "0"),
List("Burn Start ETA", "RO", "0")
),
"Execute",
{
@ -130,11 +134,18 @@ MakeMenu(
{
parameter options.
if HASNODE {
local burnTime is BurnTime(NEXTNODE:DELTAV:MAG).
local leadTime is BurnTime(NEXTNODE:DELTAV:MAG / 2).
set options["Node dV"]:TEXT to NEXTNODE:DELTAV:MAG:ToString.
set options["Node Burn Time"]:TEXT to BurnTime(NEXTNODE:DELTAV:MAG):ToString.
set options["Node Burn Time"]:TEXT to burnTime:ToString.
set options["Node Lead Time"]:TEXT to leadTime:ToString.
set options["Burn Start ETA"]:TEXT to (NEXTNODE:ETA - leadTime):ToString.
} else {
set options["Node dV"]:TEXT to "No Node".
set options["Node Burn Time"]:TEXT to "No Node".
set options["Node Lead Time"]:TEXT to "No Node".
set options["Burn Start ETA"]:TEXT to "No Node".
}
}
).
@ -171,6 +182,50 @@ MakeMenu(
}
).
MakeButton(
rows[3],
"Pro",
{
set done to false.
lock STEERING to SHIP:PROGRADE.
wait until done.
set done to false.
}
).
MakeButton(
rows[3],
"Ret",
{
set done to false.
lock STEERING to SHIP:RETROGRADE.
wait until done.
set done to false.
}
).
MakeButton(
rows[3],
"Srf Pro",
{
set done to false.
lock STEERING to SHIP:SRFPROGRADE.
wait until done.
set done to false.
}
).
MakeButton(
rows[3],
"Srf Ret",
{
set done to false.
lock STEERING to SHIP:SRFRETROGRADE.
wait until done.
set done to false.
}
).
iface:show().
until SHIP:STATUS <> "PRELAUNCH" {
@ -184,6 +239,7 @@ until SHIP:STATUS <> "PRELAUNCH" {
5.0,
data["angle"],
data["time"],
data["start"],
true
).
}