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_tmp.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 
18 /*
19  * DO NOT MODIFY THIS FILE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING
20  * IF THERE ARE COMPILER ERRORS or WARNINGS IN THIS FILE IT IS PROBABLY
21  * BECAUSE YOU WHERE DOING SOMETHING WRONG WHEN USING THE CODE
22  * AND NOT BECAUSE THERE ARE ERRORS HERE.
23  *
24  */
25 
26 #ifndef MSF_TMP_H_
27 #define MSF_TMP_H_
28 
29 #include <msf_core/msf_fwds.h>
31 #include <msf_core/eigen_utils.h>
32 
33 #include <Eigen/Dense>
34 #include <Eigen/Core>
35 #include <sstream>
36 #include <iostream>
37 #include <iomanip>
38 
39 #ifdef FUSION_MAX_VECTOR_SIZE
40 #undef FUSION_MAX_VECTOR_SIZE
41 #endif
42 #define FUSION_MAX_VECTOR_SIZE 15 // Maximum number of statevariables
43 // (can be set to a larger value).
44 #include <boost/lexical_cast.hpp>
45 #include <boost/preprocessor/punctuation/comma.hpp>
46 #include <boost/fusion/include/vector.hpp>
47 #include <boost/fusion/include/size.hpp>
48 #include <boost/fusion/include/at_c.hpp>
49 #include <boost/fusion/include/at.hpp>
50 #include <boost/fusion/include/for_each.hpp>
51 #include <boost/fusion/include/equal_to.hpp>
52 #include <boost/fusion/include/begin.hpp>
53 #include <boost/fusion/include/end.hpp>
54 #include <boost/fusion/include/next.hpp>
55 #include <boost/mpl/bool.hpp>
56 #include <boost/fusion/include/at_key.hpp>
57 
58 // This namespace contains the msf metaprogramming tools.
59 namespace msf_tmp {
60 
65 template<size_t size>
66 struct overflow {
67  operator char() {
68  return size + 9999;
69  }
70 };
71 // Always overflow, also for negative values.
75 template<int VALUE>
77  char(overflow<VALUE>());
78  return;
79 }
80 
84 template<typename T> struct echoStateVarType;
85 
89 template<int NAME, int N, int STATE_T, int OPTIONS>
90 struct echoStateVarType<
91  const msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T,
92  OPTIONS>&> {
93  static std::string value() {
94  return "const ref Eigen::Matrix<double, " + boost::lexical_cast
95  < std::string > (N) + ", 1>";
96  }
97 };
101 template<int NAME, int STATE_T, int OPTIONS>
102 struct echoStateVarType<
103  const msf_core::StateVar_T<Eigen::Quaterniond, NAME, STATE_T, OPTIONS>&> {
104  static std::string value() {
105  return "const ref Eigen::Quaterniond";
106  }
107 };
111 template<int NAME, int N, int STATE_T, int OPTIONS>
112 struct echoStateVarType<
113  msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T, OPTIONS> > {
114  static std::string value() {
115  return "Eigen::Matrix<double, " + boost::lexical_cast < std::string
116  > (N) + ", 1>";
117  }
118 };
122 template<int NAME, int STATE_T, int OPTIONS>
123 struct echoStateVarType<
124  msf_core::StateVar_T<Eigen::Quaterniond, NAME, STATE_T, OPTIONS> > {
125  static std::string value() {
126  return "Eigen::Quaterniond";
127  }
128 };
129 
130 namespace { // For internal use only:
131 // The number of entries in the correction vector for a given state var.
132 template<typename T>
133 struct CorrectionStateLengthForType;
134 template<int NAME, int N, int STATE_T, int OPTIONS>
135 struct CorrectionStateLengthForType<
136  const msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T,
137  OPTIONS>&> {
138  enum {
139  value = N
140  };
141 };
142 template<int NAME, int STATE_T, int OPTIONS>
143 struct CorrectionStateLengthForType<
144  const msf_core::StateVar_T<Eigen::Quaterniond, NAME, STATE_T, OPTIONS>&> {
145  enum {
146  value = 3
147  };
148 };
149 template<>
150 struct CorrectionStateLengthForType<const mpl_::void_&> {
151  enum {
152  value = 0
153  };
154 };
155 
156 // The number of entries in the state for a given state var.
157 template<typename T>
158 struct StateLengthForType;
159 template<int NAME, int N, int STATE_T, int OPTIONS>
160 struct StateLengthForType<
161  const msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T,
162  OPTIONS>&> {
163  enum {
164  value = N
165  };
166 };
167 template<int NAME, int STATE_T, int OPTIONS>
168 struct StateLengthForType<
169  const msf_core::StateVar_T<Eigen::Quaterniond, NAME, STATE_T, OPTIONS>&> {
170  enum {
171  value = 4
172  };
173 };
174 template<>
175 struct StateLengthForType<const mpl_::void_&> {
176  enum {
177  value = 0
178  };
179 };
180 
181 // The number of entries in the state for a given state var if it is core state.
182 template<typename T>
183 struct CoreStateLengthForType;
184 template<int NAME, int N, int STATE_T, int OPTIONS>
185 struct CoreStateLengthForType<
186  const msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T,
187  OPTIONS>&> {
188  enum {
189  value = 0
190  };
191  // Not a core state, so length is zero.
192 };
193 template<int NAME, int STATE_T, int OPTIONS>
194 struct CoreStateLengthForType<
195  const msf_core::StateVar_T<Eigen::Quaterniond, NAME, STATE_T, OPTIONS>&> {
196  enum {
197  value = 0
198  };
199  // Not a core state, so length is zero.
200 };
201 template<int NAME, int OPTIONS, int N>
202 struct CoreStateLengthForType<
203  const msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME,
204  msf_core::CoreStateWithoutPropagation, OPTIONS>&> {
205  enum {
206  value = N
207  };
208 };
209 template<int NAME, int OPTIONS>
210 struct CoreStateLengthForType<
211  const msf_core::StateVar_T<Eigen::Quaterniond, NAME,
212  msf_core::CoreStateWithoutPropagation, OPTIONS>&> {
213  enum {
214  value = 4
215  };
216 };
217 template<int NAME, int OPTIONS, int N>
218 struct CoreStateLengthForType<
219  const msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME,
220  msf_core::CoreStateWithPropagation, OPTIONS>&> {
221  enum {
222  value = N
223  };
224 };
225 template<int NAME, int OPTIONS>
226 struct CoreStateLengthForType<
227  const msf_core::StateVar_T<Eigen::Quaterniond, NAME,
228  msf_core::CoreStateWithPropagation, OPTIONS>&> {
229  enum {
230  value = 4
231  };
232 };
233 template<>
234 struct CoreStateLengthForType<const mpl_::void_&> {
235  enum {
236  value = 0
237  };
238 };
239 
240 // The number of entries in the state for a given state var if it is core state
241 // with propagation.
242 template<typename T>
243 struct PropagatedCoreStateLengthForType;
244 template<int NAME, int N, int STATE_T, int OPTIONS>
245 struct PropagatedCoreStateLengthForType<
246  const msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T,
247  OPTIONS>&> {
248  enum {
249  value = 0
250  };
251  // Not a core state, so length is zero.
252 };
253 template<int NAME, int STATE_T, int OPTIONS>
254 struct PropagatedCoreStateLengthForType<
255  const msf_core::StateVar_T<Eigen::Quaterniond, NAME, STATE_T, OPTIONS>&> {
256  enum {
257  value = 0
258  };
259  // Not a core state, so length is zero.
260 };
261 template<int NAME, int OPTIONS, int N>
262 struct PropagatedCoreStateLengthForType<
263  const msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME,
264  msf_core::CoreStateWithPropagation, OPTIONS>&> {
265  enum {
266  value = N
267  };
268 };
269 template<int NAME, int OPTIONS>
270 struct PropagatedCoreStateLengthForType<
271  const msf_core::StateVar_T<Eigen::Quaterniond, NAME,
272  msf_core::CoreStateWithPropagation, OPTIONS>&> {
273  enum {
274  value = 4
275  };
276 };
277 template<>
278 struct PropagatedCoreStateLengthForType<const mpl_::void_&> {
279  enum {
280  value = 0
281  };
282 };
283 
284 // The number of entries in the error state for a given state var if it is core
285 // state with propagation.
286 template<typename T>
287 struct PropagatedCoreErrorStateLengthForType;
288 template<int NAME, int N, int STATE_T, int OPTIONS>
289 struct PropagatedCoreErrorStateLengthForType<
290  const msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T,
291  OPTIONS>&> {
292  enum {
293  value = 0
294  };
295  // Not a core state, so length is zero.
296 };
297 template<int NAME, int STATE_T, int OPTIONS>
298 struct PropagatedCoreErrorStateLengthForType<
299  const msf_core::StateVar_T<Eigen::Quaterniond, NAME, STATE_T, OPTIONS>&> {
300  enum {
301  value = 0
302  };
303  // Not a core state, so length is zero.
304 };
305 template<int NAME, int OPTIONS, int N>
306 struct PropagatedCoreErrorStateLengthForType<
307  const msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME,
308  msf_core::CoreStateWithPropagation, OPTIONS>&> {
309  enum {
310  value = N
311  };
312 };
313 template<int NAME, int OPTIONS>
314 struct PropagatedCoreErrorStateLengthForType<
315  const msf_core::StateVar_T<Eigen::Quaterniond, NAME,
316  msf_core::CoreStateWithPropagation, OPTIONS>&> {
317  enum {
318  value = 3
319  };
320 };
321 template<>
322 struct PropagatedCoreErrorStateLengthForType<const mpl_::void_&> {
323  enum {
324  value = 0
325  };
326 };
327 
328 // Return the number a state has in the enum.
329 template<typename T>
330 struct getEnumStateName;
331 template<typename U, int NAME, int STATE_T, int OPTIONS>
332 struct getEnumStateName<const msf_core::StateVar_T<U, NAME, STATE_T, OPTIONS>&> {
333  enum {
334  value = NAME
335  };
336 };
337 template<typename U, int NAME, int STATE_T, int OPTIONS>
338 struct getEnumStateName<msf_core::StateVar_T<U, NAME, STATE_T, OPTIONS> > {
339  enum {
340  value = NAME
341  };
342 };
343 template<> struct getEnumStateName<const mpl_::void_&> {
344  enum {
345  value = -1
346  };
347  // Must not change this.
348 };
349 template<> struct getEnumStateName<mpl_::void_> {
350  enum {
351  value = -1
352  };
353  // Must not change this.
354 };
355 
356 template<typename T>
357 struct isQuaternionType;
358 template<int NAME, int STATE_T, int OPTIONS, int M, int N>
359 struct isQuaternionType<
360  const msf_core::StateVar_T<Eigen::Matrix<double, M, N>, NAME, STATE_T,
361  OPTIONS>&> {
362  enum {
363  value = false
364  };
365 };
366 template<int NAME, int STATE_T, int OPTIONS, int M, int N>
367 struct isQuaternionType<
368  msf_core::StateVar_T<Eigen::Matrix<double, M, N>, NAME, STATE_T, OPTIONS> > {
369  enum {
370  value = false
371  };
372 };
373 template<int NAME, int STATE_T, int OPTIONS>
374 struct isQuaternionType<
375  const msf_core::StateVar_T<Eigen::Quaterniond, NAME, STATE_T, OPTIONS>&> {
376  enum {
377  value = true
378  };
379 };
380 template<int NAME, int STATE_T, int OPTIONS>
381 struct isQuaternionType<
382  msf_core::StateVar_T<Eigen::Quaterniond, NAME, STATE_T, OPTIONS> > {
383  enum {
384  value = true
385  };
386 };
387 template<>
388 struct isQuaternionType<const mpl_::void_&> {
389  enum {
390  value = false
391  };
392 };
393 template<>
394 struct isQuaternionType<mpl_::void_> {
395  enum {
396  value = false
397  };
398 };
399 
403 template<typename T>
404 struct getStateIsNonTemporalDrifting;
405 template<typename U, int NAME, int STATE_T, int OPTIONS>
406 struct getStateIsNonTemporalDrifting<
407  const msf_core::StateVar_T<U, NAME, STATE_T, OPTIONS>&> {
408  enum {
410  == static_cast<int>(msf_core::AuxiliaryNonTemporalDrifting)
411  };
412 };
413 template<typename U, int NAME, int STATE_T, int OPTIONS>
414 struct getStateIsNonTemporalDrifting<
415  msf_core::StateVar_T<U, NAME, STATE_T, OPTIONS> > {
416  enum {
418  == static_cast<int>(msf_core::AuxiliaryNonTemporalDrifting)
419  };
420 };
421 template<> struct getStateIsNonTemporalDrifting<const mpl_::void_&> {
422  enum {
423  value = false
424  };
425 };
426 template<> struct getStateIsNonTemporalDrifting<mpl_::void_> {
427  enum {
428  value = false
429  };
430 };
431 
436 template<typename Sequence, template<typename > class Counter, typename First,
437  typename Last, bool T>
438 struct countStatesLinear;
439 template<typename Sequence, template<typename > class Counter, typename First,
440  typename Last>
441 struct countStatesLinear<Sequence, Counter, First, Last, true> {
442  enum { // The end does not add entries.
443  value = 0
444  };
445 };
446 template<typename Sequence, template<typename > class Counter, typename First,
447  typename Last>
448 struct countStatesLinear<Sequence, Counter, First, Last, false> {
449  typedef typename boost::fusion::result_of::next<First>::type Next;
450  typedef typename boost::fusion::result_of::deref<First>::type current_Type;
451  enum { // The length of the current state plus the tail of the list.
452  value = Counter<current_Type>::value
453  + countStatesLinear<Sequence, Counter, Next, Last,
454  SameType<typename msf_tmp::StripConstReference<First>::result_t,
455  typename msf_tmp::StripConstReference<Last>::result_t>::value>::value
456  };
457 };
458 
462 template<typename Sequence, typename First, typename Last, int CurrentIdx,
463  bool T>
464 struct CheckStateIndexing;
465 template<typename Sequence, typename First, typename Last, int CurrentIdx>
466 struct CheckStateIndexing<Sequence, First, Last, CurrentIdx, true> {
467  enum { //no index no name, no indexing errors
468  indexingerrors = 0
469  };
470 };
471 template<typename Sequence, typename First, typename Last, int CurrentIdx>
472 struct CheckStateIndexing<Sequence, First, Last, CurrentIdx, false> {
473  typedef typename boost::fusion::result_of::next<First>::type Next;
474  typedef typename boost::fusion::result_of::deref<First>::type current_Type;
475  enum { // The length of the current state plus the tail of the list.
476  // Only evaluate if not at the end of the list.
477  idxInEnum = boost::mpl::if_c<getEnumStateName<current_Type>::value != -1,
478  // If we're not at the end of the list, use the calculated enum index.
479  boost::mpl::int_<getEnumStateName<current_Type>::value>,
480  //Else use the current index, so the assertion doesn't fail.
481  boost::mpl::int_<CurrentIdx> >::type::value,
482 
483  idxInState = CurrentIdx,
484 
485  indexingerrors = boost::mpl::if_c<idxInEnum == idxInState,
486  // Error here
487  boost::mpl::int_<0>, boost::mpl::int_<1> >::type::value +
488  // And errors of other states
489  CheckStateIndexing<Sequence, Next, Last, CurrentIdx + 1,
490  SameType<typename msf_tmp::StripConstReference<First>::result_t,
491  typename msf_tmp::StripConstReference<Last>::result_t>::value>::indexingerrors
492 
493  };
494  private:
495  // Error the ordering in the enum defining the names of the states is not the
496  // same ordering as in the type vector for the states.
497  static_assert(indexingerrors==0, "Error the ordering in the enum defining the names _ "
498  "of the states is not the same ordering as in the type vector for the states");
499 };
500 //}
501 
505 template<typename TypeList, int INDEX>
506 struct getEnumStateType {
507  typedef typename boost::fusion::result_of::at_c<TypeList, INDEX>::type value;
508 };
509 
513 template<typename TypeList>
514 struct getEnumStateType<TypeList, -1> {
515  typedef mpl_::void_ value;
516 };
517 
521 template<typename Sequence, typename StateVarT,
522  template<typename > class OffsetCalculator, typename First, typename Last,
523  bool TypeFound, int CurrentVal, bool EndOfList>
524 struct ComputeStartIndex;
525 template<typename Sequence, typename StateVarT,
526  template<typename > class OffsetCalculator, typename First, typename Last,
527  int CurrentVal>
528 struct ComputeStartIndex<Sequence, StateVarT, OffsetCalculator, First, Last,
529  false, CurrentVal, true> {
530  enum { // Return error code if end of list reached and type not found.
531  value = -1
532  };
533 };
534 template<typename Sequence, typename StateVarT,
535  template<typename > class OffsetCalculator, typename First, typename Last,
536  bool TypeFound, int CurrentVal>
537 struct ComputeStartIndex<Sequence, StateVarT, OffsetCalculator, First, Last,
538  TypeFound, CurrentVal, false> {
539  enum { // We found the type, do not add additional offset.
540  value = 0
541  };
542 };
543 template<typename Sequence, typename StateVarT,
544  template<typename > class OffsetCalculator, typename First, typename Last,
545  int CurrentVal>
546 struct ComputeStartIndex<Sequence, StateVarT, OffsetCalculator, First, Last,
547  false, CurrentVal, false> {
548  typedef typename boost::fusion::result_of::next<First>::type Next;
549  typedef typename boost::fusion::result_of::deref<First>::type currentType;
550 
551  enum { // The length of the current state plus the tail of the list.
552  value = CurrentVal
553  + ComputeStartIndex<Sequence, StateVarT, OffsetCalculator, Next, Last,
554  SameType<
557  OffsetCalculator<currentType>::value,
558  SameType<typename msf_tmp::StripConstReference<First>::result_t,
559  typename msf_tmp::StripConstReference<Last>::result_t>::value>::value
560  };
561 };
562 //}
563 
567 template<typename Sequence, typename First, typename Last, int CurrentBestIdx,
568  bool foundQuaternion, bool EndOfList>
569 struct FindBestNonTemporalDriftingStateImpl;
570 template<typename Sequence, typename First, typename Last, int CurrentBestIdx,
571  bool foundQuaternion>
572 struct FindBestNonTemporalDriftingStateImpl<Sequence, First, Last,
573  CurrentBestIdx, foundQuaternion, true> {
574  enum { // Set to the current index found, which was initially set to -1.
575  value = CurrentBestIdx
576  };
577 };
578 template<typename Sequence, typename First, typename Last, int CurrentBestIdx,
579  bool foundQuaternion>
580 struct FindBestNonTemporalDriftingStateImpl<Sequence, First, Last,
581  CurrentBestIdx, foundQuaternion, false> {
582  typedef typename boost::fusion::result_of::next<First>::type Next;
583  typedef typename boost::fusion::result_of::deref<First>::type current_Type;
584  enum {
585  idxInState = getEnumStateName<
586  // We assert before calling that the indexing is correct.
588  IsCurrentStateAQuaternion = isQuaternionType<
590  IsCurrentStateNonTemporalDrifting = getStateIsNonTemporalDrifting<
592  isQuaternionAndNonTemporalDrifting = IsCurrentStateAQuaternion == true
593  && IsCurrentStateNonTemporalDrifting == true,
594  isNonTemporalDriftingPositionAndNoQuaternionHasBeenFound = IsCurrentStateNonTemporalDrifting
595  == true && foundQuaternion == false,
596 
597  currBestIdx = boost::mpl::if_c<isQuaternionAndNonTemporalDrifting,
598  //Set to this index if quaternion and nontemporal drifting
599  boost::mpl::int_<idxInState>,
600  boost::mpl::int_<
601  boost::mpl::if_c<
602  isNonTemporalDriftingPositionAndNoQuaternionHasBeenFound,
603  // If we havent found a quaternion yet and this state is non
604  // temporal drifting, we take this one.
605  boost::mpl::int_<idxInState>,
606  // Else we take the current best one.
607  boost::mpl::int_<CurrentBestIdx> >::type::value> >::type::value,
608 
609  value = FindBestNonTemporalDriftingStateImpl<Sequence, Next, Last,
610  currBestIdx, foundQuaternion || isQuaternionAndNonTemporalDrifting,
611  SameType<typename msf_tmp::StripConstReference<First>::result_t,
612  typename msf_tmp::StripConstReference<Last>::result_t>::value>::value
613 
614  };
615 };
616 
617 } // anonymous namespace
618 
623 template<typename Sequence>
625  typedef typename boost::fusion::result_of::begin<Sequence const>::type First;
626  typedef typename boost::fusion::result_of::end<Sequence const>::type Last;
627  private:
628  enum {
629  startindex = 0, // Must not change this.
630  };
631  public:
632  enum {
633  indexingerrors = CheckStateIndexing<Sequence, First, Last, startindex,
636  };
637 };
638 
649 template<typename Sequence>
651  typedef typename boost::fusion::result_of::begin<Sequence const>::type First;
652  typedef typename boost::fusion::result_of::end<Sequence const>::type Last;
653  private:
654  enum {
655  bestindex = -1, // Must not change this.
656  };
658  "indexing of the state vector is not the same as in the enum,"
659  " but this must be the same");
660  public:
661  enum {
662  value = FindBestNonTemporalDriftingStateImpl<Sequence, First, Last,
663  bestindex, false,
666  };
667 };
668 
673 template<typename Sequence, template<typename > class Counter>
674 struct CountStates {
675  typedef typename boost::fusion::result_of::begin<Sequence const>::type First;
676  typedef typename boost::fusion::result_of::end<Sequence const>::type Last;
677  enum {
678  value = countStatesLinear<Sequence, Counter, First, Last,
681  // will be zero, if no indexing errors, otherwise fails compilation.
683  };
684 };
685 
689 template<typename Sequence, typename StateVarT,
690  template<typename > class Counter>
692  typedef typename boost::fusion::result_of::begin<Sequence const>::type First;
693  typedef typename boost::fusion::result_of::end<Sequence const>::type Last;
694  typedef typename boost::fusion::result_of::deref<First>::type currentType;
695  enum {
696  value = ComputeStartIndex<Sequence, StateVarT, Counter, First, Last,
700  // Will be zero, if no indexing errors, otherwise fails compilation.
702  };
703 };
704 
708 template<typename Sequence, int StateEnum>
710  typedef typename boost::fusion::result_of::begin<Sequence const>::type First;
711  typedef typename boost::fusion::result_of::end<Sequence const>::type Last;
712  typedef typename boost::fusion::result_of::deref<First>::type currentType;
713  enum {
715  typename msf_tmp::getEnumStateType<Sequence, StateEnum>::value,
716  msf_tmp::CorrectionStateLengthForType>::value
717  };
718 };
719 
723 struct resetState {
724  template<int NAME, int N, int STATE_T, int OPTIONS>
726  msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T, OPTIONS>& t) const {
728  OPTIONS> var_T;
729  t.state_.setZero();
730  }
731  template<int NAME, int STATE_T, int OPTIONS>
735  t.state_.setIdentity();
736  }
737 };
738 
743 template<typename stateVarT>
745  copyInitStates(const stateVarT& oldstate)
746  : oldstate_(oldstate) {
747  }
748  template<typename T, int NAME, int STATE_T, int OPTIONS>
750  if (oldstate_.template getStateVar<NAME>().hasResetValue) {
751  // Copy value from old state to new state var.
752  t = oldstate_.template getStateVar<NAME>();
753  }
754  }
755 
756  private:
757  const stateVarT& oldstate_;
758  };
759 
764 template<typename stateVarT>
766  copyNonPropagationStates(const stateVarT& oldstate)
767  : oldstate_(oldstate) {
768  }
769  template<typename T, int NAME, int OPTIONS>
772  // Nothing to do for the states, which have propagation.
773  }
774  template<typename T, int NAME, int STATE_T, int OPTIONS>
776 
777  static_assert(
779  NAME, STATE_T> >::value == false),
780  "The state variable is of pointer type, but this method assumes we can "
781  "copy without dereferencing");
782 
783  static_assert(
785  "copyNonPropagationStates was instantiated for a core state. "
786  "This is an error.");
787  // Copy value from old state to new state var.
788  t = oldstate_.template getStateVar<NAME>();
789  }
790 
791  private:
792  const stateVarT& oldstate_;
793 };
794 
798 template<typename stateList_T>
800  enum {
802  msf_tmp::CorrectionStateLengthForType>::value // N correction states.
803  };
804  typedef Eigen::Matrix<double, nErrorStatesAtCompileTime,
807  : Q_(Q) {
808  }
809  template<typename T, int NAME, int STATE_T, int OPTIONS>
812  enum {
813  startIdxInCorrection = msf_tmp::getStartIndex<stateList_T, var_T,
814  msf_tmp::CorrectionStateLengthForType>::value,
815  sizeInCorrection = var_T::sizeInCorrection_
816  };
817 
818  static_assert(
819  static_cast<int>(var_T::statetype_) !=
820  static_cast<int>(msf_core::CoreStateWithPropagation) &&
821  static_cast<int>(var_T::statetype_) !=
822  static_cast<int>(msf_core::CoreStateWithoutPropagation),
823  "copyQBlocksFromAuxiliaryStatesToQ was instantiated for a core state. "
824  "This is an error.");
825 
826  static_assert(
827  static_cast<int>(sizeInCorrection) ==
828  static_cast<int>(var_T::Q_T::ColsAtCompileTime) &&
829  static_cast<int>(sizeInCorrection) ==
830  static_cast<int>(var_T::Q_T::RowsAtCompileTime),
831  "copyQBlocksFromAuxiliaryStatesToQ size of Matrix Q stored with the stateVar,"
832  "is not the same as the reported dimension in the correction vector");
833 
834  Q_.template block<sizeInCorrection, sizeInCorrection>(startIdxInCorrection,
835  startIdxInCorrection) =
836  t.Q;
837  }
838  template<typename T, int NAME, int OPTIONS>
841  // Nothing to do for the states, which have propagation, because Q
842  // calculation is done in msf_core.
843  }
844  template<typename T, int NAME, int OPTIONS>
847  OPTIONS>& UNUSEDPARAM(t)) const {
848  // Nothing to do for the states, which have propagation, because Q
849  // calculation is done in msf_core.
850  }
851  private:
852  Q_T& Q_;
853 };
854 
858 template<typename T, typename stateList_T>
859 struct correctState {
860  correctState(T& correction)
861  : data_(correction) {
862  }
863  template<int NAME, int N, int STATE_T, int OPTIONS>
865  msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T, OPTIONS>& t) const {
867  OPTIONS> var_T;
868  enum {
869  startIdxInCorrection = msf_tmp::getStartIndex<stateList_T, var_T,
870  msf_tmp::CorrectionStateLengthForType>::value
871  };
872  if (OPTIONS & msf_core::correctionMultiplicative) {
873  t.state_ = t.state_.cwiseProduct(
874  data_.template block<var_T::sizeInCorrection_, 1>(
875  startIdxInCorrection, 0));
876  } else {
877  t.state_ = t.state_
878  + data_.template block<var_T::sizeInCorrection_, 1>(
879  startIdxInCorrection, 0);
880  }
881  }
882  template<int NAME, int STATE_T, int OPTIONS>
886  enum {
887  startIdxInCorrection = msf_tmp::getStartIndex<stateList_T, var_T,
888  msf_tmp::CorrectionStateLengthForType>::value
889  };
890  // Make sure the user does not define bogus options.
891  static_assert(
892  (OPTIONS & msf_core::correctionMultiplicative) == false,
893  "You defined the Quaternion correction to be multiplicative, but this "
894  "is anyway done and not an option");
895 
896  Eigen::Quaternion<double> qbuff_q = quaternionFromSmallAngle(
897  data_.template block<var_T::sizeInCorrection_, 1>(startIdxInCorrection,
898  0));
899  t.state_ = t.state_ * qbuff_q;
900  t.state_.normalize();
901  }
902  private:
903  T& data_;
904 };
905 
909 template<typename T, typename stateList_T>
911  CoreStatetoDoubleArray(T& statearray)
912  : data_(statearray) {
913  }
914  template<int NAME, int N, int STATE_T, int OPTIONS>
916  msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T, OPTIONS>& t) const {
918  OPTIONS> var_T;
919  enum {
920  startIdxInState = msf_tmp::getStartIndex<stateList_T, var_T,
921  // Index of the data in the state vector.
922  msf_tmp::StateLengthForType>::value
923  };
924  static_assert(
925  static_cast<int>(var_T::statetype_) ==
926  static_cast<int>(msf_core::CoreStateWithPropagation) ||
927  static_cast<int>(var_T::statetype_) ==
928  static_cast<int>(msf_core::CoreStateWithoutPropagation),
929  "CoreStatetoDoubleArray: A new statetype was defined, but I don't know "
930  "whether this should be written to the double array for core states");
931  for (int i = 0; i < var_T::sizeInState_; ++i) {
932  data_[startIdxInState + i] = t.state_[i];
933  }
934  }
935  template<int NAME, int STATE_T, int OPTIONS>
939  enum {
940  startIdxInState = msf_tmp::getStartIndex<stateList_T, var_T,
941  // Index of the data in the state vector.
942  msf_tmp::StateLengthForType>::value
943  };
944  static_assert(
945  static_cast<int>(var_T::statetype_) ==
946  static_cast<int>(msf_core::CoreStateWithPropagation) ||
947  static_cast<int>(var_T::statetype_) ==
948  static_cast<int>(msf_core::CoreStateWithoutPropagation),
949  "CoreStatetoDoubleArray: A new statetype was defined, but I don't know "
950  "whether this should be written to the double array for core states");
951  // Copy quaternion values.
952  data_[startIdxInState + 0] = t.state_.w();
953  data_[startIdxInState + 1] = t.state_.x();
954  data_[startIdxInState + 2] = t.state_.y();
955  data_[startIdxInState + 3] = t.state_.z();
956  }
957  template<int NAME, int OPTIONS, int N>
959  msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME,
960  msf_core::Auxiliary, OPTIONS>& UNUSEDPARAM(t)) const {
961  // Don't copy aux states.
962  }
963  template<int NAME, int OPTIONS>
965  msf_core::StateVar_T<Eigen::Quaterniond, NAME, msf_core::Auxiliary,
966  OPTIONS>& UNUSEDPARAM(t)) const {
967  // Don't copy aux states.
968  }
969 
970  template<int NAME, int OPTIONS, int N>
972  msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME,
974  // Don't copy aux states.
975  }
976  template<int NAME, int OPTIONS>
978  msf_core::StateVar_T<Eigen::Quaterniond, NAME,
980  // Don't copy aux states.
981  }
982  private:
983  T& data_;
984 };
985 
990 template<typename T, typename stateList_T>
993  : data_(val) {
994  }
995  template<typename VALUE_T, int NAME, int STATE_T, int OPTIONS>
999  enum {
1000  startIdxInState = msf_tmp::getStartIndex<stateList_T, var_T,
1001  // Index of the data in the correction vector.
1002  msf_tmp::CorrectionStateLengthForType>::value,
1003  lengthInState = var_T::sizeInCorrection_
1004  };
1005  data_.push_back(
1006  typename T::value_type(NAME, startIdxInState, lengthInState));
1007  }
1008  private:
1009  T& data_;
1010 };
1011 
1016 template<typename stateVector_T, int INDEX>
1018  typedef typename msf_tmp::getEnumStateType<stateVector_T, INDEX>::value state_type;
1019  enum {
1021  msf_tmp::StateLengthForType>::value,
1022  };
1023 };
1024 
1029 template<typename stateVector_T, int INDEX>
1031  typedef typename msf_tmp::getEnumStateType<stateVector_T, INDEX>::value state_type;
1032  enum {
1034  msf_tmp::CorrectionStateLengthForType>::value,
1035  };
1036 };
1037 
1041 template<typename STREAM, typename stateList_T>
1043  FullStatetoString(STREAM& data)
1044  : data_(data) {
1045  }
1046  template<int NAME, int N, int STATE_T, int OPTIONS>
1048  msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T, OPTIONS>& t) const {
1049  typedef msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T,
1050  OPTIONS> var_T;
1051  enum {
1052  startIdxInState = msf_tmp::getStartIndex<stateList_T, var_T,
1053  // Index of the data in the state vector.
1054  msf_tmp::StateLengthForType>::value
1055  };
1056  data_ << NAME << " : [" << startIdxInState << "-" << startIdxInState + N - 1
1057  << "]\t : Matrix<" << N << ", 1> : [" << t.state_.transpose()
1058  << "]" << std::endl;
1059  }
1060  template<int NAME, int STATE_T, int OPTIONS>
1064  enum {
1065  startIdxInState = msf_tmp::getStartIndex<stateList_T, var_T,
1066  // Index of the data in the state vector.
1067  msf_tmp::StateLengthForType>::value
1068  };
1069  data_ << NAME << " : [" << startIdxInState << "-" << startIdxInState + 3
1070  << "]\t : Quaternion (w,x,y,z) : " << STREAMQUAT(t.state_) << std::endl;
1071  }
1072  private:
1073  STREAM& data_;
1074 };
1075 
1080 template<typename T, typename stateList_T>
1082  FullStatetoDoubleArray(T& statearray)
1083  : data_(statearray) {
1084  }
1085  template<int NAME, int N, int STATE_T, int OPTIONS>
1087  msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T, OPTIONS>& t) const {
1088  typedef msf_core::StateVar_T<Eigen::Matrix<double, N, 1>, NAME, STATE_T,
1089  OPTIONS> var_T;
1090  enum {
1091  startIdxInState = msf_tmp::getStartIndex<stateList_T, var_T,
1092  // Index of the data in the state vector.
1093  msf_tmp::StateLengthForType>::value
1094  };
1095  for (int i = 0; i < var_T::sizeInState_; ++i) {
1096  data_[startIdxInState + i] = t.state_[i];
1097  }
1098  }
1099  template<int NAME, int STATE_T, int OPTIONS>
1103  enum {
1104  startIdxInState = msf_tmp::getStartIndex<stateList_T, var_T,
1105  // Index of the data in the state vector.
1106  msf_tmp::StateLengthForType>::value
1107  };
1108  // Copy quaternion values.
1109  data_[startIdxInState + 0] = t.state_.w();
1110  data_[startIdxInState + 1] = t.state_.x();
1111  data_[startIdxInState + 2] = t.state_.y();
1112  data_[startIdxInState + 3] = t.state_.z();
1113  }
1114  private:
1115  T& data_;
1116 };
1117 }
1118 
1119 #endif // MSF_TMP_H_