Course 10 · Flight
Attitude control in six degrees of freedom
Gimbal, fins and cold gas: three ways to produce a torque, and the control loop that decides how much.
Every lesson so far has taken for granted that the vehicle points where it is told. The gravity turn needs the nose on a pitch programme; an insertion burn needs the thrust along the velocity to a fraction of a degree; a landing burn needs the engine pointing straight down at the pad. None of that happens by itself. A rocket is a long, heavy body with no natural wish to point anywhere in particular, and in the atmosphere it actively wants to turn round.
So there are two questions underneath every steering command. How does a rocket produce a turning force at all, and how does its flight computer decide how much of it to use, fifty times a second, without either failing to arrive or overshooting? The first is mechanics; the second is control. Both decide whether a flight program's commands mean anything.
Six degrees of freedom
A rigid body in space has six independent ways to move. Three are translations of its centre of mass — the motion every earlier lesson has been about, set by the total force. Three are rotations about the centre of mass — its attitude, set by the total torque. For a rocket the three rotations have names: pitch and yaw tilt the nose, and roll spins the vehicle about its long axis.
The two halves are coupled only through what the vehicle does with its attitude: where the nose points decides where the thrust goes and how the air meets the body. Otherwise they obey separate laws. For translation, force equals the rate of change of momentum. For rotation, torque about the centre of mass equals the rate of change of angular momentum :
For a rocket, which is symmetric about its long axis, the angular momentum takes a simple form in axes fixed to the body — two transverse axes and the roll axis — because those are its principal axes. With , , the body rates about them, the transverse moment of inertia (the same about both lateral axes) and the roll moment, Euler's equations for the two lateral axes are
and for roll, . The extra terms are the gyroscopic coupling between the axes, and they vanish when the roll rate is zero. That is one reason a launcher holds its roll still: with no roll rate, pitch and yaw are two independent copies of the same one-axis problem, , where is the attitude angle about that axis. The rest of this lesson works on that one axis.
Moments of inertia
The moment of inertia is to rotation what mass is to translation: the resistance to angular acceleration. About an axis through the centre of mass it is the sum over every piece of the vehicle of its mass times the square of its distance from the axis:
The square is what matters. Mass far from the axis counts for far more than mass near it. A rocket is long and thin, so about a transverse axis almost all of its mass is far away — tanks and engines tens of metres from the middle — while about its long axis everything is within a couple of metres. Pieces that are themselves large are handled with the parallel-axis theorem: a part's own moment about its centre plus its mass times the square of that centre's distance from the axis.
The numbers are lopsided. Aster 5, the simulator's Falcon 9-class preset, weighs 563 t on the pad with its centre of mass 31.4 m above its base. Its transverse moment of inertia is kg·m², the equivalent of the whole mass sitting 16.6 m from the centre. Its roll moment is kg·m², seven hundred times smaller. Turning the nose is hard; spinning the vehicle is easy, which is why roll is the axis most easily disturbed and most cheaply held.
Both change through the flight. By max-Q, with 145 t of propellant burned from low in the tanks, the transverse moment is down to kg·m². After separation the upper stage alone has kg·m² and the nearly empty booster kg·m²: fifty times and twenty times less than the stack they came from.
Three ways to make a torque
A torque is a force times its lever arm about the centre of mass. A rocket has three ways to produce one, and they differ enormously in size.
Gimballed engines. The engine is mounted on a two-axis pivot and swung a few degrees, so its thrust no longer passes through the centre of mass. Tilted by , with its pivot a distance behind the centre of mass, it gives
It is by far the strongest actuator, and it works in vacuum and in air alike, but only while the engine is burning, and only in proportion to its thrust. A single engine cannot control roll; a cluster can, by swinging opposite engines opposite ways.
Aerodynamic surfaces. Fins or grid fins deflected by make a normal force — dynamic pressure times the fin area times the slope of its normal-force coefficient — at a lever arm :
They need no propellant and work with the engines off, but only where there is air, and their authority rises and falls with exactly as the previous lesson's loads did.
Reaction control thrusters. Small cold-gas jets, fired in opposing pairs so that they make a pure torque with no net force. A pair of thrusters of thrust at lever arm gives . They work anywhere, but they are tiny, and every firing spends a gas supply that is not replenished.
For Aster 5 the difference in scale is the whole story:
| Actuator | Torque | Angular acceleration |
|---|---|---|
| Nine engines, 5° of gimbal, 29.1 m lever, at liftoff | 19.3 MN·m | 0.123 rad/s² (7.1°/s²) |
| One pair of 911 N cold-gas thrusters, 14.6 m lever, same stack | 13.3 kN·m | 0.000085 rad/s² |
| Booster's grid fins, 20° at 20 kPa subsonic, 29.1 m lever | 1.47 MN·m | 0.19 rad/s² |
| Booster's cold-gas thrusters, 29.5 m lever | 26.9 kN·m | 0.0034 rad/s² |
On the pad the gimbal is 1,450 times stronger than the thrusters: on cold gas alone the full stack would need 45 s just to tilt by 5°, and as long again to stop. After separation, the nearly empty booster on cold gas alone accelerates at 0.195°/s², so a 180° flip done as fast as possible — accelerate half way, brake the other half — takes s. Falling back through the air with its grid fins out at 20 kPa, the same booster has fifty times that angular acceleration. Each actuator has its place: the gimbal whenever the engine is lit, fins in air, cold gas in vacuum with the engines off.
Why a rocket is unstable
An arrow flies point-first because its feathers are behind its centre of mass. If the arrow yaws, the air pushes on the feathers harder than on the head and swings it back. The point where the total aerodynamic force effectively acts is the centre of pressure, and an arrow is stable because its centre of pressure is behind its centre of mass.
A launcher with no fins has it the other way round. Slender-body theory gives a pointed nose meeting the air at an angle of attack a sideways force of about , with the nose's base area, and that force acts near the very front of the vehicle. The cylindrical body adds more, distributed along its length. The centre of pressure ends up ahead of the centre of mass, and any angle of attack makes a moment that increases it. Linearised about flying straight into the wind,
where is the slope of the aerodynamic moment with angle of attack. The disturbance grows exponentially. For Aster 5 at max-Q the simulator's model gives s⁻², so s⁻¹: a small disturbance grows by a factor of every 2.2 s, and doubles every 1.5 s, until the bending load breaks the vehicle up.
Launchers are built this way on purpose. Fins big enough to make a vehicle of this length stable would be heavy, would add drag, and would make it weathervane — turn into every crosswind, bending its trajectory — which is not wanted either. It is lighter to accept the instability and fly the vehicle with the gimbal. That makes the control loop essential: without it the vehicle does not merely drift, it diverges.
A controller from the ground up
The flight computer has a commanded attitude , a measured attitude and a measured rate from its gyroscopes. It must choose a torque, every step, that brings to and holds it there. Start with the simplest rule and see what goes wrong.
Proportional: a spring
Make the torque proportional to the error :
That is a mass on a spring. It moves towards the command, but nothing takes the kinetic energy out, so it overshoots by as much as it started away and oscillates for ever, at the frequency . A larger gain makes it swing faster, not settle.
Derivative: a damper
Add a torque that opposes the rate, . That is a damper beside the spring:
with the natural frequency and damping ratio
This is the PD controller: proportional plus derivative. Its behaviour is set by those two numbers, and sorts it into three regimes. Solutions of this equation go as with .
- Underdamped, . The roots are complex: the response overshoots and rings down, oscillating at inside an envelope . The first overshoot, as a fraction of the step, is : 37 % at , 16 % at 0.5, 4.6 % at 0.7.
- Critically damped, . The fastest response that never overshoots.
- Overdamped, . Two real roots, one of them slow. It creeps in without overshooting, and takes a long time about it.
A step settles to within 2 % in about . For most attitude loops a damping ratio near 0.7 is the practical choice: a few per cent of overshoot, in return for the quickest settling.
The derivative acts on the measured rate, not on the rate of change of the error. When the command steps, the error jumps, and differentiating it would give an instantaneous kick to the actuator; the gyroscope's rate has no such jump. It is also the number the sensors deliver directly.
The unstable airframe
In the atmosphere the plant has an extra term, the airframe's own divergent moment. With the angle of attack measured from the relative wind, and per unit inertia,
The aerodynamics subtracts from the spring. The loop is stable only if — the controller's stiffness must beat the airframe's divergence — and its natural frequency is now . It also no longer ends where it was told. At rest the two terms balance and
With s⁻² and Aster 5's s⁻², the vehicle settles at 1.26 times the commanded angle of attack. There are two cures. An integral term, the I of a PID controller, accumulates the remaining error and pushes until it is gone. Or the controller can cancel the moment it knows about: if it has a model of the airframe's aerodynamics it adds to its request, the feed-forward, and feedback only has to deal with what the model got wrong.
Why the gains cannot be anything
Stiffer and faster looks better on paper. Real hardware sets the limits.
- Saturation. The gimbal has a stop. At max-Q Aster 5's five degrees give at most 0.125 rad/s², so a 4° step saturates the actuator at the first instant once exceeds 1.8 s⁻². A saturated loop is no longer linear, and it overshoots more than its gains suggest.
- Actuator rate. The Merlin gimbal slews at 15°/s: from one stop to the other takes two thirds of a second. A loop that asks for faster changes than that gets its torque late, and a late torque turns damping into driving.
- The structure and the propellant. A real launcher bends at a few hertz and its propellant sloshes. A high-gain loop reads those motions as attitude errors and can drive them. Real flight software filters them out and keeps its bandwidth below them.
- Sensing and time. Measurements are noisy and arrive at a fixed rate, 50 Hz in the simulator. Derivative gain amplifies noise.
A worked example: sizing the loop for Aster 5
On the pad, Aster 5's gimbal gives 0.123 rad/s² at full deflection. To keep the controller linear for errors up to 5°, the proportional term alone must not ask for more than that at 5°, 0.087 rad: s⁻², so rad/s. With that loop would settle in about s and overshoot by 4.6 %.
Vivapse's own autopilot chooses more gently. It takes 60 % of the available angular acceleration as its working authority — 0.074 rad/s² here — and sets a gain s⁻¹. In its linear region that is a PD loop with s⁻² and s⁻¹: rad/s and , the same damping ratio for every vehicle, with 1.7 % overshoot and a two-per-cent settling time of about 10 s. Planning on 60 % of the authority keeps the rest in hand for gusts, engine misalignment and the airframe.
At max-Q the same vehicle's divergence rate is s⁻¹. That base loop, with against , would be left with an effective stiffness of 0.06 s⁻² and would hold a commanded angle of attack at four times its intended value. The autopilot does not fly it that way: in realistic fidelity it cancels a modelled aerodynamic moment, and within half a degree of the command it stiffens the loop so that its natural frequency is at least twice , 0.91 rad/s. The figure lets you see what each of those choices is for.
Figure · a step in attitude
- RESPONSE
- Crisp
- NATURAL FREQUENCY ωₙ
- 1.00 rad/s
- DAMPING RATIO ζ
- 0.70
- OVERSHOOT
- 5 %
- SETTLES (±5 %)
- 3.0 s
- HOLDS
- 4.00°
- PEAK GIMBAL
- 2.5°
With no air, the Crisp gains (, , ) settle in 3 s with a 4.6 % overshoot, exactly as the formula said. The Oscillatory gains keep the stiffness and remove the damping: 70 % overshoot and still ringing twenty seconds later. The Sluggish gains are overdamped and take 17 s. The Autopilot gains are gentle — 6 s, barely any overshoot, and a small gimbal deflection throughout.
Now switch to max-Q with feedback only. The Crisp loop settles at 5.0°, not 4°: the airframe's moment is taking a quarter of the stiffness. The Autopilot's gentle base loop, left to fight the airframe unaided, drifts until the bending load breaks the vehicle up after nine seconds. Add feed-forward and every response returns to what it was in vacuum — for as long as the model of the airframe is right. Push above 1.8 and watch the gimbal trace hit its stops.
In Vivapse
The simulator integrates all six degrees of freedom. src/sim/vehicle.ts carries
the attitude as a quaternion — four numbers which, unlike three angles, have no
orientation where they break down — integrates the body rates with
exactly the Euler equations above, , and computes the
mass properties every step: thin shells for the tanks, solid columns for the
propellant settled at the bottom of each tank, point masses for engines, legs and
fins, all put together with the parallel-axis theorem. Its torques are the three
actuators: the thrust at the gimbal angle, , on the stage's
engine layout; the grid fins' normal force at their station; cold-gas couples at
the thruster ring, each thruster 68 N times the square of the stage diameter in
metres, with an Isp of 70 s — or, in realistic fidelity, hot-gas thrusters three
times stronger on steel methalox stages. It also includes jet damping, the small
rotational drag of exhaust that carries angular momentum away.
The built-in autopilot is src/sim/autopilot.ts, and fc.steer() hands it a
command. It is a cascade of two loops. The outer one turns the pointing error
into a desired rate, : linear for small
errors; the fastest rate from which it can still brake to a stop in the remaining
angle at acceleration for larger ones; and never more than 17°/s. The inner one
turns the rate error into a torque, , and
allocates it in order — gimbal first, then fins, then cold gas — within each
actuator's real authority. For small errors the cascade is exactly the PD loop of
the worked example. Roll is held separately, with a dead band of 1.5° so that a
vehicle that is already rolled correctly spends no gas. In realistic fidelity it
adds the modelled aerodynamic feed-forward, the stiffness floor of twice the
divergence rate within half a degree of the command, and a slow integral trim with
anti-windup for the steady torques nobody modelled, such as a misaligned engine.
What the simulator does not have is a flexible airframe or sloshing propellant;
the vehicle is a rigid body, and fidelity and its limits lists
what that leaves out. A program that wants to fly its own loop can:
fc.control({ gimbal, rcs, fins }) commands the actuators directly and switches
the autopilot off until the next fc.steer(), and the sandbox provides a PID
helper for the purpose. Both are in the flight computer
reference, and steering and guidance covers
the pitch and yaw the autopilot is asked to hold.
Try it
Replace the autopilot with your own PD loop for the first two minutes of an ascent. Choose the Aster 5 preset, launch from Cape Canaveral on custom weather with no wind, and use this as the whole program:
let phase = 'pad', lastYaw = 0;
function update(fc) {
if (phase === 'pad') { fc.throttle(1); fc.steer(90); fc.ignite(); phase = 'up'; }
const kp = 0.5, kd = 1.0; // degrees of gimbal per degree, and per degree/s
const target = fc.surfaceSpeed > 100 ? Math.min(85, fc.airPrograde) : 90;
const yawRate = (fc.yaw - lastYaw) / fc.dt; // there is no fc.yawRate: difference it
lastYaw = fc.yaw;
if (fc.t > 5) {
const pitch = kp * (target - fc.pitch) - kd * fc.pitchRate;
const yaw = kp * fc.yaw + kd * yawRate; // the yaw gimbal turns the nose the other way
fc.control({ gimbal: { pitch: clamp(pitch, -5, 5), yaw: clamp(yaw, -5, 5), roll: 0 }, rcs: 0, fins: 0 });
}
}
The gains are in degrees of gimbal per degree of error, and per degree per
second. On this vehicle each radian of gimbal deflection gives about 1.4 rad/s²
of angular acceleration (), so and mean
s⁻² and s⁻¹: a loop with
rad/s and . It flies the vehicle through
max-Q with the angle of attack under a degree. Set kd = 0 and the nose swings
several degrees either side of the target with a period of several seconds. Set
kp = 0.15 and it lags the relative wind by a degree or two, and the bending load
climbs towards 60 kPa·°.
Then remove the yaw channel — pass gimbal: clamp(pitch, -5, 5), a single number,
which commands pitch only. Nothing now holds the yaw axis, and it is as unstable
as the pitch axis was. The nose wanders out of the plane, slowly and then quickly —
three quarters of a degree by T+30 s, seven degrees by T+40 s — and about 43
seconds after liftoff the console reports an aerodynamic break-up: a bending load
of 251 kPa·° at 21 kPa and nearly 12° of angle of attack. That is at
work, on the axis you stopped controlling.
What carries forward
The autopilot is what makes a steering command mean something. Every later lesson relies on it: the guidance laws that follow decide what attitude to ask for and trust this loop to deliver it within a fraction of a degree. Powered descent guidance asks the most of it, pointing a single engine at exactly the right angle, all the way down, with no second chances.