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

Revision 1442, 5.5 kB (checked in by smidl, 12 years ago)

festerexp

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