Guidance, Navigation and Control · Theory · M11
M11-T5 — Ascent Guidance and Control
A launcher climbs through the densest air of its flight while pushing against it. The path is set by a few angles early on, and the control loop is shaped by modes of the structure that the guidance never mentions.
Reaching orbit is a long guided climb whose first two minutes are dominated by the atmosphere. The vehicle rises vertically, tips over slightly, and then lets its own velocity vector steer it: a gravity turn, which keeps the angle of attack near zero and so keeps the aerodynamic loads low. This lesson simulates such an ascent for the first stage of a small orbital launcher (maximum dynamic pressure of 28.6 kPa at 47 s, burnout at 83 km and 2.07 km/s), shows how a small pitch kick sets the whole path, computes the side load a wind gust adds, and explains the structural modes, bending and propellant slosh, that decide the control bandwidth: a 4 Hz bending mode that makes an unfiltered loop unstable and a notch that cures it.
Learning objectives
After this lesson, you should be able to:
- Describe the phases of a launcher ascent and the purpose of the gravity turn.
- Simulate a gravity turn and read the maximum dynamic pressure, the burnout state and the effect of the pitch kick.
- Compute the angle of attack and the side load that a wind gives, and explain load relief.
- Explain how a bending mode destabilizes an attitude loop and how a notch filter or gain stabilization handles it.
The intuition
UAV M5-T15: Guidance and control integration shows how a guidance command and an attitude loop are joined on a multirotor, and the loops of M1-T2: Nested Loops and Separation of Timescales are separated in bandwidth in the same spirit. A launcher is the extreme case: the dynamics change by an order of magnitude as it ascends, the atmosphere pushes on it hard, and its structure is flexible enough to appear in the loop. Hopper is a launcher in miniature (a gimballed engine on a vertical vehicle), and everything about its pitch loop in earlier modules is this problem at low speed. This lesson stays at the level of an orbital launcher's first stage, which is textbook aerospace content.
The path: vertical, kick, then turn with the flow
A launcher leaves the pad vertically so that it clears the tower and climbs out of the thickest air as fast as possible. After a few seconds it is given a small pitch kick, a deliberate tilt of one or two degrees, and from then on the pitch is commanded to follow the velocity vector: thrust along the relative velocity, which makes the angle of attack zero and the aerodynamic side force zero. Gravity then bends the path over by itself: the flight path angle falls as (thrust and drag do not turn the vector). The kick sets the whole path. For the example stage (40 000 kg, 650 kN, 120 s of burn) kicks of 0.5°, 1°, 2° and 4° give burnout flight path angles of 87.2°, 84.3°, 78.7° and 67.7° above the horizontal, and downranges of 3.2, 6.4, 12.7 and 25.0 km, while the burnout altitude changes only from 83.9 to 80.7 km and the speed from 2067 to 2097 m/s.
The atmosphere sets the loads
The dynamic pressure rises as the vehicle accelerates and falls as the air thins, reaching a maximum, max q, of 28.5 kPa at 47 s at 8.5 km and 390 m/s; it hardly depends on the kick. The aerodynamic side force is : zero on the gravity-turn path in still air, but a wind of 20 m/s across the path at max q gives an angle of attack of 2.9°, a of 83 800 Pa deg and a side force of 20.5 kN (with a normal-force slope of 2 per radian). The structure is designed for a bounded , and a pitch programme computed in advance cannot know the wind, so wind-biased programmes, or load relief (feedback of the measured angle of attack or lateral acceleration to turn into the wind), limit it.
After the atmosphere
Once the air is thin (above about 60 km) the loads no longer matter and the guidance changes: from a stored pitch programme to a closed-loop law that steers to the target orbit, like the explicit guidance of M8-T3: Explicit Guidance to a Terminal State generalized to orbital conditions, with the pitch commanded by the position and velocity error to the target.
Structure in the loop
The rigid-body loop of a launcher is an unstable plant (aerodynamic instability, per second squared) with a PD controller crossing at about 2 rad/s. A real vehicle is a long thin tube with a lightly damped first bending mode, at 4 Hz in the example. A gyro at some point on the vehicle senses the bending as well as the rigid rotation. In the example the loop gain at the bending frequency is 4.6, far above one, and the closed loop is unstable (a pole at +0.45 per second). A notch filter at the bending frequency brings the gain at that frequency to 0.33 and the loop becomes stable. Slosh, the motion of the propellant surface, has a frequency near 0.6 Hz for the illustrative tank and moves as the acceleration and the fill level change: it lies close to the control bandwidth, so it is handled by phase stabilization or by baffles, not by a notch.
The path of a launcher is set early by one small kick, and then by gravity. The loads are set by dynamic pressure times angle of attack, so the guidance keeps the angle of attack small. The control bandwidth is limited by structure: bending is notched, slosh is phase-stabilized.
Definitions
- Gravity turn
- A trajectory with the thrust along the air-relative velocity, so that the angle of attack is zero; gravity alone turns the flight path.
- Max q
- The maximum of the dynamic pressure along the trajectory.
- q alpha
- The product of the dynamic pressure and the angle of attack, proportional to the lateral aerodynamic load; limited by the structure.
- Load relief
- Guidance or control that reduces the angle of attack (or lateral acceleration) in a wind to reduce the load.
- Bending mode and slosh
- The lowest flexible mode of the structure, and the oscillation of the propellant surface; both enter the attitude loop.
Derivation: why the angle of attack is zero on a gravity turn, and the bending instability
The equations of a point mass with thrust along the velocity.
Force balance along and across the velocity in a vertical plane (flat Earth for brevity), with thrust inclined at the angle of attack α to the velocity and lift L.
On a path with zero angle of attack there is no thrust or aerodynamic force across the velocity, so the only turning force is gravity.
At low speed after the kick the turn rate is high; as the vehicle accelerates the term falls and the path flattens only slowly: the vehicle ends high and steep unless the kick is large (87° to 68° for kicks of 0.5° to 4°).
A wind makes the air-relative velocity differ from the vehicle's axis: the angle of attack is the crosswind over the airspeed, and the normal force is its aerodynamic product.
The bending mode in the loop
The rigid plant plus one lightly damped bending mode with relative residue κ at the sensor.
At resonance the bending term has a gain of times its static value, which for is 100: the peak is large although the mode is a small part of the response.
The controller's gain at 25 rad/s multiplies the resonance: with the product is above unity, and the phase at the peak decides whether the loop is unstable: here it is, with a pole at +0.45 per second.
A notch with zeros at the bending frequency (damping 0.05) and poles with more damping (0.7): the gain at is of the original.
A zero-angle-of-attack path is the one on which only gravity turns the vehicle, and its loads are the lowest. A lightly damped flexible mode multiplies the loop gain by 1/(2ζ) at its frequency, which is why a notch or a gain roll-off is needed at the bending frequency.
A worked example
An illustrative orbital launcher first stage: 40 000 kg at liftoff, 650 kN of thrust (thrust to weight 1.66), specific impulse 285 s, 232.6 kg/s, burn time 120 s, drag coefficient 0.30 on 7 m².
- The path. Vertical for 10 s, a 2 s pitch kick, then thrust along the velocity. Kicks of 0.5°, 1°, 2° and 4° give max q of 28.5, 28.5, 28.6 and 28.9 kPa at about 47 s (8.5 km, 390 m/s).
- Burnout. Altitude 83.9, 83.7, 83.1, 80.7 km; speed 2067, 2069, 2074, 2097 m/s; flight path angle 87.2°, 84.3°, 78.7°, 67.7°; downrange 3.2, 6.4, 12.7, 25.0 km.
- Wind at max q. Crosswinds of 10, 20 and 40 m/s give angles of attack of 1.47°, 2.93° and 5.84°, of 41 900, 83 800 and 167 100 Pa deg, and side forces of 10.2, 20.5 and 40.8 kN against a thrust of 650 kN.
- The attitude loop. and a 4 Hz bending mode (damping 0.005, residue −0.8): the rigid loop gain is 1.43, 1.12, 0.68, 0.36 at 0.5, 1, 2, 4 rad/s. At the bending frequency the unfiltered loop gain is 4.59 and the closed loop has a pole at +0.453 per second (unstable); with a notch the gain is 0.33 and the largest pole real part is −0.087 (stable).
- Slosh. An equivalent pendulum of length 1.2 m (illustrative) under 2 g has a frequency of 4.0 rad/s (0.64 Hz), twice the 2 rad/s control bandwidth, and it shifts with acceleration and fill level.
import math
import gnckit as g
MU, RE = 3.986004418e14, 6378137.0
G0 = 9.80665
# an illustrative small orbital launcher first stage
M0, THRUST, ISP, MPROP = 40000.0, 650e3, 285.0, 27900.0
CD, SREF = 0.30, 7.0
RHO0, HS = 1.225, 7200.0
mdot = THRUST / (ISP * G0)
tburn = MPROP / mdot
print(f'first stage: liftoff mass {M0:.0f} kg, thrust {THRUST / 1e3:.0f} kN (thrust to weight {THRUST / (M0 * G0):.2f}), mass flow {mdot:.1f} kg/s, burn time {tburn:.0f} s')
def ascent(kick_deg, t_vertical=10.0, kick_time=5.0, wind=0.0, dt=0.05):
"""Planar point-mass ascent in polar coordinates. Vertical rise, a short pitch kick, then a gravity turn: thrust along the relative velocity (zero angle of attack)."""
r, ang = RE, 0.0
vr, vt = 0.0, 0.0 # radial and tangential (inertial) speed components
m = M0; t = 0.0
gamma = math.pi / 2 # flight path angle above the local horizontal
maxq = (0.0, 0.0, 0.0, 0.0); qa_max = 0.0
kicked = False
pitch = math.pi / 2
while t < tburn:
h = r - RE
# velocity relative to the rotating atmosphere is ignored; wind enters as a horizontal air velocity
vrel_t = vt - wind if wind else vt
V = math.hypot(vr, vrel_t)
rho = RHO0 * math.exp(-h / HS)
q = 0.5 * rho * V * V
if t < t_vertical:
pitch = math.pi / 2
elif t < t_vertical + 2.0 and not kicked:
pitch = math.pi / 2 - math.radians(kick_deg)
if t > t_vertical + 1.9: kicked = True
else:
pitch = math.atan2(vr, vrel_t) # gravity turn: thrust along the relative velocity
gam = math.atan2(vr, vrel_t) if V > 1.0 else math.pi / 2
alpha = pitch - gam
D = q * SREF * CD
ar_th = THRUST / m * math.sin(pitch); at_th = THRUST / m * math.cos(pitch)
ar_d = -D / m * math.sin(gam) if V > 1 else 0.0; at_d = -D / m * math.cos(gam) if V > 1 else 0.0
gr = -MU / (r * r)
ar = ar_th + ar_d + gr + vt * vt / r
at = at_th + at_d - vr * vt / r
vr += ar * dt; vt += at * dt
r += vr * dt; ang += vt / r * dt
m -= mdot * dt; t += dt
if q > maxq[0]: maxq = (q, t, h, V)
qa_max = max(qa_max, abs(q * alpha))
h = r - RE
V = math.hypot(vr, vt)
return dict(h=h, V=V, gamma=math.degrees(math.atan2(vr, vt)), downrange=ang * RE, maxq=maxq, qa=qa_max, m=m, vt=vt, vr=vr)
t_vertical = 10.0
print('gravity turn: vertical rise for 10 s, a 2 s pitch kick, then thrust along the velocity; burnout at the end of the stage')
print(' kick (deg) max q (kPa) at (s, km, m/s) burnout: altitude (km), speed (m/s), flight path angle (deg), downrange (km)')
for kick in (0.5, 1.0, 2.0, 4.0):
r_ = ascent(kick)
q, tq, hq, Vq = r_['maxq']
print(f' {kick:6.1f} {q / 1e3:6.1f} at ({tq:5.1f}, {hq / 1e3:5.1f}, {Vq:5.0f}) {r_["h"] / 1e3:8.1f} {r_["V"]:7.0f} {r_["gamma"]:6.1f} {r_["downrange"] / 1e3:7.1f}')
print(' the kick sets the whole path: a small kick leaves the vehicle high and steep at burnout, a large one low and shallow')
print('Wind and load relief: the gravity-turn path has zero angle of attack in still air; a wind gust at max q makes alpha = wind / airspeed')
r_ = ascent(2.0)
q, tq, hq, Vq = r_['maxq']
for wind in (10.0, 20.0, 40.0):
alpha = math.atan2(wind, Vq)
print(f' a {wind:4.0f} m/s crosswind at max q ({q / 1e3:.1f} kPa, {Vq:.0f} m/s): angle of attack {math.degrees(alpha):4.2f} deg, q alpha = {q * math.degrees(alpha):7.0f} Pa deg, normal force {q * SREF * 2.0 * alpha / 1e3:5.1f} kN for a normal-force slope of 2 per rad')
print(f' thrust is {THRUST / 1e3:.0f} kN, so a lateral aerodynamic force of that order is a real load on the structure; an open-loop pitch programme cannot know the wind, which is why the programme is biased or the angle of attack is limited (load relief)')
# bending mode and notch
print('Attitude control through the atmosphere: rigid body plus one bending mode')
mua, muc = 1.5, 1.2 # aerodynamic instability (1/s^2) and control effectiveness (1/s^2 per rad of gimbal)
Kp, Kd = 2.0, 1.2 # PD attitude controller on the gimbal
wb, zb, kappa = 2 * math.pi * 4.0, 0.005, -0.8 # bending mode at 4 Hz, lightly damped; kappa: its residue relative to the rigid body at the sensor
poly = g
def pmul(*ps):
out = [1.0]
for p in ps: out = g.poly_mul(out, p)
return out
rigid_den = [1.0, 0.0, -mua]
bend_den = [1.0, 2 * zb * wb, wb * wb]
plant_num = [muc * c for c in g.poly_add(bend_den, [kappa * c for c in rigid_den])]
plant_den = pmul(rigid_den, bend_den)
ctrl_num = [Kd, Kp]
def margins_and_poles(notch):
if notch:
nn = [1.0, 2 * 0.05 * wb, wb * wb]; nd = [1.0, 2 * 0.7 * wb, wb * wb]
num = pmul(plant_num, ctrl_num, nn); den = pmul(plant_den, nd)
else:
num = pmul(plant_num, ctrl_num); den = plant_den
# closed loop 1 + L = 0
char = g.poly_add(den, num)
roots = [complex(r) for r in g.poly_roots(char)]
worst = max(r.real for r in roots)
# frequency response gain at the bending frequency
s = 1j * wb
L = g.poly_val(num, s) / g.poly_val(den, s)
return worst, abs(L), roots
for notch in (False, True):
worst, Lb, roots = margins_and_poles(notch)
print(f' {"with a notch at the bending frequency" if notch else "no filter "}: |L| at {wb / 2 / math.pi:.0f} Hz = {Lb:5.2f}; largest closed-loop pole real part {worst:+.3f} 1/s ' + ('(UNSTABLE)' if worst > 0 else '(stable)'))
print(' the rigid-body loop alone (crossover):')
for w in (0.5, 1.0, 2.0, 4.0):
s = 1j * w
Lr = muc * (Kd * s + Kp) / (s * s - mua)
print(f' |L(j{w})| = {abs(Lr):.2f}')
omega_slosh = math.sqrt(G0 * 2.0 / 1.2)
print(f'slosh: an equivalent pendulum of length 1.2 m (illustrative) in a tank under an axial acceleration of 2 g of frequency sqrt(a / l) = {omega_slosh:.1f} rad/s ({omega_slosh / 2 / math.pi:.2f} Hz) , {omega_slosh / 2:.1f} times the 2 rad/s control bandwidth, and it shifts as the acceleration and the fill level change')first stage: liftoff mass 40000 kg, thrust 650 kN (thrust to weight 1.66), mass flow 232.6 kg/s, burn time 120 s
gravity turn: vertical rise for 10 s, a 2 s pitch kick, then thrust along the velocity; burnout at the end of the stage
kick (deg) max q (kPa) at (s, km, m/s) burnout: altitude (km), speed (m/s), flight path angle (deg), downrange (km)
0.5 28.5 at ( 47.1, 8.5, 390) 83.9 2067 87.2 3.2
1.0 28.5 at ( 47.1, 8.5, 390) 83.7 2069 84.3 6.4
2.0 28.6 at ( 47.2, 8.5, 391) 83.1 2074 78.7 12.7
4.0 28.9 at ( 47.6, 8.6, 396) 80.7 2097 67.7 25.0
the kick sets the whole path: a small kick leaves the vehicle high and steep at burnout, a large one low and shallow
Wind and load relief: the gravity-turn path has zero angle of attack in still air; a wind gust at max q makes alpha = wind / airspeed
a 10 m/s crosswind at max q (28.6 kPa, 391 m/s): angle of attack 1.47 deg, q alpha = 41916 Pa deg, normal force 10.2 kN for a normal-force slope of 2 per rad
a 20 m/s crosswind at max q (28.6 kPa, 391 m/s): angle of attack 2.93 deg, q alpha = 83778 Pa deg, normal force 20.5 kN for a normal-force slope of 2 per rad
a 40 m/s crosswind at max q (28.6 kPa, 391 m/s): angle of attack 5.84 deg, q alpha = 167120 Pa deg, normal force 40.8 kN for a normal-force slope of 2 per rad
thrust is 650 kN, so a lateral aerodynamic force of that order is a real load on the structure; an open-loop pitch programme cannot know the wind, which is why the programme is biased or the angle of attack is limited (load relief)
Attitude control through the atmosphere: rigid body plus one bending mode
no filter : |L| at 4 Hz = 4.59; largest closed-loop pole real part +0.453 1/s (UNSTABLE)
with a notch at the bending frequency: |L| at 4 Hz = 0.33; largest closed-loop pole real part -0.087 1/s (stable)
the rigid-body loop alone (crossover):
|L(j0.5)| = 1.43
|L(j1.0)| = 1.12
|L(j2.0)| = 0.68
|L(j4.0)| = 0.36
slosh: an equivalent pendulum of length 1.2 m (illustrative) in a tank under an axial acceleration of 2 g of frequency sqrt(a / l) = 4.0 rad/s (0.64 Hz) , 2.0 times the 2 rad/s control bandwidth, and it shifts as the acceleration and the fill level changeIn robotics
The structure of this lesson is the structure of every launch vehicle's guidance and control.
- Pitch programmes. The first stage flies a stored pitch programme (angle against time) designed from trajectory optimization with load constraints, because the atmosphere's winds are not known in time to close a guidance loop. The programme is revised from the day-of-launch wind balloons.
- Closed-loop guidance. Above the atmosphere the guidance steers to the orbit insertion state with a law of the family of the explicit guidance of module 8 (and, for convexified problems, of module 9), recomputed continuously; the engine cut-off time is set when the target velocity is reached.
- Load relief. Some vehicles feed back the measured angle of attack or the lateral acceleration to steer into the wind (a drift-minimum or load-relief mode) at max q; the notch and the gain schedule of the attitude loop are checked across the wind dispersions.
- Structural filtering. The bending frequency changes with propellant mass, so the notch is scheduled or wide; a gyro located near a mode anti-node reduces the residue κ; and the whole loop is checked with the flexible model in the margin analysis of module 3 and the disk-margin of module 5.
- Hopper. The structure in the loop is a smaller version of the same problem: the gimbal and servo of the pitch loop are the first flexible element, and the margin analysis of module 3 with the 40 rad/s servo is the same procedure as the filter design here.
The attitude half of the problem in space is M11-T4: Attitude Control with Wheels and Thrusters. The loop margins with a delay and a servo are M10-T5: Handling Qualities, Margins and Envelope Protection; the capstone M12-L2: Capstone: Land Hopper uses a guidance law of this family.
Common misconceptions
“A launcher flies straight up and turns when it is high enough.”
It rises vertically only a few seconds, then a small kick (0.5° to 4°) is applied and gravity bends the path; the burnout flight path angle (87° to 68°) depends strongly on the kick.
“Maximum dynamic pressure depends on how the vehicle pitches.”
It hardly does (28.5 to 28.9 kPa for kicks of 0.5° to 4°). It is set by the thrust-to-weight and the atmosphere, and the pitch programme controls the angle of attack, not the dynamic pressure.
“A wind only matters when it is strong.”
The side force is proportional to qα, and at max q even a 10 m/s crosswind gives 1.5° and 10 kN: a moderate wind is a structural load that the programme must plan for.
“A flexible structure only adds small ripples to the loop.”
A lightly damped mode has a resonance gain of 1/(2ζ); with ζ = 0.005 it is 100, and the unfiltered loop gain at 4 Hz was 4.6 and unstable. The rigid-body loop can be perfectly good and the vehicle lost to the bending mode.
“A notch filter solves slosh as well.”
Slosh is at 0.6 Hz in the example, near the 2 rad/s control bandwidth, and moves with acceleration and fill level. A notch there would cost too much phase, so slosh is handled by baffles or phase stabilization.
Key takeaways
- A launcher rises vertically, takes a small pitch kick, then follows a gravity turn with thrust along the velocity (zero angle of attack).
- The kick sets the path: 0.5° to 4° gives burnout flight path angles of 87° to 68° and downranges of 3 to 25 km, while max q (28.5 kPa) and burnout speed change little.
- Side load is qSC_Nα α: a 20 m/s crosswind at max q gives 2.9° and 20.5 kN.
- A lightly damped bending mode multiplies the loop gain by 1/(2ζ) at its frequency: the unfiltered loop gain was 4.6 and the loop unstable.
- A notch at the bending frequency reduces the gain to 0.33 and stabilizes the loop.
- Slosh lies near the control bandwidth and moves with the flight, so it is handled by baffles and phase stabilization.
References and further reading
Each source is marked free or paid. Free to read does not mean free to reuse: the course resources page lists every source with its licence.
- J. H. Blakelock, Automatic Control of Aircraft and Missiles, 2nd edition, Wiley, 1991, the chapters on launch-vehicle control and structural filtering. Paid.
- R. D. Braun and R. M. Manning, "Mars exploration entry, descent and landing challenges", Journal of Spacecraft and Rockets 44(2), 2007, which also summarizes launch-vehicle design practice. Paid (AIAA).
- NASA SP-8036, Effects of Structural Flexibility on Launch Vehicle Control Systems, 1970. Free to read from the NASA Technical Reports Server; US government work.
- MIT 16.851 Satellite Engineering (OpenCourseWare) , which covers launch environments and vehicle performance. Free; licence CC BY-NC-SA 4.0.
Knowledge check
Three questions. Write an answer, then reveal the explanation. Your answers stay in your browser.
Question 1
A stage has a pitch kick of 2° and, with the gravity turn, burns out at 78.7° above the horizontal. What would a 4° kick change, and what stays about the same?
Explanation
A 4° kick flattens the path: burnout flight path angle 67.7°, downrange 25.0 km instead of 12.7 km, and altitude 80.7 km instead of 83.1 km. The speed (2097 against 2074 m/s) and max q (28.9 against 28.6 kPa) change by only 1%, since they are set by the thrust-to-weight and the atmosphere. The pitch kick therefore moves where the stage is going, not how hard the atmosphere pushes on it.
Question 2
Compute the angle of attack and side force that a 30 m/s crosswind gives at max q (391 m/s, 28.6 kPa) for a normal-force slope of 2 per radian on 7 m².
Explanation
α = atan(30/391) = 0.0766 rad = 4.39°. The side force is q S CNα α = 28 600 × 7 × 2 × 0.0766 = 30.7 kN. That is 4.7% of the thrust (650 kN) and acts at the centre of pressure ahead of the centre of mass, producing a moment which the attitude loop must resist; the structure must carry the load whether or not the controller turns into the wind.
Question 3
Why can the rigid-body loop be good and the vehicle still unstable?
Explanation
The attitude loop crosses over at about 2 rad/s, where the rigid model is accurate, but the gyro also senses the bending mode at 25 rad/s. A lightly damped mode has a resonant gain of 1/(2ζ), here 100 times its static value, so the controller's gain at that frequency times the resonance is 4.6, above 1, and with the phase of the mode the closed loop is unstable (a pole at +0.45 per second). The rigid-body analysis cannot show it; the flexible model must be in the loop analysis, and the notch removes the resonance.
What’s next
Related content
Nothing below is required to finish this lesson.
- BeforeM11-T4: Attitude Control with Wheels and Thrusters
Design a quaternion-feedback law, account for wheel torque and momentum limits, unload momentum, and design a thruster phase-plane controller.
Other courses on this site treat neighbouring topics from their own angle:
- UAV M5-T4: Quaternion-based orientation
- UAV M5-T5: Attitude control
- Linear Algebra M7-T4: SO(3)
- Linear Algebra M10-T4: The Exponential Map
- SLAM M2-T3: Rotation Matrices, Quaternions, and Pose Representation
This course leaves the following to the pages that already teach them:
- Quaternion algebra and the rotation group
- Mission design, launch windows and interplanetary transfers (outside the scope of this site)
- Structural, thermal and propulsion design (outside the scope of this site)
Get notified when the next lesson and new labs are released.
One email per new lesson or lab.