System Controlling: State Estimation
Showing posts with label State Estimation. Show all posts
Showing posts with label State Estimation. Show all posts

Friday, December 21, 2012

Discrete H infinity filter design

Short introduction

In many application cases where some of the system states can't be measured, we can use a state observer. One solution would be the Kálmán filter which I already presented. Another solution is the $H_\infty$ filter which is robust regarding the unpredictable noise source. In the Kálmán filter not only the noise process needs to be zero mean, but also the $Q$, $R$ covariance matrices have to be known, without them we can't design an appropriate observer. While in the $H_\infty$ filter doesn't make any assumptions about the noise, it minimizes the worst case estimation error.

Discrete $H_\infty$ filter design

We have the following discrete-time system
$$x_{k+1}=A_k x_k+B_k u_k + w_k\\y_k=C_k x_k+D_k u_k+v_k\tag{1}$$
The $1$ system has to be controllable and observable. We would like to achieve a small estimation error $e_k=z_k - \hat{z}_k$ for any $w_k,v_k$. In this case we want to solve the minimax problem as follows:
$$min_xmax_{w,v}J\tag{2}$$
where $J$ is:
$$J=\frac{\sum\limits_{k=0}^{N-1}{\left|\left|z_k - \hat{z}_k\right|\right|_{Q_k}^2}}{\left|\left|x_0 - \hat{x}_0\right|\right|_{P_0}^2+\sum\limits_{k=0}^{N-1}{\left|\left|w_k\right|\right|_{W_k}^2+\left|\left|v_k\right|\right|_{V_k}^2}}\tag{3}$$
Theorem: Let $\gamma>0$ be a prescribed level of noise attenuation. Then there exists a $H_\infty$ filter for $z_k$ if and only if there exists a stabilizing symmetric solution $P_k>0$ to the following discrete-time Ricatti equation:

 $$P_{k+1}=A_kP_k(I-\gamma Q_kP_k+C_k^TV_k^{-1}C_kP_k)^{-1}A_k^T+B_kW_kB_k^T\tag{4}$$
where
$$\hat{x}_{k+1}=A \hat{x}_k+B u_k+K_k(y_k-C_k\hat{x}_k)\tag{5}$$
The $K_k$ is the gain of the $H_\infty$ filter and it is given by:
$$K_k=A_kP_k(I-\gamma Q_kP_k+C_k^TV_k^{-1}C_kP_k)^{-1}C_k^TV_k^{-1}\tag{6}$$
Proof: Xuemin Shen and Li Deng: Game Theory Approach to Discrete $H_\infty$ Filter Design

As you can see the filter gain doesn’t depend from the states of the system so it's possible to calculate offline.

Cpp implementation

On github you can find a C++ implementation of the $H_\infty$ filter, this is only a chunk of the C++ class.
/*
  *@summary: The filter gain calculation
  *@param A: State space model A matrix
  *@param B: State space mode B matrix
  *@return: Filter Gain
  */
 Matrix HINF::calkGain(Matrix A, Matrix B) {
  if (A.rows() != P.cols())
   ERRORH::throwerror("A rows has to be equal with P columns");

  Matrix I = Matrix::Identity(A.cols(), A.cols());

  Matrix L = (I - lambda * Q * P + C.transpose() * V.inverse() * C * P).inverse();

  P = A * P * L * A.transpose() + B * W * B.transpose();

  K = A * P * L * C.transpose() * V.inverse();

  return K;
 }

 /*
  *@summary: Update the state
  *@param A: State space model A matrix
  *@param B: State space mode B matrix
  *@return: The new state
  */
 Matrix HINF::updateState(Matrix A, Matrix B, Matrix u) {
  x = A * x + B * u;
  return x;
 }

 /*
  *@sumary: Estimate the next states
  *@param M: Measured state
  */
 Matrix HINF::estimate(Matrix M) {

  x = x + K * (M - C * x);

  return x;
 }

Readings:


  • Kemin Zhou: ESSENTIALS OF ROBUST CONTROL
  • Xuemin Shen and Li Deng: Game Theory Approach to Discrete $H_\infty$ Filter Design

Wednesday, October 3, 2012

ACIM speed estimation

