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 | |