kOS-scripts/ascend.ks

144 lines
6.2 KiB
Plaintext
Raw Normal View History

@LAZYGLOBAL off.
run once "lib/orbital_equations".
run once "lib/orbital_maneuvers".
run once "lib/rocket".
run once "lib/util".
run once "lib/vectors".
run once "lib/warp".
2018-07-19 14:42:03 +02:00
function launch {
2019-02-10 15:33:50 +01:00
//
// Launch to orbit of provided altitude and inclination.
2019-02-10 15:33:50 +01:00
//
parameter target_orbit_altitude is 100_000. // meters
parameter target_orbit_inclination is 0. // 0-180 degrees
parameter pitchover_tilt is 20. // how many degrees to tilt at pitchover maneuver
parameter pitchover_altitude is 1000. // perform pitchover at this altitude
parameter pitchover_velocity is 100. // or this velocity
2019-02-08 22:17:19 +01:00
parameter auto_stage is true.
parameter auto_deploy_solar_panels is true.
parameter auto_deploy_fairings is true.
parameter auto_extend_antennas is true.
2019-02-08 22:17:19 +01:00
print "================ ASCEND GUIDANCE =================".
print "Target orbital altitude: " + target_orbit_altitude + "m".
print "Target orbital inclination: " + target_orbit_inclination + "°".
print "Pitchover tilt: " + pitchover_tilt + "°".
print "Pitchover at: " + pitchover_altitude + "m or " + pitchover_velocity + " m/s".
print " ".
2019-02-08 22:17:19 +01:00
// Since the "center" of an orbit must be at the center of gravity of the body, the latitude of the launch site establishes the minimum absolute orbital inclination.
2019-02-07 21:56:34 +01:00
// KSC is almost on the equator, so we're going to always round the latitude towards zero to allow any inclination from KSC and accept the inaccuracies it may introduce.
2019-02-08 22:17:19 +01:00
local launch_site_latitude is int(LATITUDE).
local target_orbit_inclination is max(target_orbit_inclination, launch_site_latitude).
// Calculate the launch azimuth; the compass heading we head for when launching to achieve orbit of desired inclination
local launch_azimuth is calculate_launch_azimuth(target_orbit_inclination, target_orbit_altitude, launch_site_latitude).
// If the latitude of the launch site is negative (ship is in the southern hemisphere), launch southwards instead of northwards
local southwards is launch_site_latitude < 0.
if southwards {
set launch_azimuth to 180 - launch_azimuth.
}
print "Launch site latitude: " + round(LATITUDE, 3) + "° (~" + launch_site_latitude + "°)".
print "Available orbital inclination: " + target_orbit_inclination + "°".
print "Launch azimuth: " + round(launch_azimuth, 3) + "°".
print "Launch southwards: " + southwards.
2019-02-08 22:17:19 +01:00
print " ".
print "Auto-staging: " + auto_stage.
print "Auto-deploy solar panels: " + auto_deploy_solar_panels.
print "Auto-deploy fairings: " + auto_deploy_fairings.
print "Auto-extend antennas: " + auto_extend_antennas.
print " ".
// LAUNCH
SAS off.
RCS off.
set NAVMODE to "SURFACE".
lock STEERING to heading(launch_azimuth, 90). // roll to launch azimuth
lock THROTTLE to 1.0.
2019-02-08 22:17:19 +01:00
when auto_stage and should_stage() then {
stage_when_ready().
2019-02-08 18:45:13 +01:00
wait 0.5.
return true. // preserve trigger
}
2018-07-19 14:42:03 +02:00
print "==> VERTICAL CLIMB".
2019-02-08 22:17:19 +01:00
print "Waiting for pitchover altitude or velocity".
wait until ALTITUDE > pitchover_altitude
or VELOCITY:surface:mag > pitchover_velocity.
print "==> PITCHOVER".
2019-02-08 22:17:19 +01:00
// Once a certain altitude or velocity is reached, a slight turn is made, called the pitchover maneuver
lock STEERING to heading(launch_azimuth, 90-pitchover_tilt).
2019-02-08 22:17:19 +01:00
print "Waiting for prograde vector to catch up".
wait until actual_prograde_pitch() > pitchover_tilt.
print "==> GRAVITY TURN".
// TODO: the angle of the launch azimuth will not account for the fact that our compass will change as we move north/south.
lock STEERING to heading(launch_azimuth, 90-actual_prograde_pitch()). // Follow prograde pitch to get 0 deg angle of attack, but force compass heading at launch azimuth.
2019-02-08 22:17:19 +01:00
print "Waiting for apoapsis to match target altitude".
wait until APOAPSIS > target_orbit_altitude.
lock THROTTLE TO 0.
2019-02-08 23:18:34 +01:00
print "==> CIRCULARIZE".
2019-02-08 22:17:19 +01:00
// Don't create maneuver node until we are out of the atmosphere; otherwise the apoapsis' altitude and eta will change due to drag
print "Waiting for ship to leave the atmosphere".
warp_for(atmosphere_exit_eta()). // we'll lose some velocity due to drag, so the warp will exit a few seconds before we actually exit the atmosphere
wait until SHIP:dynamicpressure = 0. // that's why we have this check as well
if auto_deploy_fairings {
deploy_fairings().
}
if auto_deploy_solar_panels {
print "Deploying solar panels".
PANELS on.
}
if auto_extend_antennas {
extend_antennas().
}
2019-02-08 23:18:34 +01:00
// NOTE: Potential errors in the inclination are not fixed since we are most likely going to change our orbit, which will make the inclination change cheaper later on.
circularize_at_apoapsis().
print "==> LAUNCH SEQUENCE COMPLETE".
unlock_control().
2018-07-19 14:42:03 +02:00
}
function calculate_launch_azimuth {
2019-02-08 23:18:34 +01:00
//
// Calculate the launch azimuth; the compass heading we head for when launching to achieve orbit of desired inclination.
2019-02-08 23:18:34 +01:00
// Based on:
// http://www.orbiterwiki.org/wiki/Launch_Azimuth
// https://www.princeton.edu/~stengel/MAE342Lecture4.pdf
//
parameter target_orbit_inclination.
parameter target_orbit_altitude. // to compensate for the rotation of the body, we need to know the velocity of the target orbit, which is calculated from its altitude
parameter launch_site_latitude.
local inertial_azimuth is arcsin(cos(target_orbit_inclination) / cos(launch_site_latitude)). // azimuth in inertial space, that is, disregarding the rotation of the body
local equatorial_rotational_velocity is (2 * CONSTANT:PI * BODY:radius) / BODY:rotationperiod.
2019-02-08 23:18:34 +01:00
local target_orbit_velocity is orbital_velocity_circular(target_orbit_altitude).
local launch_vector_x_component is target_orbit_velocity * sin(inertial_azimuth) - equatorial_rotational_velocity * cos(launch_site_latitude).
local launch_vector_y_component is target_orbit_velocity * cos(inertial_azimuth).
return arctan2(launch_vector_x_component, launch_vector_y_component).
}