root/applications/pmsm/pmsmDS.h @ 875

Revision 871, 9.3 kB (checked in by mido, 14 years ago)

adaptation of /applications to new version of LOG_LEVEL
also, a cosmetic change made in enumerations: logub -> logubound, loglb -> loglbound

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