MAV'RIC
|
00001 /******************************************************************************* 00002 * Copyright (c) 2009-2016, MAV'RIC Development Team 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * 00011 * 2. Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * 00015 * 3. Neither the name of the copyright holder nor the names of its contributors 00016 * may be used to endorse or promote products derived from this software without 00017 * specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00029 * POSSIBILITY OF SUCH DAMAGE. 00030 ******************************************************************************/ 00031 00032 /******************************************************************************* 00033 * \file kalman.hpp 00034 * 00035 * \author MAV'RIC Team 00036 * \author Julien Lecoeur 00037 * 00038 * \brief Kalman filter 00039 * 00040 * \details Convention used for dimensions: 00041 * - n state 00042 * - p input 00043 * - m measurement 00044 * 00045 ******************************************************************************/ 00046 00047 00048 #ifndef KALMAN_HPP__ 00049 #define KALMAN_HPP__ 00050 00051 #include "matrix.hpp" 00052 00053 00054 namespace kf 00055 { 00056 00068 template<uint32_t n, typename T> 00069 static void predict(Mat<n,1,T>& x, 00070 Mat<n,n,T>& P, 00071 const Mat<n,n,T>& F, 00072 const Mat<n,n,T>& Q) 00073 { 00074 // State 00075 x = F % x; 00076 00077 // State covariance 00078 P = (F % P % ~F) + Q; 00079 }; 00080 00081 00096 template<uint32_t n, uint32_t p, typename T> 00097 static void predict(Mat<n,1,T>& x, 00098 Mat<n,n,T>& P, 00099 const Mat<n,n,T>& F, 00100 const Mat<n,n,T>& Q, 00101 const Mat<n,p,T>& B, 00102 const Mat<p,1,T>& u) 00103 { 00104 // Do prediction without input 00105 predict(x, P, F, Q); 00106 00107 // Add effect of input 00108 x += B % u; 00109 }; 00110 00111 00126 template<uint32_t n, uint32_t m, typename T> 00127 static void update(Mat<n,1,T>& x, 00128 Mat<n,n,T>& P, 00129 Mat<m,1,T>& z, 00130 const Mat<m,n,T>& H, 00131 const Mat<m,m,T>& R, 00132 Mat<m,m,T>& S, 00133 Mat<n,m,T>& K, 00134 Mat<m,1,T>& y, 00135 const Mat<n,n,T>& I) 00136 { 00137 // Innovation 00138 y = z - H % x; 00139 00140 // Innovation covariance 00141 S = H % P % ~H + R; 00142 00143 // Kalman gain 00144 bool inversible; 00145 K = P % ~H % S.inv(inversible); 00146 00147 if(inversible) 00148 { 00149 // Update state 00150 x = x + K % y; 00151 00152 // Update state covariance 00153 P = (I - K % H) % P; 00154 } 00155 }; 00156 00157 } 00158 00159 00168 template<uint32_t n, uint32_t p, uint32_t m, typename T=float> 00169 class Kalman 00170 { 00171 public: 00172 00176 Kalman(void): 00177 x_(), 00178 P_(1.0f, true), 00179 F_(1.0f, true), 00180 Q_(0.01f, true), 00181 H_(), 00182 R_(0.01f, true), 00183 B_(), 00184 S_(), 00185 I_(1.0f, true), 00186 K_(), 00187 y_() 00188 {} 00189 00190 00201 Kalman(Mat<n,1> x, Mat<n,n> P, Mat<n,n> F, Mat<n,n> Q, Mat<m,n> H, Mat<m,m> R, Mat<n,p> B = Mat<n,p>()): 00202 x_(x), 00203 P_(P), 00204 F_(F), 00205 Q_(Q), 00206 H_(H), 00207 R_(R), 00208 B_(B), 00209 S_(), 00210 I_(1.0f, true), 00211 K_(), 00212 y_() 00213 {} 00214 00215 00221 const Mat<n,1>& x(void) const 00222 { 00223 return x_; 00224 }; 00225 00226 00232 const Mat<n,n>& P(void) const 00233 { 00234 return P_; 00235 }; 00236 00237 00241 void predict(void) 00242 { 00243 kf::predict(x_, P_, F_, Q_); 00244 } 00245 00246 00250 void predict(Mat<p,1,T> u) 00251 { 00252 kf::predict(x_, P_, F_, Q_, B_, u); 00253 } 00254 00255 00261 void update(Mat<m,1,T> z) 00262 { 00263 kf::update(x_, P_, z, H_, R_, S_, K_, y_, I_); 00264 } 00265 00266 00278 template<uint32_t mm> 00279 void update(Mat<mm,1,T> z, Mat<mm,n,T> H, Mat<mm,mm,T> R) 00280 { 00281 Mat<mm,mm,T> S; 00282 Mat<n,mm,T> K; 00283 Mat<mm,1,T> y; 00284 kf::update(x_, P_, z, H, R, S, K, y, I_); 00285 } 00286 00287 00288 protected: 00289 00290 Mat<n,1> x_; 00291 Mat<n,n> P_; 00292 Mat<n,n> F_; 00293 Mat<n,n> Q_; 00294 Mat<m,n> H_; 00295 Mat<m,m> R_; 00296 Mat<n,p> B_; 00297 00298 Mat<m,m> S_; 00299 const Mat<n,n> I_; 00300 Mat<n,m> K_; 00301 Mat<m,1> y_; 00302 }; 00303 00304 00305 #endif /* KALMAN_HPP__ */