Skip to content
Back to Essays

The Digital Autopilot: How the AGC Flew a Spacecraft with Reaction Jets

The software that translated guidance commands into precisely timed thruster firings—managing attitude, translation, and engine gimbal across every phase of flight

Matt Dennis

The Apollo Guidance Computer didn’t just navigate. It flew the spacecraft. Every attitude maneuver, every stationkeeping rotation, every engine firing—the physical act of pointing the vehicle in the right direction and keeping it there—was managed by a piece of software called the Digital Autopilot. The DAP was the interface between mathematical abstraction and mechanical reality, the code that turned guidance equations into jet firings and gimbal angles.


The Command Module DAP controlled 12 reaction control jets and the gimbal actuators on the Service Propulsion System engine. The Lunar Module DAP controlled 16 reaction control jets and the gimbal on the descent engine. Each DAP was a different program, written for different hardware with different dynamics, but both solved the same fundamental problem: receive an attitude command from the guidance software, compute the thruster firing pattern that would achieve it, execute the firings at precise times, and deal with the consequences when reality didn’t match the model.


The Problem of Attitude Control in Space

On Earth, aircraft attitude control is continuous. Move the stick, and aerodynamic surfaces generate forces proportional to the deflection. Release the stick, and stability returns. The medium—air—provides damping. In space, there is no medium. No air, no damping, no restoring force. Push a spacecraft to a new attitude with a jet firing, and it rotates to that attitude and keeps rotating forever unless you fire another jet to stop it. Every attitude change requires two actions: a jet firing to start the rotation, and a second firing to stop it.


The reaction control system jets were on-off devices. They weren’t throttleable. Each jet either fired at its rated thrust or didn’t fire at all. The Command Module’s RCS jets each produced about 100 pounds-force of thrust. The LM’s RCS jets produced about 100 pounds-force each as well. Control authority came from which jets you fired, how many simultaneously, and for how long.


The DAP’s job was to select the right combination of jets, fire them for the right duration, and produce the desired change in attitude or translation—all while minimizing propellant consumption. RCS propellant was finite and critical. Waste it on sloppy attitude control, and you might not have enough for a rendezvous maneuver or an abort.


Phase Plane Logic: The Heart of the DAP

The DAP used a control approach called phase-plane switching logic. This is a technique from classical control theory that’s well suited to systems with on-off actuators—which is exactly what bang-bang thrusters are.


The concept starts with a two-dimensional plot. The horizontal axis is attitude error—how far the spacecraft is from its desired orientation, measured in degrees or radians. The vertical axis is attitude rate—how fast the spacecraft is rotating, in degrees per second. At any instant, the spacecraft’s rotational state can be represented as a single point on this plane.


The desired state is the origin: zero error, zero rate. The spacecraft is pointed exactly where it should be and isn’t rotating. The DAP’s job was to drive the state point to the origin and keep it there.


The phase plane was divided into regions by switching lines—boundaries that determined when jets should fire. If the state point was in a region indicating “too far off and rotating the wrong way,” the DAP commanded a corrective jet firing. If the state point was in a region indicating “close to the target and rate is small,” the DAP did nothing—it coasted.


The switching lines were not straight. They were shaped to account for the spacecraft’s moment of inertia (how hard it was to rotate), the jet thrust level, and a deadband—a zone around the origin where small errors were tolerated. The deadband was adjustable. During coarse maneuvers, a wide deadband conserved propellant by allowing larger attitude excursions. During critical phases like powered descent or rendezvous, a tight deadband held the spacecraft to within fractions of a degree.


The phase-plane logic was computed independently for each of the three rotational axes: pitch, roll, and yaw. Each axis had its own switching lines, its own deadband, and its own jet-selection logic. The three axes were largely independent, though coupling effects—a jet intended to fire for yaw that also produced a small pitch torque—had to be accounted for.


Jet Selection: Which Thruster, Which Direction

Selecting the right jet for a given maneuver was a non-trivial combinatorial problem. The Command Module had 12 RCS jets arranged in four quads of three jets each, mounted on the Service Module. Each quad had one jet pointing in each of the three axes (positive, negative, and one at an angle for redundancy). The Lunar Module had 16 jets in four clusters of four, mounted on the ascent stage.


