Changeset 1240
- Timestamp:
- 10/29/10 19:10:03 (14 years ago)
- Location:
- applications/pmsm/simulator_zdenek/ekf_example
- Files:
-
- 4 modified
Legend:
- Unmodified
- Added
- Removed
-
applications/pmsm/simulator_zdenek/ekf_example/ekf_obj.cpp
r1236 r1240 7 7 double minQ(double Q){if (Q>1.0){ return 1.0;} else {return Q;};}; 8 8 9 void mat_to_int (const imat &M, int*I){10 for (int i=0;i<M.rows(); i++){11 for (int j=0;j<M.cols(); j++){9 void mat_to_int16(const imat &M, int16 *I){ 10 for (int16 i=0;i<M.rows(); i++){ 11 for (int16 j=0;j<M.cols(); j++){ 12 12 *I++ = M(i,j); 13 13 } 14 14 } 15 15 } 16 void vec_to_int (const ivec &v, int*I){17 for (int i=0;i<v.length(); i++){16 void vec_to_int16(const ivec &v, int16 *I){ 17 for (int16 i=0;i<v.length(); i++){ 18 18 *I++ = v(i); 19 19 } 20 20 } 21 21 22 #ifdef XXX 22 23 /////////////// 23 24 void EKFfixed::bayes(const vec &yt, const vec &ut){ … … 46 47 mat Pfull(4,4); 47 48 double* Pp=Pfull._data(); 48 for(int i=0;i<16;i++){*(Pp++) = zprevod(P_est[i],15);}49 for(int16 i=0;i<16;i++){*(Pp++) = zprevod(P_est[i],15);} 49 50 50 51 E._R()._M()=Pfull; … … 58 59 void EKFfixed::update_psi(void) 59 60 { 60 int t_sin,t_cos,tmp;61 int16 t_sin,t_cos,tmp; 61 62 62 63 // implementace v PC … … 64 65 t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15); 65 66 66 PSI[2]=(( long)cB*t_sin)>>15;67 tmp=(( long)cH*x_est[2])>>15;68 PSI[3]=(( long)tmp*t_cos)>>15;69 PSI[6]=-(( long)cB*t_cos)>>15;70 PSI[7]=(( long)tmp*t_sin)>>15;71 } 72 73 74 void EKFfixed::prediction(int *ux)75 { 76 int t_sin,t_cos, tmp;67 PSI[2]=((int32)cB*t_sin)>>15; 68 tmp=((int32)cH*x_est[2])>>15; 69 PSI[3]=((int32)tmp*t_cos)>>15; 70 PSI[6]=-((int32)cB*t_cos)>>15; 71 PSI[7]=((int32)tmp*t_sin)>>15; 72 } 73 74 75 void EKFfixed::prediction(int16 *ux) 76 { 77 int16 t_sin,t_cos, tmp; 77 78 78 79 // implementace v PC … … 83 84 t_cos=prevod(cos(Thetaref*x_est[3]/Qm),15); 84 85 85 tmp=(( long)cB*x_est[2])>>15;86 x_pred[0]=(( long)cA*x_est[0]+(long)tmp*t_sin+(long)cC*ux[0])>>15;87 x_pred[1]=(( long)cA*x_est[1]-(long)tmp*t_cos+(long)cC*ux[1])>>15;86 tmp=((int32)cB*x_est[2])>>15; 87 x_pred[0]=((int32)cA*x_est[0]+(int32)tmp*t_sin+(int32)cC*ux[0])>>15; 88 x_pred[1]=((int32)cA*x_est[1]-(int32)tmp*t_cos+(int32)cC*ux[1])>>15; 88 89 x_pred[2]=x_est[2]; 89 x_pred[3]=((( long)x_est[3]<<15)+(long)cG*x_est[2])>>15;90 x_pred[3]=(((int32)x_est[3]<<15)+(int32)cG*x_est[2])>>15; 90 91 91 92 update_psi(); … … 99 100 void EKFfixed::correction(void) 100 101 { 101 int Y_error[2];102 longtemp30a[4]; /* matrix [2,2] - temporary matrix for inversion */102 int16 Y_error[2]; 103 int32 temp30a[4]; /* matrix [2,2] - temporary matrix for inversion */ 103 104 104 105 choice_P(P_pred,temp15a,3); … … 189 190 P_est[15]=0x7FFF; 190 191 } 191 192 #endif 192 193 193 194 void EKF_UDfix::set_parameters ( const shared_ptr<diffbifn> &pfxu0, const shared_ptr<diffbifn> &phxu0, const mat Q0, const vec R0 ) { … … 228 229 Df=round_i(Pld._D()*(1<<15)); 229 230 ivec zer=find(Df==0); 230 for(int i=0; i<zer.length(); i++) Df(zer(i))=1;231 for(int16 i=0; i<zer.length(); i++) Df(zer(i))=1; 231 232 } 232 233 … … 236 237 vec &_mu=est._mu(); 237 238 const vec &u=cond; 238 int dim = dimension();239 int16 dim = dimension(); 239 240 ///// !!!!!!!!!!!!!!!! 240 241 U = est._R()._L().T(); … … 258 259 259 260 vec Din = D; 260 int i,j,k;261 int16 i,j,k; 261 262 double sigma; 262 263 mat G = eye(dim); … … 323 324 324 325 325 for (int iy=0; iy<dimy; iy++){326 for (int16 iy=0; iy<dimy; iy++){ 326 327 a = U.T()*C.get_row(iy); // a is not modified, but 327 328 b = elem_mult(D,a); // b is modified to become unscaled Kalman gain. … … 366 367 367 368 //statistics 368 int dim = IM->dimension();369 int16 dim = IM->dimension(); 369 370 vec mu0; 370 371 if ( !UI::get ( mu0, set, "mu0" ) ) … … 400 401 { 401 402 // vypocet napeti v systemu (x,y) 402 int uf[2];403 int16 uf[2]; 403 404 uf[0]=prevod(ux/Uref,15); 404 405 uf[1]=prevod(uy/Uref,15); 405 406 406 int Y_mes[2];407 int16 Y_mes[2]; 407 408 // zadani mereni 408 409 Y_mes[0]=prevod(isxd/Iref,15); … … 410 411 411 412 ////// vlastni rutina EKF -- ///////////////////////// 412 int t_sin,t_cos, tmp; 413 int16 t_sin,t_cos; 414 int32 tmp; 413 415 414 416 // implementace v PC 415 417 /* t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15); 416 418 t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15);*/ 417 t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15); 418 t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15); 419 420 tmp=((long)cB*x_est[2])>>15; // q15*q13 -> q13 419 tmp=prevod(sin(Thetaref*x_est[3]/32768.),15); 420 if (tmp>32767) t_sin =32767; else t_sin=tmp; 421 tmp=prevod(cos(Thetaref*x_est[3]/32768.),15); 422 if (tmp>32767) t_cos =32767; else t_cos=tmp; 423 424 tmp=((int32)cB*x_est[2])>>15; // q15*q13 -> q13 421 425 // q15*q13 + q13*q15 + q15*q13?? 422 x_est[0]=(( long)cA*x_est[0]+(long)tmp*t_sin+(long)cC*(uf[0]))>>15; // in q13423 x_est[1]=(( long)cA*x_est[1]-(long)tmp*t_cos+(long)cC*(uf[1]))>>15; // q13426 x_est[0]=((int32)cA*x_est[0]+(int32)tmp*t_sin+(int32)cC*(uf[0]))>>15; // in q13 427 x_est[1]=((int32)cA*x_est[1]-(int32)tmp*t_cos+(int32)cC*(uf[1]))>>15; // q13 424 428 x_est[2]=x_est[2]; 425 429 // q15 + q15*q13 426 x_est[3]=((( long)x_est[3]<<15)+(long)cG*x_est[2])>>15;430 x_est[3]=(((int32)x_est[3]<<15)+(int32)cG*x_est[2])>>15; 427 431 428 432 if(x_est[3]>(1<<15)) x_est[3]-=2*(1<<15); … … 431 435 //void EKFfixed::update_psi(void) 432 436 { 433 PSI[2]=(( long)cB*t_sin)>>15;434 tmp=(( long)cH*x_est[2])>>15; // ! cH =cB with different scale!!435 PSI[3]=(( long)tmp*t_cos)>>15;436 PSI[6]=-(( long)cB*t_cos)>>15;437 PSI[7]=(( long)tmp*t_sin)>>15;437 PSI[2]=((int32)cB*t_sin)>>15; 438 tmp=((int32)cH*x_est[2])>>15; // ! cH =cB with different scale!! 439 PSI[3]=((int32)tmp*t_cos)>>15; 440 PSI[6]=-((int32)cB*t_cos)>>15; 441 PSI[7]=((int32)tmp*t_sin)>>15; 438 442 } 439 443 { 440 ivec Ad(PSI,16); 444 int Ai[16]; 445 for (int i=0;i<16; i++) Ai[i]=(int)(PSI[i]); 446 ivec Ad(Ai,16); 441 447 log_level.store(logA,get_from_ivec(Ad)); 442 448 } … … 444 450 ///////// end of copy /////////////// 445 451 mmultAU(PSI,Uf,PSIU,4,4); 446 //thorton(int *U, int *D, int *PSIU, int *Q, int *G, int *Dold, unsigned intdimx);452 //thorton(int16 *U, int16 *D, int16 *PSIU, int16 *Q, int16 *G, int16 *Dold, unsigned int16 dimx); 447 453 thorton_fast(Uf,Df,PSIU,Q,G,Dfold,4); 448 454 449 455 { 450 ivec Ud(Uf,16); 456 int Ui[16]; for (int i=0;i<16; i++) Ui[i]=(int)Uf[i]; 457 458 ivec Ud(Ui,16); 451 459 log_level.store(logU,get_from_ivec(Ud)); 452 ivec dd(Df,4); 453 imat U(Uf,4,4); 460 461 int di[16]; for (int i=0;i<16; i++) di[i]=(int)Df[i]; 462 ivec dd(di,4); 463 imat U(Ui,4,4); 454 464 mat U2=to_mat(U)/32768; 455 465 mat PP=U2*diag(to_vec(dd))*U2.T(); … … 458 468 } 459 469 { 460 ivec Gd(G,16); 470 int Gi[16]; for (int i=0;i<16; i++) Gi[i]=(int)G[i]; 471 ivec Gd(Gi,16); 461 472 log_level.store(logG,get_from_ivec(Gd)); 462 473 } 463 474 464 475 465 int difz[2];476 int16 difz[2]; 466 477 difz[0]=(Y_mes[0]-x_est[0]); // shift to q15!! 467 478 difz[1]=(Y_mes[1]-x_est[1]);//<<2; 468 479 469 480 { 470 ivec dd(Df,4);//;dd(0)=Y_mes[0];dd(1)=Y_mes[1]; dd(2)=difz[0]; dd(3)=difz[1]; 481 int Di[4]; for (int i=0;i<4; i++) Di[i]=(int)Df[i]; 482 ivec dd(Di,4);//;dd(0)=Y_mes[0];dd(1)=Y_mes[1]; dd(2)=difz[0]; dd(3)=difz[1]; 471 483 log_level.store(logD,get_from_ivec(dd)); 472 484 } 473 485 474 //bierman(int *difz, int *xp, int *U, int *D, int *R, unsigned int dimy, unsigned intdimx );475 int dR[2];dR[0]=R[0];dR[1]=R[3];476 //int 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];486 //bierman(int16 *difz, int16 *xp, int16 *U, int16 *D, int16 *R, unsigned int16 dimy, unsigned int16 dimx ); 487 int16 dR[2];dR[0]=R[0];dR[1]=R[3]; 488 //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]; 477 489 bierman_fast(difz,x_est,Uf,Df,dR,2,4); 478 490 //x_est[0] = xb[0]>>2; x_est[1]=xb[1]>>2; x_est[2]=xb[2]>>2; x_est[3]=xb[3]; … … 495 507 Q[0]=prevod(.01,15); // 0.05 496 508 Q[5]=Q[0]; 497 Q[10]=prevod(0.0 1,15); // 1e-3498 Q[15]=prevod(0.0 1,15); // 1e-3509 Q[10]=prevod(0.0005,15); // 1e-3 510 Q[15]=prevod(0.001,15); // 1e-3 499 511 500 512 Uf[0]=0x7FFF;// ! // 0.05 … … 524 536 cG=prevod(Tv*Wref/Thetaref,15); //in q15! 525 537 //cH=prevod(Tv*Wref*Fmag/Iref/Ls*Thetaref,15); 538 // cH=prevod(Tv*Wref*Thetaref*Fmag/Iref/Ls,15); // < =========== 526 539 cH=prevod(Tv*Wref*Thetaref*Fmag/Iref/Ls,15); // 527 540 // cI=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref*Thetaref); … … 545 558 { 546 559 // vypocet napeti v systemu (x,y) 547 int uf[2];560 int16 uf[2]; 548 561 uf[0]=prevod(ux/Uref,15); 549 562 uf[1]=prevod(uy/Uref,15); 550 563 551 int Y_mes[2];564 int16 Y_mes[2]; 552 565 // zadani mereni 553 566 Y_mes[0]=prevod(isxd/Iref,15); … … 555 568 556 569 ////// vlastni rutina EKF -- ///////////////////////// 557 int t_sin,t_cos, tmp;570 int16 t_sin,t_cos, tmp; 558 571 559 572 // implementace v PC … … 563 576 t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15); 564 577 565 tmp=(( long)cB*x_est[2])>>15; // q15*q13 -> q13578 tmp=((int32)cB*x_est[2])>>15; // q15*q13 -> q13 566 579 // q15*q13 + q13*q15 + q15*q13?? 567 x_est[0]=(( long)cA*x_est[0]+(long)tmp*t_sin+(long)cC*(uf[0]))>>15; // in q13568 x_est[1]=(( long)cA*x_est[1]-(long)tmp*t_cos+(long)cC*(uf[1]))>>15; // q13580 x_est[0]=((int32)cA*x_est[0]+(int32)tmp*t_sin+(int32)cC*(uf[0]))>>15; // in q13 581 x_est[1]=((int32)cA*x_est[1]-(int32)tmp*t_cos+(int32)cC*(uf[1]))>>15; // q13 569 582 x_est[2]=x_est[2]; 570 583 // q15 + q15*q13 571 x_est[3]=((( long)x_est[3]<<15)+(long)cG*x_est[2])>>15;584 x_est[3]=(((int32)x_est[3]<<15)+(int32)cG*x_est[2])>>15; 572 585 573 586 if(x_est[3]>(1<<15)) x_est[3]-=2*(1<<15); … … 576 589 //void EKFfixed::update_psi(void) 577 590 { 578 PSI[2]=(( long)cB*t_sin)>>15;579 tmp=(( long)cH*x_est[2])>>15; // ! cH =cB with different scale!!580 PSI[3]=(( long)tmp*t_cos)>>15;581 PSI[6]=-(( long)cB*t_cos)>>15;582 PSI[7]=(( long)tmp*t_sin)>>15;591 PSI[2]=((int32)cB*t_sin)>>15; 592 tmp=((int32)cH*x_est[2])>>15; // ! cH =cB with different scale!! 593 PSI[3]=((int32)tmp*t_cos)>>15; 594 PSI[6]=-((int32)cB*t_cos)>>15; 595 PSI[7]=((int32)tmp*t_sin)>>15; 583 596 } 584 597 { 585 ivec Ad(PSI,16);586 log_level.store(logA,get_from_ivec(Ad)); 598 /* ivec Ad(PSI,16); 599 log_level.store(logA,get_from_ivec(Ad));*/ 587 600 } 588 601 589 602 ///////// end of copy /////////////// 590 603 mmultACh(PSI,Chf,PSICh,4,4); 591 //thorton(int *U, int *D, int *PSIU, int *Q, int *G, int *Dold, unsigned intdimx);604 //thorton(int16 *U, int16 *D, int16 *PSIU, int16 *Q, int16 *G, int16 *Dold, unsigned int16 dimx); 592 605 householder(PSICh,Q,4); 593 606 // COPY 594 for (int ii=0; ii<16; ii++){Chf[ii]=PSICh[ii];}607 for (int16 ii=0; ii<16; ii++){Chf[ii]=PSICh[ii];} 595 608 596 609 { 597 ivec Chd(Chf,16);598 log_level.store(logCh,get_from_ivec(Chd)); 599 } 600 601 602 int difz[2];610 /* ivec Chd(Chf,16); 611 log_level.store(logCh,get_from_ivec(Chd));*/ 612 } 613 614 615 int16 difz[2]; 603 616 difz[0]=(Y_mes[0]-x_est[0]); // shift to q15!! 604 617 difz[1]=(Y_mes[1]-x_est[1]);//<<2; … … 606 619 607 620 // 608 int dR[2];dR[0]=R[0];dR[1]=R[3];609 //int 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];621 int16 dR[2];dR[0]=R[0];dR[1]=R[3]; 622 //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]; 610 623 611 624 carlson(difz,x_est,Chf,dR,2,4); … … 653 666 cG=prevod(Tv*Wref/Thetaref,15); //in q15! 654 667 //cH=prevod(Tv*Wref*Fmag/Iref/Ls*Thetaref,15); 655 cH=prevod(Tv*Wref*Thetaref*Fmag/Iref/Ls,15); // 668 // cH=prevod(Tv*Wref*Thetaref*Fmag/Iref/Ls,15); // <======= 669 cH=prevod(Tv*Wref*Fmag/Iref/Ls,15); // 656 670 // cI=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref*Thetaref); 657 671 -
applications/pmsm/simulator_zdenek/ekf_example/ekf_obj.h
r1226 r1240 5 5 6 6 ----------------------------------- 7 BDM++ - C++ library for Bayesian Decision Making under Uncertaint y7 BDM++ - C++ library for Bayesian Decision Making under Uncertaint16y 8 8 9 9 Using IT++ for numerical operations … … 26 26 double minQ(double Q); 27 27 28 void mat_to_int (const imat &M, int*I);29 void vec_to_int (const ivec &v, int*I);28 void mat_to_int16(const imat &M, int16 *I); 29 void vec_to_int16(const ivec &v, int16 *I); 30 30 void UDtof(const mat &U, const vec &D, imat &Uf, ivec &Df, const vec &xref); 31 31 32 #ifdef XXX 32 33 /*! 33 \brief Extended Kalman Filter with full matrices in fixed point arithmetic34 \brief Extended Kalman Filter with full matrices in fixed point16 arithmetic 34 35 35 36 An approximation of the exact Bayesian filter with Gaussian noices and non-linear evolutions of their mean. … … 41 42 42 43 /* Declaration of local functions */ 43 void prediction(int *ux);44 void prediction(int16 *ux); 44 45 void correction(void); 45 46 void update_psi(void); 46 47 47 48 /* Constants - definovat jako konstanty ?? ?kde je vyhodnejsi aby v pameti byli?*/ 48 int Q[16]; /* matrix [4,4] */49 int R[4]; /* matrix [2,2] */50 51 int x_est[4];52 int x_pred[4];53 int P_pred[16]; /* matrix [4,4] */54 int P_est[16]; /* matrix [4,4] */55 int Y_mes[2];56 int ukalm[2];57 int Kalm[8]; /* matrix [5,2] */58 59 int PSI[16]; /* matrix [4,4] */60 61 int temp15a[16];62 63 int cA, cB, cC, cG, cH; // cD, cE, cF, cI ... nepouzivane64 65 longtemp30a[4]; /* matrix [2,2] - temporary matrix for inversion */49 int16 Q[16]; /* matrix [4,4] */ 50 int16 R[4]; /* matrix [2,2] */ 51 52 int16 x_est[4]; 53 int16 x_pred[4]; 54 int16 P_pred[16]; /* matrix [4,4] */ 55 int16 P_est[16]; /* matrix [4,4] */ 56 int16 Y_mes[2]; 57 int16 ukalm[2]; 58 int16 Kalm[8]; /* matrix [5,2] */ 59 60 int16 PSI[16]; /* matrix [4,4] */ 61 62 int16 temp15a[16]; 63 64 int16 cA, cB, cC, cG, cH; // cD, cE, cF, cI ... nepouzivane 65 66 int32 temp30a[4]; /* matrix [2,2] - temporary matrix for inversion */ 66 67 enorm<fsqmat> E; 67 68 mat Ry; … … 70 71 //! Default constructor 71 72 EKFfixed ():BM(),E(),Ry(2,2){ 72 int i;73 int16 i; 73 74 for(i=0;i<16;i++){Q[i]=0;} 74 75 for(i=0;i<4;i++){R[i]=0;} … … 102 103 UIREGISTER(EKFfixed); 103 104 105 #endif 106 104 107 /*! 105 \brief Extended Kalman Filter with UD matrices in fixed point arithmetic108 \brief Extended Kalman Filter with UD matrices in fixed point16 arithmetic 106 109 107 110 An approximation of the exact Bayesian filter with Gaussian noices and non-linear evolutions of their mean. … … 115 118 116 119 /* Constants - definovat jako konstanty ?? ?kde je vyhodnejsi aby v pameti byli?*/ 117 int Q[16]; /* matrix [4,4] */118 int R[4]; /* matrix [2,2] */119 120 int x_est[4]; /* estimate and prediction */121 122 int PSI[16]; /* matrix [4,4] */123 int PSIU[16]; /* matrix PIS*U, [4,4] */124 125 int Uf[16]; // upper triangular of covariance (inplace)126 int Df[4]; // diagonal covariance127 int Dfold[4]; // temp of D128 int G[16]; // temp for bierman129 130 int cA, cB, cC, cG, cH; // cD, cE, cF, cI ... nepouzivane120 int16 Q[16]; /* matrix [4,4] */ 121 int16 R[4]; /* matrix [2,2] */ 122 123 int16 x_est[4]; /* estimate and prediction */ 124 125 int16 PSI[16]; /* matrix [4,4] */ 126 int16 PSIU[16]; /* matrix PIS*U, [4,4] */ 127 128 int16 Uf[16]; // upper triangular of covariance (inplace) 129 int16 Df[4]; // diagonal covariance 130 int16 Dfold[4]; // temp of D 131 int16 G[16]; // temp for bierman 132 133 int16 cA, cB, cC, cG, cH; // cD, cE, cF, cI ... nepouzivane 131 134 132 135 enorm<fsqmat> E; … … 136 139 //! Default constructor 137 140 EKFfixedUD ():BM(),E(),Ry(2,2){ 138 int i;141 int16 i; 139 142 for(i=0;i<16;i++){Q[i]=0;} 140 143 for(i=0;i<4;i++){R[i]=0;} … … 173 176 174 177 /*! 175 * \brief Extended Kalman Filter with Chol matrices in fixed point arithmetic178 * \brief Extended Kalman Filter with Chol matrices in fixed point16 arithmetic 176 179 * 177 180 * An approximation of the exact Bayesian filter with Gaussian noices and non-linear evolutions of their mean. … … 185 188 186 189 /* Constants - definovat jako konstanty ?? ?kde je vyhodnejsi aby v pameti byli?*/ 187 int Q[16]; /* matrix [4,4] */188 int R[4]; /* matrix [2,2] */189 190 int x_est[4]; /* estimate and prediction */191 192 int PSI[16]; /* matrix [4,4] */193 int PSICh[16]; /* matrix PIS*U, [4,4] */194 195 int Chf[16]; // upper triangular of covariance (inplace)196 197 int cA, cB, cC, cG, cH; // cD, cE, cF, cI ... nepouzivane190 int16 Q[16]; /* matrix [4,4] */ 191 int16 R[4]; /* matrix [2,2] */ 192 193 int16 x_est[4]; /* estimate and prediction */ 194 195 int16 PSI[16]; /* matrix [4,4] */ 196 int16 PSICh[16]; /* matrix PIS*U, [4,4] */ 197 198 int16 Chf[16]; // upper triangular of covariance (inplace) 199 200 int16 cA, cB, cC, cG, cH; // cD, cE, cF, cI ... nepouzivane 198 201 199 202 enorm<chmat> E; … … 203 206 //! Default constructor 204 207 EKFfixedCh ():BM(),E(),Ry(2,2){ 205 int i;208 int16 i; 206 209 for(i=0;i<16;i++){Q[i]=0;} 207 210 for(i=0;i<4;i++){R[i]=0;} … … 235 238 236 239 237 //! EKF for comparison of EKF_UD with its fixed-point implementation240 //! EKF for comparison of EKF_UD with its fixed-point16 implementation 238 241 class EKF_UDfix : public BM { 239 242 protected: -
applications/pmsm/simulator_zdenek/ekf_example/matrix_vs.cpp
r1239 r1240 3 3 Matrix operations 4 4 5 V. Smidl 6 7 Rev. 30.8.2010 8 9 30.8.2010 Prvni verze 5 V. Smidl, Z. Peroutka 6 7 Rev. 28.10.2010 (ZP) 8 9 26.10.2010 Prvni verze (VS) 10 11 26.10.2010 Upravena chyba v Thorton_fast - spatne shiftovani o vypoctu SIGMA. 12 27.10.2010 Pokus o odstraneni problemu v Thorton_fast - potize dela omezovani (orezavani) varianci. 13 28.10.2010 Drobne upravy v kodu. 10 14 11 15 *************************************/ 12 #include "fixed.h"13 #include "stdio.h"14 #include <math.h>15 16 16 17 #include "matrix_vs.h" 17 18 18 19 /* Matrix multiply Full matrix by upper diagonal matrix; */ 19 void mmultAU(int *m1, int *up, int *result, unsigned int rows, unsigned intcolumns) {20 unsigned int i, j, k;21 longtmp_sum=0L; //in 15+qAU22 int *m2pom;23 int *m1pom=m1;24 int *respom=result;20 void mmultAU(int16 *m1, int16 *up, int16 *result, unsigned int16 rows, unsigned int16 columns) { 21 unsigned int16 i, j, k; 22 int32 tmp_sum=0L; //in 15+qAU 23 int16 *m2pom; 24 int16 *m1pom=m1; 25 int16 *respom=result; 25 26 26 27 for (i=0; i<rows; i++) //rows of result 27 28 { 28 29 for (j=0; j<columns; j++) //columns of result 29 30 { 30 31 m2pom=up+j;//?? 31 32 32 33 for (k=0; k<j; k++) //inner loop up to "j" - U(j,j)==1; 33 34 { 34 tmp_sum+=(( long)(*(m1pom++))**m2pom)>>(15-qAU);35 tmp_sum+=((int32)(*(m1pom++))**m2pom)>>(15-qAU); 35 36 m2pom+=columns; 36 37 } 37 38 // add the missing A(i,j) 38 tmp_sum +=( long)(*m1pom)<<qAU; // no need to shift39 tmp_sum +=(int32)(*m1pom)<<qAU; // no need to shift 39 40 m1pom-=(j); // shift back to first element 40 41 41 // saturation effect42 /* tmp_sum=tmp_sum>>15;43 if (tmp_sum>32767) {44 printf("Au - saturated\n");45 }46 if (tmp_sum<-32768) {47 printf("Au - saturated\n");48 }*/49 // printf("Au - saturated\n");50 51 42 *respom++=tmp_sum>>15; 52 43 … … 57 48 }; 58 49 59 /* Matrix multiply Full matrix by upper diagonal matrix; */ 60 void mmultACh(int *m1, int *up, int *result, unsigned int rows, unsigned int columns) { 61 unsigned int i, j, k; 62 long tmp_sum=0L; 63 int *m2pom; 64 int *m1pom=m1; 65 int *respom=result; 66 67 for (i=0; i<rows; i++) //rows of result 68 { 69 for (j=0; j<columns; j++) //columns of result 70 { 71 m2pom=up+j;//?? 72 73 for (k=0; k<=j; k++) //inner loop up to "j" - U(j,j)==1; 74 { 75 tmp_sum+=(long)(*(m1pom++))**m2pom; 76 m2pom+=columns; 77 } 78 m1pom-=(j+1); // shift back to first element 79 80 // saturation effect 81 tmp_sum=tmp_sum>>15; 82 if (tmp_sum>32767) { 83 if (i!=3) tmp_sum=32767; 84 } 85 if (tmp_sum<-32768) { 86 tmp_sum=-32768; 87 } 88 // printf("Au - saturated\n"); 89 90 *respom++=tmp_sum; 91 92 tmp_sum=0; 93 } 94 m1pom+=(columns); 95 } 96 }; 97 98 bool DBG=true; 99 100 void show(const char name[10], int *I, int n) { 101 if (!DBG) return; 102 103 printf("%s: ",name); 104 for (int i=0;i<n;i++) { 105 printf("%d ",*(I+i)); 106 } 107 printf("\n"); 108 } 109 110 // Thorton procedure - Kalman predictive variance in UD 111 void thorton(int *U, int *D, int *PSIU, int *Q, int *G, int *Dold, unsigned int rows) { 112 unsigned int i,j,k; 113 // copy D to Dold 114 int *Dold_pom=Dold; 115 for (i=0;i<rows;i++) { 116 *Dold_pom++=*D++; 117 } 118 D-=rows; // back to first D 119 120 // initialize G = eye() 121 int *G_pom = G; 122 *G_pom++=1<<14; 123 for (i=0;i<rows-1;i++) { 124 // clean elem before diag 125 for (j=0; j<rows; j++) { 126 *G_pom++=0.0; 127 } 128 *G_pom++=1<<14; 129 } 130 // eye created 131 132 long sigma; // in q30!!!!!! 133 for (i=rows-1; true;i--) { // check i==0 at the END! 134 sigma = 0; 135 136 for (j=0;j<rows; j++) { 137 //long s1=(((long)PSIU[i+j*rows]*PSIU[i+j*rows])>>15)*(Dold[i]); 138 long s2=((((long)PSIU[i*rows+j]*Dold[j]))>>(2*qAU-15))*PSIU[i*rows+j]; 139 // printf("%d - %d\n",s1,s2); 140 sigma += s2; 141 } 142 sigma += Q[i*rows+i]<<15; // Q is in q15 143 for (j=i+1;j<rows; j++) { 144 sigma += (((long)G[i*rows+j]*G[i*rows+j])>>13)*Q[j*rows+j]; 145 // sigma += (((long)G[i+j*rows]*G[i+j*rows])>>13)*Q[j+j*rows]; 146 } 147 148 if (sigma>16384<<15) sigma = 16384<<15; 149 *(D+i)=sigma>>15; 150 if (D[i]==0) D[i]=1; 151 //show("D",D,5); 152 153 for (j=0;j<i;j++) { 154 // printf("\n%d,%d\n",i,j); 155 sigma =0; 156 for (k=0;k<rows;k++) { 157 int tmp= (((long(PSIU[i*rows+k])*Dold[k]))>>(2*qAU-15)); 158 if (tmp>32767) printf("!"); 159 sigma += (((long(PSIU[i*rows+k])*Dold[k]))>>(2*qAU-15))*PSIU[j*rows+k]; 160 } 161 for (k=0;k<rows;k++) { 162 sigma += ((((long)G[i*rows+k])*G[j*rows+k])>>13)*Q[k*rows+k]; 163 } 164 long z=sigma/D[i]; // shift by 15 165 if (z>32767) z=32767; 166 if (z<-32768) z=-32768; 167 168 U[j*rows+i] = (int)z; 169 170 171 for (k=0;k<rows;k++) { 172 PSIU[j*rows+k] -= ((long)U[j*rows+i]*PSIU[i*rows+k])>>15; //qAU*q15/q15=qAU 173 } 174 175 for (k=0;k<rows;k++) { 176 G[j*rows+k] -= ((long)U[j*rows+i]*G[i*rows+k])>>15; 177 } 178 179 } 180 //show("U",U,25); 181 //show("G",G,25); 182 if (i==0) return; 183 } 184 } 185 186 void bierman_fast(int *difz, int *xp, int *U, int *D, int *R, unsigned int dimy, unsigned int dimx ) { 187 int alpha; 188 int beta,lambda; 189 int b[5]; // ok even for 4-dim state 190 int *a; // in [0,1] -> q15 191 unsigned int iy,j,i; 192 193 int *b_j,*b_i; 194 int *a_j; 195 int *D_j; 196 int *U_ij; 197 int *x_i; 198 int dzs; 50 51 void bierman_fast(int16 *difz, int16 *xp, int16 *U, int16 *D, int16 *R, unsigned int16 dimy, unsigned int16 dimx ) 52 { 53 int16 alpha; 54 int16 beta,lambda; 55 int16 b[5]; // ok even for 4-dim state 56 int16 *a; // in [0,1] -> q15 57 unsigned int16 iy,j,i; 58 59 int16 *b_j,*b_i; 60 int16 *a_j; 61 int16 *D_j; 62 int16 *U_ij; 63 int16 *x_i; 64 65 int32 z_pom; 66 int16 z_pom_int16; 199 67 200 68 a = U; // iyth row of U … … 202 70 // a is a row 203 71 for (j=0,a_j=a,b_j=b,D_j=D; j<dimx; j++,b_j++,D_j++,a_j++) 204 *b_j=(( long)(*D_j)*(*a_j))>>15;205 206 alpha = (long)R[iy]; //\alpha = R+vDv = R+a*b72 *b_j=((int32)(*D_j)*(*a_j))>>15; 73 74 alpha = R[iy]; //\alpha = R+vDv = R+a*b 207 75 // R in q15, a in q15, b=q15 208 76 // gamma = (1<<15)/alpha; //(in q15) … … 210 78 //max gamma = 0.0061 => gamma_ref = q7 211 79 for (j=0,a_j=a,b_j=b,D_j=D; j<dimx; j++,a_j++,b_j++,D_j++) { 212 beta = alpha; 213 lambda = -((long)(*a_j)<<15)/beta; 214 alpha += ((long)(*a_j)*(*b_j))>>15; 215 D[j] = ((((long)beta<<15)/alpha)*(*D_j))>>15; //gamma is long 80 /* beta=alpha; 81 lambda = -((int32)(*a_j)<<15)/beta; 82 alpha += ((int32)(*a_j)*(*b_j))>>15; 83 D[j] = ((int32)beta**D_j)/alpha;*/ 84 /*xx*/ 85 lambda=alpha; 86 alpha += ((int32)(*a_j)*(*b_j))>>15; 87 D[j] = ((int32)lambda**D_j)/alpha; 88 z_pom_int16 = -((int32)(*a_j)<<15)/lambda; 89 /*xx*/ 90 216 91 if (*D_j==0) *D_j=1; 217 92 218 93 for (i=0,b_i=b,U_ij=U+j; i<j; i++, b_i++,U_ij+=dimx) { 219 94 beta = *U_ij; 220 *U_ij += ((long)lambda*(*b_i))>>15; 221 *b_i += ((long)beta*(*b_j))>>15; 222 } 223 } 224 dzs = (((long)difz[iy])<<15)/alpha; // apply scaling to innovations 95 // *U_ij += ((int32)lambda*(*b_i))>>15; // puvodni reseni 96 *U_ij -= ((int32)(*a_j)*(*b_i))/lambda; // pozadovane optimalni reseni 97 // *U_ij -= ((int32)((int16)((int32)(*a_j)<<15)/lambda)**b_i)>>15; // tohle funguje - problem je s tim pretypovanim na (int16) 98 // *U_ij -= (int16)((int32)(*a_j)*(*b_i))/lambda; 99 // z_pom = (((int32)(*a_j)*(*b_i))/lambda); 100 /* z_pom = (int32)(*U_ij)-(int16)((int32)(*a_j)*(*b_i))/lambda; 101 if (z_pom > 32767) z_pom = 32767; 102 if (z_pom < - 32768) z_pom = -32768; 103 *U_ij = z_pom; /**/ 104 // *U_ij += ((int32)z_pom_int16*(*b_i))>>15; // puvodni reseni - jen jina konstanta 105 *b_i += ((int32)beta*(*b_j))>>15; 106 } 107 } 225 108 // no shift due to gamma 226 109 for (i=0,x_i=xp,b_i=b; i<dimx; i++,x_i++,b_i++) { 227 *x_i += ((long)dzs*(*b_i))>>15; // multiply by unscaled Kalman gain 228 } 229 230 //cout << "Ub: " << U << endl; 231 //cout << "Db: " << D << endl <<endl; 232 233 } 234 235 } 110 *x_i += ((int32)difz[iy]*(*b_i))/alpha; // multiply by unscaled Kalman gain 111 } 112 } 113 } 114 236 115 237 116 // Thorton procedure - Kalman predictive variance in UD 238 void thorton_fast(int *U, int *D, int *PSIU, int *Q, int *G, int *Dold, unsigned introws) {239 unsigned int i,j,k;117 void thorton_fast(int16 *U, int16 *D, int16 *PSIU, int16 *Q, int16 *G, int16 *Dold, unsigned int16 rows) { 118 unsigned int16 i,j,k; 240 119 // copy D to Dold 241 int *Dold_i,*Dold_k;242 int *D_i;243 int *PSIU_ij,*PSIU_ik,*PSIU_jk;244 int *Q_jj,*Q_ii,*Q_kk;245 int *U_ji;246 int *G_ik,*G_jk;247 int irows,jrows;248 longsigma; // in qAU+15!!249 longz;120 int16 *Dold_i,*Dold_k; 121 int16 *D_i; 122 int16 *PSIU_ij,*PSIU_ik,*PSIU_jk; 123 int16 *Q_jj,*Q_ii,*Q_kk; 124 int16 *U_ji; 125 int16 *G_ik,*G_jk; 126 int16 irows,jrows; 127 int32 sigma; // in qAU+15!! 128 int32 z; 250 129 251 130 for (i=0,Dold_i=Dold,D_i=D;i<rows;i++,Dold_i++,D_i++) { … … 271 150 for (k=0, PSIU_ik=PSIU+irows,Dold_k=Dold; 272 151 k<rows; k++, PSIU_ik++,Dold_k++) { 273 sigma += ((( long)(*PSIU_ik)**PSIU_ik)>>(qAU))*(*Dold_k);274 } 275 sigma += *(Q+i+irows)<<qAU;152 sigma += (((int32)(*PSIU_ik)**PSIU_ik)>>(qAU))*(*Dold_k); 153 } 154 sigma += (int32)(*(Q+i+irows))<<qAU; 276 155 for (j=i+1, G_ik=G+irows+i+1; j<rows; j++,G_ik++) { 277 sigma += (((long)(*G_ik)**G_ik)>>16)**(Q+j+j*rows); 278 279 } 280 281 if (sigma>((long)1<<(qAU+15))) { 156 sigma += (((int32)(*G_ik)**G_ik)>>16)**(Q+j+j*rows); 157 } 158 159 if (sigma>((int32)1<<(qAU+15))) { 282 160 *D_i = 32767; 283 161 // *(Dold+i)-=*(Q+i+irows); … … 294 172 k<rows; k++, PSIU_ik++, PSIU_jk++, Dold_k++) { 295 173 296 sigma += (((( long)(*PSIU_ik)**PSIU_jk)>>qAU)**Dold_k);174 sigma += ((((int32)(*PSIU_ik)**PSIU_jk)>>qAU)**Dold_k); 297 175 } 298 176 299 177 for (k=i,G_ik=G+irows+i,G_jk=G+jrows+i,Q_kk=Q+k*rows+k; 300 178 k<rows;k++,G_ik++,G_jk++,Q_kk+=rows+1) { 301 sigma += (((( long)*G_ik)**G_jk)>>16)**Q_kk;179 sigma += ((((int32)*G_ik)**G_jk)>>16)**Q_kk; 302 180 } 303 181 … … 307 185 308 186 U_ji=U+jrows+i; 309 *U_ji = (int )z;187 *U_ji = (int16)z; 310 188 311 189 312 190 for (k=0,PSIU_ik=PSIU+irows,PSIU_jk=PSIU+jrows; 313 191 k<rows;k++,PSIU_ik++,PSIU_jk++) { 314 *PSIU_jk -= (( long)*U_ji**PSIU_ik)>>15;192 *PSIU_jk -= ((int32)*U_ji**PSIU_ik)>>15; 315 193 } 316 194 317 195 for (k=0,G_jk=G+jrows,G_ik=G+irows; 318 196 k<rows;k++, G_jk++, G_ik++) { 319 *G_jk -= (( long)*U_ji**G_ik)>>15;197 *G_jk -= ((int32)*U_ji**G_ik)>>15; 320 198 } 321 199 … … 323 201 if (i==0) return; 324 202 } 325 }326 327 void bierman(int *difz, int *xp, int *U, int *D, int *R, unsigned int dimy, unsigned int dimx ) {328 long alpha;329 long gamma,beta,lambda;330 int b[5]; // ok even for 4-dim state331 int *a; // in [0,1] -> q15332 unsigned int iy,j,i;333 334 for (iy=0; iy<dimy; iy++) {335 // a is a row336 a = U+iy*dimx; // iyth row of U337 for (j=0;j<dimx;j++) {338 (j<iy)? b[j]=0: (j==iy)? b[j]=D[j] : b[j]=((long)D[j]*a[j])>>15;339 }340 341 alpha = (long)R[iy]; //\alpha = R+vDv = R+a*b342 // R in q15, a in q15, b=q15343 // gamma = (1<<15)/alpha; //(in q15)344 //min alpha = R[iy] = 164345 //max gamma = 0.0061 => gamma_ref = q7346 for (j=0;j<dimx;j++) {347 beta = alpha;348 lambda = -(long(a[j])<<15)/beta;349 alpha += ((long(a[j])*b[j])>>15);350 D[j] = (((long(beta)<<15)/alpha)*D[j])>>15; //gamma is long351 if (D[j]==0) D[j]=1;352 353 // cout << "a: " << alpha << "g: " << gamma << endl;354 for (i=0;i<j;i++) {355 beta = U[i*dimx+j];356 U[i*dimx+j] += (lambda*b[i])>>15;357 b[i] += (beta*b[j])>>15;358 }359 }360 int dzs = (long(difz[iy])<<15)/alpha; // apply scaling to innovations361 // no shift due to gamma362 for (i=0; i<dimx; i++) {363 xp[i] += (long(dzs*b[i]))>>15; // multiply by unscaled Kalman gain364 }365 366 //cout << "Ub: " << U << endl;367 //cout << "Db: " << D << endl <<endl;368 369 }370 371 203 } 372 204 -
applications/pmsm/simulator_zdenek/ekf_example/matrix_vs.h
r1230 r1240 12 12 13 13 #define qAU 14 14 #define qD 14 15 16 #define int16 short int 17 #define int32 int 14 18 15 19 /* Matrix multiply Full matrix by upper diagonal matrix with unit diagonal; */ 16 extern void mmultAU(int *m1, int *up, int *result, unsigned int rows, unsigned intcolumns);20 extern void mmultAU(int16 *m1, int16 *up, int16 *result, unsigned int16 rows, unsigned int16 columns); 17 21 18 22 /* Matrix multiply Full matrix by upper diagonal matrix; */ 19 extern void mmultACh(int *m1, int *up, int *result, unsigned int rows, unsigned intcolumns);23 extern void mmultACh(int16 *m1, int16 *up, int16 *result, unsigned int16 rows, unsigned int16 columns); 20 24 21 25 /* perform Thorton update of UD matrix using PSI*U, Q, and temporaries G, Dold, for size dimx*/ 22 extern void thorton(int *U, int *D, int *PSIU, int *Q, int *G, int *Dold, unsigned intdimx);26 extern void thorton(int16 *U, int16 *D, int16 *PSIU, int16 *Q, int16 *G, int16 *Dold, unsigned int16 dimx); 23 27 24 28 /* perform Bierman update of UD matrix using difz, R and xp, for size dimx*/ 25 extern void bierman(int *difz, int *xp, int *U, int *D, int *R, unsigned int dimy, unsigned intdimx );29 extern void bierman(int16 *difz, int16 *xp, int16 *U, int16 *D, int16 *R, unsigned int16 dimy, unsigned int16 dimx ); 26 30 27 31 /* perform Thorton update of UD matrix using PSI*U, Q, and temporaries G, Dold, for size dimx*/ 28 extern void thorton_fast(int *U, int *D, int *PSIU, int *Q, int *G, int *Dold, unsigned intdimx);32 extern void thorton_fast(int16 *U, int16 *D, int16 *PSIU, int16 *Q, int16 *G, int16 *Dold, unsigned int16 dimx); 29 33 30 34 /* perform Bierman update of UD matrix using difz, R and xp, for size dimx*/ 31 extern void bierman_fast(int *difz, int *xp, int *U, int *D, int *R, unsigned int dimy, unsigned intdimx );35 extern void bierman_fast(int16 *difz, int16 *xp, int16 *U, int16 *D, int16 *R, unsigned int16 dimy, unsigned int16 dimx ); 32 36 33 37 /* perform Householder update of Ch matrix using PSI*Ch , Q, */ 34 extern void householder(int *Ch /*= int *PSICh*/, int *Q, unsigned intdimx);38 extern void householder(int16 *Ch /*= int16 *PSICh*/, int16 *Q, unsigned int16 dimx); 35 39 36 40 /* perform Givens update of Ch matrix using PSI*Ch , Q, */ 37 extern void givens(int *Ch /*= int *PSICh*/, int *Q, unsigned intdimx);41 extern void givens(int16 *Ch /*= int16 *PSICh*/, int16 *Q, unsigned int16 dimx); 38 42 39 43 /* perform Carlson update of Ch matrix using difz, R and xp, for size dimx*/ 40 extern void carlson(int *difz, int *xp, int *Ch, int *R, unsigned int dimy, unsigned intdimx );44 extern void carlson(int16 *difz, int16 *xp, int16 *Ch, int16 *R, unsigned int16 dimy, unsigned int16 dimx );