PID Control Design (gnc-autonomy/control/pid-control-design)
Use when the task is PID controller design for an aerospace flight or
GNC loop: computing the output from the proportional, integral, and
derivative error terms, deriving gains from the plant model (first or
second order) by Ziegler-Nichols tuning or pole placement, protecting
the integrator with anti-windup clamping, or checking the loop's gain
and phase margins.
Domain quick reference
- The PID output is u = kpe + kiint(e) + kd*de/dt where e is the
error, int(e) its accumulated integral, and de/dt its derivative.
kp acts on the error magnitude, ki removes steady-state error by
integrating it, kd anticipates the error trend and adds damping.
- Ziegler-Nichols continuous-cycling tuning uses the ultimate gain ku
and ultimate period tu measured at the stability boundary. Classic
rules: P gives kp = 0.5ku; PI gives kp = 0.45ku with
Ti = tu/1.2; PID gives kp = 0.6*ku with Ti = tu/2 and Td = tu/8.
- Pole placement for the first-order plant G(s) = b/(s + a) with a PI
controller: matching the closed loop to s^2 + 2zetawns + wn^2
gives kp = (2zeta*wn - a)/b and ki = wn^2/b.
- Pole placement for the second-order plant
G(s) = b/(s^2 + a1s + a0) with a PID controller: matching to
(s^2 + 2zetawns + wn^2)(s + p3) gives kd = (2zetawn + p3 - a1)/b,
kp = (wn^2 + 2zetawnp3 - a0)/b, and ki = wn^2p3/b.
- Anti-windup: when the actuator saturates, the integrator keeps
accumulating and drives the loop into a long overshoot. Conditional
integration clamps the accumulated integral to +/-limit each step,
so the integrator cannot wind up beyond the actuator's authority.
- Margins for the type-1 open loop K/(s(s + a)): crossover where
K^2 = wc^2(wc^2 + a^2), phase margin 90 - atan(wc/a) in degrees.
The phase reaches -180 deg only at infinite frequency, so the gain
margin is infinite for this loop.
- Discrete implementation: on a sampled flight computer the derivative
term uses the backward difference (e_k - e_{k-1})/dt at sample time
dt, and the integral accumulates kiedt; dt must be positive and
the sample rate consistent with the loop bandwidth.
Workflow
- Write the error equation: e = command - measured state in plant
units (angle, rate, position).
- Model the plant: first order b/(s + a) or second order
b/(s^2 + a1*s + a0) from the flight dynamics (see the
flight-mechanics stability and control leaves).
- Choose a tuning route: Ziegler-Nichols from a measured ku/tu
(scripts/pid_control_design_logic.py: ziegler_nichols) or pole
placement from a target wn/zeta (pole_placement_first_order,
pole_placement_second_order).
- Add anti-windup with integrator_clamp on the accumulated integral.
- Verify the margins of the loop (stability_margins_type1) and
sanity-check the gains (kp > 0, ki >= 0, kd >= 0).
- Implement in discrete time with discrete_derivative and the sample
time dt; recompute the gains if dt changes materially.
Pitfalls
- Tuning with Ziegler-Nichols from an unvalidated ku/tu: the ultimate
values come from the stability boundary, not from any operating
point.
- Placing poles without checking that the resulting gains are
physically sane; negative integral or derivative gains are a red
flag.
- Omitting anti-windup on an actuator-limited loop: the integrator
winds up during saturation and the loop overshoots on release.
- Reading the gain margin as finite for a type-1 loop; its phase only
reaches -180 deg at infinite frequency.
- Using a continuous derivative on a sampled computer; the backward
difference needs dt and produces a gain that changes with sample
rate.
- Mixing units across error, integral, and derivative terms; the
gains must be dimensioned per term.
Behavior contract (gate 3)
The PID output, Ziegler-Nichols, pole placement, anti-windup, margin,
and discrete-derivative logic is exercised by the gate 3 contract
test: scripts/test_pid_control_design.py against
scripts/pid_control_design_logic.py (stdlib unittest, offline). Run:
python3 scripts/test_pid_control_design.py
Compliance
- ARP4754A is proprietary (SAE); name + paraphrase only per
standards-map.yaml and brief 06 (revision note: ARP4754B
supersedes; this skill keys to A, the certification-baseline
revision).
- compliance: STANDARDS-REF, gated: false.
1---2name: pid-control-design3description: Use when the task is PID tuning, proportional integral derivative terms, anti-windup, integrator clamping, pole placement, or gain and phase margin checks. Design PID controller gains for aerospace flight and GNC control loops: compute the controller output from the proportional, integral, and derivative error terms, tune the gains from the plant model with Ziegler-Nichols using the ultimate gain and ultimate period, or place closed loop poles directly for a first or second order plant, add integrator anti-windup clamping, and check the gain margin and phase margin of the loop. Trigger: pid, proportional, integral, derivative, ziegler-nichols, ultimate gain, ultimate period, anti-windup, integrator clamp, pole placement, phase margin, gain margin.4license: Apache-2.05---67# PID Control Design (gnc-autonomy/control/pid-control-design)89Use when the task is PID controller design for an aerospace flight or10GNC loop: computing the output from the proportional, integral, and11derivative error terms, deriving gains from the plant model (first or12second order) by Ziegler-Nichols tuning or pole placement, protecting13the integrator with anti-windup clamping, or checking the loop's gain14and phase margins.1516## Domain quick reference1718- The PID output is u = kp*e + ki*int(e) + kd*de/dt where e is the19 error, int(e) its accumulated integral, and de/dt its derivative.20 kp acts on the error magnitude, ki removes steady-state error by21 integrating it, kd anticipates the error trend and adds damping.22- Ziegler-Nichols continuous-cycling tuning uses the ultimate gain ku23 and ultimate period tu measured at the stability boundary. Classic24 rules: P gives kp = 0.5*ku; PI gives kp = 0.45*ku with25 Ti = tu/1.2; PID gives kp = 0.6*ku with Ti = tu/2 and Td = tu/8.26- Pole placement for the first-order plant G(s) = b/(s + a) with a PI27 controller: matching the closed loop to s^2 + 2*zeta*wn*s + wn^228 gives kp = (2*zeta*wn - a)/b and ki = wn^2/b.29- Pole placement for the second-order plant30 G(s) = b/(s^2 + a1*s + a0) with a PID controller: matching to31 (s^2 + 2*zeta*wn*s + wn^2)(s + p3) gives kd = (2*zeta*wn + p3 - a1)/b,32 kp = (wn^2 + 2*zeta*wn*p3 - a0)/b, and ki = wn^2*p3/b.33- Anti-windup: when the actuator saturates, the integrator keeps34 accumulating and drives the loop into a long overshoot. Conditional35 integration clamps the accumulated integral to +/-limit each step,36 so the integrator cannot wind up beyond the actuator's authority.37- Margins for the type-1 open loop K/(s(s + a)): crossover where38 K^2 = wc^2(wc^2 + a^2), phase margin 90 - atan(wc/a) in degrees.39 The phase reaches -180 deg only at infinite frequency, so the gain40 margin is infinite for this loop.41- Discrete implementation: on a sampled flight computer the derivative42 term uses the backward difference (e_k - e_{k-1})/dt at sample time43 dt, and the integral accumulates ki*e*dt; dt must be positive and44 the sample rate consistent with the loop bandwidth.4546## Workflow47481. Write the error equation: e = command - measured state in plant49 units (angle, rate, position).502. Model the plant: first order b/(s + a) or second order51 b/(s^2 + a1*s + a0) from the flight dynamics (see the52 flight-mechanics stability and control leaves).533. Choose a tuning route: Ziegler-Nichols from a measured ku/tu54 (scripts/pid_control_design_logic.py: ziegler_nichols) or pole55 placement from a target wn/zeta (pole_placement_first_order,56 pole_placement_second_order).574. Add anti-windup with integrator_clamp on the accumulated integral.585. Verify the margins of the loop (stability_margins_type1) and59 sanity-check the gains (kp > 0, ki >= 0, kd >= 0).606. Implement in discrete time with discrete_derivative and the sample61 time dt; recompute the gains if dt changes materially.6263## Pitfalls6465- Tuning with Ziegler-Nichols from an unvalidated ku/tu: the ultimate66 values come from the stability boundary, not from any operating67 point.68- Placing poles without checking that the resulting gains are69 physically sane; negative integral or derivative gains are a red70 flag.71- Omitting anti-windup on an actuator-limited loop: the integrator72 winds up during saturation and the loop overshoots on release.73- Reading the gain margin as finite for a type-1 loop; its phase only74 reaches -180 deg at infinite frequency.75- Using a continuous derivative on a sampled computer; the backward76 difference needs dt and produces a gain that changes with sample77 rate.78- Mixing units across error, integral, and derivative terms; the79 gains must be dimensioned per term.8081## Behavior contract (gate 3)8283The PID output, Ziegler-Nichols, pole placement, anti-windup, margin,84and discrete-derivative logic is exercised by the gate 3 contract85test: scripts/test_pid_control_design.py against86scripts/pid_control_design_logic.py (stdlib unittest, offline). Run:87python3 scripts/test_pid_control_design.py8889## Compliance9091- ARP4754A is proprietary (SAE); name + paraphrase only per92 standards-map.yaml and brief 06 (revision note: ARP4754B93 supersedes; this skill keys to A, the certification-baseline94 revision).95- compliance: STANDARDS-REF, gated: false.