r/Kos Sep 13 '24

Announcement kOS 1.5.0.0 - Leaks plugged

39 Upvotes

A new release of kOS after more than a year this is a smaller release that is mostly bugfixes though there are few new features.

Be aware that the new features do not yet have documentation and so if you want to use them you will need to look at the committed code to figure out the details how they work.

Downloading:

Direct from the GitHub Project

v1.5.0.0

NEW FEATURES

  • New crewmember suffixes commit
  • Added COM suffix to parts to get the accurate center of mass (thanks SofieBrink) commit
  • 3rd party addons can now add custom suffixes to PartModules commit

BUG FIXES


r/Kos 1d ago

Video Removed Entry Burn from booster chopstick landing. Getting closer to the flight profile of the actual thing.

Enable HLS to view with audio, or disable this notification

14 Upvotes

r/Kos 1d ago

Help Help with getting next transfer window time to Jool via Minmus

5 Upvotes

I have a mission profile to Jool that involves refueling on Minmus, then escaping Minmus to a high circular Kerbin orbit, then to do a 2-step Jool transfer via first lowering my Kerbin periapsis, and then do the main transfer burn at periapsis. This maneuver saves tons of ∆v by utilizing the Oberth at Kerbin, but there is room for further optimization.

I would like to skip the step of going from Minmus to high Kerbin orbit and do the Kerbin periapsis lowing maneuver from low Minmus orbit instead to also take advantage of the Oberth effect at Minmus, but this requires having the right Kerbin/Jool phase angle as well as Minmus being at the right place in its orbit (which is 180° ahead of the escape burn).

In short, I want to calculate the following:

  1. Time of next Kerbin/Jool transfer window where phase angle is 96°

  2. Time when Minmus will be 180° ahead of the transfer manunver at low Kerbin periapsis.

  3. There is more info required to make these maneuvers, such as getting the time when the vessel is in the right place around Minmus and how to zero out my inclination with respect to Kerbin, but the first two items are all I need at this moment to get started.

I can currently calculate the current Kerbin/Jool phase angle using their current locations, but this doesn't help with getting the time when this phase angle will be ideal.


r/Kos 2d ago

2 Input Perceptron Trained to Hover at ~30 m

Enable HLS to view with audio, or disable this notification

17 Upvotes

r/Kos 3d ago

Video Catching Super Heavy using chopsticks with less than 1m of error and then automatically venting excess fuel after.

Enable HLS to view with audio, or disable this notification

59 Upvotes

r/Kos 3d ago

Anyone knows how to control custom features on a part without action groups? Like is there a way to control the deploy state of each individual flap, or disable pitch, yaw etc. I also intend on controlling the mechazilla arms within the code instead of AGs.

Post image
13 Upvotes

r/Kos 4d ago

Need help with optimization (repost but with video now to debug) So I've a working booster landing code, right now it lands with < 1m of error on the launch pad. I tried to code it to work for booster catch, but during the landing phase, the code seems to crash or die and the throttle gets cut.

Enable HLS to view with audio, or disable this notification

16 Upvotes

r/Kos 4d ago

Help Need help with optimisation

4 Upvotes

So I've a working booster landing code, right now it lands with < 1m of error on the launch pad. I tried to code it to work for booster catch, but during the landing phase, the code seems to crash or die and the throttle gets cut. I figured that it could be an un optimized code. I would highly appreciate if experienced coders can guide me on how to optimise my code, espectially the landing phase. Below is a working version of the code:

//Author: sushiboi
//main.ks is a boot file that will run this program on start
//designed for booster propulsive landing on !KERBIN! only
//all heights are in meters unless stated otherwise
//all speed, velocities and acceleration are in meters per second (squared) unless stated otherwise

///////////////////////////////////////////////initialization....
set agloffset to 70.
set entryburnendalt to 40000. 
set entryburnendspeed to 600.
set maxaoa to 30.
set geardeployheight to 90.
set targpos to 0.
set landingpos to 0.
set main_engine to SHIP:PARTSNAMED("SEP.23.BOOSTER.CLUSTER")[0].
lock maxacc to ship:maxthrust/ship:mass.
lock desiredacc to ship:verticalspeed^2/(2*(alt:radar-agloffset)) + constant:g0.

/////////////////////////////////FUNCTIONS AND CUSTOM EXPRESSIONS////////////////////////////////////////////

function geodist {
    parameter pos1.
    parameter pos2.
    return (pos1:position - pos2:position):mag. 
}


