| 36 | | #ifdef XXX |
| 37 | | /*! |
| 38 | | \brief Extended Kalman Filter with full matrices in fixed point16 arithmetic |
| 39 | | |
| 40 | | An approximation of the exact Bayesian filter with Gaussian noices and non-linear evolutions of their mean. |
| 41 | | */ |
| 42 | | class EKFfixed : public BM { |
| 43 | | public: |
| 44 | | void init_ekf(double Tv); |
| 45 | | void ekf(double ux, double uy, double isxd, double isyd); |
| 46 | | |
| 47 | | /* Declaration of local functions */ |
| 48 | | void prediction(int16 *ux); |
| 49 | | void correction(void); |
| 50 | | void update_psi(void); |
| 51 | | |
| 52 | | /* Constants - definovat jako konstanty ?? ?kde je vyhodnejsi aby v pameti byli?*/ |
| 53 | | int16 Q[16]; /* matrix [4,4] */ |
| 54 | | int16 R[4]; /* matrix [2,2] */ |
| 55 | | |
| 56 | | int16 x_est[4]; |
| 57 | | int16 x_pred[4]; |
| 58 | | int16 P_pred[16]; /* matrix [4,4] */ |
| 59 | | int16 P_est[16]; /* matrix [4,4] */ |
| 60 | | int16 Y_mes[2]; |
| 61 | | int16 ukalm[2]; |
| 62 | | int16 Kalm[8]; /* matrix [5,2] */ |
| 63 | | |
| 64 | | int16 PSI[16]; /* matrix [4,4] */ |
| 65 | | |
| 66 | | int16 temp15a[16]; |
| 67 | | |
| 68 | | int16 cA, cB, cC, cG, cH; // cD, cE, cF, cI ... nepouzivane |
| 69 | | |
| 70 | | int32 temp30a[4]; /* matrix [2,2] - temporary matrix for inversion */ |
| 71 | | enorm<fsqmat> E; |
| 72 | | mat Ry; |
| 73 | | |
| 74 | | public: |
| 75 | | //! Default constructor |
| 76 | | EKFfixed ():BM(),E(),Ry(2,2){ |
| 77 | | int16 i; |
| 78 | | for(i=0;i<16;i++){Q[i]=0;} |
| 79 | | for(i=0;i<4;i++){R[i]=0;} |
| 80 | | |
| 81 | | for(i=0;i<4;i++){x_est[i]=0;} |
| 82 | | for(i=0;i<4;i++){x_pred[i]=0;} |
| 83 | | for(i=0;i<16;i++){P_pred[i]=0;} |
| 84 | | for(i=0;i<16;i++){P_est[i]=0;} |
| 85 | | P_est[0]=0x7FFF; |
| 86 | | P_est[5]=0x7FFF; |
| 87 | | P_est[10]=0x7FFF; |
| 88 | | P_est[15]=0x7FFF; |
| 89 | | for(i=0;i<2;i++){Y_mes[i]=0;} |
| 90 | | for(i=0;i<2;i++){ukalm[i]=0;} |
| 91 | | for(i=0;i<8;i++){Kalm[i]=0;} |
| 92 | | |
| 93 | | for(i=0;i<16;i++){PSI[i]=0;} |
| 94 | | |
| 95 | | set_dim(4); |
| 96 | | E._mu()=zeros(4); |
| 97 | | E._R()=zeros(4,4); |
| 98 | | init_ekf(0.000125); |
| 99 | | }; |
| 100 | | //! Here dt = [yt;ut] of appropriate dimensions |
| 101 | | void bayes ( const vec &yt, const vec &ut ); |
| 102 | | //!dummy! |
| 103 | | const epdf& posterior() const {return E;}; |
| 104 | | |
| 105 | | }; |
| 106 | | |
| 107 | | UIREGISTER(EKFfixed); |
| 108 | | |
| 109 | | #endif |
| | 51 | |
| | 52 | |
| | 53 | class EKFscale: public EKFCh{ |
| | 54 | LOG_LEVEL(EKFscale, logCh, logA, logC); |
| | 55 | public: |
| | 56 | mat Tx; |
| | 57 | mat Ty; |
| | 58 | |
| | 59 | void from_setting ( const Setting &set ){ |
| | 60 | EKFCh::from_setting(set); |
| | 61 | vec v; |
| | 62 | UI::get(v, set, "xmax", UI::compulsory); |
| | 63 | Tx = diag(1./v); |
| | 64 | UI::get(v, set, "ymax", UI::compulsory); |
| | 65 | Ty = diag(1./v); |
| | 66 | |
| | 67 | UI::get(log_level, set, "log_level", UI::optional); |
| | 68 | }; |
| | 69 | |
| | 70 | void log_register(logger &L, const string &prefix){ |
| | 71 | BM::log_register ( L, prefix ); |
| | 72 | |
| | 73 | L.add_vector ( log_level, logCh, RV ("Ch", dimension()*dimension() ), prefix ); |
| | 74 | L.add_vector ( log_level, logA, RV ("A", dimension()*dimension() ), prefix ); |
| | 75 | L.add_vector ( log_level, logC, RV ("C", dimensiony()*dimension() ), prefix ); |
| | 76 | }; |
| | 77 | |
| | 78 | void log_write() const{ |
| | 79 | BM::log_write(); |
| | 80 | if ( log_level[logCh] ) { |
| | 81 | mat Chsc=Tx*(est._R()._Ch()); |
| | 82 | vec v(Chsc._data(), dimension()*dimension()); |
| | 83 | if (v(0)<0) |
| | 84 | v= -v; |
| | 85 | log_level.store( logCh, round(v*32767)); |
| | 86 | } |
| | 87 | if (log_level[logA]){ |
| | 88 | mat Asc = Tx*A*inv(Tx); |
| | 89 | vec v(Asc._data(), dimension()*dimension()); |
| | 90 | log_level.store( logA, round(v*32767)); |
| | 91 | } |
| | 92 | if (log_level[logC]){ |
| | 93 | mat Csc = Ty*C*inv(Tx); |
| | 94 | vec v(Csc._data(), dimensiony()*dimension()); |
| | 95 | log_level.store( logC, round(v*32767)); |
| | 96 | } |
| | 97 | } |
| | 98 | |
| | 99 | }; |
| | 100 | UIREGISTER(EKFscale); |
| | 760 | |
| | 761 | |
| | 762 | class ekfChfixQ: public BM{ |
| | 763 | LOG_LEVEL(ekfChfixQ,logQ,logCh,logC,logRes) |
| | 764 | ekf_data E; |
| | 765 | int64 PSI_Q0, PSI_Q1, PSI_Q0_reg, PSI_Q1_reg; |
| | 766 | int Q_ni; |
| | 767 | int phi_Q; |
| | 768 | public: |
| | 769 | ekfChfixQ(){ |
| | 770 | init_ekfCh2(&E,0.000125);set_dim(2); dimc = 2; |
| | 771 | dimy = 2; |
| | 772 | Q_ni = 7; |
| | 773 | phi_Q = ((1<<Q_ni) -1)<<(15-Q_ni); |
| | 774 | |
| | 775 | PSI_Q0_reg = ((int64)((1<<15)-phi_Q)*E.Q[0])<<Q_ni; |
| | 776 | PSI_Q1_reg = ((int64)((1<<15)-phi_Q)*E.Q[3])<<Q_ni; |
| | 777 | PSI_Q0 = ((int64)E.Q[0])<<Q_ni; |
| | 778 | PSI_Q1 = ((int64)E.Q[3])<<Q_ni; |
| | 779 | } |
| | 780 | void bayes ( const vec &val, const vec &cond ) { |
| | 781 | int16 ux,uy; |
| | 782 | ux=prevod(cond[0]/Uref,15); |
| | 783 | uy=prevod(cond[1]/Uref,15); |
| | 784 | |
| | 785 | int16 yx,yy; |
| | 786 | // zadani mereni |
| | 787 | yx=prevod(val[0]/Iref,15); |
| | 788 | yy=prevod(val[1]/Iref,15); |
| | 789 | |
| | 790 | int16 detS, rem; |
| | 791 | ekfCh2(&E, ux,uy,yx,yy, &detS, &rem); |
| | 792 | |
| | 793 | Est._mu()=vec_2(E.x_est[0]*Uref/32768., E.x_est[1]*Uref/32768.); |
| | 794 | |
| | 795 | int16 xerr0 = E.x_est[0]-E.x_pred[0]; |
| | 796 | PSI_Q0 = ((int64)(phi_Q*PSI_Q0) + (((int64)xerr0*xerr0)<<15) + PSI_Q0_reg)>>15; |
| | 797 | E.Q[0] = PSI_Q0>>Q_ni; |
| | 798 | |
| | 799 | xerr0 = E.x_est[1]-E.x_pred[1]; |
| | 800 | PSI_Q1 = ((int64)(phi_Q*PSI_Q1) + (((int64)xerr0*xerr0)<<15) + PSI_Q1_reg)>>15; |
| | 801 | E.Q[3] = PSI_Q1>>Q_ni; |
| | 802 | |
| | 803 | cout << E.Q[0] << "," << E.Q[3] <<endl; |
| | 804 | ll = -0.5*qlog(detS)-0.5*rem; |
| | 805 | } |
| | 806 | const epdf& posterior() const {return Est;}; |
| | 807 | void from_setting ( const Setting &set ){ |
| | 808 | BM::from_setting(set); |
| | 809 | vec dQ,dR; |
| | 810 | UI::get ( dQ, set, "dQ", UI::optional ); |
| | 811 | UI::get ( dR, set, "dR", UI::optional ); |
| | 812 | if (dQ.length()==2){ |
| | 813 | E.Q[0]=prevod(dQ[0],15); // 1e-3 |
| | 814 | E.Q[3]=prevod(dQ[1],15); // 1e-3 |
| | 815 | } |
| | 816 | if (dR.length()==2){ |
| | 817 | E.dR[0]=prevod(dR[0],15); // 1e-3 |
| | 818 | E.dR[1]=prevod(dR[1],15); // 1e-3 |
| | 819 | } |
| | 820 | |
| | 821 | UI::get(Q_ni, set, "Q_ni", UI::optional); |
| | 822 | { // zmena Q!! |
| | 823 | phi_Q = ((1<<Q_ni) -1)<<(15-Q_ni); |
| | 824 | |
| | 825 | PSI_Q0_reg = ((int64)((1<<15)-phi_Q)*E.Q[0])<<Q_ni; |
| | 826 | PSI_Q1_reg = ((int64)((1<<15)-phi_Q)*E.Q[3])<<Q_ni; |
| | 827 | PSI_Q0 = ((int64)E.Q[0])<<Q_ni; |
| | 828 | PSI_Q1 = ((int64)E.Q[3])<<Q_ni; |
| | 829 | |
| | 830 | } |
| | 831 | UI::get(log_level, set, "log_level", UI::optional); |
| | 832 | |
| | 833 | } |
| | 834 | void log_register ( logger &L, const string &prefix ) { |
| | 835 | BM::log_register(L,prefix); |
| | 836 | L.add_vector(log_level, logQ, RV("{Q }",vec_1<int>(2)), prefix); |
| | 837 | L.add_vector(log_level, logCh, RV("{Ch }",vec_1<int>(3)), prefix); |
| | 838 | L.add_vector(log_level, logC, RV("{C }",vec_1<int>(4)), prefix); |
| | 839 | L.add_vector(log_level, logRes, RV("{dy }",vec_1<int>(2)), prefix); |
| | 840 | } |
| | 841 | void log_write() const { |
| | 842 | BM::log_write(); |
| | 843 | if ( log_level[logQ] ) { |
| | 844 | log_level.store( logQ, vec_2((double)E.Q[0],(double)E.Q[3] )); |
| | 845 | } |
| | 846 | if ( log_level[logCh] ) { |
| | 847 | log_level.store( logCh, vec_3((double)E.Chf[0],(double)E.Chf[1], (double)E.Chf[3])); |
| | 848 | } |
| | 849 | if ( log_level[logRes] ) { |
| | 850 | log_level.store( logRes, vec_2((double)E.difz[0],(double)E.difz[1])); |
| | 851 | } |
| | 852 | if ( log_level[logC] ) { |
| | 853 | vec v(4); |
| | 854 | for (int i=0;i<4;i++) v(i)=E.C[i]; |
| | 855 | log_level.store( logC, v); |
| | 856 | } |
| | 857 | } |
| | 858 | |
| | 859 | enorm<fsqmat> Est; |
| | 860 | mat Ry; |
| | 861 | }; |
| | 862 | UIREGISTER(ekfChfixQ); |
| | 863 | |