State Feedback과 Observer

학습 목표

위치만 측정하는 시스템에서 속도를 추정해 제어하고, 추정 속도와 잡음 민감도를 함께 비교합니다.

측정값으로 상태를 구분할 수 있는가

시작 조건

위치[m]·속도[m/s]를 상태로 하는 ẋ=Ax+Bu\dot x=Ax+Bu, y=Cxy=Cx입니다. A=[01−2−3]A=\begin{bmatrix}0&1\\-2&-3\end{bmatrix}, B=[01]B=\begin{bmatrix}0\\1\end{bmatrix}, C=[10]C=\begin{bmatrix}1&0\end{bmatrix}을 사용합니다.

진행 방법

  1. 가제어 행렬 [B,AB]와 가관측 행렬 [C;CA]를 만들고 rank를 구하세요.
  2. B를 영벡터로 바꾼 경우와 C=[00]C=\begin{bmatrix}0&0\end{bmatrix}인 경우를 각각 비교하세요.
  3. 입력이 작용하지 않는 경우와 측정이 없는 경우를 구분해 설명하세요.

남길 결과

import numpy as np
A=np.array([[0.,1.],[-2.,-3.]])
B=np.array([[0.],[1.]])
C=np.array([[1.,0.]])
for label,b,c in [('base',B,C),('no input',0*B,C),('no sensor',B,0*C)]:
    ctrb=np.column_stack([b,A@b]);obsv=np.vstack([c,c@A])
    print(label,np.linalg.matrix_rank(ctrb),np.linalg.matrix_rank(obsv))
# TODO: 각 조건에서 설계할 수 있는 것과 없는 것을 적으세요.

결과 기록·자가 점검

조건:

Controllability rank:

Observability rank:

설계 가능 여부:

확인할 점

State Feedback과 Observer를 연결하기

시작 조건

u=−Kx̂+8ru=-K\hat x+8r, r=1r=1입니다. 제어 Pole은 −2,−4, Observer Pole은 −8,−10입니다. x(0)=[10]x(0)=\begin{bmatrix}1\\0\end{bmatrix}, x̂(0)=[00]\hat x(0)=\begin{bmatrix}0\\0\end{bmatrix}입니다.

진행 방법

  1. K와 L을 계산하고 A−BKA-BK, A−LCA-LC의 고유값을 대조하세요.
  2. 실제 상태와 추정 상태를 동시에 적분해 0–4 s의 위치·속도와 추정 오차를 그리세요.
  3. 추정 오차가 줄어드는 과정과 출력이 목표값으로 가는 과정을 구분하세요.

남길 결과

from scipy.signal import place_poles,StateSpace,lsim
import matplotlib.pyplot as plt
K=place_poles(A,B,[-2.,-4.]).gain_matrix
L=place_poles(A.T,C.T,[-8.,-10.]).gain_matrix.T
a_aug=np.block([[A,-B@K],[L@C,A-B@K-L@C]])
b_aug=np.vstack([8*B,8*B])
t=np.linspace(0,4,801)
_,z,_=lsim(StateSpace(a_aug,b_aug,np.eye(4),np.zeros((4,1))),np.ones(len(t)),t,X0=[1,0,0,0])
fig,axes=plt.subplots(2,1,sharex=True)
for j,ax in enumerate(axes):
    ax.plot(t,z[:,j],label='state');ax.plot(t,z[:,j+2],'--',label='estimate');ax.legend();ax.grid()
axes[0].set_ylabel('Position [m]');axes[1].set_ylabel('Velocity [m/s]');axes[-1].set_xlabel('Time [s]')
print('final estimation error:',np.linalg.norm(z[-1,:2]-z[-1,2:]))
# TODO: 제어 극점과 Observer 극점을 출력해 대조하세요.

결과 기록·자가 점검

K:

L:

제어 Pole:

Observer Pole:

최종 오차:

확인할 점

Observer를 빠르게 하면 항상 좋은가

시작 조건

측정에 n(t)=0.02sin(40t)를 더합니다. Observer Pole (−8,−10), (−20,−25)를 비교하고 제어기 K는 고정합니다.

진행 방법

  1. 실습용 노트북의 함수에 두 Observer 설정을 넣고 같은 시간축에서 제어입력 u를 비교하세요.
  2. 1 s 이후의 위치 오차 RMS, 속도 오차 RMS, 제어입력 RMS를 각각 구하세요.
  3. 초기 추정 오차의 수렴과 측정 잡음에 대한 반응을 별개로 해석하세요.

남길 결과

def noisy_observer(poles):
    L=place_poles(A.T,C.T,poles).gain_matrix.T
    aa=np.block([[A,-B@K],[L@C,A-B@K-L@C]])
    bb=np.block([[8*B,np.zeros((2,1))],[8*B,L]])
    inputs=np.column_stack([np.ones(len(t)),.02*np.sin(40*t)])
    _,z,_=lsim(StateSpace(aa,bb,np.eye(4),np.zeros((4,2))),inputs,t,X0=[1,0,0,0])
    u=8-(z[:,2:]@K.T).ravel();keep=t>=1
    return u,np.sqrt(np.mean((z[keep,:2]-z[keep,2:])**2,axis=0)),np.sqrt(np.mean(u[keep]**2))
for poles in [(-8,-10),(-20,-25)]:
    u,err,rms=noisy_observer(poles);plt.plot(t,u,label=str(poles));print(poles,err,rms)
plt.xlabel('Time [s]');plt.ylabel('u [N]');plt.legend();plt.grid()
# TODO: 두 설정 중 무엇을 택할지 지표를 근거로 설명하세요.

결과 기록·자가 점검

Observer Pole:

위치 오차 RMS [m]:

속도 오차 RMS [m/s]:

입력 RMS [N]:

선택 근거:

확인할 점

공식 예제·데이터