/************************************ Extended Kalman Filter Kalman Observer Z. Peroutka Rev. 25.10.2010 EKF pocitan dle Grewala - Biermanova varianta 30.9.2010 Dodana testovaci rutina test_debug() umoznujici reinicializaci x_est. 25.10.2010 Rev. 2. 28.10.2010 xx *************************************/ #include "funkce.h" #include "parametry_motoru.h" // aktivovat v DSP #include "reference_Q15.h" //#include "reference.h" #include "matrix_vs.h" #include "ekf_bierman.h" #include "parametry_motoru.h" #include "qmath.h" #define K_PREVOD_FORM (1<<(15-Qm)) // 2^(15-Qm) #define pi2_3 21845 // 2/3*PI #define D_INIT (1<>15; tmp=((long)cH*x_est[2])>>15; PSI[3]=((long)tmp*t_cos)>>15; PSI[6]=-((long)cB*t_cos)>>15; PSI[7]=((long)tmp*t_sin)>>15; } static void prediction(int *ux) { int t_sin,t_cos, tmp; int G[16]; int Dold[4]; // implementace v DSP t_sin=qsin(x_est[3]); t_cos=qcos(x_est[3]); // t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15); // t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15); tmp=((long)cB*x_est[2])>>15; x_pred[0]=((long)cA*x_est[0]+(long)tmp*t_sin+(long)cC*ux[0])>>15; x_pred[1]=((long)cA*x_est[1]-(long)tmp*t_cos+(long)cC*ux[1])>>15; x_pred[2]=x_est[2]; x_pred[3]=(((long)x_est[3]<<15)+(long)cG*x_est[2])>>15; update_psi(); // Thorton mmultAU(PSI,U,PSIU,4,4); thorton_fast(U,D,PSIU,Q,G,Dold,4); } static void correction(void) { int Y_error[2]; unsigned int ii; int dR[2]; // prediction error Y_error[0]=Y_mes[0]-x_pred[0]; Y_error[1]=Y_mes[1]-x_pred[1]; // copy prediction to state exstimation vector for (ii=0;ii<4;ii++) x_est[ii]=x_pred[ii]; // copy diagonal from matrix R dR[0]=R[0]; dR[1]=R[3]; // Bierman_fast - correction bierman_fast(Y_error,x_est,U,D,dR,2,4); } void ekf(int *x_estimation, int Um, int beta, int Ucn, int Uc, int isx, int isy) { int Umk, ua, ub; // prepocet napeti pro EKF dle skutecneho napeti v ss obvodu Umk=((long)Um*Uc)/Ucn; // vypocet napeti v systemu (x,y) ukalm[0]=((long)Umk*qcos(beta))>>15; // usx ukalm[1]=((long)Umk*qsin(beta))>>15; // usy // zadani mereni Y_mes[0]=isx; Y_mes[1]=isy; ////// vlastni rutina EKF ///////////////////////// prediction(ukalm); correction(); // navrat estimovanych hodnot regulatoru *x_estimation=x_est[2]; *(x_estimation+1)=x_est[3]; } void reset_ekf(void) { int ii; for (ii=0;ii<4;ii++) x_est[ii]=0; for (ii=0;ii<4;ii++) x_pred[ii]=0; for (ii=0;ii<4;ii++) D[ii]=1<