ethzasl-msf - Modular Sensor Fusion
Time delay compensated single and multi sensor fusion framework based on an EKF
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
msf_measurement.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2013 Simon Lynen, ASL, ETH Zurich, Switzerland
3  * You can contact the author at <slynen at ethz dot ch>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #ifndef MEASUREMENT_H_
18 #define MEASUREMENT_H_
19 
20 #include <Eigen/Dense>
21 #include <boost/shared_ptr.hpp>
22 
23 #include <msf_core/msf_fwds.h>
24 #include <msf_core/msf_types.hpp>
25 
26 namespace msf_core {
32 template<typename EKFState_T>
34  public:
35  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
36  MSF_MeasurementBase(bool isabsoluteMeasurement, int sensorID);
38  }
43  virtual void apply(shared_ptr<EKFState_T> stateWithCovariance,
44  MSF_Core<EKFState_T>& core) = 0;
45  virtual std::string type() = 0;
46  int sensorID_;
48  double time;
49  protected:
54  template<class H_type, class Res_type, class R_type>
56  shared_ptr<EKFState_T> state, MSF_Core<EKFState_T>& core,
57  const Eigen::MatrixBase<H_type>& H,
58  const Eigen::MatrixBase<Res_type>& residual,
59  const Eigen::MatrixBase<R_type>& R);
60 
61  void calculateAndApplyCorrection(shared_ptr<EKFState_T> state,
63  const Eigen::MatrixXd& H,
64  const Eigen::MatrixXd& residual,
65  const Eigen::MatrixXd& R);
66 
67  template<class H_type, class Res_type, class R_type>
69  shared_ptr<EKFState_T> state_old, shared_ptr<EKFState_T> state_new,
70  MSF_Core<EKFState_T>& core, const Eigen::MatrixBase<H_type>& H_old,
71  const Eigen::MatrixBase<H_type>& H_new,
72  const Eigen::MatrixBase<Res_type>& residual,
73  const Eigen::MatrixBase<R_type>& R);
74 
75 };
76 
81 template<typename EKFState_T>
82 class MSF_InvalidMeasurement : public MSF_MeasurementBase<EKFState_T> {
83  public:
85  virtual void apply(shared_ptr<EKFState_T> UNUSEDPARAM(stateWithCovariance),
88  "Called apply() on an MSF_InvalidMeasurement object. This should never "
89  "happen.");
90  }
91  virtual std::string type() {
92  return "invalid";
93  }
95  : MSF_MeasurementBase<EKFState_T>(true, -1) {
96  }
98  }
99 };
100 
107 template<typename T, typename RMAT_T, typename EKFState_T>
108 class MSF_Measurement : public MSF_MeasurementBase<EKFState_T> {
109  private:
110  virtual void makeFromSensorReadingImpl(
111  const boost::shared_ptr<T const> reading) = 0;
112  protected:
113  RMAT_T R_;
114  public:
116  typedef T Measurement_type;
117  typedef boost::shared_ptr<T const> Measurement_ptr;
118 
119  MSF_Measurement(bool isAbsoluteMeasurement, int sensorID)
120  : MSF_MeasurementBase<EKFState_T>(isAbsoluteMeasurement, sensorID) {
121  R_.setZero();
122  }
123  virtual ~MSF_Measurement() {
124  }
125  ;
126  void makeFromSensorReading(const boost::shared_ptr<T const> reading,
127  double timestamp) {
128  this->time = timestamp;
129 
130  makeFromSensorReadingImpl(reading);
131 
132  // Check whether the user has set R.
133  if (R_.minCoeff() == 0.0 && R_.maxCoeff() == 0.0) {
135  2,
136  "The measurement covariance matrix seems to be not set for the current "
137  "measurement. Please double check!");
138  }
139 
140  for (int i = 0; i < R_.RowsAtCompileTime; ++i) {
141  if (R_(i, i) == 0.0) {
143  2,
144  "The measurement covariance matrix has some diagonal elements set to "
145  "zero. Please double check!");
146  }
147  }
148  }
149 // Apply is implemented by respective sensor measurement types.
150 };
151 
157 template<typename EKFState_T>
158 class MSF_InitMeasurement : public MSF_MeasurementBase<EKFState_T> {
159  private:
160  EKFState_T InitState;
161 
163  typedef typename EKFState_T::StateSequence_T StateSequence_T;
164  public:
165  EIGEN_MAKE_ALIGNED_OPERATOR_NEW MSF_InitMeasurement(
166  bool ContainsInitialSensorReadings)
167  : MSF_MeasurementBase<EKFState_T>(true, -1) {
168  ContainsInitialSensorReadings_ = ContainsInitialSensorReadings;
169  this->time = ros::Time::now().toSec();
170  }
172  }
173  ;
174  virtual std::string type() {
175  return "init";
176  }
177  typename EKFState_T::P_type& get_P() {
178  return InitState.P;
179  }
183  Eigen::Matrix<double, 3, 1>& get_w_m() {
184  return InitState.w_m;
185  }
189  Eigen::Matrix<double, 3, 1>& get_a_m() {
190  return InitState.a_m;
191  }
192 
197  template<int INDEX, typename T>
198  void setStateInitValue(const T& initvalue) {
199  InitState.template getStateVar<INDEX>().state_ = initvalue;
200  InitState.template getStateVar<INDEX>().hasResetValue = true;
201  }
202 
207  template<int INDEX>
209  InitState.template get<INDEX>().hasResetValue = false;
210  }
211 
216  template<int INDEX>
217  const typename msf_tmp::StripReference<typename boost::fusion::result_of::at_c
218  <StateSequence_T, INDEX >::type>::result_t::value_t&
220  return InitState.template get<INDEX>();
221  }
222 
223  virtual void apply(shared_ptr<EKFState_T> stateWithCovariance, MSF_Core<EKFState_T>& core);
224 };
225 
229 template<typename EKFState_T>
231  public:
236  const MSF_MeasurementBase<EKFState_T>&rhs) const {
237  return (lhs.time_ < rhs.time_);
238  }
239 };
240 
241 }
242 
244 
245 #endif // MEASUREMENT_H_