Created
September 17, 2016 20:40
-
-
Save rgioai/86bc19e326fe3ff3b56c3968226d4e52 to your computer and use it in GitHub Desktop.
kOS Script for Kerbal Space Program that uses vectors to launch a craft into a target's orbital plane, minimizing the delta-v required for inclination changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//launch_inc.ks | |
//Author: Ryan Giarusso | |
//kOS Version: 0.17 (last tested version is not current version! Use at your own risk!) | |
//First Created: 01MAY2016 | |
//Last Updated: 17SEP2016 | |
//Description: Launches craft into a target orbital plane to a specified apoapsis, using timewarp. | |
//Honest Admission: The interesting stuff is on lines 136-145 and 166-169. The rest is just a launch script based heavily | |
// on the work of @KK4TEE and @gisikw. Thanks guys! | |
set ship:control:pilotmainthrottle to 0. //Don't accidentally leave the pad early. | |
//Definitions | |
local TARGET_ALTITUDE is 100000. | |
local TARGET_ORBITABLE is "Minmus". | |
//Gravity Turn shaped as a * pct_alt^b + c | |
local GT_A is -115.23935. | |
local GT_B is 0.4095114. | |
local GT_C is 88.963. | |
//Helper Functions | |
function Orbitable() { | |
parameter tgt. | |
list targets in vessels: | |
for vs in vessels { | |
if vs:name = tgt { | |
return vessel(tgt). | |
} | |
} | |
return body(tgt). | |
} | |
local burnoutCheck is "reset". | |
function local_mvn_burnout { | |
parameter autoStage. | |
if burnoutcheck = "reset" { | |
set burnoutcheck to maxthrust. | |
return false. | |
} | |
if burnoutcheck - maxthrust > 10 { | |
if autostage { | |
stage. | |
} | |
set burnoutcheck to "reset". | |
return true. | |
} | |
return false. | |
} | |
function PID_init { | |
parameter Kp, Ki, Kd, cMin, cMax. | |
local SeekP is 0. | |
local P is 0. | |
local I is 0. | |
local D is 0. | |
local oldT is -1. | |
local oldInput is 0. | |
local P_a is list(Kp, Ki, Kd, cMin, cMax, SeekP, P, I, D, oldT, oldInput). | |
return P_a. | |
}. | |
function PID_seek { | |
parameter P_a, seekVal, curVal. | |
local Kp is P_a[0]. | |
local Ki is P_a[1]. | |
local Kd is P_a[2]. | |
local cMin is P_a[3]. | |
local cMax is P_a[4]. | |
local oldS is P_a[5]. | |
local oldP is P_a[6]. | |
local oldI is P_a[7]. | |
local oldD is P_a[8]. | |
local oldT is P_a[9]. | |
local oldInput is P_a[10]. | |
local P is seekVal - curVal. | |
local D is oldD. | |
local I is oldI. | |
local newInput is oldInput. | |
local t is time:seconds. | |
local dT is t - oldT. | |
if oldT < 0 { | |
} else { | |
if dT > 0 { | |
set D to (P - oldP)/dT. | |
local onlyPD is Kp*P + Kd*D. | |
if (oldI > 0 or onlyPD > cMin) and (oldI < 0 or onlyPD < cMax) { | |
set I to oldI + P*dT. | |
}. | |
set newInput to onlyPD + Ki*I. | |
}. | |
}. | |
set newInput to max(cMin,min(cMax,newInput)). | |
set P_a[5] to seekVal. | |
set P_a[6] to P. | |
set P_a[7] to I. | |
set P_a[8] to D. | |
set P_a[9] to t. | |
set P_a[10] to newInput. | |
return newInput. | |
}. | |
//Main Launch Function | |
function inc_launch { | |
parameter tgt_orbitable. //Vessel or body orbital plane to launch into | |
parameter tgt_apoapsis. //Apoapsis to launch to. | |
set Target to Orbitable(tgt_orbitable). | |
SAS off. | |
RCS on. | |
//Initialize pid controller (Tuned by hand) | |
local PID_array is PID_init(4, 0.033, 0.005, -60, 60). | |
local heading_offset is 0. | |
local heading_primary is 90. | |
local throttle_value is 1. | |
lock throttle to throttle_value. | |
lock steering to heading(90, 90). | |
local launch_runmode is -1. //Prelaunch | |
//Main Runmode Loop | |
until launch_runmode = 0 { | |
if launch_runmode = -1 { | |
//Prelaunch: Warp until KSC is in the orbital plane of the target | |
local vec_n is VCRS(Target:Prograde:Vector, Target:Up:Vector). | |
local current_angle is VANG(Ship:UP:Vector,vec_n). | |
if abs(current_angle - 90) < 0.01 { set launch_runmode to 1.} | |
else if abs(current_angle - 90) < 0.03 { set warp to 0. } | |
else if abs(current_angle-90) < 0.1 { set warp to 3. } | |
else if abs(current_angle-90) < 0.5 { set warp to 4. } | |
else if abs(current_angle-90) < 10 { set warp to 5. } | |
else { set warp to 6. } | |
} | |
else if launch_runmode = 1 { | |
//LAUNCH! | |
wait 0.01. //Come out of warp | |
lock throttle to 1. | |
lock steering to heading(90, 90). | |
wait 0.01. | |
stage. | |
wait 5. //Clear the pad | |
set launch_runmode to 2. | |
} | |
else if launch_runmode = 2 { | |
//Initial Flight: Locks variables for launch and gravity turn | |
//Update target_pitch | |
lock pct_alt to alt:rader / TARGET_ALTITUDE. | |
lock target_pitch to GT_A * pct_alt^GT_B + GT_C. | |
//Update target_heading | |
lock vec_n to VCRS(Target:Prograde:Vector, Target:Up:Vector). | |
lock current_angle to VANG(Ship:Prograde:Vector,vec_n). | |
lock heading_offset to PID_seek(PID_array, 90, current_angle). | |
lock target_heading to heading_primary + heading_offset. | |
lock steering to heading(target_heading, target_pitch). | |
set launch_runmode to 3. | |
} | |
else if launch_runmode = 3 { | |
//MECO: Waits for apoapsis to near target and updates throttle | |
if ship:apoapsis > 0.99999*tgt_apoapsis { | |
set launch_runmode to 4. | |
} | |
else if (ship:apoapsis > 0.875*tgt_apoapsis) { | |
// Reduce throttle, don't overshoot tgt_apoapsis | |
set throttle_value to max(0.2, 8*(1-ship:apoapsis/ap)). | |
} | |
} | |
else if launch_runmode = 4 { | |
// Can add coasting or circularization instructions | |
// Deploy fairings, antennas, panels, etc | |
set launch_runmode to 0. | |
} | |
} | |
} | |
inc_launch(TARGET_ORBITABLE, TARGET_ALTITUDE). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment