들어가며
에어컨을 26도에 맞춰두면, 실내 온도가 26도에 닿는 순간 딱 멈출까? 좋은 에어컨은 26도에 가까워질수록 슬슬 출력을 줄이다가 부드럽게 안착한다. 반대로 어설픈 온도 조절은 24도까지 확 떨어뜨렸다가 다시 28도로 올렸다가 출렁거린다. 이 “부드럽게 안착하느냐, 출렁거리느냐"의 차이를 만드는 게 바로 PID 제어다.

알게 모르게 우리는 하루 종일 PID를 쓴다. 오르막에서도 속도를 유지하는 자동차 크루즈 컨트롤, 바람 속에서 제자리에 떠 있는 드론, 3D 프린터 노즐 온도, 보일러… 전부 PID다. 세상에서 가장 널리 쓰이는 제어 알고리즘인데, 핵심 아이디어는 의외로 한 줄로 끝난다 — “목표랑 얼마나 차이 나는지 보고, 그만큼 조절한다.”
이 글에서는 그 PID를, 내가 직접 다뤘던 고압산소챔버(HBOT) 압력 제어로 풀어본다. 챔버는 압력을 잘못 맞추면 환자 고막에 무리가 가는(barotrauma) 시스템이라, “대충 맞으면 OK"가 아니라 정확하고 부드럽게 맞춰야 한다. 추상적인 수식보다 “압력을 맞추려고 밸브를 여닫는다"는 구체적인 그림으로 접근하는 게 훨씬 빠르다.
피드백 제어란
제어의 목표는 시스템의 출력을 원하는 값(setpoint)에 맞추는 것이다.
샤워 온수로 생각하면 된다. 물이 너무 차가우면 온수 쪽으로 돌리고, 너무 뜨거우면 반대로 돌린다. “원하는 온도와 실제 온도의 차이"를 보고 손잡이를 조절하는 것 — 이게 피드백 제어다.
핵심 개념은 오차(error)다.
$$ e(t) = r(t) - y(t) $$- $r(t)$: 목표값 (reference / setpoint)
- $y(t)$: 실제 출력 (측정값)
- $e(t)$: 오차
제어기는 이 오차를 입력으로 받아 오차를 줄이는 방향으로 제어 입력 $u(t)$를 만든다. 출력을 다시 측정해 오차를 계산하므로 “피드백(되먹임)“이라 부른다.
실전 예시: 고압산소챔버 압력 제어
내가 다뤘던 시스템을 PID 용어로 옮겨보자.
| PID 용어 | 챔버 시스템 | 예시 값 |
|---|---|---|
| 목표값$r$ (Setpoint) | 원하는 챔버 압력 | 2.0 ATA |
| 측정값$y$ (PV) | 압력 센서가 읽은 값 | 1.7 ATA |
| 오차$e$ | 목표 − 실제 | +0.3 ATA |
| 제어 출력$u$ (MV) | 비례제어 밸브 전류 | 4–20 mA |
| 플랜트 (Plant) | 밸브 → 유량 → 챔버 압력 | — |
압력이 목표보다 낮으면(오차 +) 흡기 밸브 전류를 올려 산소를 더 넣고, 높으면(오차 −) 밸브를 닫거나 배기를 연다. “압력을 보고 → 밸브 전류를 조절 → 다시 압력이 바뀜"이라는 폐루프가 만들어진다.

이 구조에서 압력은 상태변수(제어 대상), 밸브 전류는 조작변수(우리가 움직이는 값)다.
목표값은 “한 점"이 아니라 “궤적"이다
실제 챔버 운용에서 목표 압력을 처음부터 2.0 ATA로 바로 지정하지 않는다. 운용자가 압력 프로파일을 설정한다.
- 가압 시간: 몇 분에 걸쳐 올릴지 (예: 10분)
- 유지 압력: 몇 기압으로 유지할지 (예: 2.0 ATA)
- 유지 시간: 그 압력을 몇 분 유지할지 (예: 60분)
- 감압 시간: 몇 분에 걸쳐 내릴지 (예: 10분)
$r(t)$가 시간에 따라 천천히 올라가고(ramp) → 유지되고(hold) → 천천히 내려가는(ramp) 곡선이 된다. PID는 이 움직이는 목표를 따라간다. 제어 용어로 궤적 추종(trajectory tracking) 또는 setpoint profiling이라 한다.