In case if we would like to know the induction motor rotor speed, we can use Extended Kalman Filter(EKF) to estimate the unknown states. Here is a good tutorial where you can find more information about the EKF. Also you can read the article on the Wikipedia. I'm using the FOC block in Matlab to get the motor control current, voltage and the angle between the fluxes, just for testing purpose.
I assume that the rotor speed is constant so $\frac{d\omega_r}{dt}=0$. In this case we have the following model
$$
A= \begin{bmatrix} -\frac{R_s+\frac{L_m^2R_r}{L_r^2}}{L_s\sigma} & 0 &  \frac{L_m}{L_s\sigma L_r\tau_r} & \frac{\omega_rL_m}{L_s\sigma L_r} & 0 \\ 0 & -\frac{R_s+\frac{L_m^2R_r}{L_r^2}}{L_s\sigma}  & -\frac{\omega_rL_m}{L_s\sigma L_r} & \frac{L_m}{L_s\sigma L_r\tau_r} & 0 \\ \frac{L_m}{\tau_r} & 0 & -\frac{1}{\tau_r} & -\omega_r & 0 \\ 0 & \frac{L_m}{\tau_r} &   \omega_r & -\frac{1}{\tau_r}  & 0 \\ 0 & 0 & 0 & 0 & 0\end{bmatrix}\tag{1}
$$
$$B=\begin{bmatrix} \frac{1}{L_s\sigma} & 0 \\ 0 & \frac{1}{L_s\sigma} \\ 0 & 0 \\ 0 & 0 \\ 0 & 0 \end{bmatrix}\tag{2}$$

We can discretize the model using the following approach:
$$A_d=e^{AT} \approx I+AT\tag{3} $$
$$B_d=\int_0^T e^{At}B dt \approx BT\tag{4}$$

The Simulink model is the following

In the block above, the second and third module are the Clarke's and Park's transformation, in the previous articles I already defined this transformations. The code of the speed and flux estimator is

function [xx_out,PP_out,error,W]=ekf(I,U,Ts)
% EKF   Extended Kalman Filter  
% induction motor's parameters   
persistent PP;
persistent xx;

if isempty(PP)
    xx = [0 0 0 0 0 ]';
    %[i_alfa , i_beta , Fi_r_alfa , Fi_r_beta , W_r ]
    PP = 1e-2*diag([1 1 1 1 1]);
end
Q =  diag([1e-4 1e-4 1e-9 1e-9 5e-4]);
R =  1e1*diag([1 1]);

L_r=0.479;
L_s=0.423;
L_m=0.421;
R_s=5.27;
R_r=5.07;

tau_r = L_r/R_r;
gamma_r = 1-(L_m^2)/(L_s*L_r);
T_r = R_s+(L_m^2*R_r)/L_r^2;
 
Ak =[ 1-Ts*(T_r/(L_s*gamma_r)),          0,        Ts*(L_m/(L_s*gamma_r*L_r*tau_r)),        Ts*((xx(5)*L_m)/(L_s*gamma_r*L_r)),        0;
    0,                  1-Ts*(T_r/(L_s*gamma_r)), -Ts*((xx(5)*L_m)/(L_s*gamma_r*L_r)),     Ts*(L_m/(L_s*gamma_r*L_r*tau_r)),        0;
    Ts*(L_m/tau_r),                  0,                   1-Ts*(1/tau_r),                  -Ts*xx(5),                                    0;
    0,                      Ts*(L_m/tau_r),                  Ts*xx(5),                      1-Ts*(1/tau_r),                         0;
    0                           0                           0                    0                                           1];

Bk = [Ts/(L_s*gamma_r)              0;
            0                Ts/(L_s*gamma_r);
            0                       0;
            0                       0;
            0                       0];

%Predictor
xx = Ak*xx+Bk*U;


Gk =[ 1-Ts*(T_r/(L_s*gamma_r)),          0,        Ts*(L_m/(L_s*gamma_r*L_r*tau_r)),        Ts*((xx(5)*L_m)/(L_s*gamma_r*L_r)),        Ts*((xx(4)*L_m)/(L_s*gamma_r*L_r));
    0,                  1-Ts*(T_r/(L_s*gamma_r)), -Ts*((xx(5)*L_m)/(L_s*gamma_r*L_r)),     Ts*(L_m/(L_s*gamma_r*L_r*tau_r)),        -Ts*((xx(3)*L_m)/(L_s*gamma_r*L_r));
    Ts*(L_m/tau_r),                  0,                   1-Ts*(1/tau_r),                  -Ts*xx(5),                                    -Ts*xx(4);
    0,                      Ts*(L_m/tau_r),                  Ts*xx(5),                      1-Ts*(1/tau_r),                         Ts*xx(3);
    0                           0                           0                           0                                           1];

H = [1 0 0 0 0;
     0 1 0 0 0;];

PP=Gk*PP*Gk'+Q;

%Coorection
KalG=PP*H'*inv(H*PP*H'+R);
error = I-H*xx;
xx=xx+KalG*(error);
PP=(eye(5)-KalG*H)*PP;

