Launch into Orbit#
This tutorial launches a two-stage rocket into a 150km circular orbit. The
program assumes you are using this craft file.
The program is available in a variety of languages:
The following code connects to the server, gets the active vessel, sets up a bunch of streams to get flight telemetry then prepares the rocket for launch.
#include <math.h>
#include <unistd.h>
#include <krpc_cnano.h>
#include <krpc_cnano/services/space_center.h>
int main() {
krpc_connection_t conn;
krpc_open(&conn, "COM0");
krpc_connect(conn, "Launch into orbit");
krpc_SpaceCenter_Vessel_t vessel;
krpc_SpaceCenter_ActiveVessel(conn, &vessel);
float turn_start_altitude = 250;
float turn_end_altitude = 45000;
float target_altitude = 150000;
krpc_SpaceCenter_Flight_t flight;
krpc_SpaceCenter_Vessel_Flight(conn, &flight, vessel, KRPC_NULL);
krpc_SpaceCenter_Orbit_t orbit;
krpc_SpaceCenter_Vessel_Orbit(conn, &orbit, vessel);
krpc_SpaceCenter_Stage_t stage_2;
krpc_SpaceCenter_Vessel_DecoupleStageAt(conn, &stage_2, vessel, 2);
krpc_SpaceCenter_Resources_t stage_2_resources;
krpc_SpaceCenter_Stage_Resources(conn, &stage_2_resources, stage_2, false);
krpc_SpaceCenter_Control_t control;
krpc_SpaceCenter_Vessel_Control(conn, &control, vessel);
krpc_SpaceCenter_AutoPilot_t auto_pilot;
krpc_SpaceCenter_Vessel_AutoPilot(conn, &auto_pilot, vessel);
krpc_SpaceCenter_Control_set_SAS(conn, control, false);
krpc_SpaceCenter_Control_set_RCS(conn, control, false);
krpc_SpaceCenter_Control_set_Throttle(conn, control, 1);
printf("3...\n");
sleep(1);
printf("2...\n");
sleep(1);
printf("1...\n");
sleep(1);
printf("Launch!\n");
using System;
using System.Collections.Generic;
using System.Net;
using KRPC.Client;
using KRPC.Client.Services.SpaceCenter;
class LaunchIntoOrbit
{
public static void Main ()
{
var conn = new Connection ("Launch into orbit");
var vessel = conn.SpaceCenter ().ActiveVessel;
float turnStartAltitude = 250;
float turnEndAltitude = 45000;
float targetAltitude = 150000;
// Set up streams for telemetry
var ut = conn.AddStream (() => conn.SpaceCenter ().UT);
var flight = vessel.Flight ();
var altitude = conn.AddStream (() => flight.MeanAltitude);
var apoapsis = conn.AddStream (() => vessel.Orbit.ApoapsisAltitude);
var stage2Resources =
vessel.DecoupleStageAt (stage: 2).Resources (cumulative: false);
var srbFuel = conn.AddStream(() => stage2Resources.Amount("SolidFuel"));
// Pre-launch setup
vessel.Control.SAS = false;
vessel.Control.RCS = false;
vessel.Control.Throttle = 1;
// Countdown...
Console.WriteLine ("3...");
System.Threading.Thread.Sleep (1000);
Console.WriteLine ("2...");
System.Threading.Thread.Sleep (1000);
Console.WriteLine ("1...");
System.Threading.Thread.Sleep (1000);
Console.WriteLine ("Launch!");
#include <iostream>
#include <chrono>
#include <cmath>
#include <thread>
#include <krpc.hpp>
#include <krpc/services/space_center.hpp>
int main() {
krpc::Client conn = krpc::connect("Launch into orbit");
krpc::services::SpaceCenter space_center(&conn);
auto vessel = space_center.active_vessel();
float turn_start_altitude = 250;
float turn_end_altitude = 45000;
float target_altitude = 150000;
// Set up streams for telemetry
auto ut = space_center.ut_stream();
auto altitude = vessel.flight().mean_altitude_stream();
auto apoapsis = vessel.orbit().apoapsis_altitude_stream();
auto stage_2_resources = vessel.decouple_stage_at(2).resources(false);
auto srb_fuel = stage_2_resources.amount_stream("SolidFuel");
// Pre-launch setup
vessel.control().set_sas(false);
vessel.control().set_rcs(false);
vessel.control().set_throttle(1);
// Countdown...
std::cout << "3..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "2..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "1..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Launch!" << std::endl;
import krpc.client.Connection;
import krpc.client.RPCException;
import krpc.client.Stream;
import krpc.client.StreamException;
import krpc.client.services.SpaceCenter;
import krpc.client.services.SpaceCenter.Flight;
import krpc.client.services.SpaceCenter.Node;
import krpc.client.services.SpaceCenter.ReferenceFrame;
import krpc.client.services.SpaceCenter.Resources;
import org.javatuples.Triplet;
import java.io.IOException;
import java.lang.Math;
public class LaunchIntoOrbit {
public static void main(String[] args)
throws IOException, RPCException, InterruptedException, StreamException {
Connection connection = Connection.newInstance("Launch into orbit");
SpaceCenter spaceCenter = SpaceCenter.newInstance(connection);
SpaceCenter.Vessel vessel = spaceCenter.getActiveVessel();
float turnStartAltitude = 250;
float turnEndAltitude = 45000;
float targetAltitude = 150000;
// Set up streams for telemetry
spaceCenter.getUT();
Stream<Double> ut = connection.addStream(SpaceCenter.class, "getUT");
ReferenceFrame refFrame = vessel.getSurfaceReferenceFrame();
Flight flight = vessel.flight(refFrame);
Stream<Double> altitude = connection.addStream(flight, "getMeanAltitude");
Stream<Double> apoapsis =
connection.addStream(vessel.getOrbit(), "getApoapsisAltitude");
Resources stage2Resources = vessel.decoupleStageAt(2).resources(false);
Stream<Float> srbFuel =
connection.addStream(stage2Resources, "amount", "SolidFuel");
// Pre-launch setup
vessel.getControl().setSAS(false);
vessel.getControl().setRCS(false);
vessel.getControl().setThrottle(1);
// Countdown...
System.out.println("3...");
Thread.sleep(1000);
System.out.println("2...");
Thread.sleep(1000);
System.out.println("1...");
Thread.sleep(1000);
System.out.println("Launch!");
local krpc = require 'krpc'
local platform = require 'krpc.platform'
local math = require 'math'
local List = require 'pl.List'
local turn_start_altitude = 250
local turn_end_altitude = 45000
local target_altitude = 150000
local conn = krpc.connect('Launch into orbit')
local vessel = conn.space_center.active_vessel
flight = vessel:flight()
stage_2_resources = vessel:decouple_stage_at(2):resources(false)
-- Pre-launch setup
vessel.control.sas = false
vessel.control.rcs = false
vessel.control.throttle = 1
-- Countdown...
print('3...')
platform.sleep(1)
print('2...')
platform.sleep(1)
print('1...')
platform.sleep(1)
print('Launch!')
import math
import time
import krpc
turn_start_altitude = 250
turn_end_altitude = 45000
target_altitude = 150000
conn = krpc.connect(name="Launch into orbit")
vessel = conn.space_center.active_vessel
# Set up streams for telemetry
ut = conn.add_stream(getattr, conn.space_center, "ut")
altitude = conn.add_stream(getattr, vessel.flight(), "mean_altitude")
apoapsis = conn.add_stream(getattr, vessel.orbit, "apoapsis_altitude")
stage_2_resources = vessel.decouple_stage_at(stage=2).resources(cumulative=False)
srb_fuel = conn.add_stream(stage_2_resources.amount, "SolidFuel")
# Pre-launch setup
vessel.control.sas = False
vessel.control.rcs = False
vessel.control.throttle = 1.0
# Countdown...
print("3...")
time.sleep(1)
print("2...")
time.sleep(1)
print("1...")
time.sleep(1)
print("Launch!")
The next part of the program launches the rocket. The main loop continuously updates the auto-pilot heading to gradually pitch the rocket towards the horizon. It also monitors the amount of solid fuel remaining in the boosters, separating them when they run dry. The loop exits when the rockets apoapsis is close to the target apoapsis.
krpc_SpaceCenter_Control_ActivateNextStage(conn, NULL, control);
krpc_SpaceCenter_AutoPilot_set_Engaged(conn, auto_pilot, true);
krpc_SpaceCenter_AutoPilot_TargetPitchAndHeading(conn, auto_pilot, 90, 90);
bool srbs_separated = false;
double turn_angle = 0;
while (true) {
double altitude;
krpc_SpaceCenter_Flight_MeanAltitude(conn, &altitude, flight);
double apoapsis;
krpc_SpaceCenter_Orbit_ApoapsisAltitude(conn, &apoapsis, orbit);
if (altitude > turn_start_altitude && altitude < turn_end_altitude) {
double frac = (altitude - turn_start_altitude) / (turn_end_altitude - turn_start_altitude);
double new_turn_angle = frac * 90.0;
if (fabs(new_turn_angle - turn_angle) > 0.5) {
turn_angle = new_turn_angle;
krpc_SpaceCenter_AutoPilot_TargetPitchAndHeading(conn, auto_pilot, 90 - turn_angle, 90);
}
}
if (!srbs_separated) {
float srb_fuel;
krpc_SpaceCenter_Resources_Amount(conn, &srb_fuel, stage_2_resources, "SolidFuel");
if (srb_fuel < 0.1) {
krpc_SpaceCenter_Control_ActivateNextStage(conn, NULL, control);
srbs_separated = true;
printf("SRBs separated\n");
}
}
if (apoapsis > target_altitude * 0.9) {
printf("Approaching target apoapsis\n");
break;
}
}
// Activate the first stage
vessel.Control.ActivateNextStage ();
vessel.AutoPilot.Engaged = true;
vessel.AutoPilot.TargetPitchAndHeading (90, 90);
// Main ascent loop
bool srbsSeparated = false;
double turnAngle = 0;
while (true) {
// Gravity turn
if (altitude.Get () > turnStartAltitude &&
altitude.Get () < turnEndAltitude) {
double frac = (altitude.Get () - turnStartAltitude)
/ (turnEndAltitude - turnStartAltitude);
double newTurnAngle = frac * 90.0;
if (Math.Abs (newTurnAngle - turnAngle) > 0.5) {
turnAngle = newTurnAngle;
vessel.AutoPilot.TargetPitchAndHeading (
(float)(90 - turnAngle), 90);
}
}
// Separate SRBs when finished
if (!srbsSeparated) {
if (srbFuel.Get () < 0.1) {
vessel.Control.ActivateNextStage ();
srbsSeparated = true;
Console.WriteLine ("SRBs separated");
}
}
// Decrease throttle when approaching target apoapsis
if (apoapsis.Get () > targetAltitude * 0.9) {
Console.WriteLine ("Approaching target apoapsis");
break;
}
}
// Activate the first stage
vessel.control().activate_next_stage();
vessel.auto_pilot().set_engaged(true);
vessel.auto_pilot().target_pitch_and_heading(90, 90);
// Main ascent loop
bool srbs_separated = false;
double turn_angle = 0;
while (true) {
// Gravity turn
if (altitude() > turn_start_altitude && altitude() < turn_end_altitude) {
double frac = (altitude() - turn_start_altitude)
/ (turn_end_altitude - turn_start_altitude);
double new_turn_angle = frac * 90.0;
if (std::abs(new_turn_angle - turn_angle) > 0.5) {
turn_angle = new_turn_angle;
vessel.auto_pilot().target_pitch_and_heading(90.0 - turn_angle, 90.0);
}
}
// Separate SRBs when finished
if (!srbs_separated) {
if (srb_fuel() < 0.1) {
vessel.control().activate_next_stage();
srbs_separated = true;
std::cout << "SRBs separated" << std::endl;
}
}
// Decrease throttle when approaching target apoapsis
if (apoapsis() > target_altitude * 0.9) {
std::cout << "Approaching target apoapsis" << std::endl;
break;
}
}
// Activate the first stage
vessel.getControl().activateNextStage();
vessel.getAutoPilot().setEngaged(true);
vessel.getAutoPilot().targetPitchAndHeading(90, 90);
// Main ascent loop
boolean srbsSeparated = false;
double turnAngle = 0;
while (true) {
// Gravity turn
if (altitude.get() > turnStartAltitude &&
altitude.get() < turnEndAltitude) {
double frac = (altitude.get() - turnStartAltitude)
/ (turnEndAltitude - turnStartAltitude);
double newTurnAngle = frac * 90.0;
if (Math.abs(newTurnAngle - turnAngle) > 0.5) {
turnAngle = newTurnAngle;
vessel.getAutoPilot().targetPitchAndHeading(
(float)(90 - turnAngle), 90);
}
}
// Separate SRBs when finished
if (!srbsSeparated) {
if (srbFuel.get() < 0.1) {
vessel.getControl().activateNextStage();
srbsSeparated = true;
System.out.println("SRBs separated");
}
}
// Decrease throttle when approaching target apoapsis
if (apoapsis.get() > targetAltitude * 0.9) {
System.out.println("Approaching target apoapsis");
break;
}
}
-- Activate the first stage
vessel.control:activate_next_stage()
vessel.auto_pilot.engaged = true
vessel.auto_pilot:target_pitch_and_heading(90, 90)
-- Main ascent loop
local srbs_separated = false
local turn_angle = 0
while true do
-- Gravity turn
if flight.mean_altitude > turn_start_altitude and flight.mean_altitude < turn_end_altitude then
frac = (flight.mean_altitude - turn_start_altitude) / (turn_end_altitude - turn_start_altitude)
new_turn_angle = frac * 90
if math.abs(new_turn_angle - turn_angle) > 0.5 then
turn_angle = new_turn_angle
vessel.auto_pilot:target_pitch_and_heading(90-turn_angle, 90)
end
end
-- Separate SRBs when finished
if not srbs_separated then
if stage_2_resources:amount('SolidFuel') < 0.1 then
vessel.control:activate_next_stage()
srbs_separated = true
print('SRBs separated')
end
end
-- Decrease throttle when approaching target apoapsis
if vessel.orbit.apoapsis_altitude > target_altitude*0.9 then
print('Approaching target apoapsis')
break
end
end
# Activate the first stage
vessel.control.activate_next_stage()
vessel.auto_pilot.engaged = True
vessel.auto_pilot.target_pitch_and_heading(90, 90)
# Main ascent loop
srbs_separated = False
turn_angle = 0
while True:
# Gravity turn
if altitude() > turn_start_altitude and altitude() < turn_end_altitude:
frac = (altitude() - turn_start_altitude) / (
turn_end_altitude - turn_start_altitude
)
new_turn_angle = frac * 90
if abs(new_turn_angle - turn_angle) > 0.5:
turn_angle = new_turn_angle
vessel.auto_pilot.target_pitch_and_heading(90 - turn_angle, 90)
# Separate SRBs when finished
if not srbs_separated:
if srb_fuel() < 0.1:
vessel.control.activate_next_stage()
srbs_separated = True
print("SRBs separated")
# Decrease throttle when approaching target apoapsis
if apoapsis() > target_altitude * 0.9:
print("Approaching target apoapsis")
break
Next, the program fine tunes the apoapsis, using 25% thrust, then waits until the rocket has left Kerbin’s atmosphere.
krpc_SpaceCenter_Control_set_Throttle(conn, control, 0.25);
while (true) {
double apoapsis;
krpc_SpaceCenter_Orbit_ApoapsisAltitude(conn, &apoapsis, orbit);
if (apoapsis >= target_altitude)
break;
}
printf("Target apoapsis reached\n");
krpc_SpaceCenter_Control_set_Throttle(conn, control, 0);
printf("Coasting out of atmosphere\n");
while (true) {
double altitude;
krpc_SpaceCenter_Flight_MeanAltitude(conn, &altitude, flight);
if (altitude >= 70500)
break;
}
// Disable engines when target apoapsis is reached
vessel.Control.Throttle = 0.25f;
while (apoapsis.Get () < targetAltitude) {
}
Console.WriteLine ("Target apoapsis reached");
vessel.Control.Throttle = 0;
// Wait until out of atmosphere
Console.WriteLine ("Coasting out of atmosphere");
while (altitude.Get () < 70500) {
}
// Disable engines when target apoapsis is reached
vessel.control().set_throttle(0.25);
while (apoapsis() < target_altitude) {
}
std::cout << "Target apoapsis reached" << std::endl;
vessel.control().set_throttle(0);
// Wait until out of atmosphere
std::cout << "Coasting out of atmosphere" << std::endl;
while (altitude() < 70500) {
}
// Disable engines when target apoapsis is reached
vessel.getControl().setThrottle(0.25f);
while (apoapsis.get() < targetAltitude) {
}
System.out.println("Target apoapsis reached");
vessel.getControl().setThrottle(0);
// Wait until out of atmosphere
System.out.println("Coasting out of atmosphere");
while (altitude.get() < 70500) {
}
-- Disable engines when target apoapsis is reached
vessel.control.throttle = 0.25
while vessel.orbit.apoapsis_altitude < target_altitude do
end
print('Target apoapsis reached')
vessel.control.throttle = 0
-- Wait until out of atmosphere
print('Coasting out of atmosphere')
while flight.mean_altitude < 70500 do
end
# Disable engines when target apoapsis is reached
vessel.control.throttle = 0.25
while apoapsis() < target_altitude:
pass
print("Target apoapsis reached")
vessel.control.throttle = 0.0
# Wait until out of atmosphere
print("Coasting out of atmosphere")
while altitude() < 70500:
pass
It is now time to plan the circularization burn. First, we calculate the delta-v required to circularize the orbit using the vis-viva equation. We then calculate the burn time needed to achieve this delta-v, using the Tsiolkovsky rocket equation.
Note
The per-stage values that feed this calculation are also available
directly from the staging API: Vessel.stage_at() returns a
Stage object with properties such as Stage.delta_v,
Stage.specific_impulse and Stage.burn_time. The derivation is
shown here because we need the burn time for a specific delta-v, rather than
for burning the whole stage.
printf("Planning circularization burn\n");
krpc_SpaceCenter_CelestialBody_t body;
krpc_SpaceCenter_Orbit_Body(conn, &body, orbit);
double mu;
krpc_SpaceCenter_CelestialBody_GravitationalParameter(conn, &mu, body);
double r;
krpc_SpaceCenter_Orbit_Apoapsis(conn, &r, orbit);
double a1;
krpc_SpaceCenter_Orbit_SemiMajorAxis(conn, &a1, orbit);
double a2 = r;
double v1 = sqrt(mu * ((2.0 / r) - (1.0 / a1)));
double v2 = sqrt(mu * ((2.0 / r) - (1.0 / a2)));
double delta_v = v2 - v1;
double ut;
krpc_SpaceCenter_UT(conn, &ut);
double time_to_apoapsis;
krpc_SpaceCenter_Orbit_TimeToApoapsis(conn, &time_to_apoapsis, orbit);
krpc_SpaceCenter_Node_t node;
krpc_SpaceCenter_Control_AddNode(conn, &node, control, ut + time_to_apoapsis, delta_v, 0, 0);
float F;
krpc_SpaceCenter_Vessel_AvailableThrust(conn, &F, vessel);
float isp;
krpc_SpaceCenter_Vessel_SpecificImpulse(conn, &isp, vessel);
double Isp = isp * 9.82;
float m0;
krpc_SpaceCenter_Vessel_Mass(conn, &m0, vessel);
double m1 = m0 / exp(delta_v / Isp);
double flow_rate = F / Isp;
double burn_time = (m0 - m1) / flow_rate;
// Plan circularization burn (using vis-viva equation)
Console.WriteLine ("Planning circularization burn");
double mu = vessel.Orbit.Body.GravitationalParameter;
double r = vessel.Orbit.Apoapsis;
double a1 = vessel.Orbit.SemiMajorAxis;
double a2 = r;
double v1 = Math.Sqrt (mu * ((2.0 / r) - (1.0 / a1)));
double v2 = Math.Sqrt (mu * ((2.0 / r) - (1.0 / a2)));
double deltaV = v2 - v1;
var node = vessel.Control.AddNode (
ut.Get () + vessel.Orbit.TimeToApoapsis, prograde: (float)deltaV);
// Calculate burn time (using rocket equation)
double F = vessel.AvailableThrust;
double Isp = vessel.SpecificImpulse * 9.82;
double m0 = vessel.Mass;
double m1 = m0 / Math.Exp (deltaV / Isp);
double flowRate = F / Isp;
double burnTime = (m0 - m1) / flowRate;
// Plan circularization burn (using vis-viva equation)
std::cout << "Planning circularization burn" << std::endl;
double mu = vessel.orbit().body().gravitational_parameter();
double r = vessel.orbit().apoapsis();
double a1 = vessel.orbit().semi_major_axis();
double a2 = r;
double v1 = std::sqrt(mu * ((2.0 / r) - (1.0 / a1)));
double v2 = std::sqrt(mu * ((2.0 / r) - (1.0 / a2)));
double delta_v = v2 - v1;
auto node = vessel.control().add_node(
ut() + vessel.orbit().time_to_apoapsis(), delta_v);
// Calculate burn time (using rocket equation)
double F = vessel.available_thrust();
double Isp = vessel.specific_impulse() * 9.82;
double m0 = vessel.mass();
double m1 = m0 / std::exp(delta_v / Isp);
double flow_rate = F / Isp;
double burn_time = (m0 - m1) / flow_rate;
// Plan circularization burn (using vis-viva equation)
System.out.println("Planning circularization burn");
double mu = vessel.getOrbit().getBody().getGravitationalParameter();
double r = vessel.getOrbit().getApoapsis();
double a1 = vessel.getOrbit().getSemiMajorAxis();
double a2 = r;
double v1 = Math.sqrt(mu * ((2.0 / r) - (1.0 / a1)));
double v2 = Math.sqrt(mu * ((2.0 / r) - (1.0 / a2)));
double deltaV = v2 - v1;
Node node = vessel.getControl().addNode(
ut.get() + vessel.getOrbit().getTimeToApoapsis(), (float)deltaV, 0, 0);
// Calculate burn time (using rocket equation)
double force = vessel.getAvailableThrust();
double isp = vessel.getSpecificImpulse() * 9.82;
double m0 = vessel.getMass();
double m1 = m0 / Math.exp(deltaV / isp);
double flowRate = force / isp;
double burnTime = (m0 - m1) / flowRate;
---- Plan circularization burn (using vis-viva equation)
print('Planning circularization burn')
local mu = vessel.orbit.body.gravitational_parameter
local r = vessel.orbit.apoapsis
local a1 = vessel.orbit.semi_major_axis
local a2 = r
local v1 = math.sqrt(mu*((2./r)-(1./a1)))
local v2 = math.sqrt(mu*((2./r)-(1./a2)))
local delta_v = v2 - v1
local node = vessel.control:add_node(conn.space_center.ut + vessel.orbit.time_to_apoapsis, delta_v, 0, 0)
---- Calculate burn time (using rocket equation)
local F = vessel.available_thrust
local Isp = vessel.specific_impulse * 9.82
local m0 = vessel.mass
local m1 = m0 / math.exp(delta_v/Isp)
local flow_rate = F / Isp
local burn_time = (m0 - m1) / flow_rate
# Plan circularization burn (using vis-viva equation)
print("Planning circularization burn")
mu = vessel.orbit.body.gravitational_parameter
r = vessel.orbit.apoapsis
a1 = vessel.orbit.semi_major_axis
a2 = r
v1 = math.sqrt(mu * ((2.0 / r) - (1.0 / a1)))
v2 = math.sqrt(mu * ((2.0 / r) - (1.0 / a2)))
delta_v = v2 - v1
node = vessel.control.add_node(ut() + vessel.orbit.time_to_apoapsis, prograde=delta_v)
# Calculate burn time (using rocket equation)
F = vessel.available_thrust
Isp = vessel.specific_impulse * 9.82
m0 = vessel.mass
m1 = m0 / math.exp(delta_v / Isp)
flow_rate = F / Isp
burn_time = (m0 - m1) / flow_rate
Next, we need to rotate the craft and wait until the circularization burn. We orientate the ship along the y-axis of the maneuver node’s reference frame (i.e. in the direction of the burn) then time warp to 5 seconds before the burn.
printf("Orientating ship for circularization burn\n");
krpc_SpaceCenter_ReferenceFrame_t node_ref;
krpc_SpaceCenter_Node_ReferenceFrame(conn, &node_ref, node);
krpc_SpaceCenter_AutoPilot_set_ReferenceFrame(conn, auto_pilot, node_ref);
krpc_tuple_double_double_double_t burn_direction = {0, 1, 0};
krpc_SpaceCenter_AutoPilot_set_TargetDirection(conn, auto_pilot, &burn_direction);
krpc_SpaceCenter_AutoPilot_Wait(conn, auto_pilot, -1);
printf("Waiting until circularization burn\n");
krpc_SpaceCenter_UT(conn, &ut);
krpc_SpaceCenter_Orbit_TimeToApoapsis(conn, &time_to_apoapsis, orbit);
double burn_ut = ut + time_to_apoapsis - (burn_time / 2.0);
double lead_time = 5;
krpc_SpaceCenter_WarpTo(conn, burn_ut - lead_time, 100000, 2);
// Orientate ship
Console.WriteLine ("Orientating ship for circularization burn");
vessel.AutoPilot.ReferenceFrame = node.ReferenceFrame;
vessel.AutoPilot.TargetDirection = Tuple.Create (0.0, 1.0, 0.0);
vessel.AutoPilot.Wait ();
// Wait until burn
Console.WriteLine ("Waiting until circularization burn");
double burnUT = ut.Get () + vessel.Orbit.TimeToApoapsis - (burnTime / 2.0);
double leadTime = 5;
conn.SpaceCenter ().WarpTo (burnUT - leadTime);
// Orientate ship
std::cout << "Orientating ship for circularization burn" << std::endl;
vessel.auto_pilot().set_reference_frame(node.reference_frame());
vessel.auto_pilot().set_target_direction(std::make_tuple(0.0, 1.0, 0.0));
vessel.auto_pilot().wait();
// Wait until burn
std::cout << "Waiting until circularization burn" << std::endl;
double burn_ut = ut() + vessel.orbit().time_to_apoapsis() - (burn_time / 2.0);
double lead_time = 5;
space_center.warp_to(burn_ut - lead_time);
// Orientate ship
System.out.println("Orientating ship for circularization burn");
vessel.getAutoPilot().setReferenceFrame(node.getReferenceFrame());
vessel.getAutoPilot().setTargetDirection(
new Triplet<Double,Double,Double>(0.0, 1.0, 0.0));
vessel.getAutoPilot().wait_(-1);
// Wait until burn
System.out.println("Waiting until circularization burn");
double burnUt =
ut.get() + vessel.getOrbit().getTimeToApoapsis() - (burnTime / 2.0);
double leadTime = 5;
spaceCenter.warpTo(burnUt - leadTime, 100000, 2);
-- Orientate ship
print('Orientating ship for circularization burn')
vessel.auto_pilot.reference_frame = node.reference_frame
vessel.auto_pilot.target_direction = List{0, 1, 0}
vessel.auto_pilot:wait()
-- Wait until burn
print('Waiting until circularization burn')
local burn_ut = conn.space_center.ut + vessel.orbit.time_to_apoapsis - (burn_time/2.)
local lead_time = 5
conn.space_center.warp_to(burn_ut - lead_time)
# Orientate ship
print("Orientating ship for circularization burn")
vessel.auto_pilot.reference_frame = node.reference_frame
vessel.auto_pilot.target_direction = (0, 1, 0)
vessel.auto_pilot.wait()
# Wait until burn
print("Waiting until circularization burn")
burn_ut = ut() + vessel.orbit.time_to_apoapsis - (burn_time / 2.0)
lead_time = 5
conn.space_center.warp_to(burn_ut - lead_time)
This next part executes the burn. It sets maximum throttle, then throttles down to 5% approximately a tenth of a second before the predicted end of the burn. It then monitors the remaining delta-v until it flips around to point retrograde (at which point the node has been executed).
printf("Ready to execute burn\n");
while (true) {
krpc_SpaceCenter_UT(conn, &ut);
krpc_SpaceCenter_Orbit_TimeToApoapsis(conn, &time_to_apoapsis, orbit);
if (time_to_apoapsis - (burn_time / 2.0) <= 0)
break;
}
printf("Executing burn\n");
krpc_SpaceCenter_Control_set_Throttle(conn, control, 1);
sleep((unsigned int)(burn_time - 0.1));
printf("Fine tuning\n");
krpc_SpaceCenter_Control_set_Throttle(conn, control, 0.05);
while (true) {
krpc_tuple_double_double_double_t remaining_burn;
krpc_SpaceCenter_Node_RemainingBurnVector(conn, &remaining_burn, node, node_ref);
if (remaining_burn.e1 <= 0)
break;
}
krpc_SpaceCenter_Control_set_Throttle(conn, control, 0);
krpc_SpaceCenter_Node_Remove(conn, node);
printf("Launch complete\n");
}
// Execute burn
Console.WriteLine ("Ready to execute burn");
var timeToApoapsis = conn.AddStream (() => vessel.Orbit.TimeToApoapsis);
while (timeToApoapsis.Get () - (burnTime / 2.0) > 0) {
}
Console.WriteLine ("Executing burn");
vessel.Control.Throttle = 1;
System.Threading.Thread.Sleep ((int)((burnTime - 0.1) * 1000));
Console.WriteLine ("Fine tuning");
vessel.Control.Throttle = 0.05f;
var remainingBurn = conn.AddStream (
() => node.RemainingBurnVector (node.ReferenceFrame));
while (remainingBurn.Get ().Item2 > 0) {
}
vessel.Control.Throttle = 0;
node.Remove ();
Console.WriteLine ("Launch complete");
conn.Dispose();
}
}
// Execute burn
std::cout << "Ready to execute burn" << std::endl;
auto time_to_apoapsis = vessel.orbit().time_to_apoapsis_stream();
while (time_to_apoapsis() - (burn_time / 2.0) > 0) {
}
std::cout << "Executing burn" << std::endl;
vessel.control().set_throttle(1);
std::this_thread::sleep_for(
std::chrono::milliseconds(static_cast<int>((burn_time - 0.1) * 1000)));
std::cout << "Fine tuning" << std::endl;
vessel.control().set_throttle(0.05);
auto remaining_burn = node.remaining_burn_vector_stream(node.reference_frame());
while (std::get<1>(remaining_burn()) > 0) {
}
vessel.control().set_throttle(0);
node.remove();
std::cout << "Launch complete" << std::endl;
}
// Execute burn
System.out.println("Ready to execute burn");
Stream<Double> timeToApoapsis =
connection.addStream(vessel.getOrbit(), "getTimeToApoapsis");
while (timeToApoapsis.get() - (burnTime / 2.0) > 0) {
}
System.out.println("Executing burn");
vessel.getControl().setThrottle(1);
Thread.sleep((int)((burnTime - 0.1) * 1000));
System.out.println("Fine tuning");
vessel.getControl().setThrottle(0.05f);
Stream<Triplet<Double,Double,Double>> remainingBurn =
connection.addStream(
node, "remainingBurnVector", node.getReferenceFrame());
while (remainingBurn.get().getValue1() > 0) {
}
vessel.getControl().setThrottle(0);
node.remove();
System.out.println("Launch complete");
connection.close();
}
}
-- Execute burn
print('Ready to execute burn')
while vessel.orbit.time_to_apoapsis - (burn_time/2.) > 0 do
end
print('Executing burn')
vessel.control.throttle = 1
platform.sleep(burn_time - 0.1)
print('Fine tuning')
vessel.control.throttle = 0.05
while node:remaining_burn_vector(node.reference_frame)[2] > 0 do
end
vessel.control.throttle = 0
node:remove()
print('Launch complete')
# Execute burn
print("Ready to execute burn")
time_to_apoapsis = conn.add_stream(getattr, vessel.orbit, "time_to_apoapsis")
while time_to_apoapsis() - (burn_time / 2.0) > 0:
pass
print("Executing burn")
vessel.control.throttle = 1.0
time.sleep(burn_time - 0.1)
print("Fine tuning")
vessel.control.throttle = 0.05
remaining_burn = conn.add_stream(node.remaining_burn_vector, node.reference_frame)
while remaining_burn()[1] > 0:
pass
vessel.control.throttle = 0.0
node.remove()
print("Launch complete")
The rocket should now be in a circular 150km orbit above Kerbin.