The jet selection tables—woven into rope memory—mapped each desired torque direction to the specific combination of jets that would produce it. For a positive pitch rotation, the DAP looked up which jets to fire. For a combined pitch-and-yaw maneuver, it determined which jets could produce both torques simultaneously. The tables also handled failure cases: if a jet was marked as failed (via crew input through the DSKY), the selection logic routed around it, using alternate jets even if the resulting torque was less efficient.


The Lunar Module’s jet selection was more complex because of the LM’s asymmetric mass distribution. The center of gravity shifted significantly during descent as the descent stage burned through its 18,000 pounds of propellant. A jet firing pattern that produced pure yaw torque with full tanks might produce a mix of yaw and roll with tanks half empty. The DAP’s jet selection logic had to account for this shifting CG, using parameters updated by the guidance software as fuel was consumed.


Additionally, the LM DAP distinguished between “4-jet” and “2-jet” operation for translation. During powered descent, when the LM needed to translate laterally (move sideways without rotating), it could fire pairs of jets on opposite sides of the vehicle to produce a pure translational force. But two jets consumed propellant twice as fast as one. The DAP could be configured for minimum-fuel attitude control (fewer jets, slower response) or maximum-performance control (more jets, faster response), depending on the mission phase.


The Descent Engine Gimbal: Trim and Thrust Vector Control

The Lunar Module’s descent engine was mounted on a gimbal that allowed it to pivot approximately ±6 degrees in two axes. This gimbal served a critical function: keeping the thrust vector aligned through the vehicle’s center of gravity as that CG shifted during the descent burn.


As the descent stage consumed propellant, the CG moved. If the engine remained fixed while the CG shifted, the thrust vector would no longer pass through the CG, creating a torque that would try to tumble the spacecraft. The RCS jets could counteract this torque, but doing so would consume RCS propellant at an unacceptable rate during a 12-minute descent burn. The gimbal was the solution: by continuously repositioning the engine, the thrust vector stayed aligned with the CG, and the RCS jets only had to handle small residual disturbances.


The DAP computed the required gimbal position as part of its attitude control loop. Every computation cycle, the software calculated the estimated CG location (based on propellant consumed so far), determined the gimbal angles needed to point the engine thrust through that CG, and sent commands to the gimbal actuators—electric motors that physically repositioned the engine. This “trim” computation ran continuously during any descent engine burn.


During P66 (the manual landing phase), the gimbal became part of an elegant control synthesis. The commander’s hand controller inputs commanded attitude changes. The DAP computed the jet firings needed to achieve those attitude changes. Simultaneously, the DAP adjusted the engine gimbal to keep the thrust vector through the CG at the new attitude. The commander tilted the spacecraft to fly laterally; the DAP gimbaled the engine to keep the thrust stable. The crew never thought about the gimbal. They didn’t need to.


Coasting Flight: Minimum Impulse and the Deadband

During coast phases—translunar coast, lunar orbit, transearth coast—the spacecraft wasn’t thrusting. Attitude maintenance was a matter of staying within an acceptable orientation band and minimizing propellant consumption. The DAP’s coasting-flight mode was optimized for exactly this.


The key parameter was the deadband width. A wider deadband—say, ±5 degrees—allowed the spacecraft to drift further from the desired attitude before the DAP fired jets to correct it. This saved propellant because fewer corrections were needed. A tighter deadband—say, ±0.5 degrees—held the attitude more precisely but consumed more propellant with more frequent jet firings.


The crew could change the deadband setting through the DSKY, and the width varied by mission phase. During Passive Thermal Control (the “barbecue roll”), where the spacecraft slowly rotated to distribute solar heating, the DAP maintained the roll rate within a deadband while keeping pitch and yaw stable. During navigation star sighting (P52), the deadband was tightened to minimize attitude disturbances during the optical measurement.


