Skip to content

Instantly share code, notes, and snippets.

@BonsaiDen
Last active January 3, 2019 15:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BonsaiDen/260fc926760afcf7d92cc5564b137b4f to your computer and use it in GitHub Desktop.
Save BonsaiDen/260fc926760afcf7d92cc5564b137b4f to your computer and use it in GitHub Desktop.
FUNCTION descent_math {
PARAMETER radar_offset.
PARAMETER target_height.
LOCAL descent_rate TO -SHIP:VERTICALSPEED.
LOCAL clearance TO MAX(ALT:RADAR - radar_offset - target_height, 0).
// Work out centripetal acceleration (i.e. an upward acceleration component
// due to the planet curving away from us)
//LOCAL pos TO SHIP:GEOPOSITION:POSITION.
//LOCAL lat_speed TO VCRS(pos:NORMALIZED, SHIP:VELOCITY:orbit):SQRMAGNITUDE.
//LOCAL cen_acc TO lat_speed * lat_speed / pos:SQRMAGNITUDE.
LOCAL local_grav TO SHIP:BODY:MU / (SHIP:BODY:RADIUS + SHIP:ALTITUDE) ^ 2. // m/s^2
LOCAL down_acc TO local_grav.// - cen_acc.
LOCAL time_to_impact TO (-descent_rate + SQRT(descent_rate * descent_rate + 2 * down_acc * clearance)) / down_acc.
LOCAL speed_at_impact TO descent_rate + time_to_impact * down_acc.
LOCAL impact_speed TO SQRT(speed_at_impact * speed_at_impact + SHIP:GROUNDSPEED * SHIP:GROUNDSPEED).
LOCAL ship_thrust TO SHIP:AVAILABLETHRUST. // Kilo Newton
LOCAL ship_acc TO ship_thrust / SHIP:MASS. // m/s
LOCAL req_burn_time TO ABS(descent_rate) / (ship_acc - local_grav). // seconds
LOCAL burn_dist TO 1 / 2 * ship_acc * req_burn_time * req_burn_time. // meters
LOCAL time_to_burn TO time_to_impact - burn_dist / MAX((ship_acc * 0.5) * (ship_acc * 0.5), 1). // seconds
if descent_rate <= 0 {
SET req_burn_time TO 0.
SET time_to_impact TO 1000.
SET time_to_burn TO 1000.
}
RETURN LEX(
"radar", ALT:RADAR - radar_offset,
"descent_rate", descent_rate,
"time_to_impact", time_to_impact,
"impact_speed", impact_speed,
"time_to_burn", time_to_burn,
"req_burn_time", req_burn_time,
"burn_dist", burn_dist
).
}
// TODO TWR must be ~2.0, should be irrelevant
clearscreen.
SET radar_offset TO 1.11.
SET powered TO false.
UNTIL false {
SET d to descent_math(radar_offset, 0).
print("Height Above Ground: " + ROUND(d["radar"], 1) + "m ") at (0, 1).
print("Descent Rate: " + ROUND(d["descent_rate"], 1) + "m/s ") at (0, 2).
print("Horizontal Speed" + ROUND(SHIP:GROUNDSPEED, 1) + "m/s ") at (0, 3).
print("Time To Impact: " + ROUND(d["time_to_impact"], 1) + "s ") at (0, 4).
print("Impact Speed: " + ROUND(d["impact_speed"], 1) + "s ") at (0, 5).
print("Burn Time: " + ROUND(d["req_burn_time"], 1) + "s ") at (0, 6).
print("Burn Dist: " + ROUND(d["burn_dist"], 1) + "m ") at (0, 7).
print("Burn Countdown: " + ROUND(d["time_to_burn"], 1) + "s ") at (0, 8).
LOCAL t TO d["time_to_burn"].
LOCAL radar TO d["radar"].
// Perform aerodynamic guidance until 30s before impact
IF t < 1000.0 AND t >= 30 AND powered = false {
print("=== Initial Guidance ===") at (0, 0).
// Orient us for the initial burn
SAS off.
LOCK STEERING TO SRFRETROGRADE.
// Power pescent until 30m above ground
} ELSE IF radar > 30 {
print("=== Powered Descent ===") at (0, 0).
SET STEERINGMANAGER:PITCHTS TO 3.
SET STEERINGMANAGER:YAWTS TO 3.
// Try to reduce horizontal velocity
if radar > 500 {
LOCK STEERING TO -VELOCITY:SURFACE + VXCL(UP:VECTOR, VELOCITY:SURFACE) * 0.25 // 75% correction
} else if radar > 250 {
LOCK STEERING TO -VELOCITY:SURFACE + VXCL(UP:VECTOR, VELOCITY:SURFACE) * 0.5. // 50% correction
} else if radar > 100 {
LOCK STEERING TO -VELOCITY:SURFACE + VXCL(UP:VECTOR, VELOCITY:SURFACE) * 0.6. // 40% correction
} else if radar > 50 {
LOCK STEERING TO -VELOCITY:SURFACE + VXCL(UP:VECTOR, VELOCITY:SURFACE) * 0.75. // 25% correction
// Ignore horizontal movement during final descent
} else {
LOCK STEERING TO UP.
}
// Throttle up to cancel out vertical velocity
if t < 1.0 {
SET powered TO true.
SET THROTTLE TO 1.
}
// Cancel out horizontal speed early if too big
// TODO test
if powered = false {
if SHIP:GROUNDSPEED > 15 {
SET THROTTLE TO 0.5.
} else {
SET THROTTLE TO 0.
}
}
// Final approach to hover / landing
} ELSE IF powered = true AND t < MAX(MIN(radar / 10, 1), 0.5) {
// TODO reduce minimal value so we eventually reach the target height
// TODO configure so that we hove slightly below the target height (for landing)
// TODO enable SAS and unlock steering?
SET THROTTLE TO 0.99.
print("=== Hover ===") at (0, 0).
// TODO release and fly-off (if requested)
// TODO switch ACTIVEVESSEL to released one
} ELSE IF powered = true {
SET THROTTLE TO 0.
}
// Landing (if we actually reach the ground)
IF SHIP:STATUS = "LANDED" {
SAS on.
UNLOCK STEERING.
SET THROTTLE TO 0.
break.
}
// TODO this was reduce from 0.01
wait 0.001.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment