root/applications/pmsm/simulator_zdenek/ekf_example/mpf_double.cpp @ 1469

Revision 1469, 6.7 kB (checked in by smidl, 10 years ago)

upravy rand

Line 
1#include <math.h>
2#include <stdio.h>
3#include "fast_exp.h"
4#include "fastexp.h"
5#include "mpf_double.h"
6
7//Parameters of PMSM
8#define Lsd (3.465e-3*0.9)      //      *0.9)//H        ... zajimave - chodi to i pri Lsd = Lsq
9#define Lsq 3.465e-3//H
10//#define Ls  3.465e-3//H
11#define Rs 0.28//Ohm
12#define Fpm (0.1989*1.1)        //*1.15)        //V.s           // !!xx!!
13#define pp 4
14#define Ism 35.//40.
15
16static floatx om[N];
17static floatx Pt[N];
18static floatx sth[N];
19static floatx cth[N];
20static floatx isdm[N];
21static floatx isqm[N];
22static floatx th[N];
23static floatx w[N];
24static floatx lwi[N];
25static int i_best;
26
27static floatx qth;
28static floatx qom;
29static floatx r;
30static floatx rinv;
31
32// staticke promenne pro model
33static float _ad;
34static float _aq;
35static float _b;
36static float _cd;
37static float _cq;
38static float _dd;
39static float _dq;
40
41
42void resample() {
43        int N_babies[N];
44        floatx cumdist;
45        int i;
46        floatx ui;
47        int i_from=0;
48        int i_to=0;
49
50        floatx u0 = qrandu();
51
52        int j=0;
53        N_babies[0]=0;
54        cumdist = w[0];
55        for ( i = 0; i < N; i++ ) {
56                ui  = ( i + u0 ) / N;
57                while ( ui > cumdist ) {
58                        j++;
59                        N_babies[j]=0;
60                        cumdist+=w[j];
61                }
62                N_babies [j] ++;
63        }
64        while (j++<=(N-1)) { // delete all N_babies after j
65                N_babies[j]=0; 
66        }
67
68        // COPY
69
70        while ( i_from<N ) {
71                w[i_from]=1.0/N;
72                while ( N_babies[i_from]>1 ) { // 1 baby stays where it is
73                       
74                        while ( N_babies[i_to]>=1 ) i_to++; // find first empty slot
75
76                        //copy it
77                        Pt[i_to]=Pt[i_from];
78                        om[i_to]=om[i_from];
79                        th[i_to]=th[i_from];
80                        isdm[i_to]=isdm[i_from];
81                        isqm[i_to]=isqm[i_from];
82
83                        N_babies[i_to]++;
84                        N_babies[i_from]--;
85                }
86                i_from++;
87        }
88}
89
90void mpf_bayes ( const floatx isa, const floatx isb , const floatx usa, const floatx usb ) {
91
92        floatx isd;
93        floatx isq;
94        floatx usd;
95        floatx usq;
96
97        floatx Cd;
98        floatx Cq;
99        floatx CC;
100        floatx oCC;
101
102        floatx difid;
103        floatx difiq;
104
105        floatx zeta;
106        floatx Kd;
107        floatx Kq;
108        floatx ro;
109        floatx ypd;
110        floatx ypq;
111        floatx detRy;
112        floatx ydiffd;
113        floatx ydiffq;
114        floatx ydC;
115
116        floatx maxlwi, sumlwi,sumw2,neff_th;
117        int i;
118       
119        floatx *th_i, *Pt_i, *om_i, *isdm_i, *isqm_i;
120        floatx *w_i, *lw_i;
121        floatx *sth_i, *cth_i;
122        floatx sumw_inv;
123// implementation starts here
124        th_i = &th[0];
125        Pt_i = &Pt[0];
126        om_i = &om[0];
127        isdm_i = &isdm[0];
128        isqm_i = &isqm[0];
129        sth_i = &sth[0];
130        cth_i = &cth[0];
131        for ( i=0; i<N; i++ ) {
132
133          /////////////////////////// HACK!!!!!!!!!!!
134          //om[i] = 0;
135          /////////////////////////// HACK!!!!!!!!!!!
136         
137                // time update
138                *Pt_i = 1.0*1.0*(*Pt_i)+qom; // Pt is now predictive variance
139                floatx ff =qrandn() ;
140//              printf("%f\n", ff);
141                *th_i += *om_i*_dt+qth * ff; 
142                while ( *th_i>M_PI ) *th_i -=2*M_PI;
143                while ( *th_i<-M_PI ) *th_i+=2*M_PI;
144
145                *sth_i=sin ( *th_i );
146                *cth_i=cos ( *th_i );
147               
148                isd = *cth_i*isa+*sth_i*isb;
149                isq = -*sth_i*isa+*cth_i*isb;
150                // process old voltage
151                usd = (*cth_i)*usa+(*sth_i)*usb;
152                usq = -(*sth_i)*usa+(*cth_i)*usb;
153
154                Cd = isq*_dd;
155                Cq = -_b - isd* _dq;
156
157                difid=isd- _ad  * (*isdm_i) - _cd *(usd);
158                difiq=isq- _aq  * (*isqm_i) - _cq *(usq);
159
160                CC=Cd*Cd+Cq*Cq;
161                zeta = *Pt_i/ ( r+*Pt_i*CC );
162                oCC = ( 1-zeta*CC );
163                ro = oCC*rinv;
164
165                Kd = *Pt_i*Cd*ro;
166                Kq = *Pt_i*Cq*ro;
167
168                (*Pt_i)*=( 1.0- ( Kd*Cd+Kq*Cq ) );
169
170                ypd = Cd**om_i;
171                ypq = Cq**om_i;
172
173                //detRy = ro/r;
174                *om_i +=  Kd* ( difid - ypd ) +Kq* ( difiq-ypq );
175                ydiffd = ( ypd-difid );
176                ydiffq = ( ypq-difiq );
177                ydC = ydiffd*Cd + ydiffq*Cq;
178
179                //lwi[i] = 0.5* ( log ( detRy ) + ( ydC*ydC*zeta -(ydiffd*ydiffd+ydiffq*ydiffq) ) /r ) ;
180                lwi[i] = 0.5*( ydC*ydC*zeta -(ydiffd*ydiffd+ydiffq*ydiffq) ) *rinv ;
181               
182                *isdm_i=isd;
183                *isqm_i=isq;
184               
185                // shift all counters
186                th_i++;
187                Pt_i++;
188                om_i++;
189                isdm_i++;
190                isqm_i++;
191                sth_i++;
192                cth_i++;
193
194        }
195        maxlwi=-1e10;
196        lw_i = &lwi[0];
197        i_best = 0;
198        for ( i=0;i<N;i++,lw_i++ ) {
199                if ( *lw_i>maxlwi ) {maxlwi=*lw_i;i_best=i;}
200        }
201/*!!*/
202        lw_i = &lwi[0];
203        w_i = &w[0];
204        for ( i=0;i<N;i++,lw_i++,w_i++ ) {
205                *lw_i-=maxlwi;
206                (*w_i)*=fasterexp ( *lw_i ); // do not always resample
207        }
208
209        sumlwi=0.0;
210        sumw2=0.0;
211        w_i = &w[0];
212        for ( i=0;i<N;i++,w_i++ ) {sumlwi+=*w_i;sumw2+=*w_i**w_i;}
213        sumw_inv = 1.0/sumlwi; // multiplication is faster than division!
214        w_i = &w[0];
215        for ( i=0;i<N;i++,w_i++ ) *w_i*=sumw_inv;
216       
217        neff_th = 0.8*N*sumw2*sumw_inv*sumw_inv;
218        if (1<neff_th)
219          resample();
220}
221
222
223void mpf_init(floatx qom0, floatx qth0, floatx r0) {
224       
225//      rng_init();
226       
227        int i;
228        r=r0;
229        rinv = 1.0/r;
230        qth=qth0;
231        qom=qom0;
232
233        for ( i=0; i<N; i++ ) {
234                th[i]=qrandu() *2*M_PI - M_PI;
235                sth[i]=sin ( th[i] );
236                cth[i]=cos ( th[i] );
237               
238                om[i]=0;
239                Pt[i]=10.;
240                isdm[i]=0;
241                isqm[i]=0;
242                w[i]=1.0/N;
243        }
244
245   // inicializace promennych
246   #if (VYBER_MODELU==0)
247    // plny model s respektovanim Lsd/Lsq
248    _ad = (1.-Rs*_dt/(Lsd));
249    _aq = (1.-Rs*_dt/(Lsq));
250    _b = Fpm/Lsq*_dt;
251    _cd = _dt/(Lsd);
252    _cq = _dt/(Lsq);
253    _dd = _dt*Lsq/Lsd;
254    _dq = _dt*Lsd/Lsq; /**/
255  #else
256  // parametry modelu identifikovane z namerenych dat z prototypu v EL204
257    _ad = 0.9880;
258    _aq = 0.9817;
259    _b = 0.0076;
260    _cd = 0.0289;
261    _cq = 0.0292;
262    _dd = _dt;
263    _dq = _dt;
264  #endif   
265
266}
267void mpf_mean ( floatx *Ecosth, floatx *Esinth, floatx *Eome ) {
268        int i;
269        floatx *w_i=&w[0];
270        floatx *cth_i=&cth[0];
271        floatx *sth_i=&sth[0];
272        floatx *om_i=&om[0];
273        *Ecosth=0.0;
274        *Esinth=0.0;
275        *Eome=0.0;
276        for ( i=0;i<N;i++,w_i++,cth_i++,sth_i++,om_i++ ) {
277                *Ecosth+=(*w_i)*(*cth_i);
278                *Esinth+=(*w_i)*(*sth_i);
279                *Eome+=(*w_i)*(*om_i);
280        }
281
282}
283
284void mpf_best( floatx *Ecosth, floatx *Esinth, floatx *Eome ) 
285{
286        *Ecosth=cth[i_best];
287        *Esinth=sth[i_best];
288        *Eome=om[i_best];
289}
290
291
292void mpf_th(floatx th1[N]){
293        int i;
294        for (i=0;i<N;i++) th1[i]=th[i];
295}
296void mpf_om(floatx om1[N]){
297        int i;
298        for (i=0;i<N;i++) om1[i]=om[i];
299}
300
301floatx kalman_om( const floatx isa, const floatx isb , const floatx usa, const floatx usb, const floatx th ) {
302
303        floatx isd;
304        floatx isq;
305        floatx usd;
306        floatx usq;
307
308        floatx Cd;
309        floatx Cq;
310        floatx CC;
311        floatx oCC;
312
313        floatx difid;
314        floatx difiq;
315
316        floatx zeta;
317        floatx Kd;
318        floatx Kq;
319        floatx ro;
320        floatx ypd;
321        floatx ypq;
322        floatx detRy;
323        floatx ydiffd;
324        floatx ydiffq;
325        floatx ydC;
326
327        static floatx Pt;
328        static floatx om;
329        floatx cth, sth;
330        static floatx isdm, isqm;
331
332       
333                Pt = 1.0*1.0*Pt+qom; // Pt is now predictive variance
334                //while ( th>M_PI ) th=th-2*M_PI;
335                //while ( th<-M_PI ) th=th+2*M_PI;
336
337                sth=sin ( th );
338                cth=cos ( th );
339
340                isd = cth*isa+sth*isb;
341                isq = -sth*isa+cth*isb;
342                usd = cth*usa+sth*usb;
343                usq = -sth*usa+cth*usb;
344
345                Cd = isq*_dd;
346                Cq = -_b - isd* _dq;
347
348                difid=isd- _ad  *isdm - _cd *usd;
349                difiq=isq- _aq  *isqm - _cq *usq;
350
351                CC=Cd*Cd+Cq*Cq;
352                zeta = Pt/ ( r+Pt*CC );
353                oCC = ( 1-zeta*CC );
354                ro = oCC*rinv;
355
356                Kd = Pt*Cd*ro;
357                Kq = Pt*Cq*ro;
358
359                Pt=Pt* ( 1- ( Kd*Cd+Kq*Cq ) );
360
361                ypd = Cd*om;
362                ypq = Cq*om;
363
364                detRy = ro*rinv;
365                om = om + Kd* ( difid - ypd ) +Kq* ( difiq-ypq );
366                ydiffd = ( ypd-difid );
367                ydiffq = ( ypq-difiq );
368                ydC = ydiffd*Cd + ydiffq*Cq;
369
370                isdm=isd;
371                isqm=isq;
372               
373                return om;
374}
Note: See TracBrowser for help on using the browser.