--- id: wiki-2026-0508-feedback-control-systems title: Feedback Control Systems category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Closed-Loop Control, Control System, PID, MPC] duplicate_of: none source_trust_level: A confidence_score: 0.92 verification_status: applied tags: [control-theory, systems, dynamics, automation] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: Python framework: python-control, scipy.signal, do-mpc, casadi --- # Feedback Control Systems ## 매 한 줄 > **"매 sensor → comparator → controller → actuator → plant → sensor 매 closed loop 으로 setpoint 를 maintain"**. James Watt 의 governor (1788) → Bode/Nyquist (1930s) → state-space + Kalman (1960s) → 매 modern: **MPC, ADRC, learning-based control (Koopman/MPC, RL)**. 매 SRE autoscaler, drone, EV motor, vaccine cold-chain, fab DRIE — 매 universal. ## 매 핵심 ### 매 canonical block diagram ``` ┌─────────┐ r ──+──▶│Controller│──u──▶┌─────┐──y──┐ ─ │ C(s) │ │P(s)│ │ └─────────┘ └─────┘ │ ▲ │ └──── − ◀── sensor ◀───┘ e = r − y_meas (error) ``` ### 매 PID intuition - **P (proportional)**: 매 instant correction; 매 too high → oscillation. - **I (integral)**: 매 eliminate steady-state error; 매 too high → wind-up. - **D (derivative)**: 매 damping; 매 amplify noise. ### 매 modern 분류 - **Classical**: PID, lead-lag, root-locus, Bode design. - **State-space**: pole-placement, LQR, observer / Kalman filter. - **Robust**: H∞, μ-synthesis (uncertain plant). - **Adaptive**: MRAC, gain-scheduling. - **Predictive**: **MPC** (constraint-aware, multi-step optimize). - **Learning-based** (2026): Koopman-MPC, Gaussian-Process MPC, **safe RL with control-barrier functions**. ### 매 stability - 매 LTI 의 Routh-Hurwitz, Nyquist, gain/phase margin (≥ 6 dB / 30°). - 매 nonlinear 의 Lyapunov. ## 💻 패턴 ### PID class ```python class PID: def __init__(self, kp, ki, kd, dt, u_min=None, u_max=None): self.kp,self.ki,self.kd,self.dt = kp,ki,kd,dt self.u_min,self.u_max = u_min,u_max self.i, self.prev = 0.0, 0.0 def __call__(self, sp, pv): e = sp - pv self.i += e*self.dt d = (e - self.prev)/self.dt self.prev = e u = self.kp*e + self.ki*self.i + self.kd*d if self.u_max is not None and u > self.u_max: u = self.u_max; self.i -= e*self.dt # anti-windup if self.u_min is not None and u < self.u_min: u = self.u_min; self.i -= e*self.dt return u ``` ### Ziegler–Nichols tuning ```python # 1) Set ki=kd=0; raise kp to find Ku where output sustains oscillation at period Tu. # 2) Classic ZN: kp=0.6Ku, ki=2kp/Tu, kd=kp*Tu/8 def zn_classic(Ku, Tu): return 0.6*Ku, 2*0.6*Ku/Tu, 0.6*Ku*Tu/8 ``` ### Plant simulation (python-control) ```python import control as ct, numpy as np, matplotlib.pyplot as plt P = ct.tf([1], [1, 3, 2]) # 1/(s²+3s+2) C = ct.tf([2, 1], [1, 0]) # PI: 2 + 1/s L = ct.series(C, P) T = ct.feedback(L, 1) t, y = ct.step_response(T, T=np.linspace(0, 10, 500)) plt.plot(t, y); plt.axhline(1, ls="--") ``` ### State-space LQR ```python import numpy as np, control as ct A = np.array([[0,1],[-2,-3]]); B = np.array([[0],[1]]) Q = np.diag([10, 1]); R = np.array([[0.1]]) K, _, _ = ct.lqr(A, B, Q, R) # u = -K x ``` ### Kalman filter ```python import numpy as np def kf_step(x, P, z, A, H, Q, R): # predict x = A @ x; P = A @ P @ A.T + Q # update y = z - H @ x S = H @ P @ H.T + R K = P @ H.T @ np.linalg.inv(S) x = x + K @ y P = (np.eye(len(x)) - K @ H) @ P return x, P ``` ### Model Predictive Control (do-mpc, level tank) ```python import numpy as np, do_mpc from casadi import vertcat m = do_mpc.model.Model("continuous") h = m.set_variable("_x","h"); u = m.set_variable("_u","u") m.set_rhs("h", -0.1*h + u); m.setup() mpc = do_mpc.controller.MPC(m) mpc.set_param(n_horizon=20, t_step=0.1, store_full_solution=True) mpc.set_objective(mterm=(h-1)**2, lterm=(h-1)**2 + 0.01*u**2) mpc.set_rterm(u=0.1) mpc.bounds["lower","_u","u"] = 0; mpc.bounds["upper","_u","u"] = 2 mpc.bounds["lower","_x","h"] = 0; mpc.bounds["upper","_x","h"] = 1.5 mpc.setup() mpc.x0 = np.array([0.0]); mpc.set_initial_guess() u0 = mpc.make_step(np.array([0.0])) ``` ### Autoscaler-as-PID (SRE) ```python class CPUAutoscaler: def __init__(self, target=0.6, k=10, max_r=20): self.pid = PID(kp=k, ki=k/30, kd=0, dt=15, u_min=-3, u_max=3) self.target, self.max_r = target, max_r def step(self, cpu, replicas): delta = self.pid(self.target, cpu) return max(1, min(self.max_r, replicas + round(delta))) ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Single SISO, slow plant | **PID** (90% of industry) | | MIMO, known model | **LQR / state-space** | | Constraints + multi-step lookahead | **MPC** | | Large model uncertainty | **H∞ / robust control** | | Time-varying gain | **Gain-scheduling / adaptive** | | Unknown dynamics, lots of data | **Koopman-MPC / GP-MPC / safe RL** | | Stochastic measurement | **+ Kalman / EKF / UKF** | **기본값**: 매 SISO + slow plant → **PID with anti-windup + ZN-tuning**, 매 constraint-rich multi-input → **MPC**. ## 🔗 Graph - 부모: [[Control-Theory]] · [[Cybernetics Foundations|Cybernetics]] - 변형: [[PID]] · [[MPC]] - 응용: [[Robotics]] - Adjacent: [[Feedback-Loops in Systems]] · [[Kalman-Filter-and-State-Tracking|Kalman-Filter]] · [[Reinforcement-Learning]] ## 🤖 LLM 활용 **언제**: 매 PID 의 tuning, 매 plant 의 transfer-function 의 derivation, 매 MPC objective 의 formulation, 매 stability 의 quick check. **언제 X**: 매 safety-critical real-time control 의 untested LLM-generated code 의 직접 deploy — 매 formal verification + HIL test 필수. ## ❌ 안티패턴 - **No anti-windup**: 매 saturated actuator + integral 의 huge overshoot. - **D term on noisy measurement**: 매 amplifies high-freq noise — 매 derivative-on-measurement + low-pass filter. - **Sample rate ≪ bandwidth**: 매 dt 의 ≥ 10× system bandwidth 의 violate → 매 instability. - **Tuning by gut**: 매 reproducible (ZN, model-based, autotuning) 의 사용. - **Open-loop "feedback"**: 매 sensor 없이 매 not feedback control. - **Ignoring delay**: 매 transport delay → 매 Smith predictor / phase margin 의 reserve. ## 🧪 검증 / 중복 - Verified (Bode 1945; Åström & Murray *Feedback Systems* 2nd ed.; Rawlings, Mayne & Diehl *MPC* 2nd ed.; Brunton & Kutz *Data-Driven Science and Engineering* 2022). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 placeholder | | 2026-05-10 | Manual cleanup — classical→MPC + 7 patterns + decision matrix |