root/applications/pmsm/simulator_zdenek/ekf_example/Zdrojove kody_final/DSP/Bierman/ekf_Bierman.c @ 1263

Revision 1263, 5.5 kB (checked in by peroutka, 13 years ago)
Line 
1/************************************
2        Extended Kalman Filter
3        Kalman Observer
4
5        Z. Peroutka
6
7Rev. 25.10.2010
8
9EKF pocitan dle Grewala - Biermanova varianta
10
1130.9.2010       Dodana testovaci rutina test_debug() umoznujici reinicializaci x_est.
1225.10.2010      Rev. 2.
1328.10.2010              xx
14
15
16*************************************/
17
18#include "funkce.h"
19#include "parametry_motoru.h"         // aktivovat v DSP
20#include "reference_Q15.h"
21//#include "reference.h"
22#include "matrix_vs.h"
23#include "ekf_bierman.h"
24#include "parametry_motoru.h"
25#include "qmath.h"
26
27#define K_PREVOD_FORM   (1<<(15-Qm))               // 2^(15-Qm)
28#define pi2_3           21845                           // 2/3*PI
29
30#define D_INIT  (1<<qD)
31
32/* Declaration of global functions */
33void init_ekf(double Tv);
34void ekf(int *x_estimation, int Um, int beta, int Ucn, int Uc, int isx, int isy);
35
36/* Declaration of local functions */
37static void prediction(int *ux);
38static void correction(void);
39static void update_psi(void);
40
41// Constants - definovat jako konstanty ?? ?kde je vyhodnejsi aby v pameti byli?
42static int Q[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* matrix [4,4] */
43static int R[4]={0,0,0,0}; /* matrix [2,2] */
44
45static int PSI[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* matrix [4,4] */
46
47/* Initial conditions and variables */
48static int x_est[4]={0,0,0,0};
49static int x_pred[4]={0,0,0,0};
50
51static int Y_mes[2]={0,0};
52static int ukalm[2]={0,0};
53
54// matice pro Biermana
55static int U[16]={0x7FFF,0,0,0,0,0x7FFF,0,0,0,0,0x7FFF,0,0,0,0,0x7FFF}; /* matrix [4,4] */
56static int PSIU[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* matrix [4,4] */
57static int D[4]={D_INIT,D_INIT,D_INIT,D_INIT};
58
59// constants of PMSM mathematical model
60static int cA, cB, cC, cG, cH;  // cD, cE, cF, cI ... nepouzivane
61
62//////////////////////////////////////////////////////////////////////////////////////////////////////
63void init_ekf(double Tv)
64{
65  // Tuning of matrix Q
66  // Tuning of matrix Q         ... 0.05, 2e-4, 1e-3    // Vencovi dle MPF vyslo, q11=q22=0.023, q33=2e-4, q44=7e-4
67/*  Q[0]=prevod(0.02,15);       // 0.05
68  Q[5]=Q[0];
69  Q[10]=prevod(0.0002,15);     // 0.0002
70  Q[15]=prevod(0.001,15);      // 1e-3
71
72  // Tuning of matrix R
73  R[0]=prevod(0.1,15);         // 0.1
74  R[3]=R[0];
75/**/
76// 28.10.2010: 0.001; 0.0005; 0.0001
77  Q[0]=prevod(0.01,15);         // puvodne: Q11=0.02; Q33=0.0002; Q44=0.001
78  Q[5]=Q[0];                                     // VS: 0.001; 0.001; 0.0001
79  Q[10]=prevod(0.001,15);               // 0.01 na vsech variancich
80  Q[15]=prevod(0.0005,15);
81
82  // Tuning of matrix R
83  R[0]=prevod(0.05,15);                 // puvodni: 0.1; test: 0.08
84  R[3]=R[0];
85/**/
86
87  // Motor model parameters
88  cA=prevod(1-Tv*Rs/Ls,15);
89  cB=prevod(Tv*Wref*Fmag/Iref/Ls,15);
90  cC=prevod(Tv/Ls/Iref*Uref,15);
91//  cD=prevod(1-Tv*Bf/J,15);
92//  cE=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref,15);
93//  cF=prevod(p*Tv*Mref/J/Wref,15);
94  cG=prevod(Tv*Wref*K_PREVOD_FORM/Thetaref,15);
95//  cH=prevod(Tv*Wref*Fmag/Iref/Ls*Thetaref,15);
96  cH=prevod(Tv*Wref*Fmag/Iref/Ls,15);
97//  cI=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref*Thetaref);
98
99  /* Init matrix PSI with permanently constant terms */
100  PSI[0]=cA;
101  PSI[5]=PSI[0];
102  PSI[10]=0x7FFF;
103  PSI[14]=cG;
104  PSI[15]=0x7FFF;
105}
106
107
108static void update_psi(void)
109{
110  int t_sin,t_cos,tmp;
111
112  // implementace v DSP
113  t_sin=qsin(x_est[3]);
114  t_cos=qcos(x_est[3]);
115//  t_sin=prevod(qsin(Thetaref*x_est[3]/32768.),15);
116//  t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15);
117
118  PSI[2]=((long)cB*t_sin)>>15;
119  tmp=((long)cH*x_est[2])>>15;
120  PSI[3]=((long)tmp*t_cos)>>15;
121  PSI[6]=-((long)cB*t_cos)>>15;
122  PSI[7]=((long)tmp*t_sin)>>15;
123}
124
125
126static void prediction(int *ux)
127{
128  int t_sin,t_cos, tmp;
129
130  int G[16];
131  int Dold[4];
132
133  // implementace v DSP
134  t_sin=qsin(x_est[3]);
135  t_cos=qcos(x_est[3]);
136//  t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15);
137//  t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15);
138
139  tmp=((long)cB*x_est[2])>>15;
140  x_pred[0]=((long)cA*x_est[0]+(long)tmp*t_sin+(long)cC*ux[0])>>15;
141  x_pred[1]=((long)cA*x_est[1]-(long)tmp*t_cos+(long)cC*ux[1])>>15;
142  x_pred[2]=x_est[2];
143  x_pred[3]=(((long)x_est[3]<<15)+(long)cG*x_est[2])>>15;
144
145  update_psi();
146
147  // Thorton
148  mmultAU(PSI,U,PSIU,4,4);
149  thorton_fast(U,D,PSIU,Q,G,Dold,4);
150}
151
152static void correction(void)
153{
154  int Y_error[2];
155  unsigned int ii;
156  int dR[2];
157
158  // prediction error
159  Y_error[0]=Y_mes[0]-x_pred[0];
160  Y_error[1]=Y_mes[1]-x_pred[1];
161
162  // copy prediction to state exstimation vector
163  for (ii=0;ii<4;ii++) x_est[ii]=x_pred[ii];
164
165  // copy diagonal from matrix R
166  dR[0]=R[0];
167  dR[1]=R[3];
168
169  // Bierman_fast - correction
170  bierman_fast(Y_error,x_est,U,D,dR,2,4);
171}
172
173
174void ekf(int *x_estimation, int Um, int beta, int Ucn, int Uc, int isx, int isy)
175{
176  int Umk, ua, ub;
177
178  // prepocet napeti pro EKF dle skutecneho napeti v ss obvodu
179  Umk=((long)Um*Uc)/Ucn;
180
181  // vypocet napeti v systemu (x,y)
182  ukalm[0]=((long)Umk*qcos(beta))>>15;          // usx
183  ukalm[1]=((long)Umk*qsin(beta))>>15;          // usy
184
185  // zadani mereni
186  Y_mes[0]=isx;
187  Y_mes[1]=isy;
188
189  ////// vlastni rutina EKF /////////////////////////
190  prediction(ukalm);
191  correction();
192
193  // navrat estimovanych hodnot regulatoru
194  *x_estimation=x_est[2];
195  *(x_estimation+1)=x_est[3];
196}
197
198void reset_ekf(void)
199{
200  int ii;
201
202  for (ii=0;ii<4;ii++) x_est[ii]=0;
203  for (ii=0;ii<4;ii++) x_pred[ii]=0;
204
205  for (ii=0;ii<4;ii++) D[ii]=1<<qD;
206
207  for (ii=0;ii<16;ii++) PSIU[ii]=0;
208  for (ii=0;ii<16;ii++) U[ii]=0;
209  U[0]=0x7FFF;
210  U[5]=0x7FFF;
211  U[10]=0x7FFF;
212  U[15]=0x7FFF;
213/**/
214}
Note: See TracBrowser for help on using the browser.