Monday, December 23, 2013

KSP: Ascent and Deorbit Simulators

Kerbal Space Program is now up to version 0.23 and the career mode is starting to take shape, offering gradually unlocked technology as a reward for exploration achievements such as landing a rover on the Mun. (So, China just unlocked some achievement points.) The core of the game is still the open-universe sandbox in which you can travel to and from any of seven planets and their moons. Or at least try to. It's actually pretty hard.

I built two generations of this ship, which has served me well so far for exploring the Kerbal universe, including a successful manned (Kerbaled?) round-trip mission to Duna surface and a rather haphazardly executed round-trip mission to Laythe orbit, pictured above. In the process I've learned a lot about orbital mechanics, fuel usage, and aerobraking.

"Shit. Shit. Shit. Shit. Shit."
The big prize, though, is to land Kerbals on the surface of Laythe and return them to Kerbin. This is much harder than landing on and returning from Duna, because Laythe is much farther out, much larger, and almost completely covered in water. But as the only other inhabitable world in the game, it's definitely an enticing destination. The question is, can I pull it off with my trusty Interplanetary Transport Ships? Or do I need to figure out how to build a space plane?

Getting all the way to Laythe orbit and back is the easy part. I've done it before with one ship and I outlined a mission plan to do it with two ships in my last KSP post. With the two ships docked in Laythe orbit, one could be fully refueled for the trip to the surface, leaving the other ship with just the fuel they both need to get back to Kerbin, which is in fact not very much. So the important thing left to determine is: Could a fully-fueled ITS2 land precisely on solid ground on Laythe and have enough fuel to ascend back into orbit?

My initial hunch was that the second-generation ITS with its higher-thrust ascent stage could do it. In fact I would have already tried this mission but my most recent trips out to the Jool system have been plagued by the Deep Space Kraken, a game bug with various flavors that eat part or all of your ship in flight. Clearly I will need to be more diligent about making back-ups of my game saves in order to pull off a complicated mission like this. But in the mean time, it's given me a chance to do some more theoretical work in the hopes of providing the poor Kerbals with a bit more assurance that they can actually pull off the landing and ascent.

Tackling ascent and descent through the atmosphere (of Laythe, or any body with an atmosphere) analytically is a more difficult problem than going from point A to point B in empty space. There's no simple formula to tell you how much fuel you should use, or when to make a burn. Instead I decided to write a simulation for each. (Yes, I know Kerbal Space Program is a simulator. So I am writing a simulation of a simulator.) 

My simulation tool of choice these days, now that I don't have a free educational copy of MATLAB, is Scilab. Scilab is like free MATLAB. And in some ways (other than being free) I actually like it better. It allows you to write scripts much like MATLAB's m-files, which is how I put together the simulations. I'll explain each one individually:

Deorbit Simulator
Purpose: Determine an exact landing spot for a precision deorbit burn and unpowered descent through the atmosphere.

The deorbit maneuver is critical for landing on Laythe, because there is so little land to land on. And the fuel budget for the descent to the surface is basically zero. As I will show in the next simulation, the ascent needs almost the entire ITS2 fuel supply. So at most there is enough for a small burn get out of orbit and a small burn to arrest motion right before touchdown. The rest is unpowered descent with parachutes opening near the end. Picking the time and duration of the initial deorbit burn in order to hit a precise target on the surface is the challenge.

The deorbit simulator takes as inputs: 
  • Body parameters (defined on the KSP Wiki for all planets and moons).
  • Atmospheric parameters (also defined on the Wiki).
  • Initial orbital parameters (easy to pick out from the map view).
  • Deorbit burn time, duration, and acceleration (the independent variables).
It then runs a numeric simulation of the descent, including the effects of atmospheric drag when the altitude falls below the atmospheric threshold. To show the relative effect of drag, a plot of the descent with no atmosphere is also charted.

The engine that drives the simulation is a polar-coordinate numeric differential equation of motion solver. It sounds complicated but it's just F = ma. Force, F, is a combination of gravity, thrust (during the deorbit burn only), and atmospheric drag. Mass, m, is a constant for this simulation. Acceleration, a, is integrated to find the velocity and the position of the spacecraft over time. The only hard part is doing it all in polar coordinates. For this I turned to my mechanics textbook:

Bill Kerman, riding on physics alone.
That book, which I haven't used really at all since freshman physics, is notoriously difficult as you can probably guess by the title and lack of cover art. Because of it I spent many hours calculating the fractional change in observed gravity on a hydroplane traveling at 200mph in each of the four cardinal directions at the equator (hint: it's not much). But luckily in this case I just needed a simple formula that shows up by page 36:

It defines the changes in r, the radial distance from the center of the body, and θ, the angle of rotation around it (almost like the longitude), in the presence of acceleration due to forces acting radially and tangentially on the ship. The differential equations are more complex than in the Cartesian coordinate system of x and y positions, but they are still easy to simulate, once you know the forces at work on the ship. These are gravity, drag, and thrust. All easy to calculate. (Okay, drag is a little hard.)

Anyway, the output of the deorbit simulator is two trajectory graphs:

