/*! \file \brief DataSource for experiments with realistic simulator of the PMSM model \author Vaclav Smidl. ----------------------------------- BDM++ - C++ library for Bayesian Decision Making under Uncertainty Using IT++ for numerical operations ----------------------------------- */ #ifndef PMSM_DS #define PMSM_DS #include #include #include "simulator_zdenek/simulator.h" #include "pmsm.h" using namespace bdm; //! Simulator of PMSM machine with predefined profile on omega class pmsmDS : public DS { LOG_LEVEL(pmsmDS,logvoltage); protected: //! indices of logged variables int L_x, L_ou, L_oy, L_iu, L_optu; //! Setpoints of omega in timespans given by dt_prof vec profileWw; //! Setpoints of Mz in timespans given by dt_prof vec profileMz; //! time-step for profiles double dt_prof; //! Number of miliseconds per discrete time step int Dt; public: double x[9]; double KalmanObs[6]; //! Constructor with fixed sampling period pmsmDS () : DS() { Dt=125; Drv=RV ( "{o_ua o_ub o_ia o_ib t_ua t_ub o_om o_th Mz }" ); dtsize = Drv._dsize(); pmsmsim_fill_xy(x,KalmanObs); } void set_parameters ( double Rs0, double Ls0, double Fmag0, double Bf0, double p0, double kp0, double J0, double Uc0, double DT0, double dt0 ) { pmsmsim_set_parameters ( Rs0, Ls0, Fmag0, Bf0, p0, kp0, J0, Uc0, DT0, dt0 ); } void getdata ( vec &dt ) const { dt.set_subvector(0,vec ( KalmanObs,6 )); // add measurement noise dt(2) += (0.02*randun()-0.01); dt(3) += (0.02*randun()-0.01); // true values dt(6)=x[2]; dt(7)=x[3]; dt(8)=x[8]; } void write ( vec &ut ) {} void step() { pmsmsim_fill_xy(x,KalmanObs); static int ind=0; static double dW; // increase of W static double Ww; // W static double Mz; // W double t; t=pmsmsim_get_t(); if ( t>=dt_prof*ind ) { ind++; // check omega profile and set dW if ( ind <2 && profileWw.length() ==1 ) { Ww=profileWw ( 0 ); dW=0.0; } if ( ind0.3 ) - double ( i1<-0.3 ) ) +0.2*i1; double du2=1.4* ( double ( i2>0.3 ) - double ( i2<-0.3 ) ) +0.2*i2; double du3=1.4* ( double ( i3>0.3 ) - double ( i3<-0.3 ) ) +0.2*i3; ua = ( 2.0* ( u1-du1 )- ( u2-du2 )- ( u3-du3 ) ) /3.0; ub = ( ( u2-du2 )- ( u3-du3 ) ) /sq3; log_level.store( logvoltage , vec_2 ( ua,ub ) ); } } void set_profile ( double dt, const vec &Ww, const vec &Mz ) { dt_prof=dt; profileWw=Ww; profileMz=Mz; } void from_setting( const Setting &root ) { const SettingResolver& params_l(root["params"]); const Setting ¶ms = params_l.result; set_parameters ( params["Rs"], params["Ls"], params["Fmag"], \ params["Bf"], params["p"], params["kp"], \ params["J"], params["Uc"], params["DT"], 1.0e-6 ); // Default values of profiles for omega and Mz vec profW=vec("1.0"); vec profM=vec("0.0"); double tstep=1.0; UI::get( tstep, root, "tstep"); UI::get( profW, root, "profileW" ); UI::get( profM, root, "profileM" ); set_profile (tstep , profW, profM); } // TODO dodelat void to_setting( Setting &root ) const; }; UIREGISTER ( pmsmDS ); //! Simulator of PMSM machine with predefined profile on omega class pmsmDSctrl : public pmsmDS { double Ww; double ua; double ub; public: //! Constructor with fixed sampling period pmsmDSctrl() : pmsmDS() { Drv.add(RV ( "{Ww }" )); Urv=RV ( "{ua ub }" ); dtsize = Drv._dsize(); utsize = Urv._dsize(); } void getdata ( vec &dt ) const { pmsmDS::getdata(dt); dt(9)=Ww; } void write (const vec &ut ) { ua = ut(0); ub = ut(1); } void step() { pmsmsim_fill_xy(x,KalmanObs); double t; static int ind=0; static double dW; // increase of W static double Mz; // W t=pmsmsim_get_t(); if ( t>=dt_prof*ind ) { ind++; // check omega profile and set dW if ( ind <2 && profileWw.length() ==1 ) { Ww=profileWw ( 0 ); dW=0.0; } if ( indeval(old_true)); //second derivative IMpmsm2o* pf = dynamic_cast(pfxu.get()); if (pf) { secder=pf->eval2o(u-umin); } umin =u; EKFfull::bayes(dt); old_true.set_subvector(0,true_state); } void from_setting( const Setting &root ) { shared_ptr IM = UI::build(root, "IM"); shared_ptr OM = UI::build(root, "OM"); //parameters //statistics int dim=IM->dimension(); vec mu0; if(root.exists("mu0")) UI::get( mu0, root, "mu0"); else mu0=zeros(dim); mat P0; if(root.exists( "dP0" )) { vec dP0; UI::get(dP0,root, "dP0"); P0=diag(dP0); } else if (root.exists("P0")) UI::get(P0,root, "P0"); else P0=eye(dim); set_statistics(mu0,P0); vec dQ; UI::get( dQ, root, "dQ"); vec dR; UI::get( dR, root, "dR"); set_parameters(IM, OM, diag(dQ) , diag(dR)); //connect shared_ptr drv = UI::build(root, "drv"); set_yrv(*drv); shared_ptr rv = UI::build(root, "rv"); set_rv(*rv); } // TODO dodelat void to_setting( Setting &root ) const; }; UIREGISTER ( pmsmCRB ); //! This class behaves like BM but it is evaluating EKF class pmsmCRBMz : public EKFfull { protected: int L_CRB; public: //! constructor pmsmCRBMz():EKFfull() {} void bayes(const vec &dt) { //assume we know state exactly: vec true_state(5); true_state.set_subvector(0,vec(x,4)); // read from pmsm true_state(4)=x[8]; vec &mu = est._mu(); mu = true_state; //hack for ut EKFfull::bayes(dt); } void from_setting( const Setting &root ) { shared_ptr IM = UI::build(root,"IM"); shared_ptr OM = UI::build(root,"OM"); //statistics int dim=IM->dimension(); vec mu0; if( root.exists( "mu0")) UI::get(mu0, root, "mu0"); else mu0=zeros(dim); mat P0; if(root.exists("dP0")) { vec dP0; UI::get(dP0, root, "dP0"); P0=diag(dP0); } else if(root.exists("P0")) UI::get( P0, root, "P0" ); else P0=eye(dim); set_statistics(mu0,P0); vec dQ; UI::get(dQ, root, "dQ"); vec dR; UI::get(dR, root, "dR"); set_parameters(IM, OM, diag(dQ), diag(dR)); //connect shared_ptr drv = UI::build(root, "drv"); set_yrv(*drv); shared_ptr rv = UI::build(root, "rv"); set_rv(*rv); } // TODO dodelat void to_setting( Setting &root ) const; }; UIREGISTER ( pmsmCRBMz ); #endif #endif