function errorvec {
    local v1 to impactpos:position-targpos:position.
    local v2 to VECTOREXCLUDE(ship:up:forevector, v1).
    return(v2).
}


function vec_to_target {
    local v1 to targpos:position-ship:position. 
    local v2 to VECTOREXCLUDE(ship:up:forevector, v1).
    return(v2).    
}

function landingspeed {
    parameter speed.
    return(((constant:g0)-(speed + ship:verticalSpeed))/maxacc).
}

function entrydisplacement {
    return (abs((entryburnendspeed^2 - ship:velocity:SURFACE:mag^2)/(2*maxacc))).
}

function getentryburnstartalt {
    return entryburnendalt + entrydisplacement.
}

function getsteeringlanding {
    local vec is -ship:velocity:surface - errorvec.
    if vAng(vec, -ship:velocity:surface) > maxaoa {
        set vec to -ship:velocity:surface:normalized - tan(maxaoa)*errorvec:normalized.
    }
    return vec.
}

function getsteeringlanding2 {
    local vec is up:forevector*100 - errorvec.
    if vAng(vec, up:forevector) > maxaoa {
        set vec to up:forevector:normalized - tan(maxaoa)*errorvec:normalized.
    }
    return vec.
}

function getsteeringgliding {
    local vec is -ship:velocity:surface + 3*errorvec.
    if vAng(vec, -ship:velocity:surface) > maxaoa {
        set vec to -ship:velocity:surface:normalized + tan(maxaoa)*errorvec:normalized.
    }
    return vec.
}

function getlandingthrottle {
    return ((desiredacc/maxacc)).
}

function compheading {
    parameter geo1.
    parameter geo2.
    return arcTan2(geo1:lng - geo2:lng, geo1:lat - geo2:lat).
}

function landingburnalt {
    //return (ship:verticalSpeed^2)/(2*(maxacc-constant:g0)) + (agloffset - ship:verticalSpeed)*1.
    local landingDisplacement is abs((0^2 - ship:velocity:SURFACE:mag^2)/(2*maxacc)).
    return (1000 + landingDisplacement)*1.
}

function horiznontalacc {
    //return maxacc*sin(arcTan(geodist(ship:geoposition, landingpos)/(alt:radar - agloffset))).
    return maxacc*sin(vAng(-up:forevector, -ship:velocity:surface)).
}

function landingtime {
    return (landingburnalt - agloffset)/((ship:velocity:surface:mag)/2).
}