The left-most graph shows three trajectories (altitude vs. angle). The yellow is the undisturbed orbit: what the ship would do normally until the deorbit burn is made. The purple is after the deorbit burn, but not including the effects of atmospheric drag. This would be the unpowered descent trajectory of the ship on a body with no atmosphere. Finally, the blue trajectory includes atmospheric drag. It only really diverges from the purple trajectory in the thick lower atmosphere. Where the altitude reaches zero is the theoretical landing site based on the deorbit burn entered.

I use the term "landing site" loosely above. I have cautiously labeled the x-axis of the left-most graph "sidereal angle", the angle of the orbit with respect to the stars. So it's not exactly the longitude, because the body being orbited is also rotating at some speed. So it's important to account for the offset introduced by the body's rotation in determining the final landing site (or, if the final landing site is known, calculating exactly when to execute the deorbit burn). For this purpose, the right-most graph is useful. It shows the same trajectory, but as a function of time rather than orbital angle. The time between the deorbit burn and touchdown can be used to calculate the offset due to the body's rotation.

For example in the trajectory above, the deorbit burn occurs at 500s and touchdown occurs at about 1215s. So the entire deorbit takes 715s, just under 12 minutes. In that amount of time, Kerbin will have rotated just under 12º (it rotates at 1º per minute, conveniently). The total angle traversed between the start of the deorbit burn and touchdown is about 119º, according to the left-most graph. However, in that time Kerbin has rotated under the ship by about 12º. So, the touchdown target is about 119º-12º = 107º of longitude from the point on land immediately below the ship at the start of the burn. If only there were a large target-shaped landmark exactly 107º leading the Kerbal Space Center...

Well would you look at that!
So that's the trick, then: finding a landmark to mark the start of the deorbit burn. On Kerbin I use the center of this crater. Exactly when the ship is flying past it, I execute a deorbit burn designed using the simulator to put my landing site right at the Kerbin Space Center is, another 1/3 of the way around the planet. There is some iteration required based on the initial orbit, but it's always something like a 90-100m/s burn at that point from low orbit to achieve this. And it's been fairly accurate (in my experience, ±2º).

Touchdown within visual of the VAB and launch tower.
Picking a landing site and a burn target on Laythe is a bit harder, since there is so little land to work with. But I think I have a good candidate:

That landing site has to be at the equator in order for the ascent to have any chance of working. It also should be relatively flat. That limits it to a strip of island about 10º of longitude wide. Leading that by about 80º, there is a small island at the equator that could serve as a good burn marker. Tricky, but it seems feasible. It would also be possible to intentionally aim for the far edge of the landing site and use either early parachute deployment or short bursts of propulsion to adjust backwards if needed. (Undershooting, on the other hand, would be disastrous.)

There is a small subtlety in this deorbit simulation that I didn't realize until I created the ascent simulation below. It's that the atmosphere is, at least to some extent, rotating with the body. So the drag force amplitude and direction are not exactly opposed to the absolute direction of the craft. They are instead determined by the relative motion between the craft and the air. I added this in as a switchable option in the simulation (lines 116 or 117). The effect is noticeable:

The fixed-atmosphere simulation predicts a landing site approximately 2-3º short of the rotating atmosphere simulation's prediction, which is enough to matter for very precise landings. Laythe rotates over twice as slowly as Kerbin,though, so the variation will be less, I think.

Staged Ascent Simulator
File: ascent2.sce, ascent2_Laythe.sce
Purpose: Evaluate whether a multi-stage ascent craft can reach stable orbit.

Getting a ship into Kerbin orbit is the first and most daunting challenge in Kerbal Space Program. A massive amount of fuel and careful management of mass by staging used-up fuel tanks and rockets is the only way to push through both gravity and aerodynamic drag to get up to orbital speeds. Getting off Laythe is a bit easier, since it's 4/5th the size of Kerbin. But instead of this:

I get only this:

One ITS2 main ship, fully-fueled minus a small amount used for deorbit and soft landing on Laythe. By the numbers, it has enough delta-V capability to reach Laythe orbit. (The Wiki suggest that the magic number is 2.8m/s, compared to 4.4km/s on Kerbin.) But the exact amount is strongly related to the thrust-to-weight ratio of the ascender's stages. In the extreme, a ship with a TWR of 1 would burn all of it's fuel hovering inches off the ground. An efficient ascender probably maintains a TWR of 1.5-2.0 (just a guess). The ITS2 ascender will fall short of this range, especially once the most powerful LVT-30 engines are staged. When it is running on LV-N's only, the TWR is well below 1. By that time, the ship will need to be high and fast enough that the low-thrust but efficient LV-N's can still finish off the orbit.

So I decided to create another simulation, this one for multi-stage ascent. My first attempt was just a simple calculation: a multi-stage rocket going straight up. I figured this would be a good go/no-go test: If the rocket can't get out of the atmosphere going straight up, it has no hope of getting into orbit. It also helped me compare staging strategies to see which would get it the highest. But having confirmed that the ascender could get high enough to clear that atmosphere, I still had no guarantee that it could also go fast enough sideways to reach stable orbit. So I wrote a more thorough simulation using the same techniques and polar coordinate solver as the deorbit simulation above.

