-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkalmanfilter.h
154 lines (133 loc) · 3.54 KB
/
kalmanfilter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//kalman filter for SISO system
//@todo:MIMOの宣言の部分をコンパクトにしたい
//@todo:EKFにも対応させる
#ifndef ___KAL_KALMAN_FILTER_H
#define ___KAL_KALMAN_FILTER_H
#include "config.h"
#include "utilize.h"
#ifdef X2_KAL
#include<eigen3/Eigen/Dense>
#endif
#ifdef EIGEN_KAL
#include "eigen3.3.7/Eigen/Core"
#endif
namespace kal{
template <class Ta,class Tb,class Tc,class Td>
class StateSpace{
public:
Ta A;
Tb B;
Tc C;
Td D;
StateSpace();
StateSpace(Ta A_in,Tb B_in,Tc C_in,Td D_in);
void set_eq(Ta A_in,Tb B_in,Tc C_in,Td D_in);
};
template <class Ta,class Tb,class Tc,class Td>
StateSpace<Ta,Tb,Tc,Td>::StateSpace(){
}
template <class Ta,class Tb,class Tc,class Td>
StateSpace<Ta,Tb,Tc,Td>::StateSpace(Ta A_in,Tb B_in,Tc C_in,Td D_in){
this->A = A_in;
this->B = B_in;
this->C = C_in;
this->D = D_in;
}
template <class Ta,class Tb,class Tc,class Td>
void StateSpace<Ta,Tb,Tc,Td>::set_eq(Ta A_in,Tb B_in,Tc C_in,Td D_in){
this->A = A_in;
this->B = B_in;
this->C = C_in;
this->D = D_in;
}
//Kalmanfilter for SISO
template <class T>
class KalmanFilter{
public:
T x_;
T x_est;
//T y;
T g;
T P_bfr;
T P_aft;
T Q;//vの分散
T R;//wの分散
StateSpace<T,T,T,T> sys;
KalmanFilter();
KalmanFilter(T xx,T QQ, T RR);
void update(T u,T y);
};
template <class T>
KalmanFilter<T>::KalmanFilter(){
x_est = 0.0;
Q = 1.0;
R = 1.0;
}
template <class T>
KalmanFilter<T>::KalmanFilter(T xx,T QQ, T RR){
x_est = xx;
Q = QQ;
R = RR;
}
template <class T>
void KalmanFilter<T>::update(T u,T y){
x_ = x_est + Ts * u;
P_bfr = P_aft + Q;
g = P_bfr / (P_bfr + R);
x_est = x_ + g * (y - x_);
P_aft = (1 - g*1) * P_bfr;
}
#if defined(EIGEN_KAL)||defined(X2_KAL)
//@todo:継承する?
//Kalmanfilter for MIMO
template <class Ta,class Tb,class Tc,class Td,class Tx, class Ty>
class KalmanFilter_MIMO{
public:
Tx x_;
Tx x_est;
//Ty y;
Eigen::MatrixXd G;
Ta P_bfr;//事前
Ta P_aft;//事後
Eigen::MatrixXd Q;//vの分散
Eigen::MatrixXd R;//wの分散
StateSpace<Ta,Tb,Tc,Td> sys;
KalmanFilter_MIMO();
KalmanFilter_MIMO(Tx x, Eigen::MatrixXd Q_in, Eigen::MatrixXd R_in);
KalmanFilter_MIMO(StateSpace<Ta,Tb,Tc,Td> sys_in,Tx x, Eigen::MatrixXd Q_in, Eigen::MatrixXd R_in);
void x_init(Tx x);
void update(Tx u,Ty y,Tx& x_ret);
};
template <class Ta,class Tb,class Tc,class Td,class Tx, class Ty>
KalmanFilter_MIMO<Ta,Tb,Tc,Td,Tx,Ty>::KalmanFilter_MIMO(){
}
template <class Ta,class Tb,class Tc,class Td,class Tx, class Ty>
KalmanFilter_MIMO<Ta,Tb,Tc,Td,Tx,Ty>::KalmanFilter_MIMO(Tx x,Eigen::MatrixXd Q_in, Eigen::MatrixXd R_in){
this->x_est = x;
this->Q = Q_in;
this->R = R_in;
}
template <class Ta,class Tb,class Tc,class Td,class Tx, class Ty>
KalmanFilter_MIMO<Ta,Tb,Tc,Td,Tx,Ty>::KalmanFilter_MIMO(StateSpace<Ta,Tb,Tc,Td> sys_in,Tx x,Eigen::MatrixXd Q_in, Eigen::MatrixXd R_in): sys(sys_in){
this->x_est = x;
sys = sys_in;
Q = Q_in;
R = R_in;
}
template <class Ta,class Tb,class Tc,class Td,class Tx, class Ty>
void KalmanFilter_MIMO<Ta,Tb,Tc,Td,Tx,Ty>::x_init(Tx x){
x_ = x;
x_est = x;
}
template <class Ta,class Tb,class Tc,class Td,class Tx, class Ty>
void KalmanFilter_MIMO<Ta,Tb,Tc,Td,Tx,Ty>::update(Tx u,Ty y,Tx& x_ret){
x_ = sys.A * x_est + sys.B *u;
P_bfr = sys.A * P_aft * sys.A.transpose() + sys.B * Q * sys.B.transpose();
G = P_bfr * sys.C.transpose() * (sys.C * P_bfr * sys.C.transpose() + R).inverse();
x_est = x_ + G * (y - sys.C * x_);
x_ret = x_est;
P_aft = (Eigen::MatrixXd::Identity(sys.A.rows(),sys.A.cols()) - G * sys.C) * P_bfr;
}
#endif
}
#endif