The DAP also employed a “minimum impulse” mode for small corrections. When the attitude error was small and the rate was low, the DAP fired jets for the minimum possible duration—typically about 14 milliseconds for the Service Module RCS jets. These minimum-impulse firings applied the smallest possible attitude change, preventing the control system from oscillating around the desired attitude and wasting propellant with alternating jet firings.


The 14-millisecond minimum impulse was a hardware constraint—the minimum time the jet valves could reliably open and close. Below that duration, the fuel flow was unpredictable. The DAP’s software design respected this floor and never commanded shorter firings.


DAP Configuration: Talking to the Autopilot

The DAP wasn’t a fixed program—it was a configurable system that adapted to different mission phases and hardware configurations. The crew and Mission Control configured the DAP through a dedicated DSKY interface: VERB 46 (Establish DAP Configuration) or VERB 48 (Load DAP data), depending on the software version.


Configuration parameters included:


  • Deadband width (wide or narrow)
  • Rate command or minimum impulse mode
  • Jet selection configuration (which jets were available, which were failed)
  • Vehicle weight and moments of inertia (updated as propellant was consumed)
  • Which hand controller the commander was using (attitude or translation)

On the Lunar Module, DAP configuration was particularly important before and during powered descent. The vehicle’s mass properties changed dramatically as the descent engine burned through fuel. The DAP needed updated mass and inertia values to compute correct jet firing durations—if it used stale mass properties, it would over-fire or under-fire the jets, wasting propellant or failing to achieve the desired attitude change.


Mission Control periodically uplinked updated DAP configuration parameters, and the crew verified them before critical maneuvers. A DAP misconfiguration—wrong mass properties, wrong jet configuration—could degrade attitude control enough to affect guidance accuracy during powered descent. This never happened on any Apollo mission, a testament to the procedures and discipline of the flight controllers and crews.


The Manual Override: Rate Command Mode

When an astronaut moved the attitude hand controller, the DAP switched from automatic attitude hold to rate command mode. In this mode, the hand controller deflection commanded a rotation rate, not a position. Push the controller gently to the right, and the spacecraft began rotating to the right at a slow rate. Push it further, and the rate increased. Release the controller, and the DAP fired jets to arrest the rotation and hold the new attitude.


This was an intuitive control mode for pilots. It behaved like a helicopter: stick input commanded a rate of change, and releasing the stick stopped the motion and held position. The DAP computed the appropriate jet firings to produce the commanded rate and to brake the rotation when the controller was released.


During P66 manual landing, the commander used rate command mode continuously. He tilted the hand controller to rotate the LM, directing the thrust vector for lateral translation. Release the controller, and the DAP arrested the rotation. The DAP was doing complex computations behind every controller input—jet selection, firing duration, gimbal adjustment, deadband management—but from the commander’s perspective, the LM just went where he pointed it.


There was also a direct or “hardover” mode, accessible through the Stabilization and Control System (SCS) rather than the AGC, that bypassed the digital autopilot entirely and fired jets directly from the hand controller through relay logic. This was the ultimate backup—no computer, no software, just an electrical connection between the astronaut’s hand and the thruster valves. It consumed propellant rapidly and provided no automatic rate damping, but it would work even if the AGC was completely dead.


Fourteen Milliseconds at a Time

The Digital Autopilot was the most computationally intensive continuous process the AGC ran. It consumed Waitlist task slots for precise jet timing, Executive job capacity for attitude error computation, and output channel bandwidth for jet and gimbal commands. During powered descent, the DAP competed with the guidance equations for processor time—both were essential, both were demanding, and both had to run on the same 1 MHz machine with 2,048 words of RAM.


The DAP’s designers—including the MIT engineers who worked on both the Command Module and Lunar Module versions—made it work through relentless optimization. Jet selection tables were precomputed and stored in rope memory rather than calculated in real time. Phase-plane switching logic used simple comparisons rather than complex math. Minimum-impulse logic prevented control chatter. Deadband management reduced the frequency of jet firings to the minimum needed.


Every Apollo maneuver—from the delicate stationkeeping in lunar orbit to the aggressive attitude changes during powered descent to the slow barbecue roll during translunar coast—was flown by this software. The astronauts commanded; the DAP translated commands into physics, 14 milliseconds at a time.