bitrl & cuberl Documentation
Simulation engine for reinforcement learning agents
Loading...
Searching...
No Matches
kalman_filter.h
Go to the documentation of this file.
1#include "bitrl/bitrl_types.h"
3#include "Eigen/Dense"
4#include <boost/noncopyable.hpp>
5
6#include <any>
7#include <map>
8#include <string>
9#include <stdexcept> //for std::invalid_argument
10
11
12namespace bitrl{
13namespace estimation{
14
15
19
20template<typename MotionModelType, typename ObservationModelType>
44
89template<typename MotionModelType, typename ObservationModelType>
90class KalmanFilter: private boost::noncopyable
91{
92
93public:
94
97
98 typedef MotionModelType motion_model_type;
99 typedef ObservationModelType observation_model_type;
100 typedef typename config_type::motion_model_type::state_type state_type;
101 typedef std::map<std::string, std::any> input_type;
102
107
113 state_type& estimate(const input_type& input );
114
133 void predict(const input_type& input);
134
142 void update(const input_type& input);
143
148 {motion_model_ptr_ = &motion_model;}
149
151 void set_observation_model(const observation_model_type& observation_model)
152 {observation_model_ptr_ = &observation_model;}
153
157 KalmanFilter& with_matrix(const std::string& name, const matrix_type& mat);
158
162 void set_matrix(const std::string& name, const matrix_type& mat);
163
167 bool has_matrix(const std::string& name)const;
168
172 const state_type& get_state()const{return motion_model_ptr_->get_state();}
173
177 state_type& get_state(){return motion_model_ptr_->get_state();}
178
182 real_t get(const std::string& name)const{return motion_model_ptr_->get(name);}
183
187 const matrix_type& operator[](const std::string& name)const;
188
192 matrix_type& operator[](const std::string& name);
193
194private:
195
199 motion_model_type* motion_model_ptr_;
200
204 const observation_model_type* observation_model_ptr_;
205
209 std::map<std::string, matrix_type> matrices_;
210};
211
212
213template<typename MotionModelType, typename ObservationModelType>
214KalmanFilter<MotionModelType,
215 ObservationModelType>::KalmanFilter(const KalmanFilterConfig<MotionModelType, ObservationModelType>& config)
216 :
217 motion_model_ptr_(config.motion_model),
218 observation_model_ptr_(config.observation_model)
219{
220 // set the matrices
221 set_matrix("B", config.B);
222 set_matrix("P", config.P);
223 set_matrix("Q", config.Q);
224 set_matrix("K", config.K);
225 set_matrix("R", config.R);
226}
227
228
229template<typename MotionModelType, typename ObservationModelType>
230const DynMat<real_t>&
232
233 auto itr = matrices_.find(name);
234
235 if(itr == matrices_.end()){
236 throw std::invalid_argument("Matrix: "+name+" does not exist");
237 }
238
239 return itr->second;
240}
241
242template<typename MotionModelType, typename ObservationModelType>
245
246 auto itr = matrices_.find(name);
247
248 if(itr == matrices_.end()){
249 throw std::invalid_argument("Matrix: "+name+" does not exist");
250 }
251
252 return itr->second;
253}
254
255template<typename MotionModelType, typename ObservationModelType>
257KalmanFilter<MotionModelType,
258 ObservationModelType>::with_matrix(const std::string& name, const matrix_type& mat){
259
260 set_matrix(name, mat);
261 return *this;
262}
263
264template<typename MotionModelType, typename ObservationModelType>
265void
266KalmanFilter<MotionModelType,
267 ObservationModelType>::set_matrix(const std::string& name,
268 const matrix_type& mat){
269
270 if(name != "Q" &&
271 name != "K" &&
272 name != "R" &&
273 name != "P" &&
274 name != "B"){
275 throw std::logic_error("Invalid matrix name. Name: "+
276 name+
277 " not in [Q, K, R, P, B]");
278 }
279
280 matrices_.insert_or_assign(name, mat);
281}
282
283template<typename MotionModelType, typename ObservationModelType>
284bool
286
287 auto itr = matrices_.find(name);
288 return itr != matrices_.end();
289}
290
291template<typename MotionModelType, typename ObservationModelType>
293KalmanFilter<MotionModelType,
294 ObservationModelType>::estimate(const input_type& input ){
295 predict(input);
296 update(input);
297
298 return get_state();
299}
300
301template<typename MotionModelType, typename ObservationModelType>
302void
303KalmanFilter<MotionModelType,
304 ObservationModelType>::predict(const input_type& input ){
305
306 if(!motion_model_ptr_){
307 throw std::runtime_error("Motion model has not been set");
308 }
309
310 auto u = bitrl::utils::template resolve<DynVec<real_t>>("u", input);
311 auto w = bitrl::utils::template resolve<DynVec<real_t>>("w", input);
312
313 // make a state predicion using the
314 // motion model
315 auto& x = motion_model_ptr_->get_state();
316
317 // get the matrix that describes the dynamics
318 // of the system
319 auto& F = motion_model_ptr_->get_matrix("F");
320 auto& B = (*this)["B"];
321
322 // update the state vector
323 x = F*x + B*u + w;
324 //state.set(x);
325
326 // predict the covariance matrix
327 auto& P = (*this)["P"];
328 auto& Q = (*this)["Q"];
329 auto F_T = F.transpose();
330
331 P = (F*P*F_T) + Q;
332}
333
334template<typename MotionModelType, typename ObservationModelType>
335void
336KalmanFilter<MotionModelType,
337 ObservationModelType>::update(const input_type& input){
338
339 if(!motion_model_ptr_){
340 throw std::runtime_error("Motion model has not been set");
341 }
342
343 if(!observation_model_ptr_){
344 throw std::runtime_error("Observation model has not been set");
345 }
346
347 auto& x = motion_model_ptr_->get_state();
348 auto& P = (*this)["P"];
349 auto& R = (*this)["R"];
350
351 auto& H = observation_model_ptr_->get_matrix("H");
352 auto H_T = H.transpose();
353
354 try{
355
356 auto S = H*P*H_T + R;
357 auto S_inv = S.inverse(); //inv(S);
358
359 // compute the gain matrix
360 if(has_matrix("K")){
361 auto& K = matrices_["K"];
362 K = P*H_T*S_inv;
363 }
364 else{
365 auto K = P*H_T*S_inv;
366 set_matrix("K", K);
367 }
368
369 auto& K = (*this)["K"];
370 auto z = bitrl::utils::template resolve<DynVec<real_t>>("z", input);
371 auto innovation = z - H*x;
372
373 if(K.cols() != innovation.size()){
374 throw std::runtime_error("Matrix columns: "+
375 std::to_string(K.cols())+
376 " not equal to vector size: "+
377 std::to_string(innovation.size()));
378 }
379
380 x += K*innovation;
381 //state.set(x);
382
383 auto I = matrix_type::Identity(x.size(), x.size());
384
385 // update the error covariance matrix
386 P = (I - K*H)*P;
387 }
388 catch(...){
389
390 // this is a singular matrix what
391 // should we do? Simply use the predicted
392 // values and log the fact that there was a singular matrix
393
394 throw;
395 }
396}
397
398}
399}
Linear Kalman Filter implementation. See: An Introduction to the Kalman Filter, TR 95-041 by Greg Wel...
Definition kalman_filter.h:91
MotionModelType motion_model_type
Definition kalman_filter.h:98
void set_motion_model(motion_model_type &motion_model)
Set the motion model.
Definition kalman_filter.h:147
state_type & estimate(const input_type &input)
Estimate the state. This function simply wraps the predict and update steps described by the function...
Definition kalman_filter.h:294
KalmanFilterConfig< MotionModelType, ObservationModelType > config_type
Definition kalman_filter.h:95
std::map< std::string, std::any > input_type
Definition kalman_filter.h:101
KalmanFilter & with_matrix(const std::string &name, const matrix_type &mat)
Set the matrix and return *this.
Definition kalman_filter.h:258
void predict(const input_type &input)
Predicts the state vector x and the process covariance matrix P using the given input control u accro...
Definition kalman_filter.h:304
void set_matrix(const std::string &name, const matrix_type &mat)
Set the matrix used by the filter.
Definition kalman_filter.h:267
state_type & get_state()
Returns the state.
Definition kalman_filter.h:177
const state_type & get_state() const
Returns the state.
Definition kalman_filter.h:172
bool has_matrix(const std::string &name) const
Returns true if the matrix with the given name exists.
Definition kalman_filter.h:285
const matrix_type & operator[](const std::string &name) const
Returns the name-th matrix.
Definition kalman_filter.h:231
DynMat< real_t > matrix_type
Definition kalman_filter.h:96
ObservationModelType observation_model_type
Definition kalman_filter.h:99
void update(const input_type &input)
Updates the gain matrix , the state vector and covariance matrix P using the given measurement z_k a...
Definition kalman_filter.h:337
real_t get(const std::string &name) const
Returns the state property with the given name.
Definition kalman_filter.h:182
config_type::motion_model_type::state_type state_type
Definition kalman_filter.h:100
void set_observation_model(const observation_model_type &observation_model)
Set the observation model.
Definition kalman_filter.h:151
OutT resolve(const std::string &name, const std::map< std::string, std::any > &input)
Definition std_map_utils.h:25
Definition bitrl_consts.h:14
double real_t
real_t
Definition bitrl_types.h:23
Eigen::MatrixX< T > DynMat
Dynamically sized matrix to use around the library.
Definition bitrl_types.h:49
Configuration class for the Kalman filter.
Definition kalman_filter.h:22
DynMat< real_t > R
Definition kalman_filter.h:42
const observation_model_type * observation_model
Pointer to the observation model.
Definition kalman_filter.h:36
DynMat< real_t > B
Definition kalman_filter.h:38
ObservationModelType observation_model_type
Definition kalman_filter.h:26
DynMat< real_t > P
Definition kalman_filter.h:39
MotionModelType motion_model_type
Definition kalman_filter.h:25
DynMat< real_t > Q
Definition kalman_filter.h:40
DynMat< real_t > K
Definition kalman_filter.h:41
motion_model_type * motion_model
Pointer to the motion model.
Definition kalman_filter.h:31