Initial cleanup of ascent logic, not tested

This commit is contained in:
2026-05-20 10:54:07 -07:00
parent 8aec6aa8a4
commit 6dd14708bc
5 changed files with 183 additions and 97 deletions
+65
View File
@@ -0,0 +1,65 @@
// Inital gravity turn
run once staging.
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)).
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
wait until ship:apoapsis >= targetAltitude.
lock steering to ship:prograde.
lock throttle to 0.
// don't do futher calcs until out of the atmosphere or very close to apoapsis
wait until ship:altitude >= body:atm:height or eta:apoapsis < 60.
executeNode(createCircularizationNode()).
print "Circularized".
}
+11
View File
@@ -0,0 +1,11 @@
copyPath("0:/ascent.ks", "1:/ascent.ks").
copyPath("0:/maneuver.ks", "1:/maneuver.ks").
copyPath("0:/staging.ks", "1:/staging.ks").
run once ascent.
wait until ship:unpacked.
core:part:getmodule("kOSProcessor"):doevent("Open Terminal").
basicAscent(90, 80000).
core:part:getmodule("kOSProcessor"):doevent("Close Terminal").
-97
View File
@@ -1,97 +0,0 @@
//hellolaunch
set TARGET_ALTITUDE to 80000.
set ETA_TARGET to 60.
//First, we'll clear the terminal screen to make it look nice
wait until ship:unpacked.
clearscreen.
core:part:getmodule("kOSProcessor"):doevent("Open Terminal").
lock throttle to 1.0.
//This is our countdown loop, which cycles from 10 to 0
print "Counting down:".
from {local countdown is 5.} until countdown = 0 step {set countdown to countdown - 1.} do {
print "..." + countdown.
wait 1. // pauses the script here for 1 second.
}
when maxThrust = 0 then {
print "Staging".
stage.
preserve.
}.
// GRAVITY TURN
// pitch to 80 degrees over the first 100 m/s
set tarSteer to heading(90, 90).
lock steering to tarSteer.
until ship:velocity:surface:mag >= 100 {
set tarSteer to heading(90, 90 - (ship:velocity:surface:mag / 10)).
wait 0.
}
print "Finished initial pitch".
// actual gravity turn
lock steering to ship:srfprograde.
// lock steering to heading(90, max(90 - vang(ship:up:vector, ship:srfprograde:vector), 10)).
// wait until eta:apoapsis > 45.
// // burn to target apoapsis
// clearscreen.
// set circ_pid to pidloop(1/30, 0, 0, 0, 1).
// set circ_pid:setpoint to ETA_TARGET.
// set gravThrottle to 1.0.
// lock throttle to gravThrottle.
// until apoapsis >= TARGET_ALTITUDE {
// set gravThrottle to circ_pid:update(time:seconds, eta:apoapsis).
// print "Throttle: " + round(100 * gravThrottle, 0) + "%" at (0, 0).
// print "ETA: " + round(eta:apoapsis, 0) at (0, 1).
// wait 0.
// }
// clearscreen.
wait until ship:apoapsis >= TARGET_ALTITUDE.
print "80km apoapsis reached".
lock throttle to 0.
lock steering to ship:prograde.
wait until ship:altitude >= 70000.
// try to get apoapsis closer to target
if ship:apoapsis < TARGET_ALTITUDE and eta:apoapsis > 30 {
lock throttle to 1.
wait until ship:apoapsis >= TARGET_ALTITUDE.
lock throttle to 0.
}
wait until eta:apoapsis < 30.
// CIRCULARIZATION CALCS
set circThrottle to 0.
lock throttle to circThrottle.
set throttlePID to pidLoop(0.25, 0, 0, 0, 1).
set throttlePID:setpoint to 15.
set circPitch to 0.
lock steering to heading(90, circPitch).
set pitchPID to pidLoop(1, 0, 0, -10, 10).
set pitchPID:setpoint to 15.
until apoapsis - periapsis < 100 or periapsis > TARGET_ALTITUDE {
set circThrottle to max(0.1, throttlePID:update(time:seconds, eta:apoapsis)).
set circPitch to pitchPID:update(time:seconds, eta:apoapsis).
wait 0.
}
unlock steering.
unlock throttle.
wait 1.
set ship:control:pilotmainthrottle to 0.
print "Circularized.".
+69
View File
@@ -0,0 +1,69 @@
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).
}
wait 0.
}
lock throttle to 0.
unlock throttle.
unlock steering.
remove nd.
}
+38
View File
@@ -0,0 +1,38 @@
declare function basicStaging {
when ship:maxThrust = 0 then {
print "Staging".
stage.
preserve.
}.
}
function calcBurnTime {
parameter dvNeeded.
local totalTime to 0.
local dvRemaining to dvNeeded.
local stageNum to ship:stagenum.
until dvRemaining <= 0 or stageNum < 0 {
local stageDv to ship:stagedeltav(stageNum):current.
local stageTime to ship:stagedeltav(stageNum):duration.
if stageDv <= 0 {
set stageNum to stageNum - 1.
} else if stageDv >= dvRemaining {
set totalTime to totalTime + stageTime * (dvRemaining / stageDv).
set dvRemaining to 0.
} else {
set totalTime to totalTime + stageTime.
set dvRemaining to dvRemaining - stageDv.
set stageNum to stageNum - 1.
}
}
if dvRemaining > 0 {
print "WARNING: Insufficient dV. Short by " + round(dvRemaining, 1) + " m/s.".
}
return totalTime.
}