# How does the Apollo LM ascent guidance program P12 actually work?

P12 is the AGC guidance program for normal ascent from the lunar surface to orbit. According to the mission planning documents, after separation and ignition, the ascent stage holds its initial attitude for two seconds (to get clear of the descent stage) before pitching to the lunar vertical; it remains vertical for another 8 seconds or so, then begins a gradual pitchover from vertical to horizontal over the course of the burn.

Unburdened by atmosphere, the optimal ascent path should be pretty close to the linear tangent steering law, but video from within the cabin of the LM shows that at least the early portion of the ascent seems to pitch in discrete steps as noted in this question.

According to the doc, however, "the insertion-phase guidance logic is defined by an acceleration command which is a linear function of time"; it's not clear from the text whether the insertion phase is a separate state from the early part of the ascent.

Can someone more fluent in AGC code than I am explain the workings of P12 (source on github) in a little more detail?

In particular:

1. What is the commanded pitch attitude versus time profile?
2. Is it discrete, continuous, or both in different phases of ascent? (let’s say “continuous” means actuated more rapidly than once per second.)
3. Is it based on a linear tangent law, or on some other principle?
• One complication is that the LM doesn't just want to get into "an orbit", but rather "an orbit that permits rendezvous with the CSM".
– Mark
Oct 12, 2018 at 22:29

1. My analysis isn't far enough yet to fully explain the attitude versus time calculations.

2. Although there are a lot of calculations done before the burn, there are also additional calculations performed inside the burn loop, so I am fairly confident that it is a continuous process. There are several flags that are set or cleared during the ascent process; apparently this is how the phases of ascent are done, but I am still analyzing how it's done.

3. I haven't yet found anything like the formulas in Frank Perkins' paper on linear-tangent steering laws. Perhaps the formulas that are actually used are mathematically equivalent -- I'm not quite there yet.

Apollo missions carried two nearly identical guidance computers. The software for the Command Module computer was called "Colossus" and later "Comanche"; the software for the Lunar Module was called "Luminary". The programmers tried to reuse code as much as possible between the two systems, as well as between similar operations on the same system. This means that there are a large number of global variables that help subroutines know what they're being called for. The CM and LEM also occasionally contact each other by radio, giving each other their positions and velocities in space, to facilitate rendezvous.

Astronauts normally took off from the lunar surface by running program P12 "Powered Ascent Guidance". The source code is in Luminary/P12.agc. Lines 35-53 clean up the existing processes/tasks that are running on the computer, and initialize global variables needed by subroutines. The DSKY user interface is configured in lines 55-72. On lines 73-74, the GUIDINIT subroutine is called (lines 222-236), which transforms the LEM's position in moon coordinates into universal coordinates. Lines 75-76 sets a global flag that indicates a pre-ignition state. On line 77, the P12INIT subroutine is called (lines 179-199), which initializes engine globals to that of the ascent engine. This continues into subroutine COMMINIT (lines 200-215), which transforms the "target" CM's coordinates into universal coordinates. Control returns to lines 79-84, which calls LEMPREC to integrate the intended orbit by the Encke method. Lines 85-109 calculate the cross-range and apolune values of the intended flight path, which are displayed to the astronauts (lines 110-113).

The computer then waits for the astronaut to press the PROCEED button (lines 111-116). Some vector calculations are performed (lines 118-143), a flag is set indicating vertical ascent (144-145), and then control jumps to ASCENT (see below). It returns back, calculating some pitch and yaw corrections (lines 147-166), turning off the pre-ignition state (168-169), and then jumping to BURNBABY (171-177).

BURNBABY in file Luminary/BURN_BABY_BURN--MASTER_IGNITION_ROUTINE.agc is a widely-used routine to start the descent or ascent engine. The caller passes a pointer to a table with various parameters including the addresses of subroutines to call back when certain events occur. BURNBABY forks several processes that perform a ullage burn of the RCS as necessary (not needed for P12), ignite the engine, read sensors, recalculate the LEM's position and velocity, query the CSM for its position and velocity, update the DSKY display, and wait for the end of the burn. One of the tasks periodically calls back the subroutine ATMAG, which in turn calls ASCENT.

ASCENT in file Luminary/ASCENT_GUIDANCE.agc is where the in-flight calculations during lunar ascent are performed. I need another day to examine it. I hope to finish this answer tomorrow.

• Have you had a chance to analyze P12 further? Dec 6, 2018 at 1:25
• @RussellBorogove: I was able to translate the code into mathematical formulas, but I couldn't make sense of the formulas. I suppose I should edit them into my answer. Dec 6, 2018 at 2:57
• @DrSheldon that sounds like a lot of effort. Not only the AGC code is available, but the guidance equations documentation as well. For the ascent guidance read here: ibiblio.org/apollo/NARA-SW/R-567-sec5-rev8-5.3.pdf PDF page 129 ff. The same PDF has the descent guidance as well. Dec 6, 2018 at 9:24
• Aha! "Since the [guidance] commands will be fixed for a 2-second period..." -- it updates the guidance only every 2 seconds, hence the discretization of attitude control. Dec 10, 2018 at 2:23
• @OrganicMarble There is more where that is coming from: ibiblio.org/apollo/… Jun 8, 2019 at 17:18