/*! \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 ----------------------------------- */ #include #include #include "simulator.h" #include "pmsm.h" //! Simulator of PMSM machine with predefined profile on omega class pmsmDS : public DS { protected: //! indeces 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; //! options for logging, - log predictions of 'true' voltage bool opt_modu; //! options for logging, - public: //! Constructor with fixed sampling period pmsmDS () {Dt=125; Drv=RV ( "{o_ua o_ub o_ia o_ib t_ua t_ub }" );} 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 ); } //! parse options: "modelu" => opt_modu=true; void set_options ( string &opt ) { opt_modu = ( opt.find ( "modelu" ) ==string::npos ); } void getdata ( vec &dt ) {dt=vec ( KalmanObs,6 );} void write ( vec &ut ) {} void step() { static int ind=0; static double dW; // increase of W static double Ww; // W static double Mz; // W if ( t>=dt_prof*ind ) { ind++; // check omega profile and set dW if ( ind0.1 ) - double ( i1<-0.1 ) ) +0.05*i1; double du2=0.7* ( double ( i2>0.1 ) - double ( i2<-0.1 ) ) +0.05*i2; double du3=0.7* ( double ( i3>0.1 ) - double ( i3<-0.1 ) ) +0.05*i3; ua = ( 2.0* ( u1-du1 )- ( u2-du2 )- ( u3-du3 ) ) /3.0; ub = ( ( u2-du2 )- ( u3-du3 ) ) /sq3; L.logit ( L_optu , vec_2 ( ua,ub ) ); } } void set_profile ( double dt, const vec &Ww, const vec &Mz ) {dt_prof=dt; profileWw=Ww; profileMz=Mz;} }; //! This class behaves like BM but it is evaluating EKF class pmsmCRB : public EKFCh{ protected: vec interr; vec old_true; vec secder; int L_CRB; int L_err; int L_sec; public: //! constructor pmsmCRB():EKFCh(){old_true=zeros(6);} void bayes(const vec &dt){ //assume we know state exactly: vec true_state=vec(x,4); // read from pmsm est.set_mu(true_state); //integration error old_true(4)=KalmanObs[4]; old_true(5)=KalmanObs[5];// add U interr = (true_state - pfxu->eval(old_true)); //second derivative IMpmsm2o* pf = dynamic_cast(pfxu); if (pf) {secder=pf->eval2o(vec_2(KalmanObs[4],KalmanObs[5]));} EKFCh::bayes(dt); old_true.set_subvector(0,true_state); } void log_add(logger &L, const string &name="" ){ L_CRB=L.add(rx,"crb"); L_err=L.add(rx,"err"); L_sec=L.add(rx,"d2"); } void logit(logger &L){ L.logit(L_err, interr); L.logit(L_CRB,diag(est._R().to_mat())); L.logit(L_sec,secder); } };