// ═══════════════════════════════════════════════════════════ // 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. }