diff --git a/ascent.ks b/ascent.ks new file mode 100644 index 0000000..dada18f --- /dev/null +++ b/ascent.ks @@ -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". +} \ No newline at end of file diff --git a/boot/boot.ks b/boot/boot.ks new file mode 100644 index 0000000..e98fc2b --- /dev/null +++ b/boot/boot.ks @@ -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"). \ No newline at end of file diff --git a/boot/hellolaunch.ks b/boot/hellolaunch.ks deleted file mode 100644 index 68df8ac..0000000 --- a/boot/hellolaunch.ks +++ /dev/null @@ -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.". diff --git a/maneuver.ks b/maneuver.ks new file mode 100644 index 0000000..2323e61 --- /dev/null +++ b/maneuver.ks @@ -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. +} \ No newline at end of file diff --git a/staging.ks b/staging.ks new file mode 100644 index 0000000..63bfc85 --- /dev/null +++ b/staging.ks @@ -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. +} \ No newline at end of file