Guidance code for my Loa 4 space shuttle in KSP realism overhaul. Two scripts, one for ascent of the whole stack, and one for landing the booster just after separation, now put on github for your viewing pleasure.

THIS CODEBASE IS IN THE MIDDLE OF A REWRITE

I was in the middle of completely redoing all the descent guidance code before I had to stop because of school commitments. Much of it is commented out or missing entirely. When I return to this project, I will probably end up nuking it and starting from scratch.

HOW IT USED TO WORK

The ascent code is relatively simple, it runs two asynchronous routines, one for attitude control and one for throttle. During the first stage of flight, fuel drains from the booster and not from the spaceplane, and the thrust of the engines must be differentially adjusted to keep the center of thrust in line with the center of mass. The pitch is simply controlled by a mapping between angle and altitude. After stage separation, the spaceplane adjusts its angle of attack to prevent the vertical velocity from dropping below a certain point.

The booster landing code is substantially more complicated. Descent occurs in several stages. The first is a retroburn which slows the booster down and places it on a course for the landing site. The launch will not always be perfectly in line with the target, so a perpendicular correction component is added to this burn. The next phase is a pre-entry coast, during which the booster aligns itself to the correct attitude. During re-entry, the booster maintains a very high angle of attack, using body lift to reduce the harshness of deceleration and heating. After this, the guided phase of descent begins. The booster has sufficiently large control surfaces that it can correct its trajectory substantially (on the order of 10 km), which allows it to correct for imprecision in the previous descent phases. Two PID controllers simultaneously adjust pitch and roll. The trajectory is constantly corrected towards a hyperbola which starts at the current position and is tangent to the velocity vector, and reaches a point slightly above the landing site with a slope of 2/3. A simple simulation is run every frame to check where the rocket would come to a stop if the engines were lit at that instant, and when that position is directly above the landing site, the engines are ignited and the landing phase begins. At first, three engines are used to kill the majority of the velocity. Then, it switches to only one engine, allowing the booster to hover. The engines are offset slightly from the center of mass, so some Very Annoying Vector Math is used to account for this by offsetting the pointing vector by a fixed angle. The booster corrects towards a velocity vector pointed towards the landing site with a magnitude mapped to altitude and displacement. When altitude drops below a certain point the engine is cut and the rocket settles onto the pad.

This method is absolutely functional, but is deeply flawed in that it tends to overcorrect and fall into a mode of poorly damped oscillation during guided descent. It also requires substantial parameter tuning if the ascent trajectory or landing site position needs to be changed. In short, this code is jank and I want to redo it.

HOW IT’S GOING TO WORK

I would like to replace the entire descent and ascent procedures with a single common system, centered around a complete trajectory solving algorithm. On a mathematical high level, it is based around a second order differential equation F(S, dS/dt, R) = d2S/dt2 where S is the current state (position, angle), R is the current control inputs (pitch, yaw, roll, and throttle), and t is time. The function F will be the sum of aerodynamic, thrust, and gravitational forces/moments. Prior to launch, the program will be given a start state, on the pad with zero velocity, and an end state, at the target altitude with orbital velocity. The key to using this as a control algorithm is the function R(t) which maps control values to time. Before flight, values of R(t) will be calculated such that numeric integration of F from the start state will result at the end state. Infinitely many such solutions can exist, so it will be optimized for the lowest fuel consumption and g-loading. R(t) can be computed using a deterministic method, but I find the idea of using a statistical approach such as a Monte Carlo method to be very appealing. Though not computationally efficient, a statistical method will be fun to learn and also be a lot less math for me to do. During flight, values of R(t) will be looked up every frame to control the spacecraft. If a significant deviation from the flight plan is detected, such as thrust loss due to an engine failure, the simulation will be rerun on the fly with the current state as the starting point. The landing program will be almost identical, simply changing the start point to the booster directly after separation, and the end state to be the booster on the landing pad with zero velocity. The function F will need to be tweaked to adjust for the changed aerodynamics of the lone booster without the shuttle.

This holistic method is substantially more appealing because of its extensibility. It has no reliance on hardcoded values, and can be easily adapted to completely different designs and use cases. It also gives much finer control over end states, meaning that spacecraft can easily be put on a precise target orbit for rendezvous.