Watch on YouTube: https://youtu.be/q7GDV539nnc
I don’t want to start off on the wrong foot and say automating a munar landing was easy, so let me say this instead. I was not prepared for the level of difficulty presented by Minmus. To be clear, the Mun landing required more than 25 attempts to achieve a 50% success rate, and that felt like a near miracle. With Mun, the goal was simpler. Its orbit around Kerbin is aligned with the ecliptic. This was a design decision made by the game designers to make it easier for players to make meaningful progress in the game. I’m glad they did because the game is arguably one of the most difficult on the market. The script suffers the same penalties experienced by new players. Things can go sideways quickly.
To review, the munar automation script stabilizes into low Kerbin orbit at 80km before computing a transfer orbit maneuver with a predetermined prograde delta-v. Then, after executing the maneuver, it settles into an elliptical orbit with a low periapsis before circularizing at 20km munar altitude. Finally, deorbit and hoverslam to land on the surface. Simple, right? Again, no.
Turns out you can’t simply adjust the prograde delta-v and let the script figure things out. After about ten attempts doing exactly that, I realized there were some significant barriers. For one, the Mun is in the way sometimes, and the script takes a looooooong time to find a solution. Also, it became clear there was a lot of room for improvement in my approach to throttle control. At this point, the results were not good. In the rare cases when I was able to chart an intercept course, the maneuver execution was … imprecise … and I ended up on an escape trajectory.
This makes sense, if you think about it. There’s a lag between the moment we detect some condition is satisfied and the moment the engines stop producing thrust. Chalk it up to a symptom of an engine with high thrust and high specific impulse. We overshoot every time, as a direct result of this delay. We can use simple solutions attempting to compensate, like decreasing throttle by 75% when we approach the engine cutoff condition. This only really reduces the magnitude of the observed effect and does very little to contribute to a more robust solution.
Our best approach is to rethink the control strategy entirely. The first time, it was simply a matter of activating engines at full throttle, deactivating when a condition is met. To achieve a more nuanced result, we will need to take into consideration how far away we are from achieving the condition. In mathematical terms, this means using a ramp input instead of a step input. A ramp input is more like slowing down gradually before stopping, whereas a step input is like slamming on the brakes at the last moment.
Let’s start by incorporating a proportional controller. Rather than providing a constant step input to the throttle, we reduce the throttle based on the remaining delta-v required for the maneuver. This allows us to go full throttle at the beginning, when there’s a large gap to traverse, and then reduce throttle as we approach the target. This gives us the ability to exercise fine control at the end of the maneuver when precision is most important.
Using this proportional control technique, the script is able to stabilize on an intercept orbit with Minmus. However, even with our precise throttle control, we still experience strange oscillations around the target in some cases. In one case, this was caused by a less-than where I needed a less-than-or-equal-to. In most cases, though, it was because the conditions were error-prone.
One key error I encountered was assumptions about the precision of the time warp tool. I incorrectly assumed the ETA for orbital transition would be accurate within a second. Sadly, it is not. This means sometimes the warp completes before the vessel enters the Minmus orbital patch. This has catastrophic effects on the automation process, as it picks the planet periapsis ETA instead of the Minmus periapsis, which is highly correlated with my cursing at the game. After sorting out this subtle nuance in the logic, the rest fell into place. Ok, so what does the code look like?
As with the Mun landing script, we use a runmode variable to manage each phase of the mission. We’ll start from orbit this time, to focus on the differences presented by a Minmus transfer orbit. Let’s dive in!
The main difference between Minmus and Mun orbits is the inclination. Minmus is inclined about 6 degrees from the ecliptic plane. Without adjusting the inclination, we may need to wait considerably longer to plot a transfer orbit, as Minmus shifts in and out of plane relative to Kerbin. Also, Mun intermittently interferes, making it more important to match the inclination.
As a result, our first maneuver after achieving stable orbit is to compute an inclination maneuver. We do this by creating a node with a starting delta-v in the normal direction. We move the node forward in time, comparing the inclination of the resulting orbit against the previous value until we detect an inflection point. Then, we adjust the delta-v until the resulting relative inclination approaches zero.
Once we have our maneuver planned, we simply time warp to the maneuver and execute the burn. Here, we use a proportional controller based on the ship’s scalar speed and the maneuver delta-v requirement. The limit condition is defined based on a simple threshold. We cut the throttle when the relative inclination approaches zero. Then, we proceed to the next runmode to compute the elliptical transfer orbit.
This phase uses the same iterative technique with constant prograde delta-v to find a maneuver node time with a Minmus intercept. Once we have a valid transfer orbit planned, we time warp to the maneuver and execute another burn. Again, we use a proportional controller based on speed and delta-v requirement. Again we use a limit condition.
Early versions of the logic simply added the appropriate delta-v and hoped for the best. This often left the vehicle on an elliptical orbit, but not necessarily on a Minmus intercept. This is because of the extended burn time introduced by the proportional controller. Maneuver nodes assume instantaneous impulse, and there’s no way to add so much energy so fast without squishing the meatbags.
A better way to achieve our stable intercept is to use a different condition entirely. Rather than wait for a specific delta-v change, we cut the engines immediately upon detecting a Minmus intercept. This helps to guarantee an intercept, but it’s worth noting this is not an efficient algorithm. It simply results in a well understood landing sequence, where we can re-use the components from our Mun landing script. We use different values for the altitudes, but otherwise the rules are the same. At this point, we have achieved our most significant milestone in the process. Time to enjoy the fruit of our labor.
While we watch the best attempt, let’s reflect again on the difficulty of this challenge. For the Mun landing, it took 25 attempts. This time, it took more than twice as many attempts. In total, this video required 64 attempts to reach the same success rate criteria. It seems only fitting to show all the attempts as one magnificent composite. So, sit back and relax. Enjoy this time lapse of all the attempts at the same time.
