Skip to content

Instantly share code, notes, and snippets.

@embix
Last active January 5, 2018 02:44
Show Gist options
  • Save embix/7e9f3f5ce2a39d6e1ec06e0f8b871666 to your computer and use it in GitHub Desktop.
Save embix/7e9f3f5ce2a39d6e1ec06e0f8b871666 to your computer and use it in GitHub Desktop.
Kerbal Space Program: get GDLV3 into low Kerbin orbit, release payload and deorbit booster (works but needs tuning: final orbit of payload was 72720m/118675m), tested in LINQPad
// fetch Google.Protobuf and KRPC.Client from nuget gallery
// namespace imports:
//KRPC.Client
//KRPC.Client.Services.SpaceCenter
//System
// removed due to ambiguity with linq expressions: KRPC.Client.Services.KRPC
class GDLV3_To_KEO
{
public static readonly System.Net.IPAddress kspKrpcServer = System.Net.IPAddress.Parse("ipv4/ipv6 of KSP with kRPC");
const String VesselName = "GDLV3";
public static void Main()
{
using (var conn =
//new Connection("Sub-orbital flight",IPAddress = kspKrpcServer);
new Connection("kspRpcSpike", kspKrpcServer))
{
var vessel = conn.SpaceCenter().ActiveVessel;
// Assert script matches the vessel it was designed for, or at least a revision/mod thereof
if(!vessel.Name.Contains(VesselName))
{
Console.WriteLine($"Script is for '{VesselName}' but active vessel is '{vessel.Name}', aborting launch sequence.");
return;
}
else
{
Console.WriteLine($"Found vessel '{vessel.Name}' in biome {vessel.Biome}.");
// todo: check biome is kerbin/launch pad (well, actually, it's Shores)
// todo: check not moving relative to kerbin
};
// don't ever hurt kerbals
if(vessel.CrewCount>0){
Console.WriteLine($"Vessel contains {vessel.CrewCount} crew members. Launch script not permitted to be applied on living beings. Aborting launch sequence.");
return;
}
vessel.AutoPilot.TargetPitchAndHeading(90, 90);
vessel.AutoPilot.Engage();
vessel.Control.Throttle = 1;
System.Threading.Thread.Sleep(1000);
Console.WriteLine("Launch!");
vessel.Control.ActivateNextStage();
{
var solidFuel = Connection.GetCall(() => vessel.Resources.Amount("SolidFuel"));
var expr = KRPC.Client.Services.KRPC.Expression.LessThan(
conn,
KRPC.Client.Services.KRPC.Expression.Call(conn, solidFuel),
KRPC.Client.Services.KRPC.Expression.ConstantFloat(conn, 0.1f)
);
var evnt = conn.KRPC().AddEvent(expr);
lock (evnt.Condition)
{
evnt.Wait();
}
}
Console.WriteLine("Booster separation");
vessel.Control.ActivateNextStage();
{
var meanAltitude = Connection.GetCall(() => vessel.Flight(null).MeanAltitude);
var expr = KRPC.Client.Services.KRPC.Expression.GreaterThan(
conn,
KRPC.Client.Services.KRPC.Expression.Call(conn, meanAltitude),
KRPC.Client.Services.KRPC.Expression.ConstantDouble(conn, 10000)
);
var evnt = conn.KRPC().AddEvent(expr);
lock (evnt.Condition)
{
evnt.Wait();
}
}
Console.WriteLine("Gravity turn");
vessel.AutoPilot.TargetPitchAndHeading(45, 90);
{
var apoapsisAltitude = Connection.GetCall(() => vessel.Orbit.ApoapsisAltitude);
var expr = KRPC.Client.Services.KRPC.Expression.GreaterThan(
conn,
KRPC.Client.Services.KRPC.Expression.Call(conn, apoapsisAltitude),
KRPC.Client.Services.KRPC.Expression.ConstantDouble(conn, 80000) //75k inteded plus 5k safety margin (drag)
);
var evnt = conn.KRPC().AddEvent(expr);
lock (evnt.Condition)
{
evnt.Wait();
}
}
Console.WriteLine("Wait for Apoapsis");
vessel.Control.Throttle = 0;
{
var meanAltitude = Connection.GetCall(() => vessel.Flight(null).MeanAltitude);
var expr = KRPC.Client.Services.KRPC.Expression.GreaterThan(
conn,
KRPC.Client.Services.KRPC.Expression.Call(conn, meanAltitude),
KRPC.Client.Services.KRPC.Expression.ConstantDouble(conn, 75000)
);
var evnt = conn.KRPC().AddEvent(expr);
lock (evnt.Condition)
{
evnt.Wait();
}
}
Console.WriteLine("Circuralize Orbit");
vessel.AutoPilot.TargetPitchAndHeading(0, 90);
Thread.Sleep(2500);// hope we manage to change attitude in that time
vessel.Control.Throttle = 1;
{
var apoapsisAltitude = Connection.GetCall(() => vessel.Orbit.PeriapsisAltitude);
var expr = KRPC.Client.Services.KRPC.Expression.GreaterThan(
conn,
KRPC.Client.Services.KRPC.Expression.Call(conn, apoapsisAltitude),
KRPC.Client.Services.KRPC.Expression.ConstantDouble(conn, 72000) //70k+ inteded plus 2k safety margin (we may want to rendevouz to that vessel!)
);
var evnt = conn.KRPC().AddEvent(expr);
lock (evnt.Condition)
{
evnt.Wait();
}
}
Console.WriteLine(@"Achieved Orbit! \o/");
vessel.Control.Throttle = 0;
Thread.Sleep(5000);// let vessel stabilize
Console.WriteLine($"Releasing payload into Orbit: Apo={vessel.Orbit.ApoapsisAltitude}m, Peri={vessel.Orbit.PeriapsisAltitude}");// todo: argument of periapsis
vessel.Control.ActivateNextStage();
Thread.Sleep(10000);// gain enough distance to payload
Console.WriteLine("deorbitting booster");
vessel.AutoPilot.TargetPitchAndHeading(180, 90);
Thread.Sleep(5000);// turn retrograde and let vessel stabilize
Console.WriteLine("final deorbit burn");
vessel.Control.Throttle = 1;
{
var apoapsisAltitude = Connection.GetCall(() => vessel.Orbit.PeriapsisAltitude);
var expr = KRPC.Client.Services.KRPC.Expression.LessThan(
conn,
KRPC.Client.Services.KRPC.Expression.Call(conn, apoapsisAltitude),
KRPC.Client.Services.KRPC.Expression.ConstantDouble(conn, 30000) //deorbit fast, burn in atmosphere
);
var evnt = conn.KRPC().AddEvent(expr);
lock (evnt.Condition)
{
evnt.Wait();
}
}
Console.WriteLine("deactivating control");
vessel.Control.Throttle = 0;
vessel.AutoPilot.Disengage();
//autodispose since where in a using-environment: conn.Dispose();
}
}
}
@embix
Copy link
Author

embix commented Jan 5, 2018

Designed for GDLV3. Uses kRPC.

GDLV3 at launch pad

GDLV3 in orbit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment