Last active
August 23, 2024 05:00
-
-
Save numberlesstim/035e4a80c4d83198dd20129f6d630195 to your computer and use it in GitHub Desktop.
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
//gist 035e4a80c4d83198dd20129f6d630195 | |
function getDriftVector { | |
parameter acceleration. //magnitute of your acceleration (through engines) as scalar (m/s^2) | |
parameter targetVector. //direction you want to accelerate in as (normalized) vector | |
parameter gravity. //gravity-acceleration as vector | |
if targetVector:mag = 0 return targetVector. | |
if acceleration = 0 return v(0,0,0). | |
//intersect sphere with straight: | |
local A is targetVector:x^2 + targetVector:y^2 + targetVector:z^2. | |
local B is -2 * targetVector:x * gravity:x -2 * targetVector:y * gravity:y -2 * targetVector:z * gravity:z. | |
local C is gravity:x^2 + gravity:y^2 + gravity:z^2 - acceleration^2. | |
local t is -0.5*(B/A) + sqrt((0.5*(B/A))^2 - C/A). | |
local aVec is t * targetVector - gravity. | |
return aVec. | |
} | |
function slopeNormal { | |
parameter position is ship:position. | |
parameter radiuss is 2. | |
set g1 to ship:body:geopositionof(position + heading(0,0):vector * radiuss). | |
set g2 to ship:body:geopositionof(position + heading(120,0):vector * radiuss). | |
set g3 to ship:body:geopositionof(position + heading(240,0):vector * radiuss). | |
set slopeNorm to -vcrs(g1:position - g2:position, g3:position - g2:position):normalized. | |
return slopeNorm. | |
} | |
function getMaxTerrain { | |
parameter pointA, pointB. | |
if overflowProtector { | |
set nTerrainSamples to max(2, floor(nTerrainSamples * 0.9)). | |
set cc to 2. | |
print (" <color=red>Reducing to " + nTerrainSamples + "</color>"):padright(terminal:width) at(0,13). | |
overflowProtector off. | |
return body:geopositionof(pointA):terrainHeight. | |
} | |
overflowProtector on. | |
local nSamples is nTerrainSamples. | |
local ret is body:geopositionof(pointA):terrainHeight. | |
local stepvec is (pointB - pointA)/nSamples. | |
for i in range(1, nSamples + 1) set ret to max(ret, body:geopositionof(pointA + stepvec * i):terrainHeight). | |
if body:hasocean set ret to max(0, ret). | |
overflowProtector off. | |
return ret. | |
} | |
set locklex to lex("altMargin", false, "sl", false, "overrideTopvector", false, "reactionMult", false, "alternativeTouchdown", false, "touchdownTurnMult", false, "touchdownMargin", false). | |
if not (defined altMargin) AND not (defined altMargin@) locklex:altMargin on. | |
if not (defined sl) AND not (defined sl@) locklex:sl on. | |
if not (defined overrideTopvector) AND not (defined overrideTopvector@) locklex:overrideTopvector on. | |
if not (defined reactionMult) AND not (defined reactionMult@) locklex:reactionMult on. | |
if not (defined alternativeTouchdown) AND not (defined alternativeTouchdown@) locklex:alternativeTouchdown on. | |
if not (defined touchdownTurnMult) AND not (defined touchdownTurnMult@) locklex:touchdownTurnMult on. | |
if not (defined touchdownMargin) AND not (defined touchdownMargin@) locklex:touchdownMargin on. | |
if not (defined nTerrainSamples) set nTerrainSamples to 15. | |
if not (defined warpMargin) set warpMargin to 20. | |
done off. | |
doprint on. | |
overflowProtector off. | |
set cc to 0. | |
lock rawAlt to body:radius + altitude. | |
lock engAcc to ship:availablethrust/ship:mass. | |
lock gravAcc to -up:vector * (body:mu/(rawAlt^2)). | |
lock totAcc to engAcc * ship:facing:forevector + gravAcc. | |
lock endAlt to 0. | |
set b to ship:bounds. | |
if locklex:altMargin lock altMargin to b:extents:mag. | |
if locklex:overrideTopvector lock overrideTopvector to false. | |
if locklex:reactionMult lock reactionMult to 10. | |
if locklex:alternativeTouchdown lock alternativeTouchdown to false. | |
if locklex:touchdownTurnMult lock touchdownTurnMult to 5. | |
if locklex:touchdownMargin lock touchdownMargin to 1 + tan(vang(up:vector, slopeNormal())) * vxcl(ship:facing:vector, b:extents):mag. | |
if locklex:sl lock sl to choose 1 if b:bottomaltradar <= touchdownMargin else max(sqrt((b:bottomaltradar - touchdownMargin)*(engAcc - gravAcc:mag)), 1). | |
lock str to lookdirup(getDriftVector(engAcc, srfretrograde:vector, gravAcc), choose overrideTopvector if overrideTopvector:typename = "vector" else ship:facing:topvector). | |
lock stopDist to airspeed^2/(2*totAcc:mag). | |
lock endPosBurn to srfprograde:vector * stopDist. | |
lock endAltRaw to min(altitude, (endPosBurn - body:position):mag - body:radius). | |
lock endAlt to endAltRaw - getMaxTerrain(endPosBurn, endPosBurn/2) - altMargin. | |
lock thr to (reactionMult-(endAlt - (altitude - b:bottomalt)))/reactionMult. | |
lock throttle to thr. | |
lock steering to str. | |
lock downrangeVel to vxcl(vcrs(up:vector, ship:facing:forevector), velocity:surface). | |
lock downrangeGrndSpd to vdot(vxcl(up:vector, -ship:facing:forevector):normalized, downrangeVel). | |
when thr > 0 then when downrangeVel:mag < touchdownTurnMult * engAcc then { | |
if alternativeTouchdown { | |
lock altMargin to 1 - touchdownMargin. | |
when downrangeGrndSpd < touchdownTurnMult AND -verticalspeed < .5 then { | |
lock thr to choose (groundspeed - sl/2)/engAcc if vdot(velocity:surface, ship:facing:forevector) < 0 else 0. | |
lock str to lookdirup(vxcl(up:vector, ship:facing:forevector), choose overrideTopvector if overrideTopvector:typename = "vector" else ship:facing:topvector). | |
wait 0. | |
} | |
} | |
else { | |
lock endAlt to b:bottomaltradar. | |
lock minP to 90 - vang(up:vector, getDriftVector(engAcc, srfretrograde:vector, gravAcc)). | |
local spd0 is downrangeGrndSpd. | |
lock pA to minP + (90-minP)/max(1, downrangeGrndSpd). | |
lock pB to max(minP, arctan(gravAcc:mag * touchdownTurnMult/groundspeed)). | |
lock p to max(min(60, pA), pB). | |
when pA > 60 and pB > 60 then lock p to pB. | |
lock aim to -vxcl(up:vector, velocity:surface):normalized + up:vector * tan(p). | |
lock str to lookdirup(aim, choose overrideTopvector if overrideTopvector:isType("Vector") else ship:facing:topvector). | |
lock tAlt to b:bottomaltradar - 5 + vang(up:vector, ship:facing:vector). | |
lock tVS to min(0, max(-sl, talt - b:bottomaltradar)). | |
lock thr to tVS - verticalspeed. | |
} | |
when list("landed", "splashed"):contains(status) then { | |
lock steering to choose "kill" if alternativeTouchdown else lookdirup(slopenormal(), choose overrideTopvector if overrideTopvector:isType("Vector") else ship:facing:topvector). | |
lock throttle to 0. | |
print " === Touchdown metrics === ". | |
print " Groundspeed: " + round(groundspeed, 2) + " m/s". | |
print " Sinkrate: " + round(-verticalspeed, 2) + " m/s". | |
print " Up-Angle: " + round(vang(up:vector, ship:facing:forevector), 2) + " deg". | |
print " Spinrate: " + round(ship:angularvel:mag, 3) + " deg/s". | |
wait 0. | |
unlock throttle. | |
done on. | |
} | |
} | |
on round(time:seconds/5) { | |
set b to ship:bounds. | |
if cc > 0 { | |
set cc to cc - 1. | |
} | |
else { | |
print " ":padright(terminal:width) at(0,13). | |
} | |
return not done. | |
} | |
on round(time:seconds*10) { | |
if doprint { | |
print (" endAlt: " + round(endAlt) + "m"):padright(terminal:width) at(0,0). | |
print (" altmargin: " + round(altmargin,1) + "m"):padright(terminal:width) at(0,1). | |
print (" touchdownMargin: " + round(touchdownMargin,1) + "m"):padright(terminal:width) at(0,2). | |
print (" sl: " + round(sl,1) + "m/s"):padright(terminal:width) at(0,3). | |
print (" groundspeed: " + round(groundspeed, 2)):padright(terminal:width) at(0,4). | |
print (" verticalspeed: " + round(verticalspeed, 2)):padright(terminal:width) at(0,5). | |
print (" expected slope: " + round(vang(up:vector, slopeNormal(endPosBurn)),1) + " deg"):padright(terminal:width) at(0,6). | |
print (" reactionMult: " + reactionMult):padright(terminal:width) at(0,7). | |
print (" touchdownTurnMult: " + touchdownTurnMult):padright(terminal:width) at(0,8). | |
print (" overrideTopvector: " + (choose "active" if overrideTopvector:typename = "vector" else "off")):padright(terminal:width) at(0,9). | |
print ("alternativeTouchdown: " + alternativeTouchdown):padright(terminal:width) at(0,10). | |
print (" done: " + done):padright(terminal:width) at(0,11). | |
print (" nTerrainSamples: " + nTerrainSamples):padright(terminal:width) at(0,12). | |
print " ":padright(terminal:width) at(0,14). | |
} | |
return not done. | |
} | |
function autowarp { | |
parameter margin is false. | |
print "No guarantees! This is still experimental!". | |
local stopVec is velocity:surface:normalized * stopDist. | |
local stopDistVert is vxcl(up:vector, stopVec). | |
local tx is time:seconds. | |
local step is eta:periapsis. | |
until step < 1e-3 { | |
set tx to tx + step. | |
if (positionat(ship, tx) - body:position):mag - (body:radius + body:geopositionof(positionat(ship, tx)):terrainheight) < altMargin OR tx > time:seconds + eta:periapsis{ | |
set tx to tx - step. | |
set step to step/2. | |
} | |
} | |
set tx to tx - (choose margin if margin:isType("Scalar") else warpMargin). | |
if abs(steeringmanager:angleerror) > 80 set tx to tx - (choose margin if margin:isType("Scalar") else warpMargin). | |
else if abs(steeringmanager:angleerror) > 160 set tx to tx - 2 * (choose margin if margin:isType("Scalar") else warpMargin). | |
set warp to 1. | |
wait until kuniverse:timewarp:issettled. | |
warpto(tx). | |
} | |
clearscreen. for i in range(terminal:height) print " ". |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment