root/applications/pmsm/pmsmDS.h @ 1053

Revision 897, 9.1 kB (checked in by mido, 15 years ago)

small patch of documentation

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