I like rockets, especially when they do things like fly back and land on their launch pad or a barge in the ocean. I don’t have the budget to do stuff like that, but I have Kerbal Space Program (KSP). Recently, I wrote a script (a program) that automatically launches a small two-stage rocket, and then flies the first stage back to the launch pad and lands it.
For those who don’t know, Kerbal Space Program is a space flight simulator game. The player can build and fly rockets to different planets, as well as manage certain aspects of a space agency. The game also allows users to create and install mods. Mods change the game’s functionality to add various new features and parts. One of my favorite mods is kOS (Kerbal Operating System), which adds computers that can be put on rockets and programmed to autonomously control the spacecraft.
I’m going to talk about the overall design of the script I wrote for kOS and some of the challenges I faced, without going into too much detail about the code. That would be boring as most of it is doing weird things with vectors and PID loops.
Probably the hardest part of landing a rocket is predicting where it will hit the ground. I looked into calculating this using the ballistic reentry equations, but kOS doesn’t provide a way to access the data about atmospheric conditions needed to calculate things such as the coefficient of drag. Fortunately for me, someone made an open source mod called Trajectories, which did almost exactly what I needed.
The trajectories mod simply shows the rocket’s trajectory on the map. There was no way to access that information from kOS, so I downloaded the source code for both Trajectories and kOS and started looking for a way to connect the two. After searching through a ton of code and some trial and error, I managed to code an interface between the two. Now I could get latitude and longitude coordinates for the rocket’s impact point. The code is available on my github account: https://github.com/CalebJ2 (update: this is now merged into the official kOS and Trajectories mods)
After the rocket launches, it waits until it has only about one fourth of its fuel left, and then cuts the throttle and releases the second stage (which quickly accelerates away). Currently, the second stage just crashes because a certain bug in kOS doesn’t allow it to be controlled, but after that is fixed by the kOS developers, I will make it actually fly to orbit (which it is capable of doing).
The first stage then points itself in the direction between its impact point and the launch pad, and fires its engines. The distance between the impact point and the launch pad decreases until the rocket starts to overshoot its target. When the distance starts to increase again, the rocket switches to glide mode.
It might seem funny that a rocket would be able to glide, but it is possible even if it’s limited. By angling the rocket in the direction that I want the impact point to move, it can correct its trajectory by up to several hundred meters (depending on how much time it has to correct). The code to do this was more complex than I expected it to be, as it required something resembling a vector rotation. Instead of doing a proper matrix rotation, I estimated one by adding vectors together (bad explanation, but it would take a while to explain). The glide mode is able to fine tune the rocket’s impact point to be within about five meters of the center of the launch pad.
Now I want the rocket to land in the most fuel efficient way possible. This means waiting until the last possible second to fire the engines, because the smaller the amount of time you spend fighting gravity, the better. Ideally, the rocket will stop falling right as it touches the ground. This is generally called a suicide burn by the Kerbal Space Program community (a burn is when the engines are fired for a certain period of time). Instead of “suicide burn,” SpaceX calls this a “hover slam” probably because they don’t want to think about what happens if you fail.
The script constantly checks how high the rocket is, and how far the rocket will fall before it can stop itself. When the two distances are equal, it fires the engines. Here is the main equation I used:
Stopping distance = `-v^2/(2a)` where `v` = downward velocity and `a` = average downward acceleration when at full throttle (this number will be negative).
Finding the average upward acceleration is done by adding together the average acceleration due to the three forces acting on the rocket: engine thrust, gravity, and air resistance. This gives a good estimate of vertical stopping distance (usually around 900 meters). To simplify my calculations, I didn’t take the decreasing mass of the rocket due to fuel usage into account, causing it to give a number higher than it should (which I accounted for by subtracting 15).
After the rocket fires its engines and has stopped falling, it usually ends up about five meters off the ground, allowing for some final correction. Then the rocket enters a hover mode, quickly maneuvers itself to the center of the launch pad, and gently lowers itself down.
Mission accomplished!