강의자료 · 제어공학2

PID Control

실행 준비

Python 경로는 python-control을 사용합니다. 모듈이 없으면 Colab·Jupyter의 코드 셀에서 %pip install control==0.10.2를 실행하세요.

학습 목표

빠른 응답만 보고 Gain을 고르면 Overshoot나 모델 변화에 취약할 수 있습니다. 서로 다른 성능 지표를 비교합니다.

P·PI·PID 기준 비교

시작 조건

Motor는 J=.01J=.01,b=.1b=.1,K=.01K=.01,R=1R=1,L=.5L=.5. P=(500,0,0), PI=(500,300,0), PID=(500,300,30)입니다.

진행 방법

  1. 음의 단위 Feedback으로 세 Closed-loop 모델을 만드세요.
  2. 0≤t≤20\le t\le 2 s의 Unit Step을 같은 그림에 표시하고 Pole을 먼저 확인하세요.
  3. 안정한 모델에 대해 Overshoot·Settling Time·Steady-State Error를 기록하세요.

남길 결과

import numpy as np
import matplotlib.pyplot as plt
import control as ctl
s = ctl.tf('s')
G=.01/((.01*s+.1)*(.5*s+1)+.01**2)
configs={'P':(500,0,0),'PI':(500,300,0),'PID':(500,300,30)}
for name,(kp,ki,kd) in configs.items():
    C=kp+ki/s+kd*s
    T=ctl.feedback(C*G,1)
    print(name,ctl.poles(T))
# TODO: 응답과 성능 지표를 기록하세요.

결과 기록·자가 점검

제어기:

Kp:

Ki:

Kd:

안정 여부:

Overshoot [%]:

Settling Time [s]:

Steady-State Error:

확인할 점

한 항씩 변화시키기

시작 조건

PID 기준 (500,300,30)에서 Kp만 250,500,750으로 바꿉니다. Ki·Kd는 고정합니다.

진행 방법

  1. 활동 1의 PID (500,300,30)(500,300,30) 결과를 기준으로 두고 KpK_p만 250과 750으로 각각 바꾸세요. Ki=300K_i=300, Kd=30K_d=30, Plant와 시간축은 유지하세요.
  2. 두 설정의 Unit Step을 기준 곡선과 같은 그림에 표시하세요. 같은 ctl.step_info 설정으로 구한 Overshoot·Settling Time·Steady-State Error를 활동 1과 같은 열로 기록하세요.
  3. 두 추가 설정 중 하나를 선택하고, 기준값보다 개선하려는 지표와 허용하려는 변화를 표의 값으로 설명하세요.

남길 결과

import numpy as np
import matplotlib.pyplot as plt
import control as ctl
s = ctl.tf('s')
G=.01/((.01*s+.1)*(.5*s+1)+.01**2)
for kp in [250,500,750]:
    T=ctl.feedback((kp+300/s+30*s)*G,1)
    print(kp,ctl.dcgain(T))
# TODO: 시간응답과 두 번째 Gain 비교를 완성하세요.

결과 기록·자가 점검

변경 항:

값:

Overshoot [%]:

Settling Time [s]:

Steady-State Error:

확인할 점

입력 한계와 적분 누적

시작 조건

1차 Plant ẏ=−y+u\dot y=-y+u, 목표 2→.5(5초에 변경), u∈[0,1]u\in[0,1], dt=.01 s입니다. Kp=2K_p=2, Ki=1K_i=1입니다.

진행 방법

  1. 제공된 PI 시뮬레이션에서 실제 입력과 제한 전 입력을 함께 그리세요.
  2. conditional integration을 켠 경우와 끈 경우를 비교하세요.
  3. 목표를 낮춘 뒤 오차가 오래 남는 이유를 적분 상태와 연결해 설명하세요.

남길 결과

비교 표의 IAE는 목표 변경 시각부터 마지막 기록 시각까지의 ∫5tlast|r(t)−y(t)|dt\int_{5}^{t_{\mathrm{last}}}|r(t)-y(t)|\,dt입니다. 입력 포화 지속 시간은 전체 기록에서 제한된 uu가 0 또는 1인 표본 수에 dt를 곱해 구하세요.

두 적분 처리 방식에 같은 구간과 계산법을 사용합니다.

import numpy as np
import matplotlib.pyplot as plt
def simulate(antiwindup):
    t=np.arange(0,12,.01);y=0.;integral=0.;rows=[]
    for now in t:
        ref=2. if now<5 else .5;e=ref-y;raw=2*e+integral;u=np.clip(raw,0,1)
        if not antiwindup or (0<raw<1) or (raw>=1 and e<0) or (raw<=0 and e>0):integral+=e*.01
        y+=(-y+u)*.01;rows.append((ref,y,raw,u,integral))
    return t,np.array(rows)
for flag in [False,True]:
    time,trace=simulate(flag);plt.plot(time,trace[:,1],label=str(flag))
plt.xlabel('Time [s]');plt.ylabel('Output');plt.legend()
# TODO: 입력·적분 상태와 5초 이후의 지표를 추가하세요.

결과 기록·자가 점검

적분 처리:

목표 변경 후 IAE:

최대 적분값:

입력 포화 지속 시간 [s]:

확인할 점