#include #include "ekf_obj.h" //#include "../simulator.h" double minQ(double Q){if (Q>1.0){ return 1.0;} else {return Q;};}; void mat_to_int16(const imat &M, int16 *I){ for (int16 i=0;i>15; tmp=((int32)cH*x_est[2])>>15; PSI[3]=((int32)tmp*t_cos)>>15; PSI[6]=-((int32)cB*t_cos)>>15; PSI[7]=((int32)tmp*t_sin)>>15; } void EKFfixed::prediction(int16 *ux) { int16 t_sin,t_cos, tmp; // implementace v PC //t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15); //t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15); t_sin=prevod(sin(Thetaref*x_est[3]/Qm),15); t_cos=prevod(cos(Thetaref*x_est[3]/Qm),15); tmp=((int32)cB*x_est[2])>>15; x_pred[0]=((int32)cA*x_est[0]+(int32)tmp*t_sin+(int32)cC*ux[0])>>15; x_pred[1]=((int32)cA*x_est[1]-(int32)tmp*t_cos+(int32)cC*ux[1])>>15; x_pred[2]=x_est[2]; x_pred[3]=(((int32)x_est[3]<<15)+(int32)cG*x_est[2])>>15; update_psi(); mmult(PSI,P_est,temp15a,3,3,3); // mtrans(PSI,temp15b,5,5); mmultt(temp15a,PSI,P_pred,3,3,3); maddD(P_pred,Q,3,3); } void EKFfixed::correction(void) { int16 Y_error[2]; int32 temp30a[4]; /* matrix [2,2] - temporary matrix for inversion */ choice_P(P_pred,temp15a,3); maddD(temp15a,R,1,1); minv2(temp15a,temp30a); Ry(0,0)=zprevod(temp15a[0],15); Ry(0,1)=zprevod(temp15a[1],15); Ry(1,0)=zprevod(temp15a[2],15); Ry(1,1)=zprevod(temp15a[3],15); mmultDr(P_pred,temp15a,3,3,1,1); mmult1530(temp15a,temp30a,Kalm,3,1,1); /* estimate the state system */ choice_x(x_pred, temp15a); msub(Y_mes,temp15a,Y_error,1,0); mmult(Kalm,Y_error,temp15a,3,1,0); madd(x_pred,temp15a,x_est,3,0); /* matrix of covariances - version without MMULTDL() */ /* Version with MMULTDL() */ mmultDl(P_pred,temp15a,1,3,3,1); mmult(Kalm,temp15a,P_est,3,1,3); msub(P_pred,P_est,P_est,3,3); /* END */ } void EKFfixed::ekf(double ux, double uy, double isxd, double isyd) { // vypocet napeti v systemu (x,y) ukalm[0]=prevod(ux/Uref,Qm); ukalm[1]=prevod(uy/Uref,Qm); // zadani mereni Y_mes[0]=prevod(isxd/Iref,Qm); Y_mes[1]=prevod(isyd/Iref,Qm); ////// vlastni rutina EKF ///////////////////////// prediction(ukalm); correction(); // navrat estimovanych hodnot regulatoru vec& mu = E._mu(); (mu)(0)=zprevod(x_est[0],Qm)*Iref; (mu)(1)=zprevod(x_est[1],Qm)*Iref; (mu)(2)=zprevod(x_est[2],Qm)*Wref; (mu)(3)=zprevod(x_est[3],15)*Thetaref; } void EKFfixed::init_ekf(double Tv) { // Tuning of matrix Q Q[0]=prevod(.05,15); // 0.05 Q[5]=Q[0]; Q[10]=prevod(0.0002,15); // 1e-3 Q[15]=prevod(0.001,15); // 1e-3 // Tuning of matrix R R[0]=prevod(0.1,15); // 0.05 R[3]=R[0]; // Motor model parameters cA=prevod(1-Tv*Rs/Ls,15); cB=prevod(Tv*Wref*Fmag/Iref/Ls,15); cC=prevod(Tv/Ls/Iref*Uref,15); // cD=prevod(1-Tv*Bf/J,15); // cE=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref,15); // cF=prevod(p*Tv*Mref/J/Wref,15); cG=prevod(Tv*Wref*4/Thetaref,15); // cH=prevod(Tv*Wref*Fmag/Iref/Ls*Thetaref,15); cH=prevod(Tv*Wref*Fmag/Iref/Ls,17); //cB in q // cI=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref*Thetaref); /* Init matrix PSI with permanently constant terms */ PSI[0]=cA; PSI[5]=PSI[0]; PSI[10]=0x7FFF; PSI[14]=cG; PSI[15]=0x7FFF; P_est[0]=0x7FFF; P_est[5]=0x7FFF; P_est[10]=0x7FFF; P_est[15]=0x7FFF; } #endif void EKF_UDfix::set_parameters ( const shared_ptr &pfxu0, const shared_ptr &phxu0, const mat Q0, const vec R0 ) { pfxu = pfxu0; phxu = phxu0; set_dim ( pfxu0->_dimx() ); dimy = phxu0->dimension(); dimc = pfxu0->_dimu(); vec &_mu = est._mu(); // if mu is not set, set it to zeros, just for constant terms of A and C if ( _mu.length() != dimension() ) _mu = zeros ( dimension() ); A = zeros ( dimension(), dimension() ); C = zeros ( dimy, dimension() ); //initialize matrices A C, later, these will be only updated! pfxu->dfdx_cond ( _mu, zeros ( dimc ), A, true ); // pfxu->dfdu_cond ( *_mu,zeros ( dimu ),B,true ); phxu->dfdx_cond ( _mu, zeros ( dimc ), C, true ); // phxu->dfdu_cond ( *_mu,zeros ( dimu ),D,true ); R = R0; Q = Q0; // } // aux fnc void UDtof(const mat &U, const vec &D, imat &Uf, ivec &Df, const vec &xref){ mat P= U*diag(D)*U.T(); mat T = diag(1.0/(xref)); mat Pf = T*P*T; ldmat Pld(Pf); mat Ut=Pld._L().T()*(1<<15); // U is in q15 -- diagonal is 0!!! Uf=round_i(Ut); Df=round_i(Pld._D()*(1<<15)); ivec zer=find(Df==0); for(int16 i=0; idfdx_cond ( _mu, u, A, false ); //update A by a derivative of fx phxu->dfdx_cond ( _mu, u, C, false ); //update A by a derivative of fx mat PhiU = A*U; ////// /* vec xref(4); xref(0)= 30.0*1.4142; xref(1)= 30.0*1.4142; xref(2)= 6.283185*200.; xref(3) = 3.141593;*/ //xref(4) = 34.0; vec Din = D; int16 i,j,k; double sigma; mat G = eye(dim); //////// thorton //move mean; _mu = pfxu->eval(_mu,u); for (i=dim-1; i>=0;i--){ sigma = 0.0; for (j=0; jeval(_mu,u); vec xp=_mu; // used in bierman for (int16 iy=0; iy IM = UI::build ( set, "IM", UI::compulsory ); shared_ptr OM = UI::build ( set, "OM", UI::compulsory ); //statistics int16 dim = IM->dimension(); vec mu0; if ( !UI::get ( mu0, set, "mu0" ) ) mu0 = zeros ( dim ); mat P0; vec dP0; if ( UI::get ( dP0, set, "dP0" ) ) P0 = diag ( dP0 ); else if ( !UI::get ( P0, set, "P0" ) ) P0 = eye ( dim ); est._mu()=mu0; est._R()=ldmat(P0); //parameters vec dQ, dR; UI::get ( dQ, set, "dQ", UI::compulsory ); UI::get ( dR, set, "dR", UI::compulsory ); set_parameters ( IM, OM, diag ( dQ ), dR ); UI::get(log_level, set, "log_level", UI::optional); } void EKFfixedUD::bayes(const itpp::vec& yt, const itpp::vec& ut) { ekf(ut[0],ut[1],yt[0],yt[1]); } void EKFfixedUD::ekf(double ux, double uy, double isxd, double isyd) { // vypocet napeti v systemu (x,y) int16 uf[2]; uf[0]=prevod(ux/Uref,15); uf[1]=prevod(uy/Uref,15); int16 Y_mes[2]; // zadani mereni Y_mes[0]=prevod(isxd/Iref,15); Y_mes[1]=prevod(isyd/Iref,15); ////// vlastni rutina EKF -- ///////////////////////// int16 t_sin,t_cos; int32 tmp; // implementace v PC /* t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15); t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15);*/ tmp=prevod(sin(Thetaref*x_est[3]/32768.),15); if (tmp>32767) t_sin =32767; else t_sin=tmp; tmp=prevod(cos(Thetaref*x_est[3]/32768.),15); if (tmp>32767) t_cos =32767; else t_cos=tmp; tmp=((int32)cB*x_est[2])>>15; // q15*q13 -> q13 // q15*q13 + q13*q15 + q15*q13?? x_est[0]=((int32)cA*x_est[0]+(int32)tmp*t_sin+(int32)cC*(uf[0]))>>15; // in q13 x_est[1]=((int32)cA*x_est[1]-(int32)tmp*t_cos+(int32)cC*(uf[1]))>>15; // q13 x_est[2]=x_est[2]; // q15 + q15*q13 x_est[3]=(((int32)x_est[3]<<15)+(int32)cG*x_est[2])>>15; if(x_est[3]>(1<<15)) x_est[3]-=2*(1<<15); if(x_est[3]<-(1<<15)) x_est[3]+=2*(1<<15); //void EKFfixed::update_psi(void) { PSI[2]=((int32)cB*t_sin)>>15; tmp=((int32)cH*x_est[2])>>15; // ! cH =cB with different scale!! PSI[3]=((int32)tmp*t_cos)>>15; PSI[6]=-((int32)cB*t_cos)>>15; PSI[7]=((int32)tmp*t_sin)>>15; } { int Ai[16]; for (int i=0;i<16; i++) Ai[i]=(int)(PSI[i]); ivec Ad(Ai,16); log_level.store(logA,get_from_ivec(Ad)); } ///////// end of copy /////////////// mmultAU(PSI,Uf,PSIU,4,4); //thorton(int16 *U, int16 *D, int16 *PSIU, int16 *Q, int16 *G, int16 *Dold, unsigned int16 dimx); thorton_fast(Uf,Df,PSIU,Q,G,Dfold,4); { int Ui[16]; for (int i=0;i<16; i++) Ui[i]=(int)Uf[i]; ivec Ud(Ui,16); log_level.store(logU,get_from_ivec(Ud)); int di[16]; for (int i=0;i<16; i++) di[i]=(int)Df[i]; ivec dd(di,4); imat U(Ui,4,4); mat U2=to_mat(U)/32768; mat PP=U2*diag(to_vec(dd))*U2.T(); vec pp(PP._data(),16); log_level.store(logP,pp); } { int Gi[16]; for (int i=0;i<16; i++) Gi[i]=(int)G[i]; ivec Gd(Gi,16); log_level.store(logG,get_from_ivec(Gd)); } int16 difz[2]; difz[0]=(Y_mes[0]-x_est[0]); // shift to q15!! difz[1]=(Y_mes[1]-x_est[1]);//<<2; { int Di[4]; for (int i=0;i<4; i++) Di[i]=(int)Df[i]; ivec dd(Di,4);//;dd(0)=Y_mes[0];dd(1)=Y_mes[1]; dd(2)=difz[0]; dd(3)=difz[1]; log_level.store(logD,get_from_ivec(dd)); } //bierman(int16 *difz, int16 *xp, int16 *U, int16 *D, int16 *R, unsigned int16 dimy, unsigned int16 dimx ); int16 dR[2];dR[0]=R[0];dR[1]=R[3]; //int16 xb[4]; xb[0]=x_est[0]<<2; xb[1]=x_est[1]<<2; xb[2]=x_est[2]<<2; xb[3]=x_est[3]; bierman_fast(difz,x_est,Uf,Df,dR,2,4); //x_est[0] = xb[0]>>2; x_est[1]=xb[1]>>2; x_est[2]=xb[2]>>2; x_est[3]=xb[3]; // navrat estimovanych hodnot regulatoru vec& mu = E._mu(); (mu)(0)=zprevod(x_est[0],15)*Iref; (mu)(1)=zprevod(x_est[1],15)*Iref; (mu)(2)=zprevod(x_est[2],15)*Wref; (mu)(3)=zprevod(x_est[3],15)*Thetaref; //x_est[2]=x[2]*32768/Wref; //x_est[3]=x[3]*32768/Thetaref; // mat T=diag(concat(vec_2(Iref,Iref), vec_2(Wref,Thetaref))); } void EKFfixedUD::init_ekf(double Tv) { // Tuning of matrix Q Q[0]=prevod(.001,15); // 0.05 Q[5]=Q[0]; Q[10]=prevod(0.0005,15); // 1e-3 Q[15]=prevod(0.0001,15); // 1e-3 Uf[0]=0x7FFF;// ! // 0.05 Uf[1]=Uf[2]=Uf[3]=Uf[4]=0; Uf[5]=0x7FFF;//! Uf[6]=Uf[6]=Uf[8]=Uf[9]=0; Uf[10]=0x7FFF;//! // 1e-3 Uf[11]=Uf[12]=Uf[13]=Uf[4]=0; Uf[15]=0x7FFF; // 1e-3 Df[0]=1<<14; Df[1]=1<<14; Df[2]=1<<14; Df[3]=1<<14; // Tuning of matrix R R[0]=prevod(0.05,15); // 0.05 R[3]=R[0]; // Motor model parameters cA=prevod(1-Tv*Rs/Ls,15); cB=prevod(Tv*Wref*Fmag/Iref/Ls,15); cC=prevod(Tv/Ls/Iref*Uref,15); // cD=prevod(1-Tv*Bf/J,15); // cE=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref,15); // cF=prevod(p*Tv*Mref/J/Wref,15); cG=prevod(Tv*Wref/Thetaref,15); //in q15! //cH=prevod(Tv*Wref*Fmag/Iref/Ls*Thetaref,15); // cH=prevod(Tv*Wref*Thetaref*Fmag/Iref/Ls,15); // < =========== cH=prevod(Tv*Wref*Thetaref*Fmag/Iref/Ls,15); // // cI=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref*Thetaref); /* Init matrix PSI with permanently constant terms */ PSI[0]=cA; PSI[5]=PSI[0]; PSI[10]=0x7FFF; PSI[14]=cG; PSI[15]=0x7FFF; } void EKFfixedUD2::bayes(const itpp::vec& yt, const itpp::vec& ut) { ekf2(ut[0],ut[1],yt[0],yt[1]); } void EKFfixedUD2::ekf2(double ux, double uy, double isxd, double isyd) { // vypocet napeti v systemu (x,y) int16 uf[2]; uf[0]=prevod(ux/Uref,15); uf[1]=prevod(uy/Uref,15); int16 Y_mes[2]; // zadani mereni Y_mes[0]=prevod(isxd/Iref,15); Y_mes[1]=prevod(isyd/Iref,15); ////// vlastni rutina EKF -- ///////////////////////// int16 t_sin,t_cos; int32 tmp; x_est[0]=x_est[0]; // q15 + q15*q13 x_est[1]=(((int32)x_est[1]<<15)+(int32)cG*x_est[0]+(1<<14))>>15; // if(x_est[1]>(1<<15)) x_est[1]-=2*(1<<15); // if(x_est[1]<-(1<<15)) x_est[1]+=2*(1<<15); ///////// end of copy /////////////// mmultAU(PSI,Uf,PSIU,2,2); //void EKFfixed::update_psi(void) { int Ai[4]; for (int i=0;i<4; i++) Ai[i]=(int)(PSI[i]); ivec Ad(Ai,4); log_level.store(logA,get_from_ivec(Ad)); } //thorton(int16 *U, int16 *D, int16 *PSIU, int16 *Q, int16 *G, int16 *Dold, unsigned int16 dimx); thorton_fast(Uf,Df,PSIU,Q,G,Dfold,2); // implementace v PC /* t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15); * t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15);*/ tmp=prevod(sin(Thetaref*x_est[1]/32768.),15); if (tmp>32767) t_sin =32767; else t_sin=tmp; tmp=prevod(cos(Thetaref*x_est[1]/32768.),15); if (tmp>32767) t_cos =32767; else t_cos=tmp; { C[0]=((int32)cB*t_sin)>>15; tmp=((int32)cH*x_est[0])>>15; // ! cH =cB with different scale!! C[1]=((int32)tmp*t_cos)>>15; C[2]=-((int32)cB*t_cos)>>15; C[3]=((int32)tmp*t_sin)>>15; } { int Ui[4]; for (int i=0;i<4; i++) Ui[i]=(int)Uf[i]; int Ci[4]; for (int i=0;i<4; i++) Ci[i]=(int)C[i]; imat Ud(Ui,2,2); imat Cd(Ci,2,2); // imat CU = Cd*Ud/(1<<15); log_level.store(logU,get_from_ivec(ivec(Ud._data(),Ud._datasize()))); int di[2]; for (int i=0;i<2; i++) di[i]=(int)Df[i]; ivec dd(di,2); imat U(Ui,2,2); mat U2=to_mat(U)/32768; mat PP=U2*diag(to_vec(dd))*U2.T(); vec pp(PP._data(),4); log_level.store(logP,pp); } { int Gi[4]; for (int i=0;i<4; i++) Gi[i]=(int)G[i]; ivec Gd(Gi,4); log_level.store(logG,get_from_ivec(Gd)); } tmp=((int32)cB*x_est[0])>>15; // q15*q13 -> q13 // q15*q13 + q13*q15 + q15*q13?? y_est[0]=((int32)cA*y_old[0]+(int32)tmp*t_sin+(int32)cC*(uf[0])+(1<<14))>>15; // in q13 y_est[1]=((int32)cA*y_old[1]-(int32)tmp*t_cos+(int32)cC*(uf[1])+(1<<14))>>15; // q13 int16 difz[2]; difz[0]=(Y_mes[0]-y_est[0]); // shift to q15!! difz[1]=(Y_mes[1]-y_est[1]);//<<2; y_old[0] = Y_mes[0]; y_old[1] = Y_mes[1]; { int Di[2]; for (int i=0;i<2; i++) Di[i]=(int)Df[i]; ivec dd(Di,2);//;dd(0)=Y_mes[0];dd(1)=Y_mes[1]; dd(2)=difz[0]; dd(3)=difz[1]; log_level.store(logD,get_from_ivec(dd)); int Ci[4]; for (int i=0;i<4; i++) Ci[i]=(int)C[i]; ivec CC(Ci,4);//;dd(0)=Y_mes[0];dd(1)=Y_mes[1]; dd(2)=difz[0]; dd(3)=difz[1]; log_level.store(logC,get_from_ivec(CC)); } //bierman(int16 *difz, int16 *xp, int16 *U, int16 *D, int16 *R, unsigned int16 dimy, unsigned int16 dimx ); int16 dR[2];dR[0]=R[0];dR[1]=R[3]; //int16 xb[4]; xb[0]=x_est[0]<<2; xb[1]=x_est[1]<<2; xb[2]=x_est[2]<<2; xb[3]=x_est[3]; bierman_fastC(difz,x_est,Uf,Df,C,dR,2,2); //x_est[0] = xb[0]>>2; x_est[1]=xb[1]>>2; x_est[2]=xb[2]>>2; x_est[3]=xb[3]; // navrat estimovanych hodnot regulatoru vec& mu = E._mu(); (mu)(0)=zprevod(x_est[0],15)*Wref; (mu)(1)=zprevod(x_est[1],15)*Thetaref; //x_est[2]=x[2]*32768/Wref; //x_est[3]=x[3]*32768/Thetaref; // mat T=diag(concat(vec_2(Iref,Iref), vec_2(Wref,Thetaref))); } void EKFfixedUD2::init_ekf2(double Tv) { // Tuning of matrix Q Q[0]=prevod(0.01,15); // 1e-3 Q[3]=prevod(0.01,15); // 1e-3 Uf[0]=0x7FFF;// ! // 0.05 Uf[1]=Uf[2]=0; Uf[3]=0x7FFF;//! Df[0]=1<<14; Df[1]=1<<14; // Tuning of matrix R R[0]=prevod(0.01,15); // 0.05 R[3]=R[0]; // Motor model parameters cA=prevod(1-Tv*Rs/Ls,15); cB=prevod(Tv*Wref*Fmag/Iref/Ls,15); cC=prevod(Tv/Ls/Iref*Uref,15); // cD=prevod(1-Tv*Bf/J,15); // cE=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref,15); // cF=prevod(p*Tv*Mref/J/Wref,15); cG=prevod(Tv*Wref/Thetaref,15); //in q15! //cH=prevod(Tv*Wref*Fmag/Iref/Ls*Thetaref,15); // cH=prevod(Tv*Wref*Thetaref*Fmag/Iref/Ls,15); // < =========== cH=prevod(Tv*Wref*Fmag*Thetaref/Iref/Ls,15); // // cI=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref*Thetaref); /* Init matrix PSI with permanently constant terms */ PSI[0]=0x7FFF; PSI[1]=0; PSI[2]=cG; PSI[3]=0x7FFF; } void EKFfixedUD3::bayes(const itpp::vec& yt, const itpp::vec& ut) { ekf3(ut[0],ut[1],yt[0],yt[1]); } void EKFfixedUD3::ekf3(double ux, double uy, double isxd, double isyd) { // vypocet napeti v systemu (x,y) int16 uf[2]; uf[0]=prevod(ux/Uref,15); uf[1]=prevod(uy/Uref,15); int16 Y_mes[2]; // zadani mereni Y_mes[0]=prevod(isxd/Iref,15); Y_mes[1]=prevod(isyd/Iref,15); ////// vlastni rutina EKF -- ///////////////////////// int16 t_sin,t_cos; int32 tmp; int16 Mm=x_est[2]; x_est[0]=(((int32)x_est[0]<<15) + (int32)cF*x_est[2] + (1<<14))>>15; // q15 + q15*q13 x_est[1]=(((int32)x_est[1]<<15)+(int32)cG*x_est[0] + (1<<14))>>15; x_est[2]=x_est[2]; // if(x_est[1]>(1<<15)) x_est[1]-=2*(1<<15); // if(x_est[1]<-(1<<15)) x_est[1]+=2*(1<<15); ///////// end of copy /////////////// mmultAU(PSI,Uf,PSIU,3,3); //thorton(int16 *U, int16 *D, int16 *PSIU, int16 *Q, int16 *G, int16 *Dold, unsigned int16 dimx); thorton_fast(Uf,Df,PSIU,Q,G,Dfold,3); // implementace v PC /* t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15); * t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15);*/ tmp=prevod(sin(Thetaref*x_est[1]/32768.),15); if (tmp>32767) t_sin =32767; else t_sin=tmp; tmp=prevod(cos(Thetaref*x_est[1]/32768.),15); if (tmp>32767) t_cos =32767; else t_cos=tmp; { C[0]=((int32)cB*t_sin)>>15; tmp=((int32)cH*x_est[0])>>15; // ! cH =cB with different scale!! C[1]=((int32)tmp*t_cos)>>15; C[2] = 0; C[3]=-((int32)cB*t_cos)>>15; C[4]=((int32)tmp*t_sin)>>15; C[5]=0; } tmp=((int32)cB*x_est[0])>>15; // q15*q13 -> q13 // q15*q13 + q13*q15 + q15*q13?? y_est[0]=((int32)cA*y_old[0]+(int32)tmp*t_sin+(int32)cC*(uf[0])+(1<<14))>>15; // in q13 y_est[1]=((int32)cA*y_old[1]-(int32)tmp*t_cos+(int32)cC*(uf[1])+(1<<14))>>15; // q13 int16 difz[2]; difz[0]=(Y_mes[0]-y_est[0]); // shift to q15!! difz[1]=(Y_mes[1]-y_est[1]);//<<2; y_old[0] = Y_mes[0]; y_old[1] = Y_mes[1]; //bierman(int16 *difz, int16 *xp, int16 *U, int16 *D, int16 *R, unsigned int16 dimy, unsigned int16 dimx ); int16 dR[2];dR[0]=R[0];dR[1]=R[3]; //int16 xb[4]; xb[0]=x_est[0]<<2; xb[1]=x_est[1]<<2; xb[2]=x_est[2]<<2; xb[3]=x_est[3]; bierman_fastC(difz,x_est,Uf,Df,C,dR,2,3); //x_est[0] = xb[0]>>2; x_est[1]=xb[1]>>2; x_est[2]=xb[2]>>2; x_est[3]=xb[3]; // navrat estimovanych hodnot regulatoru vec& mu = E._mu(); (mu)(0)=zprevod(x_est[0],15)*Wref; (mu)(1)=zprevod(x_est[1],15)*Thetaref; (mu)(2)=zprevod(x_est[2],15)*Mref; //x_est[2]=x[2]*32768/Wref; //x_est[3]=x[3]*32768/Thetaref; // mat T=diag(concat(vec_2(Iref,Iref), vec_2(Wref,Thetaref))); } void EKFfixedUD3::init_ekf3(double Tv) { // Tuning of matrix Q Q[0]=prevod(0.001,15); // 1e-3 Q[4]=prevod(0.001,15); // 1e-3 Q[8]=prevod(0.001,15); // 1e-3 Uf[0]=0x7FFF;// ! // 0.05 Uf[1]=Uf[2]=Uf[3]=0; Uf[4]=0x7FFF;//! Uf[5]=Uf[6]=Uf[7]=0; Uf[8]=0x7FFF;//! Df[0]=1<<14; Df[1]=1<<14; Df[2]=1<<14; // Tuning of matrix R R[0]=prevod(0.01,15); // 0.05 R[3]=R[0]; // Motor model parameters cA=prevod(1-Tv*Rs/Ls,15); cB=prevod(Tv*Wref*Fmag/Iref/Ls,15); cC=prevod(Tv/Ls/Iref*Uref,15); // cD=prevod(1-Tv*Bf/J,15); // cE=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref,15); cF=prevod(-p*Tv*Mref/J/Wref,15); cG=prevod(Tv*Wref/Thetaref,15); //in q15! //cH=prevod(Tv*Wref*Fmag/Iref/Ls*Thetaref,15); // cH=prevod(Tv*Wref*Thetaref*Fmag/Iref/Ls,15); // < =========== cH=prevod(Tv*Wref*Fmag*Thetaref/Iref/Ls,15); // // cI=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref*Thetaref); /* Init matrix PSI with permanently constant terms */ PSI[0]=0x7FFF; PSI[1]=0; PSI[2]= cF; PSI[3]=cG; PSI[4]=0x7FFF; PSI[5]=0; PSI[6]=0; PSI[7]=0; PSI[8]=0x7FFF; } void EKFfixedCh::bayes(const itpp::vec& yt, const itpp::vec& ut) { ekf(ut[0],ut[1],yt[0],yt[1]); } void EKFfixedCh::ekf(double ux, double uy, double isxd, double isyd) { // vypocet napeti v systemu (x,y) int16 uf[2]; uf[0]=prevod(ux/Uref,15); uf[1]=prevod(uy/Uref,15); int16 Y_mes[2]; // zadani mereni Y_mes[0]=prevod(isxd/Iref,15); Y_mes[1]=prevod(isyd/Iref,15); ////// vlastni rutina EKF -- ///////////////////////// int16 t_sin,t_cos, tmp; // implementace v PC /* t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15); * t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15);*/ t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15); t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15); tmp=((int32)cB*x_est[2])>>15; // q15*q13 -> q13 // q15*q13 + q13*q15 + q15*q13?? x_est[0]=((int32)cA*x_est[0]+(int32)tmp*t_sin+(int32)cC*(uf[0]))>>15; // in q13 x_est[1]=((int32)cA*x_est[1]-(int32)tmp*t_cos+(int32)cC*(uf[1]))>>15; // q13 x_est[2]=x_est[2]; // q15 + q15*q13 x_est[3]=(((int32)x_est[3]<<15)+(int32)cG*x_est[2])>>15; if(x_est[3]>(1<<15)) x_est[3]-=2*(1<<15); if(x_est[3]<-(1<<15)) x_est[3]+=2*(1<<15); //void EKFfixed::update_psi(void) { PSI[2]=((int32)cB*t_sin)>>15; tmp=((int32)cH*x_est[2])>>15; // ! cH =cB with different scale!! PSI[3]=((int32)tmp*t_cos)>>15; PSI[6]=-((int32)cB*t_cos)>>15; PSI[7]=((int32)tmp*t_sin)>>15; } { /* ivec Ad(PSI,16); log_level.store(logA,get_from_ivec(Ad));*/ } ///////// end of copy /////////////// mmultACh(PSI,Chf,PSICh,4,4); //thorton(int16 *U, int16 *D, int16 *PSIU, int16 *Q, int16 *G, int16 *Dold, unsigned int16 dimx); //householder(PSICh,Q,4); givens_fast(PSICh,Q,4); // COPY for (int16 ii=0; ii<16; ii++){Chf[ii]=PSICh[ii];} { int Chi[16]; for (int i=0;i<16;i++) Chi[i]=Chf[i]; ivec Chd(Chi,16); log_level.store(logCh,get_from_ivec(Chd)); imat mCh(Chd._data(), 4,4); imat P = mCh*mCh.T(); ivec iP(P._data(),16); log_level.store(logP,get_from_ivec(iP)); } int16 difz[2]; difz[0]=(Y_mes[0]-x_est[0]); // shift to q15!! difz[1]=(Y_mes[1]-x_est[1]);//<<2; // int16 dR[2];dR[0]=R[0];dR[1]=R[3]; //int16 xb[4]; xb[0]=x_est[0]<<2; xb[1]=x_est[1]<<2; xb[2]=x_est[2]<<2; xb[3]=x_est[3]; carlson_fast(difz,x_est,Chf,dR,2,4); //x_est[0] = xb[0]>>2; x_est[1]=xb[1]>>2; x_est[2]=xb[2]>>2; x_est[3]=xb[3]; // navrat estimovanych hodnot regulatoru vec& mu = E._mu(); (mu)(0)=zprevod(x_est[0],15)*Iref; (mu)(1)=zprevod(x_est[1],15)*Iref; (mu)(2)=zprevod(x_est[2],15)*Wref; (mu)(3)=zprevod(x_est[3],15)*Thetaref; //x_est[2]=x[2]*32768/Wref; //x_est[3]=x[3]*32768/Thetaref; // mat T=diag(concat(vec_2(Iref,Iref), vec_2(Wref,Thetaref))); } void EKFfixedCh::init_ekf(double Tv) { // Tuning of matrix Q Q[0]=prevod(.01,15); // 0.05 Q[5]=Q[0]; Q[10]=prevod(0.0005,15); // 1e-3 Q[15]=prevod(0.001,15); // 1e-3 Chf[0]=0x3FFF;// ! // 0.05 Chf[1]=Chf[2]=Chf[3]=Chf[4]=0; Chf[5]=0x3FFF;//! Chf[6]=Chf[6]=Chf[8]=Chf[9]=0; Chf[10]=0x3FFF;//! // 1e-3 Chf[11]=Chf[12]=Chf[13]=Chf[4]=0; Chf[15]=0x3FFF; // 1e-3 // Tuning of matrix R R[0]=prevod(0.05,15); // 0.05 R[3]=R[0]; // Motor model parameters cA=prevod(1-Tv*Rs/Ls,15); cB=prevod(Tv*Wref*Fmag/Iref/Ls,15); cC=prevod(Tv/Ls/Iref*Uref,15); // cD=prevod(1-Tv*Bf/J,15); // cE=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref,15); // cF=prevod(p*Tv*Mref/J/Wref,15); cG=prevod(Tv*Wref/Thetaref,15); //in q15! //cH=prevod(Tv*Wref*Fmag/Iref/Ls*Thetaref,15); cH=prevod(Tv*Wref*Thetaref*Fmag/Iref/Ls,15); // <======= //cH=prevod(Tv*Wref*Fmag/Iref/Ls,15); // // cI=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref*Thetaref); /* Init matrix PSI with permanently constant terms */ PSI[0]=cA; PSI[5]=PSI[0]; PSI[10]=0x7FFF; PSI[14]=cG; PSI[15]=0x7FFF; } void EKFfixedCh2::bayes(const itpp::vec& yt, const itpp::vec& ut) { ekf2(ut[0],ut[1],yt[0],yt[1]); } void EKFfixedCh2::ekf2(double ux, double uy, double isxd, double isyd) { // vypocet napeti v systemu (x,y) int16 uf[2]; uf[0]=prevod(ux/Uref,15); uf[1]=prevod(uy/Uref,15); int16 Y_mes[2]; // zadani mereni Y_mes[0]=prevod(isxd/Iref,15); Y_mes[1]=prevod(isyd/Iref,15); ////// vlastni rutina EKF -- ///////////////////////// int16 t_sin,t_cos; int32 tmp; x_est[0]=x_est[0]; // q15 + q15*q13 x_est[1]=(((int32)x_est[1]<<15)+(int32)cG*x_est[0])>>15; // if(x_est[1]>(1<<15)) x_est[1]-=2*(1<<15); // if(x_est[1]<-(1<<15)) x_est[1]+=2*(1<<15); ///////// end of copy /////////////// mmultACh(PSI,Chf,PSICh,2,2); //void EKFfixed::update_psi(void) { int Ai[4]; for (int i=0;i<4; i++) Ai[i]=(int)(PSICh[i]); ivec Ad(Ai,4); log_level.store(logA,get_from_ivec(Ad)); } //thorton(int16 *U, int16 *D, int16 *PSIU, int16 *Q, int16 *G, int16 *Dold, unsigned int16 dimx); givens_fast(PSICh,Q,2); for (int i=0;i<4;i++) Chf[i]=PSICh[i]; // implementace v PC /* t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15); * t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15);*/ tmp=prevod(sin(Thetaref*x_est[1]/32768.),15); if (tmp>32767) t_sin =32767; else t_sin=tmp; tmp=prevod(cos(Thetaref*x_est[1]/32768.),15); if (tmp>32767) t_cos =32767; else t_cos=tmp; { C[0]=((int32)cB*t_sin)>>15; tmp=((int32)cH*x_est[0])>>15; // ! cH =cB with different scale!! C[1]=((int32)tmp*t_cos)>>15; C[2]=-((int32)cB*t_cos)>>15; C[3]=((int32)tmp*t_sin)>>15; } { int Chi[4]; for (int i=0;i<4; i++) Chi[i]=(int)Chf[i]; // int Ci[4]; for (int i=0;i<4; i++) Ci[i]=(int)C[i]; imat Chd(Chi,2,2); // imat Cd(Ci,2,2); imat CCh = Chd; log_level.store(logCh,get_from_ivec(ivec(CCh._data(),CCh._datasize()))); } tmp=((int32)cB*x_est[0])>>15; // q15*q13 -> q13 // q15*q13 + q13*q15 + q15*q13?? y_est[0]=((int32)cA*y_old[0]+(int32)tmp*t_sin+(int32)cC*(uf[0]))>>15; // in q13 y_est[1]=((int32)cA*y_old[1]-(int32)tmp*t_cos+(int32)cC*(uf[1]))>>15; // q13 int16 difz[2]; difz[0]=(Y_mes[0]-y_est[0]); // shift to q15!! difz[1]=(Y_mes[1]-y_est[1]);//<<2; y_old[0] = Y_mes[0]; y_old[1] = Y_mes[1]; { int Ci[4]; for (int i=0;i<4; i++) Ci[i]=(int)C[i]; ivec CC(Ci,4);//;dd(0)=Y_mes[0];dd(1)=Y_mes[1]; dd(2)=difz[0]; dd(3)=difz[1]; log_level.store(logC,get_from_ivec(CC)); } //bierman(int16 *difz, int16 *xp, int16 *U, int16 *D, int16 *R, unsigned int16 dimy, unsigned int16 dimx ); int16 dR[2];dR[0]=R[0];dR[1]=R[3]; //int16 xb[4]; xb[0]=x_est[0]<<2; xb[1]=x_est[1]<<2; xb[2]=x_est[2]<<2; xb[3]=x_est[3]; carlson_fastC(difz,x_est,Chf,C,dR,2,2); //x_est[0] = xb[0]>>2; x_est[1]=xb[1]>>2; x_est[2]=xb[2]>>2; x_est[3]=xb[3]; // navrat estimovanych hodnot regulatoru vec& mu = E._mu(); (mu)(0)=zprevod(x_est[0],15)*Wref; (mu)(1)=zprevod(x_est[1],15)*Thetaref; //x_est[2]=x[2]*32768/Wref; //x_est[3]=x[3]*32768/Thetaref; // mat T=diag(concat(vec_2(Iref,Iref), vec_2(Wref,Thetaref))); } void EKFfixedCh2::init_ekf2(double Tv) { // Tuning of matrix Q Q[0]=prevod(0.005,15); // 1e-3 Q[3]=prevod(0.001,15); // 1e-3 Chf[0]=0x1FFF;// ! // 0.05 Chf[1]=Chf[2]=0; Chf[3]=0x1FFF;//! // Tuning of matrix R R[0]=prevod(0.001,15); // 0.05 R[3]=R[0]; // Motor model parameters cA=prevod(1-Tv*Rs/Ls,15); cB=prevod(Tv*Wref*Fmag/Iref/Ls,15); cC=prevod(Tv/Ls/Iref*Uref,15); // cD=prevod(1-Tv*Bf/J,15); // cE=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref,15); // cF=prevod(p*Tv*Mref/J/Wref,15); cG=prevod(Tv*Wref/Thetaref,15); //in q15! //cH=prevod(Tv*Wref*Fmag/Iref/Ls*Thetaref,15); // cH=prevod(Tv*Wref*Thetaref*Fmag/Iref/Ls,15); // < =========== cH=prevod(Tv*Wref*Fmag/Iref/Ls,15); // // cI=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref*Thetaref); /* Init matrix PSI with permanently constant terms */ PSI[0]=0x7FFF; PSI[2]=cG; PSI[3]=0x7FFF; }