xx_out = xx;
PP_out=PP;

W = xx(5);

I spent a lot of time to tune the filter matrices Q,R, but this is the best result what I got.
I wasn't satisfied with the result above so I extended this model with the torque, in this case the rotor speed can be expressed as follows:
$$
\frac{d\omega_r}{dt} =\frac{3p^2L_m}{8JL_r}\left(i_{sq}\psi_{rd}-i_{sd}\psi_{rq}\right)-\frac{p}{2J}T_l\tag{5}
$$
we assume that the torque is constant or the changes between two sampling time is very small
$$
\frac{dT_l }{dt}=0\tag{6}
$$
In this case the EKF's code is
function [xx_out,PP_out,error,W]=ekf(I,U,Ts)
% EKF   Extended Kalman Filter  
% induction motor's parameters   
persistent PP;
persistent xx;

if isempty(PP)
    xx = [0 0 0 0 0 0]';
    %[i_alfa , i_beta , Fi_r_alfa , Fi_r_beta , W_r ]
    PP = 1e-8*diag([1 1 1 1 1 1]);
end
Q =  diag([1e-3 1e-3 1e-9 1e-9 1e-5 1e-5]);
R =  1e-3*diag([1 1]);

L_r=0.479;
L_s=0.423;
L_m=0.421;
R_s=5.27;
R_r=5.07;
p = 2;
J =0.02;
fv = 0.0038;

m = (3*p^2*L_m)/(8*J*L_r);

tau_r = L_r/R_r;
gamma_r = 1-(L_m^2)/(L_s*L_r);
T_r = R_s+(L_m^2*R_r)/L_r^2;
 
Ak =[ 1-Ts*(T_r/(L_s*gamma_r)),          0,        Ts*(L_m/(L_s*gamma_r*L_r*tau_r)),        Ts*((xx(5)*L_m)/(L_s*gamma_r*L_r)),             0       0;
    0,                  1-Ts*(T_r/(L_s*gamma_r)), -Ts*((xx(5)*L_m)/(L_s*gamma_r*L_r)),     Ts*(L_m/(L_s*gamma_r*L_r*tau_r)),                0       0;
    Ts*(L_m/tau_r),                  0,                   1-Ts*(1/tau_r),                  -Ts*xx(5),                                       0       0;
    0,                      Ts*(L_m/tau_r),                  Ts*xx(5),                      1-Ts*(1/tau_r),                                 0       0;
    -Ts*m*xx(4)                  Ts*m*xx(3)                       0                               0                                   1           (-p*Ts)/(J*2);
           0                    0                               0                               0                                   0               1];

Bk = [Ts/(L_s*gamma_r)              0;
            0                Ts/(L_s*gamma_r);
            0                       0;
            0                       0;
            0                       0;
            0                       0];

%Predictor
xx = Ak*xx+Bk*U;


Gk =[ 1-Ts*(T_r/(L_s*gamma_r)),          0,        Ts*(L_m/(L_s*gamma_r*L_r*tau_r)),        Ts*((xx(5)*L_m)/(L_s*gamma_r*L_r)),        Ts*((xx(4)*L_m)/(L_s*gamma_r*L_r))   0;
    0,                  1-Ts*(T_r/(L_s*gamma_r)), -Ts*((xx(5)*L_m)/(L_s*gamma_r*L_r)),     Ts*(L_m/(L_s*gamma_r*L_r*tau_r)),        -Ts*((xx(3)*L_m)/(L_s*gamma_r*L_r))     0;
    Ts*(L_m/tau_r),                  0,                   1-Ts*(1/tau_r),                  -Ts*xx(5),                                    -Ts*xx(4)                          0;
    0,                      Ts*(L_m/tau_r),                  Ts*xx(5),                      1-Ts*(1/tau_r),                                 Ts*xx(3)                        0;
    -Ts*m*xx(4)              Ts*m*xx(3)                       Ts*m*xx(2)                       -Ts*m*xx(1)                                      1                           (-p*Ts)/(J*2);
    0                               0                           0                           0                           0                                           1];                         
             
H = [1 0 0 0 0 0;
     0 1 0 0 0 0;];

PP = Gk*PP*Gk'+Q;


KalG = PP*H'*inv(H*PP*H'+R);
error = I-H*xx;
xx = xx + KalG*(error);
PP = (eye(6)-KalG*H)*PP;

xx_out = xx;
PP_out = PP;

W = xx(5);

The result is

The error between the measured and the estimated is smaller than the previous model, also it was easier to tune the estimator. The disadvantage of the model, that is has six state which means that the calculations takes longer than the previous model.