threed_odometry
IIR.hpp
Go to the documentation of this file.
1 #ifndef _IIR_HPP_
2 #define _IIR_HPP_
3 
4 #include <Eigen/Core>
5 #include <Eigen/Cholesky>
7 #include <base/Eigen.hpp>
8 
9 //#define IIR_DEBUG_PRINTS 1
10 
11 namespace threed_odometry
12 {
16  template < unsigned int _Order, unsigned int _DataDimension > class IIR
17  {
18 
19  public:
20 
21  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
22 
23  protected:
24 
27  Eigen::Matrix <double, _Order+1, 1> bCoeff, aCoeff;
28 
30  Eigen::Matrix <double, _DataDimension, _Order+1> originalData, filteredData;
31 
33  Eigen::Matrix <double, (_Order+1)*_DataDimension, (_Order+1)*_DataDimension> originalDataCov, filteredDataCov;
34  Eigen::Matrix <double, _DataDimension, (_Order+1)*_DataDimension> bMatrix, aMatrix;
35  Eigen::Matrix <double, (_Order+1)*_DataDimension, (_Order+1)*_DataDimension> crossCov;
36 
37 
38  public:
39 
47  IIR(const Eigen::Matrix <double, _Order+1, 1> &b, const Eigen::Matrix <double, _Order+1, 1> &a)
48  :bCoeff(b), aCoeff(a)
49  {
50  originalData.setZero();
51  filteredData.setZero();
52  originalDataCov.setZero();
53  filteredDataCov.setZero();
54  crossCov.setZero();
55 
57  aMatrix.setZero(); bMatrix.setZero();
58  Eigen::Matrix<double, _DataDimension, _Order+1> aSubMatrix, bSubMatrix;
59 
60  for (register int i=0; i<static_cast<int>(_DataDimension); ++i)
61  {
62  aSubMatrix.row(i) = 1.0/a[0] * a.transpose();
63  bSubMatrix.row(i) = 1.0/a[0] * b.transpose();
64  }
65 
66  for (register int i=0; i<static_cast<int>(_DataDimension); ++i)
67  {
68  aMatrix.template block<_DataDimension, _Order+1> (0, i*(_Order+1)) = aSubMatrix;
69  bMatrix.template block<_DataDimension, _Order+1> (0, i*(_Order+1)) = bSubMatrix;
70  }
71 
73  aMatrix.template block<_DataDimension, _DataDimension>(0,0) = Eigen::Matrix<double, _DataDimension, _DataDimension>::Zero();
74 
75  }
76 
84  Eigen::Matrix<double, _DataDimension, 1> perform (const Eigen::Matrix <double, _DataDimension, 1> &data)
85  {
86  Eigen::Matrix <double, _DataDimension, _DataDimension> dataCov; dataCov.setZero();
87  return this-> perform (data, dataCov, false);
88  }
89 
97  Eigen::Matrix<double, _DataDimension, 1> perform (const Eigen::Matrix <double, _DataDimension, 1> &data,
98  Eigen::Matrix <double, _DataDimension, _DataDimension> &dataCov,
99  const bool covariance = true)
100  {
101  Eigen::Matrix<double, _DataDimension, 1> result;
102 
104  originalData.template block<_DataDimension, _Order>(0,0) = originalData.template block<_DataDimension, _Order>(0,1);
105  originalData.col(_Order) = data;
106 
107  #ifdef IIR_DEBUG_PRINTS
108  std::cout<<"[IIR-FILTER] originalData.cols "<<originalData.cols()<<" filteredData.cols "<<filteredData.cols()<<"\n";
109  #endif
110 
112  result = this->iirFilter(bCoeff, aCoeff, originalData, filteredData);
113 
115  if (covariance == true)
116  {
117 
119  if (!base::isnotnan(dataCov))
120  {
121  #ifdef IIR_DEBUG_PRINTS
122  std::cout<<"[IIR] dataCov has NaN values\n";
123  #endif
124 
125  dataCov.setZero();
126  }
127 
128  #ifdef IIR_DEBUG_PRINTS
129  std::cout<<"[IIR] dataCov :\n"<<dataCov<<"\n";
130  #endif
131 
133  originalDataCov.template block<_Order*_DataDimension, _Order*_DataDimension>(0,0) =
134  originalDataCov.template block<_Order*_DataDimension, _Order*_DataDimension> (_DataDimension, _DataDimension);
135  originalDataCov.template block<_DataDimension, _DataDimension>(_Order*_DataDimension, _Order*_DataDimension) = dataCov;
136 
137  crossCov.template block<_Order*_DataDimension, _Order*_DataDimension>(0,0) =
138  crossCov.template block<_Order*_DataDimension, _Order*_DataDimension> (_DataDimension, _DataDimension);
139  crossCov.template block<_DataDimension, _DataDimension>(_Order*_DataDimension, _Order*_DataDimension) = dataCov - (result * result.transpose());
140 
141  dataCov = this->iirFilterCov(bMatrix, aMatrix, originalDataCov, filteredDataCov);
142 
143  #ifdef IIR_DEBUG_PRINTS
144  std::cout<<"[IIR] ResultCov:\n"<<dataCov<<"\n";
145  #endif
146 
148  filteredDataCov.template block<_Order*_DataDimension, _Order*_DataDimension> (0,0) =
149  filteredDataCov.template block<_Order*_DataDimension, _Order*_DataDimension> (_DataDimension, _DataDimension);
150  }
151 
152  #ifdef IIR_DEBUG_PRINTS
153  std::cout<<"[IIR] Result:\n"<<result<<"\n";
154  #endif
155 
157  filteredData.template block<_DataDimension, _Order>(0,0) = filteredData.template block<_DataDimension, _Order>(0,1);
158 
159  return result;
160  }
161 
162  protected:
163 
180  Eigen::Matrix <double, _DataDimension, 1> iirFilter (
181  const Eigen::Matrix <double, _Order+1, 1> &b,
182  const Eigen::Matrix <double, _Order+1, 1> &a,
183  const Eigen::Matrix <double, _DataDimension, _Order+1> &x,
184  Eigen::Matrix <double, _DataDimension, _Order+1> &y)
185  {
186  register int j;
187  register int i = static_cast<int>(_Order);
188 
189  Eigen::Matrix <double, _DataDimension, 1> tmpA, tmpB;
190  tmpB.setZero(); tmpA.setZero();
191 
193  for(j=1; j<static_cast<int>(_Order+1); ++j)
194  {
195  tmpB += b[j-1]*x.col(i);
196  tmpA += a[j]*y.col(i-1);
197 
198  i--;
199  }
200  tmpB += b[j-1]*x.col(i);
201 
202  y.col(_Order) = 1.0/a[0] * (tmpB - tmpA);
203 
204  return y.col(_Order);
205  };
206 
207 
224  Eigen::Matrix <double, _DataDimension, _DataDimension> iirFilterCov (
225  const Eigen::Matrix <double, _DataDimension, (_Order+1)*_DataDimension> &bMatrix,
226  const Eigen::Matrix <double, _DataDimension, (_Order+1)*_DataDimension> &aMatrix,
227  const Eigen::Matrix <double, (_Order+1)*_DataDimension, (_Order+1)*_DataDimension> &xCov,
228  Eigen::Matrix <double, (_Order+1)*_DataDimension, (_Order+1)*_DataDimension> &yCov)
229  {
230  //Eigen::Matrix <double, (_Order+1)*_DataDimension, (_Order+1)*_DataDimension> xSigma = xCov.llt().matrixL();
231  //Eigen::Matrix <double, (_Order+1)*_DataDimension, (_Order+1)*_DataDimension> ySigma = yCov.llt().matrixL();
232 
233  #ifdef IIR_DEBUG_PRINTS
234  std::cout<<"[IIR-FILTER] bMatrix is\n"<<bMatrix<<"\naMatrix is\n"<<aMatrix<<"\n";
235  std::cout<<"[IIR-FILTER] xCov is\n"<<xCov<<"\nyCov is\n"<<yCov<<"\n";
236  std::cout<<"[IIR-FILTER] xyCov is\n"<<crossCov<<"\n";
237  #endif
238 
239  yCov.template block<_DataDimension, _DataDimension> (_Order*_DataDimension, _Order*_DataDimension) =
240  bMatrix * xCov * bMatrix.transpose() + aMatrix * yCov * aMatrix.transpose() - bMatrix * crossCov * aMatrix.transpose() - aMatrix * crossCov * bMatrix.transpose();
241 
242  return yCov.template block<_DataDimension, _DataDimension> (_Order*_DataDimension, _Order*_DataDimension);
243  };
244 
245  };
246 }
247 
248 #endif
249 
Eigen::Matrix< double, _DataDimension, _DataDimension > iirFilterCov(const Eigen::Matrix< double, _DataDimension,(_Order+1)*_DataDimension > &bMatrix, const Eigen::Matrix< double, _DataDimension,(_Order+1)*_DataDimension > &aMatrix, const Eigen::Matrix< double,(_Order+1)*_DataDimension,(_Order+1)*_DataDimension > &xCov, Eigen::Matrix< double,(_Order+1)*_DataDimension,(_Order+1)*_DataDimension > &yCov)
IIR filter Cov.
Definition: IIR.hpp:224
Implements an Infinite Impulse Response filter with order _Order specified as template parameters and...
Definition: IIR.hpp:16
Eigen::Matrix< double, _DataDimension, _Order+1 > originalData
Definition: IIR.hpp:30
Eigen::Matrix< double,(_Order+1)*_DataDimension,(_Order+1)*_DataDimension > filteredDataCov
Definition: IIR.hpp:33
Eigen::Matrix< double,(_Order+1)*_DataDimension,(_Order+1)*_DataDimension > originalDataCov
Definition: IIR.hpp:33
Eigen::Matrix< double, _DataDimension,(_Order+1)*_DataDimension > aMatrix
Definition: IIR.hpp:34
Eigen::Matrix< double, _DataDimension, 1 > iirFilter(const Eigen::Matrix< double, _Order+1, 1 > &b, const Eigen::Matrix< double, _Order+1, 1 > &a, const Eigen::Matrix< double, _DataDimension, _Order+1 > &x, Eigen::Matrix< double, _DataDimension, _Order+1 > &y)
IIR filter.
Definition: IIR.hpp:180
Eigen::Matrix< double,(_Order+1)*_DataDimension,(_Order+1)*_DataDimension > crossCov
Definition: IIR.hpp:35
Eigen::Matrix< double, _DataDimension, _Order+1 > filteredData
Definition: IIR.hpp:30
Eigen::Matrix< double, _DataDimension,(_Order+1)*_DataDimension > bMatrix
Definition: IIR.hpp:34
IIR(const Eigen::Matrix< double, _Order+1, 1 > &b, const Eigen::Matrix< double, _Order+1, 1 > &a)
Constructor.
Definition: IIR.hpp:47
Definition: IIR.hpp:11
Eigen::Matrix< double, _Order+1, 1 > aCoeff
Definition: IIR.hpp:27
Eigen::Matrix< double, _DataDimension, 1 > perform(const Eigen::Matrix< double, _DataDimension, 1 > &data, Eigen::Matrix< double, _DataDimension, _DataDimension > &dataCov, const bool covariance=true)
Definition: IIR.hpp:97
Eigen::Matrix< double, _Order+1, 1 > bCoeff
Definition: IIR.hpp:27
Eigen::Matrix< double, _DataDimension, 1 > perform(const Eigen::Matrix< double, _DataDimension, 1 > &data)
Definition: IIR.hpp:84