Improvements and gui to ascent script
This commit is contained in:
@@ -0,0 +1 @@
|
||||
logs
|
||||
@@ -1,73 +0,0 @@
|
||||
// Inital gravity turn
|
||||
// #include staging
|
||||
run once staging.
|
||||
// #include maneuver
|
||||
run once maneuver.
|
||||
|
||||
function doAscentSteering {
|
||||
parameter heading.
|
||||
|
||||
// initial pitch-over
|
||||
set tarSteer to heading(heading, 90).
|
||||
lock steering to tarSteer.
|
||||
until ship:velocity:surface:mag >= 100 {
|
||||
set tarSteer to heading(heading, 90 - (ship:velocity:surface:mag / 10)).
|
||||
if defined UPDATE_LOG { UPDATE_LOG(). }
|
||||
wait 0.
|
||||
}
|
||||
|
||||
lock steering to ship:srfprograde.
|
||||
print "Locked steering to surface prograde".
|
||||
}
|
||||
|
||||
function createCircularizationNode {
|
||||
// Re-use existing node if already planned
|
||||
if hasnode {
|
||||
print "Existing node found. Skipping creation.".
|
||||
return nextnode.
|
||||
}
|
||||
|
||||
local rBurn to body:radius + apoapsis.
|
||||
local vTarget to sqrt(body:mu / rBurn).
|
||||
local dvEst to vTarget - ship:velocity:orbit:mag.
|
||||
|
||||
local nd to node(time:seconds + eta:apoapsis, 0, 0, dvEst).
|
||||
add nd.
|
||||
return nd.
|
||||
}
|
||||
|
||||
function basicAscent {
|
||||
parameter heading is 90, targetAltitude is 80000.
|
||||
|
||||
lock throttle to 1.
|
||||
|
||||
print "Counting down:".
|
||||
from {local countdown is 5.} until countdown = 0 step {set countdown to countdown - 1.} do {
|
||||
print "..." + countdown.
|
||||
wait 1.
|
||||
}
|
||||
|
||||
// initial stage to takeoff
|
||||
stage.
|
||||
|
||||
// stage everytime thrust drops to zero
|
||||
basicStaging().
|
||||
// basic gravity-ish turn
|
||||
doAscentSteering(heading).
|
||||
|
||||
// coast to apoapsis
|
||||
until ship:apoapsis >= targetAltitude {
|
||||
if defined UPDATE_LOG { UPDATE_LOG(). }
|
||||
}
|
||||
lock steering to ship:prograde.
|
||||
lock throttle to 0.
|
||||
|
||||
// don't do futher calcs until out of the atmosphere or very close to apoapsis
|
||||
until ship:altitude >= body:atm:height or eta:apoapsis < 60 {
|
||||
if defined UPDATE_LOG { UPDATE_LOG(). }
|
||||
}
|
||||
|
||||
executeNode(createCircularizationNode()).
|
||||
|
||||
print "Circularized".
|
||||
}
|
||||
+5
-51
@@ -1,52 +1,6 @@
|
||||
copyPath("0:/ascent.ks", "1:/ascent.ks").
|
||||
copyPath("0:/maneuver.ks", "1:/maneuver.ks").
|
||||
copyPath("0:/staging.ks", "1:/staging.ks").
|
||||
copyPath("0:/logger.ks", "1:/logger.ks").
|
||||
// #include logger
|
||||
run once logger.
|
||||
// #include ascent
|
||||
run once ascent.
|
||||
|
||||
createDir("1:/logs").
|
||||
set LOG to loggerCreate(
|
||||
"1:/logs/flight-" + ship:shipName + "-" + time:full + ".json",
|
||||
list(
|
||||
"time",
|
||||
"altitude",
|
||||
"apoapsis",
|
||||
"periapsis",
|
||||
"eccentricity",
|
||||
"throttle",
|
||||
"pitch",
|
||||
"heading",
|
||||
"mass",
|
||||
"stageNum"
|
||||
),
|
||||
1.0
|
||||
).
|
||||
set LOG_DATA to {
|
||||
return list(
|
||||
time:seconds,
|
||||
round(ship:altitude, 1),
|
||||
round(ship:apoapsis, 1),
|
||||
round(ship:periapsis, 1),
|
||||
round(ship:orbit:eccentricity, 4),
|
||||
round(ship:throttle, 3),
|
||||
round(ship:pitch, 2),
|
||||
round(ship:heading, 2),
|
||||
round(ship:mass, 3),
|
||||
stage:number
|
||||
).
|
||||
}.
|
||||
|
||||
function UPDATE_LOG {
|
||||
loggerUpdate(LOG, LOG_DATA()).
|
||||
}
|
||||
|
||||
wait until ship:unpacked.
|
||||
core:part:getmodule("kOSProcessor"):doevent("Open Terminal").
|
||||
|
||||
basicAscent(90, 80000).
|
||||
|
||||
core:part:getmodule("kOSProcessor"):doevent("Close Terminal").
|
||||
loggerFlush(LOG).
|
||||
if addons:RT:hasKSCConnection(ship) {
|
||||
runPath("0:/scripts/basic.ks").
|
||||
} else {
|
||||
print "No connection to the KSC".
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
wait until ship:unpacked.
|
||||
runPath("0:/scripts/helo.ks").
|
||||
-79
@@ -1,79 +0,0 @@
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// maneuver.ks
|
||||
// Utility functions related to maneuvers.
|
||||
//
|
||||
// Usage:
|
||||
// executeNode(nd: node)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
// #include staging
|
||||
run once staging.
|
||||
|
||||
function executeNode {
|
||||
parameter nd is node(0, 0, 0, 0).
|
||||
|
||||
if node:deltav:mag = 0 {
|
||||
print "Empty node".
|
||||
return.
|
||||
}
|
||||
|
||||
local burnTime to calcBurnTime(nd:deltav:mag).
|
||||
print "Node in: " + round(nd:eta) + "s, dV: " + round(nd:deltav:mag, 1) + " m/s, burn time: " + round(burnTime, 1) + "s".
|
||||
|
||||
// ── Align to node vector.
|
||||
// If already inside burn window, skip the 60s lead-in wait.
|
||||
lock steering to lookdirup(nd:deltav, ship:facing:topvector).
|
||||
|
||||
if nd:eta > burnTime / 2 + 60 {
|
||||
wait until nd:eta <= burnTime / 2 + 60.
|
||||
}
|
||||
|
||||
// ── Wait until pointed correctly, unless burn is critically overdue
|
||||
if nd:eta > 0 {
|
||||
wait until vang(ship:facing:vector, nd:deltav) < 1
|
||||
or nd:eta <= burnTime / 2.
|
||||
}
|
||||
|
||||
// ── Snapshot initial dV for overburn detection
|
||||
local dv0 to nd:deltav.
|
||||
|
||||
ag1 off.
|
||||
|
||||
until ag1 {
|
||||
local tBurn to time:seconds + nd:eta.
|
||||
local vActual to velocityat(ship, tBurn):orbit.
|
||||
local vTarget to nd:deltav + vActual.
|
||||
local dvLive to vTarget - ship:velocity:orbit.
|
||||
|
||||
lock steering to lookdirup(dvLive, ship:facing:topvector).
|
||||
|
||||
// ── Overburn detection
|
||||
if vdot(dv0, nd:deltav) < 0 {
|
||||
print "Overburn detected. Cutting throttle.".
|
||||
lock throttle to 0.
|
||||
break.
|
||||
}
|
||||
|
||||
// ── Residual dV negligible
|
||||
if nd:deltav:mag < 0.1 {
|
||||
lock throttle to 0.
|
||||
break.
|
||||
}
|
||||
|
||||
// ── Throttle proportional to remaining dV magnitude
|
||||
local maxAcc to ship:maxthrust / ship:mass.
|
||||
if vang(ship:facing:vector, dvLive) > 1 {
|
||||
lock throttle to 0.
|
||||
} else {
|
||||
lock throttle to min(1, dvLive:mag / maxAcc).
|
||||
}
|
||||
|
||||
if defined UPDATE_LOG { UPDATE_LOG(). }
|
||||
wait 0.
|
||||
}
|
||||
|
||||
lock throttle to 0.
|
||||
unlock throttle.
|
||||
unlock steering.
|
||||
remove nd.
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// Inital gravity turn
|
||||
// #include staging
|
||||
run once staging.
|
||||
// #include maneuver
|
||||
run once maneuver.
|
||||
|
||||
function signedHeading {
|
||||
local fwd is ship:srfprograde:vector.
|
||||
local n is north:vector.
|
||||
local e is vCrs(up:vector, north:vector).
|
||||
|
||||
local hdg is arcTan2(vdot(fwd, e), vdot(fwd, n)).
|
||||
return mod(hdg + 360, 360).
|
||||
}
|
||||
|
||||
function basicAscent {
|
||||
parameter targetHeading is 90, targetAltitude is 80000.
|
||||
|
||||
if ship:altitude > body:atm:height return.
|
||||
|
||||
// get parts of interest
|
||||
set fairings to ship:partstitledpattern("^AE-FF.*").
|
||||
set antennas to ship:partstitledpattern("^(CommTech|Communotron|HG-|RA-|Reflectron).*").
|
||||
|
||||
lock throttle to 1.
|
||||
|
||||
print "Counting down:".
|
||||
from {local countdown is 5.} until countdown = 0 step {set countdown to countdown - 1.} do {
|
||||
print "..." + countdown.
|
||||
wait 1.
|
||||
}
|
||||
|
||||
// initial stage to takeoff
|
||||
stage.
|
||||
|
||||
// stage everytime thrust drops to zero
|
||||
when ship:maxThrust = 0 then {
|
||||
print "Staging".
|
||||
stage.
|
||||
return true.
|
||||
}.
|
||||
|
||||
// initial pitch-over
|
||||
set tarSteer to heading(targetHeading, 90).
|
||||
lock steering to tarSteer.
|
||||
until ship:velocity:surface:mag >= 100 {
|
||||
set tarSteer to heading(targetHeading, 90 - (ship:velocity:surface:mag / 10)).
|
||||
wait 0.
|
||||
}
|
||||
|
||||
// lock steering to the target heading, but account for drift, and the pitch
|
||||
// of the surface normal vector
|
||||
lock calculatedHeading to mod(targetHeading + 2 * (targetHeading - signedHeading()) + 360, 360).
|
||||
lock steering to heading(
|
||||
calculatedHeading,
|
||||
max(5, 90 - vAng(up:vector, ship:srfprograde:vector))
|
||||
).
|
||||
print "Locked steering to surface prograde pitch and target heading".
|
||||
|
||||
when ship:q < 0.01 then {
|
||||
for f in fairings {
|
||||
// get the module and deploy it
|
||||
set m to f:getmodule("ModuleProceduralFairing").
|
||||
if m:hasevent("deploy") m:doevent("deploy").
|
||||
}
|
||||
|
||||
wait 0.1.
|
||||
|
||||
panels on.
|
||||
radiators on.
|
||||
for a in antennas {
|
||||
set m to a:getmodule("ModuleRTAntenna").
|
||||
if m:hasevent("activate") m:doevent("activate").
|
||||
if m:getfield("target") = "no-target" m:setfield("target", "Mission Control").
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// coast to apoapsis
|
||||
wait until ship:apoapsis >= targetAltitude.
|
||||
unlock calculatedHeading.
|
||||
lock steering to ship:prograde.
|
||||
lock throttle to 0.
|
||||
|
||||
// don't do futher calcs until out of the atmosphere or very close to apoapsis
|
||||
until ship:altitude >= body:atm:height or eta:apoapsis < 60.
|
||||
|
||||
|
||||
// if we're using a booster to get to orbit drop it before finishing the cirularization
|
||||
when ship:periapsis > 30000 then {
|
||||
if ship:stagenum <> 0 and ship:stagedeltav(ship:stagenum - 1):current > 0 {
|
||||
print "Dropping booster".
|
||||
|
||||
// shutdown engines before dropping them
|
||||
for e in ship:engines {
|
||||
if e:ignition e:shutdown().
|
||||
}
|
||||
|
||||
stage.
|
||||
}
|
||||
}
|
||||
executeNode(createCircularizationNodeAp()).
|
||||
|
||||
print "Circularized".
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// core:part:getmodule("kOSProcessor"):doevent("Open Terminal").
|
||||
|
||||
if ship:bounds:bottomaltradar > 5 {
|
||||
print "Script shouldn't start off the ground".
|
||||
} else {
|
||||
set MODULES to list(
|
||||
"ascent.ks",
|
||||
"maneuver.ks",
|
||||
"staging.ks",
|
||||
"logger.ks"
|
||||
).
|
||||
|
||||
for mod in MODULES {
|
||||
copyPath("0:/scripts/" + mod, "1:/" + mod).
|
||||
}
|
||||
|
||||
// #include ascent
|
||||
run once ascent.
|
||||
|
||||
// --- GUI ---
|
||||
local targetAlt is 80000.
|
||||
local targetHdg is 90.
|
||||
local guiConfirmed is false.
|
||||
|
||||
local g is GUI(300).
|
||||
set g:x to 100.
|
||||
set g:y to 100.
|
||||
|
||||
local titleLabel is g:addlabel("Ascent Parameters").
|
||||
set titleLabel:style:align to "center".
|
||||
set titleLabel:style:hstretch to true.
|
||||
|
||||
g:addlabel("Target Altitude (m):").
|
||||
local altBox is g:addtextfield(targetAlt:tostring).
|
||||
set altBox:style:hstretch to true.
|
||||
|
||||
g:addlabel("Heading (degrees):").
|
||||
local hdgBox is g:addtextfield(targetHdg:tostring).
|
||||
set hdgBox:style:hstretch to true.
|
||||
|
||||
local confirmBtn is g:addbutton("Launch").
|
||||
set confirmBtn:onclick to {
|
||||
set targetAlt to altBox:text:tonumber(targetAlt).
|
||||
set targetHdg to hdgBox:text:tonumber(targetHdg).
|
||||
set guiConfirmed to true.
|
||||
g:hide().
|
||||
}.
|
||||
|
||||
g:show().
|
||||
wait until guiConfirmed.
|
||||
g:dispose().
|
||||
// --- END GUI ---
|
||||
|
||||
basicAscent(targetHdg, targetAlt).
|
||||
|
||||
// core:part:getmodule("kOSProcessor"):doevent("Close Terminal").
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// #include maneuver
|
||||
run once maneuver.
|
||||
|
||||
createCircularizationNodeAp().
|
||||
@@ -0,0 +1,4 @@
|
||||
// #include maneuver
|
||||
run once maneuver.
|
||||
|
||||
createCircularizationNodePe().
|
||||
@@ -0,0 +1,4 @@
|
||||
// #include maneuver
|
||||
run once maneuver.
|
||||
|
||||
if hasNode executeNode(nextNode).
|
||||
@@ -0,0 +1,19 @@
|
||||
core:part:getmodule("kOSProcessor"):doevent("Open Terminal").
|
||||
|
||||
set tr to ship:partstagged("tailRotor")[0].
|
||||
set rm to tr:getModule("ModuleRoboticServoRotor").
|
||||
set rpmMax to 410.
|
||||
|
||||
set pid to pidLoop(0.0025, 0, 0, rpmMax, rpmMax).
|
||||
set pid:setpoint to 0.
|
||||
|
||||
until false {
|
||||
set L_z to ship:angularMomentum:z.
|
||||
set rpmLimit to pid:update(time:seconds, L_z).
|
||||
rm:setfield("rpm limit", rpmLimit).
|
||||
|
||||
clearscreen.
|
||||
print "Lz : " + round(L_z, 2) at (5, 5).
|
||||
print "RPM Limit : " + round(rpmLimit, 2) at (5, 6).
|
||||
wait 0.
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
function groundSlope {
|
||||
parameter xOffset is 0, yOffset is 0.
|
||||
local east is vCrs(north:vector, up:vector).
|
||||
|
||||
local center is (
|
||||
ship:position +
|
||||
(yOffset * north:vector) +
|
||||
(xOffset * east)
|
||||
).
|
||||
|
||||
local a is body:geopositionof(center + 5 * north:vector).
|
||||
local b is body:geopositionof(center - 3 * north:vector + 4 * east).
|
||||
local c is body:geopositionof(center - 3 * north:vector - 4 * east).
|
||||
|
||||
local aVec is a:altitudeposition(a:terrainheight).
|
||||
local bVec is b:altitudeposition(b:terrainheight).
|
||||
local cVec is c:altitudeposition(c:terrainheight).
|
||||
|
||||
local slope is vCrs(cVec - aVec, bVec - aVec):normalized.
|
||||
// local centerPos is body:geopositionof(center).
|
||||
// set slopeDraw to vecDraw(
|
||||
// centerPos:altitudeposition(centerPos:terrainheight),
|
||||
// slope,
|
||||
// green,
|
||||
// "",
|
||||
// 10,
|
||||
// true
|
||||
// ).
|
||||
|
||||
return slope.
|
||||
}
|
||||
|
||||
wait until not hasNode.
|
||||
|
||||
// Suicide burn calcs
|
||||
set tval to 0.
|
||||
lock throttle to tval.
|
||||
lock steering to ship:srfretrograde.
|
||||
|
||||
lock h to ship:bounds:bottomaltradar.
|
||||
lock v0 to ship:verticalspeed.
|
||||
lock g to (body:mu / ((body:radius + ship:altitude)^2)).
|
||||
lock a to ship:maxthrust / ship:mass.
|
||||
lock d to (v0^2) / (2 * (a - g)).
|
||||
|
||||
|
||||
// wait for burn
|
||||
until h <= (1.1 * d) {
|
||||
clearscreen.
|
||||
print "Altitude AGL : " + round(h) at (4, 0).
|
||||
print "Vertical Speed : " + round(v0, 1) at (4, 1).
|
||||
print "Gravity : " + round(g, 2) at (4, 2).
|
||||
print "Acceleration : " + round(a, 2) at (4, 3).
|
||||
print "Distance : " + round(d, 2) at (4, 4).
|
||||
wait 0.
|
||||
}
|
||||
unlock d.
|
||||
unlock a.
|
||||
|
||||
set tval to 1.
|
||||
|
||||
set steeringLocked to false.
|
||||
until h < 1 {
|
||||
if v0 > -4 {
|
||||
// equalize acceleration to stop downward velocity
|
||||
set tval to max(0.001, ship:mass * g / ship:maxThrust).
|
||||
}
|
||||
else if v0 > -6 and not steeringLocked {
|
||||
// slow enough that we just want to kill vertical velocity
|
||||
lock steering to up.
|
||||
set steeringLocked to true.
|
||||
}
|
||||
|
||||
clearscreen.
|
||||
print "Altitude AGL : " + round(h) at (4, 0).
|
||||
print "Vertical Speed : " + round(v0, 1) at (4, 1).
|
||||
print "Gravity : " + round(g, 2) at (4, 2).
|
||||
print "Throttle : " + 100 * round(tval, 3) at (4, 3).
|
||||
wait 0.
|
||||
}
|
||||
|
||||
clearscreen.
|
||||
print "Holding position".
|
||||
lock steering to groundSlope().
|
||||
wait until ship:angularvel:mag < 0.1.
|
||||
wait 5.
|
||||
print "Stable".
|
||||
@@ -3,14 +3,14 @@
|
||||
// CSV logger with buffered writes.
|
||||
//
|
||||
// Usage:
|
||||
// local log to loggerCreate("0:/logs/flight.csv", list("time", "altitude", "apoapsis")).
|
||||
// loggerUpdate(log, list(time:seconds, altitude, apoapsis)).
|
||||
// loggerFlush(log). // call at end of script to flush remaining buffer
|
||||
// local LOGGER to loggerCreate("0:/logs/flight.csv", list("time", "altitude", "apoapsis")).
|
||||
// loggerUpdate(LOGGER, list(time:seconds, altitude, apoapsis)).
|
||||
// loggerFlush(LOGGER). // call at end of script to flush remaining buffer
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
// ── Creates a logger and writes the CSV header.
|
||||
// Parameters:
|
||||
// filePath : string — destination path, e.g. "0:/logs/flight.csv"
|
||||
// filePath : string — destination path, e.g. "logs/flight.csv"
|
||||
// columns : list — ordered list of column name strings
|
||||
// flushPeriod : scalar — seconds between buffer flushes (default 1.0)
|
||||
// Returns a logger lexicon to be passed to loggerUpdate / loggerFlush.
|
||||
@@ -20,11 +20,12 @@ function loggerCreate {
|
||||
parameter flushPeriod is 1.0.
|
||||
|
||||
// Create or overwrite the file and write the header row
|
||||
local f to open(filePath).
|
||||
if not archive:exists(filePath) archive:create(filePath).
|
||||
local f to archive:open(filePath).
|
||||
f:clear().
|
||||
f:writeln(_loggerFormatRow(columns)).
|
||||
|
||||
local logger to lexicon(
|
||||
local l to lexicon(
|
||||
"file", f,
|
||||
"columns", columns,
|
||||
"buffer", list(),
|
||||
@@ -32,30 +33,30 @@ function loggerCreate {
|
||||
"lastFlush", time:seconds
|
||||
).
|
||||
|
||||
return logger.
|
||||
return l.
|
||||
}
|
||||
|
||||
// ── Appends a data row to the buffer.
|
||||
// Values must be in the same order as the columns list passed to loggerCreate.
|
||||
// Flushes the buffer to disk if the flush period has elapsed.
|
||||
function loggerUpdate {
|
||||
parameter logger.
|
||||
parameter l.
|
||||
parameter values.
|
||||
|
||||
logger["buffer"]:add(_loggerFormatRow(values)).
|
||||
l["buffer"]:add(_loggerFormatRow(values)).
|
||||
|
||||
if time:seconds - logger["lastFlush"] >= logger["flushPeriod"] {
|
||||
loggerFlush(logger).
|
||||
if time:seconds - l["lastFlush"] >= l["flushPeriod"] {
|
||||
loggerFlush(l).
|
||||
}
|
||||
}
|
||||
|
||||
// ── Flushes all buffered rows to disk immediately.
|
||||
// Call at the end of a script to ensure no data is lost.
|
||||
function loggerFlush {
|
||||
parameter logger.
|
||||
parameter l.
|
||||
|
||||
local f to logger["file"].
|
||||
local buf to logger["buffer"].
|
||||
local f to l["file"].
|
||||
local buf to l["buffer"].
|
||||
|
||||
local i to 0.
|
||||
until i >= buf:length {
|
||||
@@ -64,7 +65,7 @@ function loggerFlush {
|
||||
}
|
||||
|
||||
buf:clear().
|
||||
set logger["lastFlush"] to time:seconds.
|
||||
set l["lastFlush"] to time:seconds.
|
||||
}
|
||||
|
||||
// ── Formats a list of values as a CSV row string.
|
||||
@@ -0,0 +1,89 @@
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// maneuver.ks
|
||||
// Utility functions related to maneuvers.
|
||||
//
|
||||
// Usage:
|
||||
// executeNode(nd: node)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
// #include staging
|
||||
run once staging.
|
||||
|
||||
function executeNode {
|
||||
parameter nd is node(0, 0, 0, 0).
|
||||
print "boof".
|
||||
|
||||
if nd:deltav:mag = 0 {
|
||||
print "Empty node".
|
||||
return.
|
||||
}
|
||||
|
||||
local burnTime to calcBurnTime(nd:deltav:mag).
|
||||
print "Node in: " + round(nd:eta) + "s, dV: " + round(nd:deltav:mag, 1) + " m/s, burn time: " + round(burnTime, 1) + "s".
|
||||
|
||||
// wait for node to be close then align to vector
|
||||
wait until nd:eta <= burnTime / 2 + 60.
|
||||
local np to nd:deltav.
|
||||
lock steering to np.
|
||||
wait until vang(ship:facing:vector, nd:deltav) < 1.
|
||||
print "Maneuver vector lined up".
|
||||
|
||||
// wait until burn
|
||||
wait until nd:eta <= burnTime / 2.
|
||||
print "Burn time".
|
||||
|
||||
// ── Snapshot initial dV for overburn detection
|
||||
local dv0 to nd:deltav.
|
||||
|
||||
local throttleSet to 0.
|
||||
lock throttle to throttleSet.
|
||||
|
||||
// ag1 off.
|
||||
// until ag1 {
|
||||
until False {
|
||||
local maxAcc to ship:maxThrust / ship:mass.
|
||||
set throttleSet to min(nd:deltav:mag / maxAcc, 1).
|
||||
set np to nd:deltav.
|
||||
|
||||
// ── Overburn detection
|
||||
if vdot(dv0, nd:deltav) < 0 {
|
||||
print "Overburn detected. Cutting throttle.".
|
||||
lock throttle to 0.
|
||||
break.
|
||||
}
|
||||
|
||||
// ── Residual dV negligible
|
||||
if nd:deltav:mag < 0.1 {
|
||||
wait until vdot(dv0, nd:deltav) < 0.5.
|
||||
lock throttle to 0.
|
||||
break.
|
||||
}
|
||||
|
||||
wait 0.
|
||||
}
|
||||
|
||||
lock throttle to 0.
|
||||
unlock throttle.
|
||||
unlock steering.
|
||||
remove nd.
|
||||
}
|
||||
|
||||
function createCircularizationNodeAp {
|
||||
local rBurn to body:radius + apoapsis.
|
||||
local vTarget to sqrt(body:mu / rBurn).
|
||||
local dvEst to vTarget - velocityat(ship, time:seconds + eta:apoapsis):orbit:mag.
|
||||
|
||||
local nd to node(time:seconds + eta:apoapsis, 0, 0, dvEst).
|
||||
add nd.
|
||||
return nd.
|
||||
}
|
||||
|
||||
function createCircularizationNodePe {
|
||||
local rBurn to body:radius + periapsis.
|
||||
local vTarget to sqrt(body:mu / rBurn).
|
||||
local dvEst to vTarget - velocityat(ship, time:seconds + eta:periapsis):orbit:mag.
|
||||
|
||||
local nd to node(time:seconds + eta:periapsis, 0, 0, dvEst).
|
||||
add nd.
|
||||
return nd.
|
||||
}
|
||||
@@ -8,14 +8,6 @@
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
|
||||
declare function basicStaging {
|
||||
when ship:maxThrust = 0 then {
|
||||
print "Staging".
|
||||
stage.
|
||||
preserve.
|
||||
}.
|
||||
}
|
||||
|
||||
function calcBurnTime {
|
||||
parameter dvNeeded.
|
||||
|
||||
@@ -27,6 +19,7 @@ function calcBurnTime {
|
||||
local stageDv to ship:stagedeltav(stageNum):current.
|
||||
local stageTime to ship:stagedeltav(stageNum):duration.
|
||||
|
||||
print "Stage: " + stageNum.
|
||||
if stageDv <= 0 {
|
||||
set stageNum to stageNum - 1.
|
||||
} else if stageDv >= dvRemaining {
|
||||
@@ -37,6 +30,9 @@ function calcBurnTime {
|
||||
set dvRemaining to dvRemaining - stageDv.
|
||||
set stageNum to stageNum - 1.
|
||||
}
|
||||
|
||||
print " - time: " + totalTime.
|
||||
print " - dv : " + dvRemaining.
|
||||
}
|
||||
|
||||
if dvRemaining > 0 {
|
||||
@@ -45,3 +41,11 @@ function calcBurnTime {
|
||||
|
||||
return totalTime.
|
||||
}
|
||||
|
||||
function deployables {
|
||||
ag1 on.
|
||||
wait 0.5.
|
||||
panels on.
|
||||
radiators on.
|
||||
ag2 on.
|
||||
}
|
||||
Reference in New Issue
Block a user