root/applications/pmsm/pmsmDS.h @ 686

Revision 686, 9.4 kB (checked in by smidl, 15 years ago)

pmsm using new syntax for bayes

  • Property svn:eol-style set to native
Line 
1/*!
2  \file
3  \brief DataSource for experiments with realistic simulator of the PMSM model
4  \author Vaclav Smidl.
5
6  -----------------------------------
7  BDM++ - C++ library for Bayesian Decision Making under Uncertainty
8
9  Using IT++ for numerical operations
10  -----------------------------------
11*/
12
13#include <base/loggers.h>
14#include <estim/kalman.h>
15#include "simulator_zdenek/simulator.h"
16#include "pmsm.h"
17
18using namespace bdm;
19
20//! Simulator of PMSM machine with predefined profile on omega
21class pmsmDS : public DS
22{
23
24protected:
25    //! indeces of logged variables
26    int L_x, L_ou, L_oy, L_iu, L_optu;
27    //! Setpoints of omega in timespans given by dt_prof
28    vec profileWw;
29    //! Setpoints of Mz in timespans given by dt_prof
30    vec profileMz;
31    //! time-step for profiles
32    double dt_prof;
33    //! Number of miliseconds per discrete time step
34    int Dt;
35    //! options for logging, - log predictions of 'true' voltage
36    bool opt_modu;
37    //! options for logging, -
38public:
39    //! Constructor with fixed sampling period
40    pmsmDS () : DS()
41    {
42        Dt=125;
43        Yrv=RV ( "{o_ua o_ub o_ia o_ib t_ua t_ub o_om o_th Mz }" );
44                ytsize = Yrv._dsize();
45                Drv = Yrv;
46    }
47    void set_parameters ( double Rs0, double Ls0, double Fmag0, double Bf0, double p0, double kp0, double J0, double Uc0, double DT0, double dt0 )
48    {
49        pmsmsim_set_parameters ( Rs0, Ls0, Fmag0, Bf0, p0, kp0, J0, Uc0, DT0, dt0 );
50    }
51    //! parse options: "modelu" => opt_modu=true;
52    void set_options ( string &opt )
53    {
54        opt_modu = ( opt.find ( "modelu" ) !=string::npos );
55    }
56    void getdata ( vec &dt ) const
57    {
58        dt.set_subvector(0,vec ( KalmanObs,6 ));
59        dt(6)=x[2];
60        dt(7)=x[3];
61        dt(8)=x[8];
62    }
63    void write ( vec &ut ) {}
64
65    void step()
66    {
67        static int ind=0;
68        static double dW; // increase of W
69        static double Ww; // W
70        static double Mz; // W
71        if ( t>=dt_prof*ind )
72        {
73            ind++;
74            // check omega profile and set dW
75                        if ( ind <2 && profileWw.length() ==1 )
76                        {
77                                Ww=profileWw ( 0 );
78                                dW=0.0;
79                        }
80                        if ( ind<profileWw.length() )
81            {
82                    dW = profileWw ( ind )-profileWw ( ind-1 );
83                    dW *=125e-6/dt_prof;
84            }
85            else
86            {
87                dW = 0;
88            }
89            // Check Mz profile and set Mz
90            if ( ind<profileMz.length() )
91            {
92                //sudden increase
93                Mz = profileMz(ind);
94            }
95            else
96            {
97                Mz = 0;
98            }
99        }
100        Ww += dW;
101        //Simulate Dt seconds!
102        for ( int i=0; i<Dt; i++ )
103        {
104            pmsmsim_step ( Ww , Mz);
105        }
106//              for ( int i=0;i<Dt;i++ ) {      pmsmsim_noreg_step ( Ww , Mz);}
107
108        //discretization
109        double ustep=1.2;
110        KalmanObs [ 0 ] = ustep*itpp::round( KalmanObs [ 0 ]/ ustep) ;
111        KalmanObs [ 1 ] = ustep*itpp::round(KalmanObs [ 1 ]/ ustep);
112        double istep=0.085;
113        KalmanObs [ 2 ] = istep*itpp::round( KalmanObs [ 2 ]/ istep) ;
114        KalmanObs [ 3 ] = istep*itpp::round(KalmanObs [ 3 ]/ istep);
115
116    };
117
118    void log_register ( logger &L )
119    {
120        L_x = L.add ( rx, "x" );
121        L_oy = L.add ( ry, "o" );
122        L_ou = L.add ( ru, "o" );
123        L_iu = L.add ( ru, "t" );
124        // log differences
125        if ( opt_modu )
126        {
127            L_optu = L.add ( ru, "model" );
128        }
129    }
130
131    void log_write ( logger &L )
132    {
133        L.logit ( L_x, vec ( x,4 )      );
134        L.logit ( L_oy, vec_2 ( KalmanObs[2],KalmanObs[3] ) );
135        L.logit ( L_ou, vec_2 ( KalmanObs[0],KalmanObs[1] ) );
136        L.logit ( L_iu, vec_2 ( KalmanObs[4],KalmanObs[5] ) );
137        if ( opt_modu )
138        {
139            double sq3=sqrt ( 3.0 );
140            double ua,ub;
141            double i1=x[0];
142            double i2=0.5* ( -i1+sq3*x[1] );
143            double i3=0.5* ( -i1-sq3*x[1] );
144            double u1=KalmanObs[0];
145            double u2=0.5* ( -u1+sq3*KalmanObs[1] );
146            double u3=0.5* ( -u1-sq3*KalmanObs[1] );
147
148            double du1=1.4* ( double ( i1>0.3 ) - double ( i1<-0.3 ) ) +0.2*i1;
149            double du2=1.4* ( double ( i2>0.3 ) - double ( i2<-0.3 ) ) +0.2*i2;
150            double du3=1.4* ( double ( i3>0.3 ) - double ( i3<-0.3 ) ) +0.2*i3;
151            ua = ( 2.0* ( u1-du1 )- ( u2-du2 )- ( u3-du3 ) ) /3.0;
152            ub = ( ( u2-du2 )- ( u3-du3 ) ) /sq3;
153            L.logit ( L_optu , vec_2 ( ua,ub ) );
154        }
155
156    }
157
158    void set_profile ( double dt, const vec &Ww, const vec &Mz )
159    {
160        dt_prof=dt;
161        profileWw=Ww;
162        profileMz=Mz;
163    }
164
165    void from_setting( const Setting &root )
166    {
167                const SettingResolver& params_l(root["params"]);
168                const Setting &params = params_l.result;
169        set_parameters ( params["Rs"], params["Ls"], params["Fmag"], \
170                         params["Bf"], params["p"], params["kp"], \
171                         params["J"], params["Uc"], params["DT"], 1.0e-6 );
172
173        // Default values of profiles for omega and Mz
174        vec profW=vec("1.0");
175        vec profM=vec("0.0");
176        double tstep=1.0;
177        root.lookupValue( "tstep", tstep );
178        UI::get( profW, root, "profileW" );
179        UI::get( profM, root, "profileM" );
180        set_profile (tstep , profW, profM);
181
182        string opts;
183        if ( root.lookupValue( "options", opts ) )
184            set_options(opts);
185    }
186
187    // TODO dodelat void to_setting( Setting &root ) const;
188};
189
190UIREGISTER ( pmsmDS );
191
192
193//! This class behaves like BM but it is evaluating EKF
194class pmsmCRB : public EKFfull
195{
196protected:
197    vec interr;
198    vec old_true;
199    vec secder;
200    int L_CRB;
201    int L_err;
202    int L_sec;
203public:
204    //! constructor
205    pmsmCRB():EKFfull()
206    {
207        old_true=zeros(6);
208    }
209
210    void bayes(const vec &dt)
211    {
212        static vec umin(2);
213                vec u(2);
214                vec &mu = est._mu();
215                //assume we know state exactly:
216        vec true_state=vec(x,4); // read from pmsm
217        mu=true_state;
218
219        //integration error
220        old_true(4)=KalmanObs[4];
221        old_true(5)=KalmanObs[5];// add U
222        u(0) = KalmanObs[0]; // use the required value for derivatives
223        u(1) = KalmanObs[1];
224        interr = (true_state - pfxu->eval(old_true));
225
226        //second derivative
227        IMpmsm2o* pf = dynamic_cast<IMpmsm2o*>(pfxu.get());
228        if (pf)
229        {
230            secder=pf->eval2o(u-umin);
231        }
232
233        umin =u;
234        EKFfull::bayes(dt);
235        old_true.set_subvector(0,true_state);
236    }
237
238    void log_add(logger &L, const string &name="" )
239    {
240        L_CRB=L.add(rx,"crb");
241        L_err=L.add(rx,"err");
242        L_sec=L.add(rx,"d2");
243    }
244    void logit(logger &L)
245    {
246        L.logit(L_err, interr);
247        L.logit(L_CRB,diag(_R()));
248        L.logit(L_sec,secder);
249    }
250
251    void from_setting( const Setting &root )
252    {
253        shared_ptr<diffbifn> IM = UI::build<diffbifn>(root, "IM");
254        shared_ptr<diffbifn> OM = UI::build<diffbifn>(root, "OM");
255
256        //parameters
257
258        //statistics
259        int dim=IM->dimension();
260
261        vec mu0;
262        if(root.exists("mu0"))
263                        UI::get( mu0, root, "mu0");
264                else
265            mu0=zeros(dim);
266
267        mat P0;
268        if(root.exists( "dP0" ))
269                {
270                        vec dP0;       
271                        UI::get(dP0,root, "dP0");
272            P0=diag(dP0);
273                }
274                else if (root.exists("P0"))
275                        UI::get(P0,root, "P0");
276                else
277            P0=eye(dim);
278
279        set_statistics(mu0,P0);
280
281        vec dQ;
282        UI::get( dQ, root, "dQ");
283        vec dR;
284        UI::get( dR, root, "dR");
285        set_parameters(IM, OM, diag(dQ) , diag(dR));
286
287        //connect
288        shared_ptr<RV> drv = UI::build<RV>(root, "drv");
289        set_yrv(*drv);
290        shared_ptr<RV> rv = UI::build<RV>(root, "rv");
291        set_rv(*rv);
292    }
293
294    // TODO dodelat void to_setting( Setting &root ) const;
295};
296
297UIREGISTER ( pmsmCRB );
298
299
300//! This class behaves like BM but it is evaluating EKF
301class pmsmCRBMz : public EKFfull
302{
303protected:
304    int L_CRB;
305public:
306    //! constructor
307    pmsmCRBMz():EKFfull() {}
308
309    void bayes(const vec &dt)
310    {
311//assume we know state exactly:
312        vec true_state(5);
313        true_state.set_subvector(0,vec(x,4)); // read from pmsm
314        true_state(4)=x[8];
315
316        vec &mu = est._mu();
317        mu = true_state;
318        //hack for ut
319        EKFfull::bayes(dt);
320    }
321
322    void log_add(logger &L, const string &name="" )
323    {
324        L_CRB=L.add(concat(rx,RV("Mz",1,0)),"crbz");
325    }
326    void logit(logger &L)
327    {
328        L.logit(L_CRB,diag(_R()));
329    }
330
331    void from_setting( const Setting &root )
332    {
333        shared_ptr<diffbifn> IM = UI::build<diffbifn>(root,"IM");
334                shared_ptr<diffbifn> OM = UI::build<diffbifn>(root,"OM");
335
336        //statistics
337        int dim=IM->dimension();
338        vec mu0;
339        if( root.exists( "mu0"))
340                        UI::get(mu0, root, "mu0");
341                else
342            mu0=zeros(dim);
343
344        mat P0;
345
346                if(root.exists("dP0"))
347                {
348                        vec dP0;                               
349                        UI::get(dP0, root, "dP0");
350                        P0=diag(dP0);
351                }
352                else if(root.exists("P0"))
353                        UI::get( P0, root, "P0" );
354                else
355                        P0=eye(dim);
356
357        set_statistics(mu0,P0);
358
359        vec dQ;
360        UI::get(dQ, root, "dQ");
361        vec dR;
362        UI::get(dR, root, "dR");
363        set_parameters(IM, OM, diag(dQ), diag(dR));
364
365        //connect
366                shared_ptr<RV> drv = UI::build<RV>(root, "drv");
367        set_yrv(*drv);
368                shared_ptr<RV> rv = UI::build<RV>(root, "rv");
369        set_rv(*rv);
370    }
371
372    // TODO dodelat void to_setting( Setting &root ) const;
373};
374
375UIREGISTER ( pmsmCRBMz );
Note: See TracBrowser for help on using the browser.