/* \file \brief Models for synchronous electric drive using IT++ and BDM \author Vaclav Smidl. ----------------------------------- BDM++ - C++ library for Bayesian Decision Making under Uncertainty Using IT++ for numerical operations ----------------------------------- */ #include #include #include #include #include "pmsm.h" #include "simulator.h" #include "iopom.h" using namespace itpp; //!Extended Kalman filter with unknown \c Q class EKF_unQ : public EKFCh , public BMcond { public: //! Default constructor EKF_unQ ( RV rx, RV ry,RV ru,RV rQ ) :EKFCh ( rx,ry,ru ),BMcond ( rQ ) {}; void condition ( const vec &Q0 ) { Q.setD ( Q0,0 ); //from EKF preA.set_submatrix ( dimy+dimx,dimy,Q._Ch() ); }; void bayes(const vec dt){ EKFCh::bayes(dt); vec xtrue(4); //UGLY HACK!!! reliance on a predictor!! xtrue(0)=x[0]; xtrue(1)=x[1]; xtrue(2)=x[2]; xtrue(3)=x[3]; ll = -0.5* ( 4 * 1.83787706640935 +_P.logdet() +_P.invqform(xtrue)); } }; class EKF_unQful : public EKFfull , public BMcond { public: //! Default constructor EKF_unQful ( RV rx, RV ry,RV ru,RV rQ ) :EKFfull ( rx,ry,ru ),BMcond ( rQ ) {}; void condition ( const vec &Q0 ) { Q=diag(Q0); }; void bayes(const vec dt){ EKFfull::bayes(dt); vec xtrue(4); //UGLY HACK!!! reliance on a predictor!! xtrue(0)=x[0]; xtrue(1)=x[1]; xtrue(2)=x[2]; xtrue(3)=x[3]; BM::ll = -0.5* ( 4 * 1.83787706640935 +log(det(P)) +xtrue* ( inv(P)*xtrue ) ); } }; void set_simulator_t(double &Ww) { if (t>0.2) x[8]=1.2; // 1A //0.2ZP if (t>0.4) x[8]=10.8; // 9A if (t>0.6) x[8]=25.2; // 21A if (t>0.7) Ww=2.*M_PI*10.; if (t>1.0) x[8]=1.2; // 1A if (t>1.2) x[8]=10.8; // 9A if (t>1.4) x[8]=25.2; // 21A if (t>1.6) Ww=2.*M_PI*50.; if (t>1.9) x[8]=1.2; // 1A if (t>2.1) x[8]=10.8; // 9A if (t>2.3) x[8]=25.2; // 21A if (t>2.5) Ww=2.*M_PI*100; if (t>2.8) x[8]=1.2; // 1A if (t>3.0) x[8]=10.8; // 9A if (t>3.2) x[8]=25.2; // 21A if (t>3.4) Ww=2.*M_PI*150; if (t>3.7) x[8]=1.2; // 1A if (t>3.9) x[8]=10.8; // 9A if (t>4.1) x[8]=25.2; // 21A if (t>4.3) Ww=2.*M_PI*0; if (t>4.8) x[8]=-1.2; // 1A if (t>5.0) x[8]=-10.8; // 9A if (t>5.2) x[8]=-25.2; // 21A if (t>5.4) Ww=2.*M_PI*(-10.); if (t>5.7) x[8]=-1.2; // 1A if (t>5.9) x[8]=-10.8; // 9A if (t>6.1) x[8]=-25.2; // 21A if (t>6.3) Ww=2.*M_PI*(-50.); if (t>6.7) x[8]=-1.2; // 1A if (t>6.9) x[8]=-10.8; // 9A if (t>7.1) x[8]=-25.2; // 21A if (t>7.3) Ww=2.*M_PI*(-100.); if (t>7.7) x[8]=-1.2; // 1A if (t>7.9) x[8]=-10.8; // 9A if (t>8.1) x[8]=-25.2; // 21A if (t>8.3) x[8]=10.8; // 9A if (t>8.5) x[8]=25.2; // 21A if (t>9) Ww=2.*M_PI*0; x[8]=0.0; } int main() { // Kalman filter int Ndat = 90000; double h = 1e-6; int Nsimstep = 125; int Npart = 50; //StrSim:06: vec SSAT(Ndat); // internal model IMpmsm fxu; // Rs Ls dt Fmag(Ypm) kp p J Bf(Mz) fxu.set_parameters ( 0.28, 0.003465, Nsimstep*h, 0.1989, 1.5 ,4.0, 0.04, 0.0 ); // observation model OMpmsm hxu; vec mu0= "0.0 0.0 0.0 0.0"; // vec Qdiag ( "0.01 0.01 0.01 0.0001" ); //zdenek: 0.01 0.01 0.0001 0.0001 vec Qdiag ( "10 10 10 0.001" ); //zdenek: 0.01 0.01 0.0001 0.0001 vec Rdiag ( "100 100" ); //var(diff(xth)) = "0.034 0.034" chmat Q ( Qdiag ); chmat R ( Rdiag ); EKFCh KFE ( rx,ry,ru ); KFE.set_est ( mu0, chmat( 1*eye ( 4 ) ) ); KFE.set_parameters ( &fxu,&hxu,Q,R); RV rQ ( "100","{Q}","4","0" ); EKF_unQful KFEp ( rx,ry,ru,rQ ); KFEp.set_est ( mu0, 1*ones ( 4 ) ); KFEp.set_parameters ( &fxu,&hxu,diag(Qdiag),diag(Rdiag) ); mgamma_fix evolQ ( rQ,rQ ); MPF M ( rx,rQ,evolQ,evolQ,Npart,KFEp ); // initialize evolQ.set_parameters ( 1000.0 ,Qdiag, 0.5); //sigma = 1/10 mu evolQ.condition ( Qdiag ); //Zdenek default epdf& pfinit=evolQ._epdf(); M.set_est ( pfinit ); evolQ.set_parameters ( 100000.0, Qdiag, 0.9999 ); // epdf& KFEep = KFE._epdf(); epdf& Mep = M._epdf(); mat Xt=zeros ( Ndat ,9 ); //true state from simulator mat Dt=zeros ( Ndat,4+2 ); //observation mat XtE=zeros ( Ndat, 4 ); mat XtM=zeros ( Ndat,4+4 ); //Q + x // SET SIMULATOR pmsmsim_set_parameters ( 0.28,0.003465,0.1989,0.0,4,1.5,0.04, 200., 3e-6, h ); double Ww=0.0; vec dt ( 2 ); vec ut ( 2 ); for ( int tK=1;tK