가압을 ramp으로 천천히 올리는 데에는 이유가 있다. 목표를 계단처럼 바꾸면 순간 오차가 커져 밸브가 풀로 열리고, 그 결과 적분 와인드업과 큰 오버슈트로 이어진다. 반면 목표를 서서히 올리면 매 순간 오차가 작게 유지돼 밸브가 부드럽게 동작한다. setpoint ramping은 와인드업·오버슈트를 구조적으로 미리 막아주는 기법이며, HBOT에서는 동시에 barotrauma도 방지한다.
가압·유지 / 감압 제어기를 분리하기
압력을 올리는 동역학(흡기 밸브 → 산소 유입)과 내리는 동역학(배기)은 특성이 다르다. 하나의 PID로 양방향을 다루기보다 가압+유지용과 감압용 PID를 분리하는 편이 깔끔하다. 각 구간에 맞는 게인을 따로 둘 수 있기 때문이다. 상황에 따라 제어기를 바꿔 쓰는 것을 모드 스위칭(switching control) 또는 넓게는 게인 스케줄링이라 부른다.
제어기를 전환하는 순간(가압→유지, 유지→감압) 밸브 명령이 튀지 않으려면 무충돌 절환(bumpless transfer) 을 적용해야 한다. 새로 켜지는 PID의 적분기 상태를 현재 밸브 출력에 맞춰 초기화하면 전환 순간 압력이 출렁이는 걸 막을 수 있다.
결국 실전 챔버 제어는 “step 목표를 따라가는 단순 PID"가 아니라, 운용자 정의 궤적을 추종하는 모드별 분리 PID 구조다. 아래에서 다룰 P·I·D의 기본 원리는 이 각각의 PID 블록 안에서 그대로 동작한다.
PID 제어기의 구조
PID는 이름 그대로 비례(P) · 적분(I) · 미분(D) 세 항의 합으로 제어 입력을 만든다.
$$ u(t) = K_p e(t) + K_i \int_0^t e(\tau)\,d\tau + K_d \frac{de(t)}{dt} $$라플라스 영역 전달함수로는 다음과 같다.
$$ C(s) = K_p + \frac{K_i}{s} + K_d s $$세 항은 각각 오차의 현재·과거·미래를 담당한다. 챔버로 치면 “지금 압력이 얼마나 부족한지(P) · 그동안 얼마나 못 맞췄는지(I) · 지금 얼마나 빠르게 차오르는지(D)“를 동시에 보는 셈이다.
P · I · D 각 항의 역할
P — 비례 항 (지금 얼마나 차이 나는가)
$$ u_P(t) = K_p e(t) $$오차에 비례해 밸브 전류를 올린다. 압력이 목표보다 많이 모자라면 밸브를 많이 열고, 거의 다 왔으면 조금만 연다.
- $K_p$를 키우면 압력이 빨리 차오른다.
- 너무 키우면 목표 압력을 지나쳐버리는 오버슈트가 생기고, 심하면 출렁출렁 진동한다.
비례 항만으로는 목표에 정확히 못 맞춘다. 압력이 목표에 가까워질수록 오차가 줄고, 그러면 밸브를 거의 닫아버려 미세하게 모자란 상태로 멈춰버린다. 이 정상상태 오차(steady-state error) 가 P 제어의 한계다.
I — 적분 항 (그동안 쌓인 차이)
$$ u_I(t) = K_i \int_0^t e(\tau)\,d\tau $$작은 오차라도 계속 남아 있으면 시간에 따라 누적해서 밸브를 조금씩 더 연다. “1.95 ATA에서 계속 멈춰 있네? 그럼 누적해서 더 밀어주자” — I 항의 역할이다.
- 정상상태 오차를 0으로 제거해 목표 압력에 정확히 도달시키는 핵심 항.
- 누적 특성 때문에 반응이 굼떠지고, 과하면 오버슈트와 진동을 만든다.
- 챔버처럼 밸브에 물리적 한계가 있는 시스템에서는 적분 와인드업을 반드시 처리해야 한다(아래 절 참고).
D — 미분 항 (얼마나 빠르게 변하는가)
$$ u_D(t) = K_d \frac{de(t)}{dt} $$압력이 빠르게 차오르는 중이면 “이대로면 목표를 지나치겠다"고 판단해 밸브를 미리 줄인다. 브레이크를 미리 살짝 밟는 셈이다.
- 오버슈트를 억제하고 응답을 안정적으로 만든다. barotrauma를 막아야 하는 챔버에서 특히 의미 있다.
- 압력 센서 노이즈에 민감하다. 신호가 조금만 떨려도 미분값이 크게 튀므로 미분 필터가 거의 필수다.
- 실무에서는 D를 빼고 PI 제어만 쓰는 경우도 많다.
| 항 | 보는 것 | 챔버에서의 효과 | 부작용 |
|---|---|---|---|
| P | 지금 압력 차이 | 빠르게 차오름 | 오버슈트, 정상상태 오차 |
| I | 누적된 차이 | 목표 압력 정확히 도달 | 굼뜸, 와인드업 |
| D | 압력 변화 속도 | 오버슈트 억제 (barotrauma 방지) | 센서 노이즈 증폭 |
튜닝: 게인은 어떻게 정하나
$K_p, K_i, K_d$ 세 값을 어떻게 정할까? 가장 고전적인 방법이 1942년 Ziegler-Nichols 튜닝법이다.
한계 감도법 절차:
- I, D를 끄고 P 제어만 켠다.
- $K_p$를 0부터 서서히 키우면서, 챔버 압력이 일정 진폭으로 진동하기 시작하는 게인을 찾는다 → 한계 게인 $K_u$.
- 그때의 진동 주기 $T_u$를 잰다.
- 아래 표로 게인을 계산한다.
| 제어기 | $K_p$ | $T_i$ | $T_d$ |
|---|---|---|---|
| P | $0.5\,K_u$ | — | — |
| PI | $0.45\,K_u$ | $T_u / 1.2$ | — |
| PID | $0.6\,K_u$ | $T_u / 2$ | $T_u / 8$ |
$K_i = K_p / T_i$, $K_d = K_p \cdot T_d$로 환산한다.
실제 챔버에서 한계 게인을 찾겠다고 압력을 진동시키는 건 안전상 위험할 수 있다. 시뮬레이션이나 저압 영역에서 조심스럽게 진행하거나, 모델 기반 튜닝(IMC, Lambda 튜닝)을 쓰는 편이 낫다. Ziegler-Nichols는 오버슈트가 큰 편이라 초기 출발점으로 쓰고 손으로 다듬는 게 일반적이다.
실무에서 마주치는 문제
이론만큼 중요한 게 구현 디테일이다. 챔버 펌웨어를 짜다 보면 두 가지는 반드시 만난다.
적분 와인드업 (Integral Windup)
밸브 전류는 4–20 mA로 물리적 상한이 있다. 가압 초기에 압력이 한참 모자라면 제어기는 계속 “밸브 더 열어"를 요구하지만, 이미 20 mA(완전 개방)라 더 열 수가 없다. 그런데도 적분항은 멈추지 않고 계속 누적된다.
목표에 도달해 오차 부호가 바뀌어도, 그동안 잔뜩 쌓인 적분값을 다 풀어내느라 밸브가 늦게 닫혀 큰 오버슈트가 난다.
대응책:
- 적분 클램핑: 밸브가 포화(20 mA 또는 4 mA) 상태일 때 적분 누적을 멈춘다.
- back-calculation: 포화로 잘려나간 출력만큼 적분값을 되돌린다.
미분 노이즈와 미분 킥
- 압력 센서의 고주파 잡음을 미분이 증폭한다 → 저역통과 필터를 거친 미분(filtered derivative)을 쓴다.
- 목표 압력을 계단형으로 바꾸면 오차가 순간 튀어 미분항이 큰 펄스를 만든다(derivative kick) → 측정 압력에만 미분을 적용(derivative on measurement)해 회피한다.
이런 디테일까지 반영한 형태를 실용형 PID(practical PID) 라 부른다.
PID의 한계와 그 너머
기본형 PID는 강한 비선형성·큰 시간지연·다변수 간섭에 약하다. 챔버 압력 제어는 꽤 비선형적인 문제다.
- 밸브 차압에 따라 유량 관계가 비선형이고, 기체 압축성 때문에 압력 구간마다 시스템 반응이 다르다. 고정 게인 PID 하나로 전 구간을 커버하기 어렵다.
- 흡기 밸브와 배기 밸브의 특성이 달라 가압/감압 동작이 비대칭이다.
- 최종 압력뿐 아니라 가압·감압 속도 프로파일(barotrauma 방지)을 추종해야 한다.
이런 한계를 넘기 위한 방향:
- 게인 스케줄링: 압력대별로 게인을 바꿔 적용한다. 가압/유지/감압 제어기를 분리하는 것도 큰 틀에서 여기에 속한다.
- 분수차 PID (FOPID): 적분·미분 차수를 실수로 확장해 자유도를 높인다.
- 적응형 PID: MRAS나 신경망으로 게인을 실시간 조정한다.
- 궤적 추종 + 고장허용 제어: 압력 프로파일을 추종하면서 밸브 고장 등에도 견디게 한다(최신 챔버 제어 논문의 방향).
이런 발전된 기법들도 결국 PID 뼈대 위에서 확장된다. 기본 PID를 제대로 이해하는 것이 출발점인 이유다.
정리
PID는 오차의 현재(P)·과거(I)·미래(D)를 각각 다루는 세 항의 합이다. 챔버로 보면, P는 압력을 빠르게 채우고, I는 목표 압력에 정확히 맞추고, D는 오버슈트(과압)를 막는다.
실전 챔버 제어의 포인트를 정리하면:
- 목표를 한 점이 아니라 궤적(가압→유지→감압 프로파일)으로 주고 추종시킨다.
- setpoint ramping은 와인드업·오버슈트·barotrauma를 구조적으로 막아준다.
- 가압·유지와 감압 제어기는 분리하고, 전환 시 무충돌 절환(bumpless transfer)을 적용한다.
- Ziegler-Nichols는 초기 게인 추정에 쓰지만, 안전이 중요한 시스템에서는 조심해서 적용한다.
- 적분 와인드업과 미분 노이즈 처리가 실제 성능을 좌우한다.