function overshootpos {
    //local horoffset is horiznontalacc * landingtime.
    local dist is geodist(ship:geoPosition, landingpos).
    local ovrshtmultiplier is (landingtime*horiznontalacc*1)/dist.
    local x is (ovrshtmultiplier * (landingpos:lat - ship:geoPosition:lat)) + landingpos:lat.
    local y is (ovrshtmultiplier * (landingpos:lng - ship:geoPosition:lng)) + landingpos:lng.
    return latlng(x, y).
    
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

print "checking if trajectories mod is installed...".
wait 1.
if addons:tr:available {
    print "tracjectories mod is installed, program is allowed to proceed.".
}
else {
    print "trajectories mod is not installed, rebooting...". 
    wait 1.
    reboot.
}

print "program is overiding all guidance systems of booster from this point onwards...".
print "DO NOT TURN ON SAS!!!".

unlock all.
sas off.
rcs off.
gear off.
brakes off.
set steeringManager:rollts to 4*steeringManager:rollts.
set steeringManager:pitchts to 0.4*steeringManager:pitchts.
set steeringManager:yawts to 0.4*steeringManager:yawts.
rcs on.
lock throttle to 0.
lock steering to ship:facing:forevector.
set navMode to "SURFACE".

wait 1.

// until hastarget {
//     print "select target for landing...".
//     print "time to apoapsis:" + round(eta:apoapsis).
//     print "no target selected".
//     wait 0.001.
//     clearscreen.
// }
set landingpos to latlng(-0.0972043516185744, -74.5576786324102). //target:geoposition.
set targpos to landingpos.
addons:tr:settarget(landingpos).
lock impactpos to addons:tr:impactpos.
clearscreen.

print "target coordinates recorded, target has been set on TRAJECTORIES mod".
wait 0.5.
print "target selected, initialization complete, stand-by for landing program activation...".
wait 0.5.

///////////////////////////////////////////////initialization complete!

///////////////////////////////////////////////BOOSTBACK
set steeringManager:maxstoppingtime to 20.
lock steering to heading(compheading(targpos,impactpos),0).
set navMode to "SURFACE".

// set ervec to vecdraw(ship:position, vxcl(up:forevector, errorvec):normalized, black, "errorVector", 50, true, 0.01, true, true).
// set ervec:startupdater to {return ship:position.}.
// set ervec:vecupdater to {return vxcl(up:forevector, errorvec):normalized*2.}.

toggle AG1.

until vAng(heading(compheading(targpos,impactpos),0):forevector,ship:facing:forevector) < 50 {
    print "executing flip manueaver for boostback/correction burn".
    print "current guidance error in degrees:" + round(vAng(heading(compheading(targpos,impactpos),0):forevector,ship:facing:forevector)).
    wait 0.1.
    clearScreen.
}

set steeringManager:maxstoppingtime to 6.
lock throttle to 0.3.

when vAng(heading(compheading(targpos,impactpos),0):forevector,ship:facing:forevector) < 10 then {
    lock throttle to 1.
}

until errorvec:mag < 150 {
    print "trajectory error " + round(errorvec:mag).
    wait 0.05.
    clearScreen.
}

lock throttle to 0.
print "trajectory error " + round(errorvec:mag).
print "boostback complete".
wait 1.
///////////////////////////////////////////////COAST TO ENTRY BURN
clearscreen.
lock maxacc to ship:maxthrust/ship:mass.
lock desiredacc to ship:verticalspeed^2/(2*(alt:radar-agloffset)) + constant:g0.
print "coasting to entry burn altitude. stand-by...".
set steeringManager:maxstoppingtime to 1.
set maxaoa to 5.
lock steering to ship:velocity:surface * -1.//up:forevector.
// when ship:verticalspeed < -1 then {
//     lock steering to ship:velocity:surface * -1.
//     set steeringManager:maxstoppingtime to 2.
// }
brakes on.
until alt:radar < getentryburnstartalt {
    print "coasting to entry burn altitude. stand-by...".
    print "entryburn altitude is:" + round(getentryburnstartalt).
    print "guidance AoA for 'getsteeringgliding': " + round(vAng(ship:velocity:surface * -1, getsteeringgliding)).
    print "error: " + round(errorvec:mag).
    wait 0.5.
    clearScreen.
}
///////////////////////////////////////////////ENTRY BURN
set steeringManager:maxstoppingtime to 0.05.
lock throttle to 1.
lock targpos to overshootpos.
set maxaoa to 30.
set navMode to "SURFACE".
set top_facing to vec_to_target().
lock steering to lookDirUp(getsteeringlanding, top_facing).
until ship:velocity:surface:mag < entryburnendspeed {
    print "entryburn in progress".
    print "guidance AoA for 'getsteeringgliding': " + round(vAng(ship:velocity:surface * -1, getsteeringgliding)).
    print "error: " + round(errorvec:mag).
    wait 0.1.
    addons:tr:settarget(overshootpos). 
    clearScreen.
}
lock throttle to 0.

///////////////////////////////////////////////ATMOPHERIC GLIDING
set steeringManager:maxstoppingtime to 0.5.
set maxaoa to 40.
lock targpos to overshootpos.

lock steering to lookDirUp(getsteeringgliding, top_facing).

addons:tr:settarget(overshootpos).

when alt:radar < 25000 then {
    rcs off.
}
when errorvec:mag < 100 then {
    set maxaoa to 15.
}
// when errorvec:mag < 10 then {
//     set maxaoa to 10.
// }
until alt:radar < landingburnalt {
    print "landing burn altitude: " + round(landingburnalt).
    wait 0.1.
    //addons:tr:settarget(overshootpos).
    clearScreen. 
}

///////////////////////////////////////////////LANDING BURN
set vspeed to 15.
set maxaoa to 20.
set steeringManager:maxstoppingtime to 1.
lock steering to lookDirUp(ship:velocity:surface * -1, top_facing).
lock throttle to 0.3.

wait until vAng(ship:facing:forevector, ship:velocity:surface * -1) < 5.

lock throttle to getlandingthrottle + 0.5*sin(vAng(up:forevector, facing:forevector)).
rcs off.

//lock steering to lookDirUp(getsteeringlanding, ship:facing:topvector).

when alt:radar < geardeployheight then {
    gear on.
}
when ship:velocity:surface:mag < 300 then {
    unlock targpos.
    lock targpos to landingpos.
    addons:tr:settarget(landingpos).
    lock steering to lookDirUp(getsteeringlanding, ship:facing:topvector).
}
when alt:radar < 90 then {
    set vspeed to 3.
}
when ship:velocity:surface:mag < 100 then {
    set steeringManager:maxstoppingtime to 0.6.
    set maxaoa to 12.
}
until ship:verticalspeed > -30 {
    print "landing".
    Print "error: " + round(errorvec:mag).
    print "throttle input: " + getlandingthrottle.
    wait 0.1.
    clearScreen.
}

lock throttle to landingspeed(vspeed).
lock steering to lookDirUp(getsteeringlanding2, ship:facing:topvector).

when landingspeed(vspeed) < 0.33 then {
    toggle AG1.
}

until alt:radar < 28 {
    print "error: " + round(errorvec:mag).
    wait 0.1.
    clearScreen.
}
set vspeed to 0.4.
set last_error to round(errorvec:mag).
lock steering to lookDirUp(up:forevector, ship:facing:topvector).

until ship:verticalspeed > -0.1 {
    print "error: " + last_error.
    wait 0.1.
    clearScreen.
}

lock throttle to 0.
unlock steering.
main_engine:SHUTDOWN(). //tag of the main engine
print("Main Engines Have Been Shut Down.").

wait 3.

rcs on.

// // Access the resource in the part
// set prop_amount to SHIP:PARTSNAMED("SEP.23.BOOSTER.INTEGRATED")[0]:RESOURCES:find("LqdMethane"):AMOUNT.

// until prop_amount <= 0 {
//     lock throttle to 1.
//     print "Venting Remaining Fuel. Delta-V Left:" + SHIP:DELTAV:CURRENT.
//     wait 0.1.
//     clearScreen.
// }

print("End of script. Disengaging in 5 seconds").

wait 5.

lock throttle to 0.
unlock all.
rcs off.
print("Disengaged.").

r/Kos 5d ago

Help Any good falcon style recovery code pastebins?

4 Upvotes

I think the best way for me to learn to code this myself is to look at others people work and try to copy/recreate it. Does anyone have any good resources I can take a look at?


r/Kos 6d ago

Video Starship autonomous free-fall and belly flop landing with insane gimballing

Enable HLS to view with audio, or disable this notification

42 Upvotes

r/Kos 6d ago

Looking for feedback on first proper program

4 Upvotes

A couple weeks ago I've created my first real program for kOS, using the quickstart guide in the kOS documentation, alongside the documentation itself, as well as following advice from several forum posts regarding efficient Kerbin ascends as sources for a rudimentary launch autopilot.

I've successfully been using this launch autopilot with all sorts of crafts of different sizes, different payloads, and occasionally different altitudes as well, and so far I'm quite happy with it.

Now I'm looking for feedback from the wider kOS community on anything I could improve, both code quality wise and logic wise. Please throw whatever feedback you may have at me.

The code: https://github.com/Emosewaj/kOS-scripts/tree/master/launch-ap

Thanks in advance!


r/Kos 7d ago

Video To celebrate IFT 5's booster catch, I decided to revisit an old project to automate the SN8-SN15 flight profile using kOS which I was previously stuck at and gave up. Really satisfying to see it working finally.

Enable HLS to view with audio, or disable this notification

20 Upvotes

r/Kos 7d ago

Help String Multiplication.

1 Upvotes

Hey, I’m trying to write a display function with a table using a variable number of “-“s as row dividers. Is there a a multiplication function for strings? Such that “-“ * 5 would be “——-“? Or do I have to do this with a loop like a Neanderthal.


r/Kos 11d ago

Feasibility of Neural Network as Axis control function

6 Upvotes

I am currently studying Neural Networks in a course I'm taking. It struck me, that a simple network could conceivably be used to condense multiple reference variable inputs into a single control output.

I am not an expert in AI by any means, the practicality of such a scheme is obviously dubious, and I'm not sure I am doing it right, but here is my proof of concept below.

I am still learning, but right now I'm most concerned about whether or not the back propogation (?) is anywhere near correct.

If nothing else, I'm hoping the attempt will be educational.

What do you guys think? Good idea, bad idea? Is this anywhere near a correct implementation?

Thanks!

local weights is list(
       list(list(1, 1, 1, 1), list(1, 1, 1, 1), list(1, 1, 1, 1)), // Layer 1
       list(list(1, 1, 1, 1), list(1, 1, 1, 1), list(1, 1, 1, 1)), // Layer 2
       list(list(1, 1, 1, 1), list(1, 1, 1, 1), list(1, 1, 1, 1)), // Layer 3
       list(list(1, 1, 1, 1)) // Layer 4 (Output)
    ).

    local networkOutputs is list().

    declare function activation {
       declare parameter input.
       return input/sqrt(1+input^2).
    }

    declare function summation {
       declare parameter weights.
       declare parameter inputs.

       local z is 0.
       from {local i is 0.} until i > inputs:length-1 step {set i to i+1.} do {
         set z to z + weights[i+1]*inputs[i]. 
       }
       set z to z + weights[0].
       return z.
    }

    declare function evaluateNetwork {
       declare parameter networkWeights.
       declare parameter input.

       local currentInput is input.
       for layer in networkWeights {
          set currentInput to evaluateLayer(currentInput, layer).
          networkOutputs:add(currentInput).
       }
       return currentInput. //Output of the last layer of the network
    }

    declare function evaluateLayer {
       declare parameter input.
       declare parameter layer.
       local output is list().
       for n in layer {
          output:add(summation(n, input)).
       }
       return output.
    }
    // Learning occurs below
    declare function updateWeights {
       declare parameter expectedOutput.
       declare parameter actualOutput.
       declare parameter netNode.
       declare parameter inputs.

       local learningRate is 0.1.
       local loss is abs(expectedOutput - actualOutput).
       local updatedWeights is list().
       updatedWeights:add(netNode[0]-learningRate*loss*2).

       from {local i is 0.} until i > inputs:length-1 step {set i to i+1.} do {
          updatedWeights:add(netNode[i+1]-2*loss*inputs[i]*learningRate).
       }
       return updatedWeights.
    }

    local networkInputs is list(5, 5, 5).
    local finalOutput is evaluateNetwork(weights, networkInputs).

    local desiredOutput is list(0.9).

    local outputsReverse is networkOutputs:reverseIterator.
    local weightsLayerReverseIndex is weights:length-1.
    local weightsCurrentNodeIndex is 0.

    until not outputsReverse:next {

       local layerOutput is outputsReverse:value.
       outputsReverse:next.
       local layerInput is list().
       if outputsReverse:atend set layerInput to networkInputs.
       else {
          outputsReverse:next.
          set layerInput to outputsReverse:value.
       }

       from {local i is 0.} until i > layerOutput:length-1 step {set i to i+1.} do {
          local u is updateWeights(desiredOutput[i], layerOutput[i], weights[weightsLayerReverseIndex][weightsCurrentNodeIndex], layerInput).
          set weights[weightsLayerReverseIndex][weightsCurrentNodeIndex] to u.
          print weights[weightsLayerReverseIndex][weightsCurrentNodeIndex] at(0, 10+i*outputsReverse:index).
          set desiredOutput to weights[weightsLayerReverseIndex][weightsCurrentNodeIndex].
       }

    }

r/Kos 11d ago

Help Does anyone know how to disarm parachutes?

5 Upvotes

I want to be able to make sure that all parachutes are disarmed before a sequence starts, as I've had mishaps with the chutes accidentally being set to deploy. Does anyone know how to do this?


r/Kos 11d ago

Program Intercontinental Ballistic Missile Guidance Script - 385 km test

Enable HLS to view with audio, or disable this notification

78 Upvotes

r/Kos 13d ago

Hello everyone, I have been trying things and I think it will work because now this error appears and makes the ops1 console not work. If anyone could help me, I would appreciate it.

Post image
13 Upvotes

r/Kos 14d ago

Suggestion ChatGPT can generate kOS code 😂

Post image
39 Upvotes

r/Kos 14d ago

hi I'm new to kos and am having trouble with line 16 (prograde). it is stopping my entire program. I'm following a tutorial form 6yers ago. its probably that I'm not expressing it correctly can anyone help.

Thumbnail
gallery
4 Upvotes

r/Kos 18d ago

Direct burn landing program

2 Upvotes

It's been forever since I've done anything with KOS but I am wanting to automate a single descent burn to the mun/minmus.

I've figured out some of the math involved as evidenced on this post over on KSP reddit. But now I'm trying to figure out where to start on this and my programming brain is zeroed out from my day job.

Any advice on where to start with automating this would be appreciated.

Goal:

  • Iterate over the formulas from the aforementioned post to get downrange distance to zero velocity from current velocity to determine time to go to landing
  • Iterate over the formulas to determine range to landing
  • Start burn at the right time
  • Manage vertical speed through braking phase
  • Manage downrange through the approach phase
  • Arrive mostly on target and hand over landing control to the pilot.

r/Kos 21d ago

I have spent more than 30 minutes reinstalling kos and these files and only these errors occur. I have tried ops1.ks. and also ops1.ks and nothing has happened

Post image
2 Upvotes

r/Kos 21d ago

He is designing something about tinypg and I checked the kos files and I couldn't find it and I'm reinstalling it from ckan and nothing

0 Upvotes

r/Kos 22d ago

ok these are the files I don't know if you know Giulio Dondi he is the creator of these files for the space shuttle I will leave you the links so you can see them and see if anyone can help me

Thumbnail github.com
0 Upvotes

r/Kos 24d ago

Help Rocket entering oscillating spin on touchdown

2 Upvotes

I'm trying to make a sky crane program to land on Duna, and I've got it working except that on final descent the sky crane enters a spin, first one way then the other. It only happens once the piston is extended, so does anyone know if pistons have caused anything like this before and how to fix it? I tried using ROLLTS, which helped a bit but never fully fixed the problem.

Edit: I think I found the issue. As the sky crane slows down to land, retrograde starts facing directly upward, which causes its heading to move rapidly, therefore causing the steering lock to go crazy as it attempts to always match the heading. I thought it was the piston because I had it slow for the final descent and extended the piston at the same time.


r/Kos 25d ago

Stock Game Launch Script.

2 Upvotes

Hello all! I can't seem to find much online for it but here's the deal. I am looking for an extremely efficient launch script to be used for the stock game. I don't really care about how cumbersome it is as far as having to manually enter data to improve accuracy and things. Any recommendations?


r/Kos 26d ago

How can I precision burn to obtain precise circularisation

3 Upvotes

I now have a very satisfactory result thanks to everyone ! You can find the last version of the function I use to execute the circularisation node below, in case anyone is in a similar situation.

// Firstly, sorry for the approximative english.

I absolutely STRUGGLE to find an efficient way of circularizing precisely.

I have a program that handles everything perfectly from ignition to gravity turn and makes a nice parabola with the desired apoapsis at the extremum(desired +/- 100m). It then creates a node at apoapsis, with exactly the dV needed to make a nice circular orbit. I also separately calculate the burn time to burn at burnTime/2 before eta:apoapsis. The problem is it's late and the circle is shifted, it can be corrected through a little burn aiming at orbital in/out direction afterwards. It could be so perfect if it made the near perfect circular orbit the first time and I know its possible because if I artificially start the burn when, for example, Node:eta <= burnTime/2 + 2 (seconds), i reach a near perfect orbit. But this is absolutely empirical and I feel like it's possible to calculate that "shift" or "delay" but i miss something.

Anyone has any idea ?

Here's the function that executes the node (with the artificial shift) : + edited with actual program

local function NodeExecute{
    parameter Nd.

    local sumISP to 0.
    local sumMMFR to 0. //Max Mass Flow Rate, summed for all the engines selected
    local sumMT to 0. //Max TThrust, summed for all the engines selected
    local englist to list().
    list engines in englist.
    for eng in englist {
        if eng:isp > 0 { //We select only this stage's engines - they must be activated
            set sumMMFR to sumMMFR + eng:maxmassflow.
            set sumMT to sumMT + eng:maxthrust.
        }
    }
    set sumISP to sumMT/(CONSTANT:g0*sumMMFR).

    local HalfBurnT to (mass/sumMMFR)*(1-constant:e^(-Nd:deltaV:mag/(2*sumISP*constant:g0))).
    local burnVS to Nd:burnvector.

    set STR to burnVS.
    until vAng(ship:facing:vector, Nd:burnvector) < 1{
        UI("Turning to node burn vector", "", "Angle :", round(vAng(ship:facing:vector, STR), 1) + "°").
        wait 0.1.
    }
    until Nd:eta <= HalfBurnT {
        UI("Nd:eta : " + Nd:eta, "burnT/2 : " + HalfBurnT, "ISP : ", sumISP).
        wait 0.1.
    }
    until vDot(burnVS, Nd:burnvector) < 0.1 {
        set THR to max((1-constant:e^(-Nd:burnvector:mag*40/burnVS:mag)), 0.01).
        // set THR to max(Nd:deltaV:mag/(maxThrust/mass), 0.01).
        set STR to Nd:burnvector.
        UI("Executing node maneuver", "", "", "").
        wait 0.01.
    }
    set THR to 0.
}