The simulator handles multiple stages and multiple engine/fuel groups per stage. In other words, a stage can be a block of five identical engines or groups of different types of engines, each with a certain amount of fuel allotted to them. The stage need not be a physical group that is jettisoned, either. It could be as simple as turning one engine off. For example, the final stage of the ascent is to turn off the Poodle engine and use only the LV-Ns to save fuel. Building in this staging logic made it a bit harder than writing the deorbit calculator, but the basic physics are exactly the same.

The inputs are parameters of the body and ship, much like the deorbit calculator. There are sets of matrices for defining the different stages as well: empty mass, fuel mass, end fuel mass (not necessarily zero). Finally there is a throttle and pitch rate definition per stage. (Each stage can have a different throttle level and pitch rate, but they are taken to be constants within the stage. You can certainly add an extra stage with different throttle and pitch rates if it needs to be discontinuously varying within a given physical stage.)

The output of the simulation is two sets of graphs: the left-most one showing masses and thrust-to-mass ratio, the right-most one showing altitude and velocity. As with the deorbit calculator, the x-axis can be time or (sidereal) angle. You will know you have achieved stable orbit if the end graph looks something like this:

After the initial ascent, the plot of altitude and speed vs. angle (or time) is a periodic function and the altitude never dips back down below the atmospheric threshold. How to get to this point is mostly a matter of trial-and-error. The simulation does no optimization; you must pick the right amount of fuel to use per stage and, critically, the right pitch rates. The pitch rates control the angle of thrust - starting out completely vertical and ending, in theory, completely horizontal. Too slow of a pitch and you go into a large parabolic arc that crashes back into the ground. Too fast of a pitch and you wind up not even getting out of the atmosphere, or worse, thrusting toward the ground!

After manually optimizing an ascent of the full ship from Kerbin as much as I cared to, I compared the predicted fuel remaining to my actual launches and found that they were in agreement, at least to within 10-20%. I've done enough Kerbin launches to know what the best pitch rates and throttle settings are, too, and the simulation corresponded pretty well with them. So that gave me some confidence to see what it would predict for my Laythe ascender. And here are the results:

It can make it! Just barely, as expected. You can see from the fuel plot on the right graph just how little fuel is left by the end - somewhere around one ton out of an intial 32 tons! The assumption is that the craft starts with nearly full tanks, minus two tons used for deorbit and soft landing. So unless I can conserve some of those two tons, there really isn't any more to spare. The only way to squeeze a little more safety margin out of it would be to dump RCS fuel before lift-off to save some weight. In case you are curious, the staging logic is like this:
  1. All five rockets ignite and burn at 13/15 throttle until the entire 10t of LVT-30 fuel is completely used up. At that point the LVT-30's and their fuel tanks are jettisoned.

  2. The three remaining rockets (two LV-N's and one Poodle) remain lit until all of the central tank fuel (intially 16t-2t = 14t) is used up. At this point the Poodle shuts down on its own.

  3. The LV-N's finish the job, efficiently putting the ship in orbit at around 80km and with minimal fuel to spare for rendezvous with the orbiting ship that will refuel it for the trip home.
I knew that getting this ship back off of Laythe would be a pretty close call, but this simulation at least gives me some level of confidence that it is possible, if I get the staging and pitch rates just right. I'm also quietly hoping that dumping the RCS fuel will make it less of a close call. I guess I will find out soon. In the mean time, it's been interesting reminding myself how to do polar coordinate kinematics!


  1. You make us wait so long for new posts, but they are worth the wait.

  2. I'm just finding this and I am having a bunch of issues adapting your ascent file to the new ksp properties, staging, and rotation. Any tips?

    1. I haven't tried to match it up to newer versions in a while, but I think much of the math should still work. The most confusing thing is the pitch rate, because it sets the ending angle based on the amount of fuel allotted. I probably should have coded it so you enter the ending angle and it figures out the pitch rate iteratively (has to run through at least once to figure out how long the fuel will last, and probably a few times to converge since the Isp will change with trajectory). Maybe something for my to try for v2!

    2. How do I figure out the pitch rate compared to my pitch angles in ksp?

    3. If you have a mostly constant pitch rate during a stage, you would get it from the start and end angle and the stage time (which is itself an output, based on fuel consumption and varying Isp, so some iteration is required). If the pitch rate is not continuous, you could program it in as an additional stage. For example if you immediately pitch over from 80º to 45º at the start of stage 2, you could program in stage 2.1 with a very fast pitch rate using the first 5% of stage 2's fuel and then stage 2.2 with zero pitch rate using the remaining 95% of stage 2's fuel.

      Admittedly a bit roundabout compared to setting angles directly, but since the burn time per stage is unknown at the start of the simulation it's not easy to program stages by start/end angle. Maybe it could be rewritten so that the angle is a function of the fraction of stage fuel consumed, rather than time. Or so that it automatically iterates through a few passes to determine the burn times and calculates pitch rates based on start/end angles.

  3. Thank you for sharing such a great deal of insight.