bitrl & cuberl Documentation
Simulation engine for reinforcement learning agents
Loading...
Searching...
No Matches
extended_kalman_filter.h
Go to the documentation of this file.
1#ifndef EXTENDED_KALMAN_FILTER_H
2#define EXTENDED_KALMAN_FILTER_H
3
4#include "bitrl/bitrl_types.h"
5#include "Eigen/Dense"
6#include <boost/noncopyable.hpp>
7#include <map>
8#include <string>
9#include <iostream>
10
11namespace bitrl{
12namespace estimation{
13
41
42template<typename MotionModelTp, typename ObservationModelTp>
43class ExtendedKalmanFilter: private boost::noncopyable
44{
45public:
46
47 typedef MotionModelTp motion_model_type;
48 typedef ObservationModelTp observation_model_type;
49 typedef typename motion_model_type::input_type motion_model_input_type;
50 typedef typename motion_model_type::matrix_type matrix_type;
51 typedef typename motion_model_type::state_type state_type;
52 typedef typename observation_model_type::input_type observation_model_input_type;
53
56
62 const observation_model_type& observation_model);
63
68
72 void estimate(const std::tuple<motion_model_input_type,
74
86 void predict(const motion_model_input_type& input);
87
95
98 {motion_model_ptr_ = &motion_model;}
99
101 void set_observation_model(const observation_model_type& observation_model)
102 {observation_model_ptr_ = &observation_model;}
103
105 void set_matrix(const std::string& name, const matrix_type& mat);
106
108 bool has_matrix(const std::string& name)const;
109
111 const state_type& get_state()const{return motion_model_ptr_->get_state();}
112
114 state_type& get_state(){return motion_model_ptr_->get_state();}
115
117 real_t get(const std::string& name)const{return motion_model_ptr_->get_state_property(name);}
118
120 const DynMat<real_t>& operator[](const std::string& name)const;
121
123 DynMat<real_t>& operator[](const std::string& name);
124
128 ExtendedKalmanFilter& with_matrix(const std::string& name, const matrix_type& mat);
129
130protected:
131
134
137
139 std::map<std::string, matrix_type> matrices_;
140
141};
142
143template<typename MotionModelTp, typename ObservationModelTp>
145 :
146 motion_model_ptr_(nullptr),
147 observation_model_ptr_(nullptr)
148{}
149
150template<typename MotionModelTp, typename ObservationModelTp>
151ExtendedKalmanFilter<MotionModelTp,
152 ObservationModelTp>::ExtendedKalmanFilter(motion_model_type& motion_model,
153 const observation_model_type& observation_model)
154 :
155 motion_model_ptr_(&motion_model),
156 observation_model_ptr_(&observation_model)
157{}
158
159template<typename MotionModelTp, typename ObservationModelTp>
160ExtendedKalmanFilter<MotionModelTp,
161 ObservationModelTp>::~ExtendedKalmanFilter()
162{}
163
164template<typename MotionModelTp, typename ObservationModelTp>
165void
166ExtendedKalmanFilter<MotionModelTp,
167 ObservationModelTp>::set_matrix(const std::string& name,
168 const matrix_type& mat){
169
170 if(name != "Q" && name != "K" && name != "R" && name != "P"){
171 throw std::logic_error("Invalid matrix name. Name: "+
172 name+
173 " not in [Q, K, R, P]");
174 }
175
176 matrices_.insert_or_assign(name, mat);
177}
178
179template<typename MotionModelTp, typename ObservationModelTp>
182 const matrix_type& mat){
183 set_matrix(name, mat);
184 return *this;
185}
186
187template<typename MotionModelTp, typename ObservationModelTp>
188bool
190
191 auto itr = matrices_.find(name);
192 return itr != matrices_.end();
193}
194
195template<typename MotionModelTp, typename ObservationModelTp>
196const DynMat<real_t>&
198
199 auto itr = matrices_.find(name);
200
201 if(itr == matrices_.end()){
202 throw std::invalid_argument("Matrix: "+name+" does not exist");
203 }
204
205 return itr->second;
206}
207
208template<typename MotionModelTp, typename ObservationModelTp>
211
212 auto itr = matrices_.find(name);
213
214 if(itr == matrices_.end()){
215 throw std::invalid_argument("Matrix: "+name+" does not exist");
216 }
217
218 return itr->second;
219}
220
221
222template<typename MotionModelTp, typename ObservationModelTp>
223void
224ExtendedKalmanFilter<MotionModelTp,
225 ObservationModelTp>::estimate(const std::tuple<motion_model_input_type,
227
228 predict(input.template get<0>());
229 update(input.template get<1>());
230}
231
232template<typename MotionModelTp, typename ObservationModelTp>
233void
235
238 motion_model_ptr_->evaluate(u);
239
240 auto& P = (*this)["P"];
241 auto& Q = (*this)["Q"];
242
243 auto& L = motion_model_ptr_->get_matrix("L");
244 auto L_T = L.transpose(); //trans(L);
245
246 auto& F = motion_model_ptr_->get_matrix("F");
247 auto F_T = F.transpose(); //trans(F);
248
249 P = F * P * F_T + L*Q*L_T;
250}
251
252template<typename MotionModelTp, typename ObservationModelTp>
253void
254ExtendedKalmanFilter<MotionModelTp,
255 ObservationModelTp>::update(const observation_model_input_type& z){
256
257 auto& state = motion_model_ptr_->get_state();
258 auto& P = (*this)["P"];
259 auto& R = (*this)["R"];
260
261 auto zpred = observation_model_ptr_->evaluate(z);
262
263 auto& H = observation_model_ptr_->get_matrix("H");
264 auto H_T = H.transpose(); //trans(H);
265
266 // compute \partial{h}/\partial{v} the jacobian of the observation model
267 // w.r.t the error vector
268 auto& M = observation_model_ptr_->get_matrix("M");
269 auto M_T = M.transpose(); //trans(M);
270
271 try{
272
273 // S = H*P*H^T + M*R*M^T
274 auto S = H*P*H_T + M*R*M_T;
275
276 auto S_inv = S.inverse(); //inv(S);
277
278 if(has_matrix("K")){
279 auto& K = (*this)["K"];
280 K = P*H_T*S_inv;
281 }
282 else{
283 auto K = P*H_T*S_inv;
284 set_matrix("K", K);
285 }
286
287 auto& K = (*this)["K"];
288
289 auto innovation = z - zpred;
290
291 // we need to take the transpose
292 auto innovation_t = innovation.transpose();
293
294 if(K.cols() != innovation_t.rows()){
295 throw std::runtime_error("Matrix columns: "+
296 std::to_string(K.cols())+
297 " not equal to vector size: "+
298 std::to_string(innovation_t.rows()));
299 }
300
301 //auto vec = K * innovation_t;
302 state += K * innovation_t; //.add(K*innovation);
303
304 //IdentityMatrix<real_t> I(state.size());
305 auto I = matrix_type::Identity(state.size(), state.size());
307 P = (I - K*H)*P;
308 }
309 catch(...){
310
311 // this is a singular matrix what
312 // should we do? Simply use the predicted
313 // values and log the fact that there was a singular matrix
314
315 throw;
316 }
317}
318
319
320}
321}
322
323
324#endif
Definition extended_kalman_filter.h:44
state_type & get_state()
Returns the state.
Definition extended_kalman_filter.h:114
ExtendedKalmanFilter()
Constructor.
Definition extended_kalman_filter.h:144
bool has_matrix(const std::string &name) const
Returns true if the matrix with the given name exists.
Definition extended_kalman_filter.h:189
motion_model_type::matrix_type matrix_type
Definition extended_kalman_filter.h:50
motion_model_type::state_type state_type
Definition extended_kalman_filter.h:51
void set_observation_model(const observation_model_type &observation_model)
Set the observation model.
Definition extended_kalman_filter.h:101
void update(const observation_model_input_type &z)
Updates the gain matrix K, the state vector x and covariance matrix P using the given measurement z_k...
Definition extended_kalman_filter.h:255
real_t get(const std::string &name) const
Returns the state property with the given name.
Definition extended_kalman_filter.h:117
ExtendedKalmanFilter & with_matrix(const std::string &name, const matrix_type &mat)
Set the matrix and return *this.
Definition extended_kalman_filter.h:181
MotionModelTp motion_model_type
Definition extended_kalman_filter.h:47
motion_model_type * motion_model_ptr_
pointer to the function that computes f
Definition extended_kalman_filter.h:133
const state_type & get_state() const
Returns the state.
Definition extended_kalman_filter.h:111
void set_matrix(const std::string &name, const matrix_type &mat)
Set the matrix used by the filter.
Definition extended_kalman_filter.h:167
ObservationModelTp observation_model_type
Definition extended_kalman_filter.h:48
const observation_model_type * observation_model_ptr_
pointer to the function that computes h
Definition extended_kalman_filter.h:136
~ExtendedKalmanFilter()
Destructor.
Definition extended_kalman_filter.h:161
void estimate(const std::tuple< motion_model_input_type, observation_model_input_type > &input)
Estimate the state. This function simply wraps the predict and update steps described by the function...
Definition extended_kalman_filter.h:225
observation_model_type::input_type observation_model_input_type
Definition extended_kalman_filter.h:52
void set_motion_model(motion_model_type &motion_model)
Set the motion model.
Definition extended_kalman_filter.h:97
const DynMat< real_t > & operator[](const std::string &name) const
Returns the name-th matrix.
Definition extended_kalman_filter.h:197
std::map< std::string, matrix_type > matrices_
Matrices used by the filter internally.
Definition extended_kalman_filter.h:139
void predict(const motion_model_input_type &input)
Predicts the state vector x and the process covariance matrix P using the given input control u accro...
Definition extended_kalman_filter.h:234
motion_model_type::input_type motion_model_input_type
Definition extended_kalman_filter.h:49
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