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_checkFuzzyTracking.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011-2012 Stephan Weiss, ASL, ETH Zurich, Switzerland
3  * You can contact the author at <stephan dot weiss at ieee dot org>
4  * Copyright (C) 2012-2013 Simon Lynen, ASL, ETH Zurich, Switzerland
5  * You can contact the author at <slynen at ethz dot ch>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 #ifndef MSF_CHECKFUZZYTRACKING_H_
20 #define MSF_CHECKFUZZYTRACKING_H_
21 
22 #include <msf_core/msf_tools.h>
23 
24 namespace msf_core {
25 
26 template<typename EKFState_T, typename NONTEMPORALDRIFTINGTYPE>
28 
29  private:
30 
31  enum {
32  qbuffRowsAtCompiletime = msf_tmp::StateLengthForType<
34  nBuff_ = 30
35  };
36 
38  // If there is no non temporal drifting state this matrix will have zero rows,
39  // to make use of it illegal.
40  Eigen::Matrix<double, nBuff_, qbuffRowsAtCompiletime> qbuff_;
41 
42  public:
44 
45  void reset() {
46  // Buffer for vision failure check.
48  qbuff_ = Eigen::Matrix<double, nBuff_, qbuffRowsAtCompiletime>::Constant(0);
49  }
50 
52  reset();
53  }
54 
55  bool check(shared_ptr<EKFState_T> delaystate, EKFState_T& buffstate,
56  double fuzzythres) {
57  // For now make sure the non drifting state is a quaternion.
58  bool isfuzzy = false;
59 
60  const bool isquaternion =
61  msf_tmp::isQuaternionType<
63  static_assert(
64  isquaternion,
65  "Assumed that the non drifting state is a Quaternion, "
66  "which is not the case for the currently defined state vector. If you "
67  "want to use an euclidean state, please first adapt qbuff and the error "
68  "detection routines");
69  typedef typename EKFState_T::StateDefinition_T StateDefinition_T;
70  typedef typename EKFState_T::StateSequence_T StateSequence_T;
71 
72  enum {
73  indexOfStateWithoutTemporalDrift = msf_tmp::IndexOfBestNonTemporalDriftingState<
74  StateSequence_T>::value,
76  nErrorStatesAtCompileTime = EKFState_T::nErrorStatesAtCompileTime,
78  nStatesAtCompileTime = EKFState_T::nStatesAtCompileTime
79  };
80 
81  // Update qbuff_ and check for fuzzy tracking.
83  // should be unit quaternion if no error
84  Eigen::Quaternion<double> errq =
85  const_cast<const EKFState_T&>(*delaystate)
86  .template get<indexOfStateWithoutTemporalDrift>().conjugate() *
87  Eigen::Quaternion<double>(
88  getMedian(qbuff_. template block<nBuff_, 1> (0, 3)),
89  getMedian(qbuff_. template block<nBuff_, 1> (0, 0)),
90  getMedian(qbuff_. template block<nBuff_, 1> (0, 1)),
91  getMedian(qbuff_. template block<nBuff_, 1> (0, 2))
92  );
93 
94  if (std::max(errq.vec().maxCoeff(), -errq.vec().minCoeff()) /
95  fabs(errq.w()) * 2 > fuzzythres) // Fuzzy tracking (small angle approx).
96  {
97  MSF_WARN_STREAM("Fuzzy tracking triggered: " <<
98  std::max(errq.vec().maxCoeff(), -errq.vec().minCoeff()) /
99  fabs(errq.w())*2 << " limit: " << fuzzythres <<"\n");
100 
101  // Copy the non propagation states back from the buffer.
102  boost::fusion::for_each(
103  delaystate->statevars,
105  );
106 
107  static_assert(static_cast<int>(
108  EKFState_T::nPropagatedCoreErrorStatesAtCompileTime) == 9,
109  "Assumed that nPropagatedCoreStates == 9, "
110  "which is not the case");
111  isfuzzy = true;
112  }
113  else // If tracking ok: Update mean and 3sigma of past N non drifting state values.
114  {
115  qbuff_. template block<1, 4>(nontemporaldrifting_inittimer_ - nBuff_ - 1, 0) =
116  Eigen::Matrix<double, 1, 4>(const_cast<const EKFState_T&>(*delaystate).
117  template get<indexOfStateWithoutTemporalDrift>().coeffs());
119  }
120  }
121  else // At beginning get mean and 3sigma of past N non drifting state values.
122  {
123  qbuff_. template block<1, 4> (nontemporaldrifting_inittimer_ - 1, 0) =
124  Eigen::Matrix<double, 1, 4>(const_cast<const EKFState_T&>(*delaystate).
125  template get<indexOfStateWithoutTemporalDrift>().coeffs());
126  nontemporaldrifting_inittimer_++;
127  }
128  return isfuzzy;
129  }
130 };
131 
132 template<typename EKFState_T>
134  public:
135  bool check(shared_ptr<EKFState_T> UNUSEDPARAM(delaystate),
136  EKFState_T& UNUSEDPARAM(buffstate),
137  double UNUSEDPARAM(fuzzythres)) {
138  return false;
139  }
140  void reset() {
141  }
142  ;
143 };
144 }
145 #endif // MSF_CHECKFUZZYTRACKING_H_