| 551 | void EKFfixedUD2::bayes(const itpp::vec& yt, const itpp::vec& ut) |
| 552 | { |
| 553 | ekf2(ut[0],ut[1],yt[0],yt[1]); |
| 554 | } |
| 555 | |
| 556 | |
| 557 | void EKFfixedUD2::ekf2(double ux, double uy, double isxd, double isyd) |
| 558 | { |
| 559 | // vypocet napeti v systemu (x,y) |
| 560 | int16 uf[2]; |
| 561 | uf[0]=prevod(ux/Uref,15); |
| 562 | uf[1]=prevod(uy/Uref,15); |
| 563 | |
| 564 | int16 Y_mes[2]; |
| 565 | // zadani mereni |
| 566 | Y_mes[0]=prevod(isxd/Iref,15); |
| 567 | Y_mes[1]=prevod(isyd/Iref,15); |
| 568 | |
| 569 | ////// vlastni rutina EKF -- ///////////////////////// |
| 570 | int16 t_sin,t_cos; |
| 571 | int32 tmp; |
| 572 | |
| 573 | // implementace v PC |
| 574 | /* t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15); |
| 575 | * t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15);*/ |
| 576 | tmp=prevod(sin(Thetaref*x_est[3]/32768.),15); |
| 577 | if (tmp>32767) t_sin =32767; else t_sin=tmp; |
| 578 | tmp=prevod(cos(Thetaref*x_est[3]/32768.),15); |
| 579 | if (tmp>32767) t_cos =32767; else t_cos=tmp; |
| 580 | |
| 581 | tmp=((int32)cB*x_est[2])>>15; // q15*q13 -> q13 |
| 582 | // q15*q13 + q13*q15 + q15*q13?? |
| 583 | x_est[0]=((int32)cA*x_est[0]+(int32)tmp*t_sin+(int32)cC*(uf[0]))>>15; // in q13 |
| 584 | x_est[1]=((int32)cA*x_est[1]-(int32)tmp*t_cos+(int32)cC*(uf[1]))>>15; // q13 |
| 585 | x_est[2]=x_est[2]; |
| 586 | // q15 + q15*q13 |
| 587 | x_est[3]=(((int32)x_est[3]<<15)+(int32)cG*x_est[2])>>15; |
| 588 | |
| 589 | if(x_est[3]>(1<<15)) x_est[3]-=2*(1<<15); |
| 590 | if(x_est[3]<-(1<<15)) x_est[3]+=2*(1<<15); |
| 591 | |
| 592 | //void EKFfixed::update_psi(void) |
| 593 | { |
| 594 | PSI[2]=((int32)cB*t_sin)>>15; |
| 595 | tmp=((int32)cH*x_est[2])>>15; // ! cH =cB with different scale!! |
| 596 | PSI[3]=((int32)tmp*t_cos)>>15; |
| 597 | PSI[6]=-((int32)cB*t_cos)>>15; |
| 598 | PSI[7]=((int32)tmp*t_sin)>>15; |
| 599 | } |
| 600 | { |
| 601 | int Ai[16]; |
| 602 | for (int i=0;i<16; i++) Ai[i]=(int)(PSI[i]); |
| 603 | ivec Ad(Ai,16); |
| 604 | log_level.store(logA,get_from_ivec(Ad)); |
| 605 | } |
| 606 | |
| 607 | ///////// end of copy /////////////// |
| 608 | mmultAU(PSI,Uf,PSIU,4,4); |
| 609 | //thorton(int16 *U, int16 *D, int16 *PSIU, int16 *Q, int16 *G, int16 *Dold, unsigned int16 dimx); |
| 610 | thorton_fast(Uf,Df,PSIU,Q,G,Dfold,4); |
| 611 | |
| 612 | { |
| 613 | int Ui[16]; for (int i=0;i<16; i++) Ui[i]=(int)Uf[i]; |
| 614 | |
| 615 | ivec Ud(Ui,16); |
| 616 | log_level.store(logU,get_from_ivec(Ud)); |
| 617 | |
| 618 | int di[16]; for (int i=0;i<16; i++) di[i]=(int)Df[i]; |
| 619 | ivec dd(di,4); |
| 620 | imat U(Ui,4,4); |
| 621 | mat U2=to_mat(U)/32768; |
| 622 | mat PP=U2*diag(to_vec(dd))*U2.T(); |
| 623 | vec pp(PP._data(),16); |
| 624 | log_level.store(logP,pp); |
| 625 | } |
| 626 | { |
| 627 | int Gi[16]; for (int i=0;i<16; i++) Gi[i]=(int)G[i]; |
| 628 | ivec Gd(Gi,16); |
| 629 | log_level.store(logG,get_from_ivec(Gd)); |
| 630 | } |
| 631 | |
| 632 | |
| 633 | int16 difz[2]; |
| 634 | difz[0]=(Y_mes[0]-x_est[0]); // shift to q15!! |
| 635 | difz[1]=(Y_mes[1]-x_est[1]);//<<2; |
| 636 | |
| 637 | { |
| 638 | int Di[4]; for (int i=0;i<4; i++) Di[i]=(int)Df[i]; |
| 639 | ivec dd(Di,4);//;dd(0)=Y_mes[0];dd(1)=Y_mes[1]; dd(2)=difz[0]; dd(3)=difz[1]; |
| 640 | log_level.store(logD,get_from_ivec(dd)); |
| 641 | } |
| 642 | |
| 643 | //bierman(int16 *difz, int16 *xp, int16 *U, int16 *D, int16 *R, unsigned int16 dimy, unsigned int16 dimx ); |
| 644 | int16 dR[2];dR[0]=R[0];dR[1]=R[3]; |
| 645 | //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]; |
| 646 | bierman_fast(difz,x_est,Uf,Df,dR,2,4); |
| 647 | //x_est[0] = xb[0]>>2; x_est[1]=xb[1]>>2; x_est[2]=xb[2]>>2; x_est[3]=xb[3]; |
| 648 | |
| 649 | // navrat estimovanych hodnot regulatoru |
| 650 | vec& mu = E._mu(); |
| 651 | (mu)(0)=zprevod(x_est[0],15)*Iref; |
| 652 | (mu)(1)=zprevod(x_est[1],15)*Iref; |
| 653 | (mu)(2)=zprevod(x_est[2],15)*Wref; |
| 654 | (mu)(3)=zprevod(x_est[3],15)*Thetaref; |
| 655 | |
| 656 | //x_est[2]=x[2]*32768/Wref; |
| 657 | //x_est[3]=x[3]*32768/Thetaref; |
| 658 | // mat T=diag(concat(vec_2(Iref,Iref), vec_2(Wref,Thetaref))); |
| 659 | } |
| 660 | |
| 661 | void EKFfixedUD2::init_ekf2(double Tv) |
| 662 | { |
| 663 | // Tuning of matrix Q |
| 664 | Q[0]=prevod(0.0005,15); // 1e-3 |
| 665 | Q[3]=prevod(0.0001,15); // 1e-3 |
| 666 | |
| 667 | Uf[0]=0x7FFF;// ! // 0.05 |
| 668 | Uf[1]=Uf[2]=0; |
| 669 | Uf[5]=0x7FFF;//! |
| 670 | |
| 671 | Df[0]=1<<14; |
| 672 | Df[1]=1<<14; |
| 673 | |
| 674 | // Tuning of matrix R |
| 675 | R[0]=prevod(0.05,15); // 0.05 |
| 676 | R[3]=R[0]; |
| 677 | |
| 678 | // Motor model parameters |
| 679 | cA=prevod(1-Tv*Rs/Ls,15); |
| 680 | cB=prevod(Tv*Wref*Fmag/Iref/Ls,15); |
| 681 | cC=prevod(Tv/Ls/Iref*Uref,15); |
| 682 | // cD=prevod(1-Tv*Bf/J,15); |
| 683 | // cE=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref,15); |
| 684 | // cF=prevod(p*Tv*Mref/J/Wref,15); |
| 685 | cG=prevod(Tv*Wref/Thetaref,15); //in q15! |
| 686 | //cH=prevod(Tv*Wref*Fmag/Iref/Ls*Thetaref,15); |
| 687 | // cH=prevod(Tv*Wref*Thetaref*Fmag/Iref/Ls,15); // < =========== |
| 688 | cH=prevod(Tv*Wref*Thetaref*Fmag/Iref/Ls,15); // |
| 689 | // cI=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref*Thetaref); |
| 690 | |
| 691 | /* Init matrix PSI with permanently constant terms */ |
| 692 | PSI[0]=0x7FFF; |
| 693 | PSI[2]=cG; |
| 694 | PSI[3]=0x7FFF; |
| 695 | |
| 696 | } |
| 697 | |
| 698 | |