[September 1, 2024] I am currently migrating my blog away from WordPress. I am trying to keep all url's and content the same. This is a work in progress. The old WordPress website is archived and available at https://archive.bartslinger.com. This is all in markdown now, which is awesome. Maybe I blog about that later.

# Over-engineering a Mun landing in Kerbal Space Program

This is an over-engineered attempt to perform a very efficient Mun landing, which I worked on together with my friend Joost Meulenbeld. Using kRPC, we have written an autopilot that executes the landing automatically.

## Methodology

For a perfectly spherical body, the ideal trajectory would be to place the periapsis just centimeters above the surface. An almost horizontal suicide burn then kills of all horizontal velocity. However, Mun is not a perfectly spherical body and this approach would risk us to fly into a mountain. The varying mass also prevents us from making a simple calculation.

Our method is to first generate a reference approach profile. We built a simulator that implements the orbital mechanics. Instead of starting the simulator in orbit and simulating our way towards the surface, the simulation is started on the landing spot. The fuel mass is increasing in this 'reversed' simulator, but everything else is the same. The simulator starts with a constant pitch angle of 10 degrees and 90% throttle. The angle can be lowered further, depending on obstacles on the surface of Mun. 90% throttle is chosen to leave some margin for control, as we want to do a precision landing of course.

## The 'reversed' landing simulator

The state vector for the simulator is:

Where

The differential state equations are:

The differential equations are converted to python and are solved by the solve_ivp function of scipy, with time steps of 0.1s.

## Getting to orbit

Now that we have a 'reversed' simulator, the task is to find a set of control inputs that results in a circular orbit at 10 km above the surface.

- Apply 90% throttle at 10 degrees pitch, until the apoapsis reaches 10 km above the surface.
- Coast to the apoapsis.
- Perform a circularization burn at apoapsis.

For step 1, we need to know the apoapsis of the orbit in order to stop burning in time. From the simulator, we only have
the state vector which does not contain orbit parameters. The following calculations allow us to calculate orbit
parameters just from

The required orbital velocity for a circular orbit at radius

The duration of the cirularization burn is estimated using a constant mass:

For the circularization burn, a throttle setting

## Iterate to find correct fuel mass

The reversed simulator needs to start with an unknown quantity of fuel. The initial run can start with 0 kg. This will result in a certain amount of fuel in circular orbit. The amount of landed fuel is iterated a couple of times until the the orbit fuel mass matches with the fuel on board the ship.

The flight profile is now complete. Altitude and throttle are plotted here against time:

## Compensate for rotation of Mun

The angle

where

## Feedback control in the landing burn

The de-orbit burn is purely feed-forward. This needs to be timed precisely. A tiny deviation in the de-orbit burn can result in a large error at the start of the landing burn.

The reference trajectory describes the desired vehicle state for every moment in time. However, there will be small deviations from this profile that need to be corrected for. Since Mun itself is rotating, we must aim for the landing to happen at t=0. Every second difference increases the error by 9 meters. The variables we try to control are longitude and radius (altitude). A relatively simple controller is implemented that decouples these. To control longitude, we use thrust. For altitude control, we use the pitch angle.

Full video of the landing burn### Longitude control

The longitude error is defined by

where

The throttle setpoint is defined by the following PD controller with feed-forward from the reference trajectory:

The gains

### Altitude control

The altitude error is:

The pitch angle setpoint is controlled with the following PD-controller with feed-forward from the reference trajectory:

These gains are also tuned kerbal-style, and the pitch setpoint is bound between 0 degrees and 20 degrees. The reference trajectory is 10 degrees.

### Horizontal 'suicide burn'

For the last 1000 meters, a different horizontal controller is used for improved landing accuracy. It is somewhat similar to a suicide burn, except that it requires slightly less than 100% throttle. When we are this close to the target, it is safe to ignore orbit dynamics and pretend that Mun is flat.

If the following constant horizontal acceleration setpoint

where

Technically we would need a little more thrust to compensate for the pitch of the vehicle. Also, the target height is increased by 5 meters so that we can quickly rotate the vehicle upright for a smooth vertical touchdown.

## What's next

This post just shows the part where we get from orbit to the surface of the Mun, but we have already automated the entire flight starting at launch from Kerbin. The next step will be to build a Mun base that mines for fuel. Instead of landing on the surface, we can build vehicles that automatically dock to the Mun base and don't require landing legs. Then, we can transfer massive amounts of fuel from the Mun base to an orbital station, where we can refuel the biggest rockets and spaceships to send to the edge of the Kerbol System and beyond!

## Source code

For those who are interested: the code is open-source, but not documented.