Skip to content

Instantly share code, notes, and snippets.

@rgioai
Created September 17, 2016 20:40
Show Gist options
  • Save rgioai/86bc19e326fe3ff3b56c3968226d4e52 to your computer and use it in GitHub Desktop.
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.
//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