2018-08-05 19:40:16 +02:00
@LAZYGLOBAL off.
2018-07-27 17:23:38 +02:00
run once "lib/equations".
run once "lib/node".
run once "lib/rocket".
run once "lib/util".
run once "lib/vectors".
run once "lib/warp".
2018-07-19 14:42:03 +02:00
2018-07-26 04:06:14 +02:00
function launch {
// Launch to orbit of provided altitude and inclination.
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
print "========= LAUNCHING =========".
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 " ".
// LAUNCH AZIMUTH
// 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.
2018-08-05 19:40:16 +02:00
local launch_site_latitude is round_towards_zero(LATITUDE).
local target_orbit_inclination is max(target_orbit_inclination, launch_site_latitude).
2018-07-26 04:06:14 +02:00
// 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.
}
2018-08-05 19:40:16 +02:00
print "Launch site latitude: " + round(LATITUDE, 3) + "° (~" + launch_site_latitude + "°)".
2018-07-26 04:06:14 +02:00
print "Available orbital inclination: " + target_orbit_inclination + "°".
2018-08-05 19:40:16 +02:00
print "Launch azimuth: " + round(launch_azimuth, 3) + "°".
2018-07-26 04:06:14 +02:00
print "Launch southwards: " + southwards.
print "--- VERTICAL CLIMB ---".
2018-08-05 19:40:16 +02:00
SAS off.
RCS on.
2018-07-26 04:06:14 +02:00
set NAVMODE to "SURFACE".
2018-08-05 19:40:16 +02:00
lock STEERING to heading(launch_azimuth, 90). // roll to launch azimuth
2018-07-26 04:06:14 +02:00
lock THROTTLE to 1.0.
2018-07-26 23:47:23 +02:00
// LAUNCH
2018-07-27 17:23:38 +02:00
// Enable auto-staging
when should_stage() then {
2018-07-26 23:47:23 +02:00
stage_when_ready().
2018-07-26 04:06:14 +02:00
return true. // preserve trigger
}
2018-07-19 14:42:03 +02:00
2018-07-26 04:06:14 +02:00
// Once a certain altitude (or velocity) is reached, a slight turn is made, called the pitchover maneuver
2018-08-05 19:40:16 +02:00
wait until ALTITUDE > pitchover_altitude
or VELOCITY:surface:mag > pitchover_velocity.
2018-07-26 04:06:14 +02:00
print "--- PITCHOVER ---".
2018-08-05 19:40:16 +02:00
lock STEERING to heading(launch_azimuth, 90-pitchover_tilt).
2018-07-26 04:06:14 +02:00
wait until actual_prograde_pitch() > pitchover_tilt. // wait until the prograde "catches up" to our tilted heading
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.
2018-08-05 19:40:16 +02:00
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.
2018-07-26 04:06:14 +02:00
wait until APOAPSIS > target_orbit_altitude.
lock THROTTLE TO 0.
print "--- CIRCULARIZE ---".
print "Waiting for ship to leave the atmosphere..".
2018-08-05 19:40:16 +02:00
wait until SHIP:dynamicpressure = 0. // don't create maneuver node until we are out of the atmosphere - otherwise the apoapsis altitude and eta will change due to drag
2018-07-26 04:06:14 +02:00
print "Deploying solar panels".
2018-08-05 19:40:16 +02:00
PANELS on.
2018-07-26 04:06:14 +02:00
// Create maneuver node that will circularize the orbit.
// 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.
2018-08-05 19:45:56 +02:00
local node is NODE(TIME:SECONDS + ETA:APOAPSIS, 0, 0, 0).
2018-07-26 04:06:14 +02:00
2018-07-27 21:32:14 +02:00
// Burn magnitude in the prograde direction is the difference between the required velocity to acheive circular orbit at apoapsis altitude and our velocity at apoapsis
2018-07-28 00:58:17 +02:00
local required_velocity is orbital_velocity_from_ap_pe(APOAPSIS, APOAPSIS, target_orbit_altitude).
2018-08-05 19:40:16 +02:00
set node:prograde to required_velocity - velocityat(SHIP, TIME:seconds + ETA:apoapsis):orbit:mag.
2018-07-26 04:06:14 +02:00
add node.
execute_node().
print "========= LAUNCH SEQUENCE COMPLETE =========".
unlock_control().
2018-07-19 14:42:03 +02:00
}
2018-07-26 04:06:14 +02:00
function calculate_launch_azimuth {
// Calculate the launch azimuth; the compass heading we head for when launching to achieve orbit of desired inclination.
// 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.
2018-08-05 19:40:16 +02:00
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
2018-07-26 04:06:14 +02:00
2018-08-05 19:40:16 +02:00
local equatorial_rotational_velocity is (2 * CONSTANT:PI * BODY:radius) / BODY:rotationperiod.
2018-07-28 00:58:17 +02:00
local target_orbit_velocity is orbital_velocity_from_ap_pe(target_orbit_altitude, target_orbit_altitude, target_orbit_altitude).
2018-07-26 04:06:14 +02:00
2018-08-05 19:40:16 +02:00
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).
2018-07-26 04:06:14 +02:00
}
2018-07-19 14:42:03 +02:00
2018-07-26 04:06:14 +02:00
launch(100_000, 0).