root/applications/pmsm/simulator_zdenek/ekf_example/ekf_obj.cpp @ 1168

Revision 1168, 4.0 kB (checked in by smidl, 14 years ago)

pmsm stuff fro bierman

  • Property svn:eol-style set to native
Line 
1
2#include <estim/kalman.h>
3
4#include "ekf_obj.h"
5#include "../simulator.h"
6
7double minQ(double Q){if (Q>1.0){ return 1.0;} else {return Q;};};
8
9///////////////
10void EKFfixed::bayes(const vec &yt, const vec &ut){
11        ekf(yt(0),yt(1),ut(0),ut(1));
12       
13        vec xhat(4);   
14        //UGLY HACK!!! reliance on a predictor!!
15        xhat(0)=zprevod(x_est[0],Qm)*Iref;
16        xhat(1)=zprevod(x_est[1],Qm)*Iref;
17        xhat(2)=zprevod(x_est[2],Qm)*Wref;
18        xhat(3)=zprevod(x_est[3],15)*Thetaref;
19       
20        E.set_mu(xhat);
21       
22        if ( BM::evalll ) {
23                //from enorm
24                vec xdif(x,4);//first 4 of x
25                //UGLY HACK!!! reliance on a predictor!!
26/*              xdif(0)=x[0]-zprevod(x_pred[0],Qm)*Iref;
27                xdif(1)=x[1]-zprevod(x_pred[1],Qm)*Iref;
28                xdif(2)=x[2]-zprevod(x_pred[2],Qm)*Wref;
29                xdif(3)=x[3]-zprevod(x_pred[3],15);*/
30               
31                xdif -=xhat; //(xdif=x-xhat)
32               
33                mat Pfull(4,4);
34                double* Pp=Pfull._data();
35                for(int i=0;i<16;i++){*(Pp++) = zprevod(P_est[i],15);}
36               
37                E._R()._M()=Pfull;
38               
39               
40                BM::ll = -0.5* ( 4 * 1.83787706640935 +log ( det ( Pfull ) ) +xdif* ( inv(Pfull)*xdif ) );
41        }
42};
43
44
45void EKFfixed::update_psi(void)
46{
47  int t_sin,t_cos,tmp;
48
49  // implementace v PC
50  t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15);
51  t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15);
52
53  PSI[2]=((long)cB*t_sin)>>15;
54  tmp=((long)cH*x_est[2])>>15;
55  PSI[3]=((long)tmp*t_cos)>>15;
56  PSI[6]=-((long)cB*t_cos)>>15;
57  PSI[7]=((long)tmp*t_sin)>>15;
58}
59
60
61void EKFfixed::prediction(int *ux)
62{
63  int t_sin,t_cos, tmp;
64
65  // implementace v PC
66  t_sin=prevod(sin(Thetaref*x_est[3]/32768.),15);
67  t_cos=prevod(cos(Thetaref*x_est[3]/32768.),15);
68
69  tmp=((long)cB*x_est[2])>>15;
70  x_pred[0]=((long)cA*x_est[0]+(long)tmp*t_sin+(long)cC*ux[0])>>15;
71  x_pred[1]=((long)cA*x_est[1]-(long)tmp*t_cos+(long)cC*ux[1])>>15;
72  x_pred[2]=x_est[2];
73  x_pred[3]=(((long)x_est[3]<<15)+(long)cG*x_est[2])>>15;
74
75  update_psi();
76
77  mmult(PSI,P_est,temp15a,3,3,3);
78//  mtrans(PSI,temp15b,5,5);
79  mmultt(temp15a,PSI,P_pred,3,3,3);
80  maddD(P_pred,Q,3,3);
81}
82
83void EKFfixed::correction(void)
84{
85  int Y_error[2];
86  long temp30a[4]; /* matrix [2,2] - temporary matrix for inversion */
87
88  choice_P(P_pred,temp15a,3);
89  maddD(temp15a,R,1,1);
90  minv2(temp15a,temp30a);
91        Ry(0,0)=zprevod(temp15a[0],15);
92        Ry(0,1)=zprevod(temp15a[1],15);
93        Ry(1,0)=zprevod(temp15a[2],15);
94        Ry(1,1)=zprevod(temp15a[3],15);
95 
96  mmultDr(P_pred,temp15a,3,3,1,1);
97  mmult1530(temp15a,temp30a,Kalm,3,1,1);
98
99
100  /* estimate the state system */
101  choice_x(x_pred, temp15a);
102  msub(Y_mes,temp15a,Y_error,1,0);
103  mmult(Kalm,Y_error,temp15a,3,1,0);
104  madd(x_pred,temp15a,x_est,3,0);
105
106  /* matrix of covariances - version without MMULTDL() */
107
108/* Version with MMULTDL() */
109  mmultDl(P_pred,temp15a,1,3,3,1);
110
111  mmult(Kalm,temp15a,P_est,3,1,3);
112  msub(P_pred,P_est,P_est,3,3);
113/* END */
114}
115
116
117void EKFfixed::ekf(double ux, double uy, double isxd, double isyd)
118{
119  // vypocet napeti v systemu (x,y)
120  ukalm[0]=prevod(ux/Uref,Qm);
121  ukalm[1]=prevod(uy/Uref,Qm);
122
123  // zadani mereni
124  Y_mes[0]=prevod(isxd/Iref,Qm);
125  Y_mes[1]=prevod(isyd/Iref,Qm);
126
127  ////// vlastni rutina EKF /////////////////////////
128  prediction(ukalm);
129  correction();
130
131  // navrat estimovanych hodnot regulatoru
132  vec& mu = E._mu();
133  (mu)(0)=zprevod(x_est[0],Qm)*Iref;
134  (mu)(1)=zprevod(x_est[1],Qm)*Iref;
135  (mu)(2)=zprevod(x_est[2],Qm)*Wref;
136  (mu)(3)=zprevod(x_est[3],15)*Thetaref;
137}
138
139void EKFfixed::init_ekf(double Tv)
140{
141  // Tuning of matrix Q
142  Q[0]=prevod(.01,15);       // 0.05
143  Q[5]=Q[0];
144  Q[10]=prevod(0.0001,15);      // 1e-3
145  Q[15]=prevod(0.0001,15);      // 1e-3
146
147  // Tuning of matrix R
148  R[0]=prevod(0.05,15);         // 0.05
149  R[3]=R[0];
150
151  // Motor model parameters
152  cA=prevod(1-Tv*Rs/Ls,15);
153  cB=prevod(Tv*Wref*Fmag/Iref/Ls,15);
154  cC=prevod(Tv/Ls/Iref*Uref,15);
155//  cD=prevod(1-Tv*Bf/J,15);
156//  cE=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref,15);
157//  cF=prevod(p*Tv*Mref/J/Wref,15);
158  cG=prevod(Tv*Wref*4/Thetaref,15);
159  cH=prevod(Tv*Wref*Fmag/Iref/Ls*Thetaref,15);
160//  cI=prevod(kp*p*p*Tv*Fmag*Iref/J/Wref*Thetaref);
161
162  /* Init matrix PSI with permanently constant terms */
163  PSI[0]=cA;
164  PSI[5]=PSI[0];
165  PSI[10]=0x7FFF;
166  PSI[14]=cG;
167  PSI[15]=0x7FFF;
168}
Note: See TracBrowser for help on using the browser.