Skip to content

Instantly share code, notes, and snippets.

@keiya
Created May 6, 2019 18:50
Show Gist options
  • Save keiya/fd262f839667ba9e70fb008c052ff778 to your computer and use it in GitHub Desktop.
Save keiya/fd262f839667ba9e70fb008c052ff778 to your computer and use it in GitHub Desktop.
automatic gravity turn & circularize for Kerbal Space Program (KSP)
SET ThrotPID TO PIDLOOP(0.1, 0.01, 0.01).
SET ThrotPID:MAXOUTPUT TO 1.
SET ThrotPID:MINOUTPUT TO 0.
SET MY_VESS TO SHIP.
//SAS ON.
RCS ON.
SET thrott TO 1.
LOCK THROTTLE TO thrott.
SET HEAD TO HEADING(90,90).
LOCK STEERING TO HEAD.
STAGE.
LIST ENGINES IN elist.
SET PITCH TO 89.
UNTIL SHIP:APOAPSIS > 80000 {
PRINT "Stage: " + STAGE:NUMBER AT (0,0).
FOR e IN elist {
IF e:FLAMEOUT {
STAGE.
PRINT "STAGING!" AT (0,0).
UNTIL STAGE:READY {
WAIT 0.
}
LIST ENGINES IN elist.
//CLEARSCREEN.
BREAK.
}
}
IF SHIP:ALTITUDE > 21500 {
autoThrot((SHIP:ALTITUDE/1000)^2).
} ELSE IF SHIP:ALTITUDE > 2000 {
autoThrot(SQRT(SHIP:ALTITUDE)*3).
} ELSE IF SHIP:ALTITUDE > 0 {
autoThrot(119).
}
autoGravTurn(90, 90000).
//PRINT MY_VESS:DYNAMICPRESSURE * constant:ATMtokPa.
WAIT 0.01.
}
UNLOCK ALL.
SAS ON.
WAIT 0.1.
SET SASMODE TO "PROGRADE".
UNTIL SHIP:ALTITUDE > 70000 {
}
SET panelsOpen TO FALSE.
panelUtil().
SAS OFF.
circularize().
RCS OFF.
FUNCTION circularize {
set th to 0.
lock throttle to th.
set dV to ship:facing:vector:normalized.
lock steering to lookdirup(dV, ship:facing:topvector).
//ag1 off. //ag1 to abort
local timeout is time:seconds + 9000.
when dV:mag < 0.05 then set timeout to time:seconds + 3.
until ag1 or dV:mag < 0.02 or time:seconds > timeout {
set posVec to ship:position - body:position.
set vecNormal to vcrs(posVec,velocity:orbit).
set vecHorizontal to -1 * vcrs(ship:position-body:position, vecNormal).
set vecHorizontal:mag to sqrt(body:MU/(body:Radius + altitude)). //this is the desired velocity vector to obtain circular orbit at current altitude
set dV to vecHorizontal - velocity:orbit. //deltaV as a vector
//Debug vectors
//set mark_n to VECDRAWARGS(ship:position, vecNormal:normalized * (velocity:orbit:mag / 100), RGB(1,0,1), "n", 1, true).
set mark_h to VECDRAWARGS(ship:position, vecHorizontal / 100, RGB(0,1,0), "h", 1, true).
set mark_v to VECDRAWARGS(ship:position, velocity:orbit / 100, RGB(0,0,1), "dv", 1, true).
set mark_dv to VECDRAWARGS(ship:position + velocity:orbit / 100, dV, RGB(1,1,1), "dv", 1, true).
//throttle control
if vang(ship:facing:vector,dV) > 1 { set th to 0. }
else { set th to max(0,min(1,dV:mag/10)). }
wait 0.
}
}
FUNCTION autoThrot {
PARAMETER desiredSpeed.
SET ThrotPID:SETPOINT TO desiredSpeed.
SET thrott TO ThrotPID:UPDATE(TIME:SECONDS, MY_VESS:AIRSPEED).
}.
FUNCTION autoGravTurn {
PARAMETER desiredHeading.
PARAMETER desiredApAlt.
SET HEAD TO HEADING(desiredHeading, (90-SHIP:APOAPSIS/(desiredApAlt-SHIP:ALTITUDE/4)*90)).
}.
FUNCTION panelUtil {
//Only performs the checks within if the panels aren't already open
IF NOT panelsOpen {
//Checks if we're out of the atmosphere
IF SHIP:ALTITUDE > BODY:ATM:HEIGHT {
//Opens the panels
PANELS ON.
//Changes the variable so we can track the status of the panels
SET panelsOpen TO TRUE.
//Informs the user that we're taking action
HUDTEXT("Panel Utility: Leaving Atmosphere; Opening Panels", 3, 2, 30, YELLOW, FALSE).
PRINT "Opening Panels".
}.
//Checks if we're landed and stationary
IF SHIP:STATUS = "Landed" AND SHIP:VELOCITY:SURFACE:MAG < 0.01 {
//Opens the panels
PANELS ON.
//Changes the variable so we can track the status
SET panelsOpen TO TRUE.
//Informs the user that we're taking action
HUDTEXT("Panel Utility: Landed and stationary; Opening Panels", 3, 2, 30, YELLOW, FALSE).
PRINT "Opening Panels".
}.
//Only performs the checks within if the panels are already open
} ELSE IF panelsOpen {
//Checks to see if we're in the atmosphere; doesn't close the panels if we're
//stationary to prevent it and the stationary check from fighting for control of
//the panels.
IF SHIP:ALTITUDE < BODY:ATM:HEIGHT
AND SHIP:VELOCITY:SURFACE:MAG >= 0.01 {
//Closes the panels
PANELS OFF.
//Changes the variable so we can track the status of the panels
SET panelsOpen TO FALSE.
//Informs the user why we're taking action based on which situation we're in
IF SHIP:STATUS = "Landed" {
//If we're landed, we're probably starting to move from a standstill
HUDTEXT("Panel Utility: Landed and moving; Closing Panels", 3, 2, 30, YELLOW, FALSE).
PRINT "Closing Panels".
} ELSE {
//If we're not landed, we're probably re-entering
HUDTEXT("Panel Utility: Entering Atmosphere; Closing Panels", 3, 2, 30, YELLOW, FALSE).
PRINT "Closing Panels".
}.
}.
}.
}.