부록 부록
A.3 부록 C — python-control·NumPy·Matplotlib 치트시트
부록 · 참조. 본문 실습에 쓴 도구를 한 장에. ✅ 아래
controlAPI는 control 0.10.2(컨테이너 검증, 목차 2)에서 전부 존재 확인. 버전이 다르면 일부 인자가 다를 수 있다.
A.3.1 시스템 생성·변환
import control as ct, numpy as np
G = ct.tf([1], [1, 2, 4]) # 전달함수 1/(s²+2s+4)
H = ct.ss(A, B, C, D) # 상태공간
Gz = ct.tf([1], [1, -0.9], 0.1) # 이산 전달함수 (dt=0.1)
ct.ss2tf(H); ct.tf2ss(G) # 상호 변환 (4.1)
ct.minreal(G) # 최소 실현(숨은 모드 제거, 4.2)
ct.c2d(G, 0.1, method='zoh') # 연속→이산 ('zoh'|'tustin'|'euler'|...) (3.2)
A.3.2 해석 (극·영점·응답)
ct.poles(G); ct.zeros(G) # 극·영점 (1.2)
ct.dcgain(G) # DC 이득 G(0)
np.linalg.eigvals(A) # = 극 (4.1.6)
t, y = ct.step_response(G) # 계단응답 (1.3)
ct.step_info(G) # 오버슈트·정착·상승·피크시간 dict
ct.bode_plot(G, dB=True) # Bode (2.3)
gm, pm, wpc, wgc = ct.margin(G) # 이득·위상 여유 + 교차주파수 (2.4)
ct.nyquist_plot(G) # Nyquist (2.4)
ct.root_locus(G, grid=True) # 근궤적 + ζ·ωₙ 격자 (2.2)
ct.pzmap(G) # 극·영점 지도
A.3.3 설계 (피드백·극배치·LQR)
T = ct.feedback(G, H) # 폐루프 G/(1+GH) (1.2.5)
ct.series(G, H); ct.parallel(G, H) # 직렬(곱)·병렬(합)
K = ct.place(A, B, [-2+2j, -2-2j]) # 극배치 (4.3)
L = ct.place(A.T, C.T, poles).T # 관측기(쌍대 극배치) (4.4)
K, S, E = ct.lqr(A, B, Q, R) # LQR: 이득K·리카티S·폐루프극E (4.5)
Kd, Sd, Ed = ct.dlqr(Ad, Bd, Q, R) # 이산 LQR: 이산 리카티S·폐루프극E (4.5, 6.1 MPC 종단비용)
Cc = ct.ctrb(A, B); Co = ct.obsv(A, C)# 가제어·가관측 행렬 (4.2)
np.linalg.matrix_rank(Cc) # = n 이면 가제어
A.3.4 NumPy/SciPy (수치)
np.roots([1, 3, 2, 6]) # 다항식 근 (안정성, 2.1)
np.linalg.eigvals(A); np.linalg.inv(A)
np.linalg.eigvalsh(P) # 대칭/에르미트 전용 고유값(더 빠름·실수 보장, 리아푸노프 P, 6.2)
np.linalg.cholesky(P) # √P (UKF, 5.3)
from scipy.linalg import solve_continuous_are, solve_lyapunov, expm
solve_continuous_are(A, B, Q, R) # 리카티 (LQR 직접)
solve_lyapunov(A.T, -Q) # 리아푸노프 (6.2)
from scipy.optimize import curve_fit # 시스템 식별 (FOPDT, 1.4)
from scipy.signal import cont2discrete # 이산화 대안
rng = np.random.default_rng(0)
rng.multivariate_normal(mu, Sig, 1000) # 가우시안 샘플 (5.1)
np.cov(X.T) # 공분산 추정
A.3.5 Matplotlib (그래프)
import matplotlib
matplotlib.use('Agg') # headless(컨테이너·서버)면 Agg, show() 대신 savefig
import matplotlib.pyplot as plt
plt.plot(t, y); plt.grid(True)
plt.xlabel('t [s]'); plt.ylabel('y'); plt.legend()
plt.savefig('out.png') # headless
# plt.show() # GUI 있을 때
A.3.6 MPC (cvxpy)
import cvxpy as cp # (6.1, 7.6)
x = cp.Variable((n, N+1)); u = cp.Variable((m, N))
cost = sum(cp.quad_form(x[:,i], Q) + cp.quad_form(u[:,i], R) for i in range(N))
con = [x[:,0]==x0] + [x[:,i+1]==A@x[:,i]+B@u[:,i] for i in range(N)] \
+ [cp.abs(u[:,i])<=u_max for i in range(N)]
cp.Problem(cp.Minimize(cost), con).solve(solver=cp.OSQP)
u0 = u[:,0].value # 첫 입력만 적용
A.3.7 설치 (0.3 요약)
python3 -m venv ~/ctrl-venv && source ~/ctrl-venv/bin/activate
pip install numpy scipy matplotlib sympy control cvxpy
# slycot(일부 고급 함수): sudo apt install gfortran libopenblas-dev && pip install slycot
# 또는 conda install -c conda-forge control slycot
본문에서 각 함수의 의미와 함정을 다룬다 — 이 표는 호출 형태 참조용. 검증 환경·전체 예제는 저장소
verify/(목차 2).