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

Revision 1468, 5.8 kB (checked in by smidl, 11 years ago)

uprava generatoru

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