00001
00012 #ifndef ROBOTCONSTANTMOTIONMODEL_HPP_
00013 #define ROBOTCONSTANTMOTIONMODEL_HPP_
00014
00015 #include "rtslam/robotAbstract.hpp"
00016
00022 #define PERT_DETERMINISTIC 0
00023
00024
00025 namespace jafar {
00026 namespace rtslam {
00027
00028
00060 template<unsigned LIN_ORDER, unsigned ANG_ORDER>
00061 class RobotConstantMotionModel: public RobotAbstract {
00062 private:
00063 ublas::range iaPos, iaOriQuat, iaAbsVel, iaAngVel, iaAbsAcc, iaAngAcc, iaAbsJerk, iaAngJerk;
00064 public:
00069 RobotConstantMotionModel(const map_ptr_t & _mapPtr);
00070
00071 ~RobotConstantMotionModel(void) {}
00072
00073 virtual std::string typeName() const {
00074 return "Constant-motion-model of order " + std::string(1,'0'+LIN_ORDER) + "/" + std::string(1,'0'+ANG_ORDER);
00075 }
00076
00077
00091 void move_func(const vec & _x, const vec & _u, const vec & _n, const double _dt, vec & _xnew, mat & _XNEW_x,
00092 mat & _XNEW_pert, unsigned tempSet = 0) const;
00093
00094 void computePertJacobian();
00095
00096 static size_t size() {
00097 return 7+LIN_ORDER*3+ANG_ORDER*3;
00098 }
00099 static size_t size_control() {
00100 return 0;
00101 }
00102 static size_t size_perturbation() {
00103 return 6;
00104 }
00105
00106 virtual size_t mySize() {return size();}
00107 virtual size_t mySize_control() {return size_control();}
00108 virtual size_t mySize_perturbation() {return size_perturbation();}
00109
00110 void setVelocityStd(double velLinStd, double velAngStd)
00111 {
00112 double factor = 1.;
00113 unsigned start = pose.size();
00114 for(size_t j = 0; j < LIN_ORDER; ++j)
00115 {
00116 if (j < LIN_ORDER)
00117 {
00118 for (size_t i = start; i < start + 3; ++i)
00119 state.P(i,i) = velLinStd*velLinStd*factor;
00120 start += 3;
00121 }
00122 if (j < ANG_ORDER)
00123 {
00124 for (size_t i = start; i < start + 3; ++i)
00125 state.P(i,i) = velAngStd*velAngStd*factor;
00126 start += 3;
00127 }
00128 factor *= 100;
00129 }
00130 }
00131
00132 virtual void writeLogHeader(kernel::DataLogger& log) const;
00133 virtual void writeLogData(kernel::DataLogger& log) const;
00134
00135 protected:
00146 template<class Vx, class Vp, class Vq, class Vv, class Vw,
00147 class Vva, class Vwa, class Vvj, class Vwj>
00148 inline void splitState(const Vx x, Vp & p, Vq & q, Vv & v, Vw & w,
00149 Vva & va, Vwa & wa, Vvj & vj, Vwj & wj) const {
00150 switch (LIN_ORDER)
00151 {
00152 case 3: vj = ublas::project(x, iaAbsJerk);
00153 case 2: va = ublas::project(x, iaAbsAcc);
00154 case 1: v = ublas::project(x, iaAbsVel);
00155 case 0: p = ublas::project(x, iaPos);
00156 }
00157 switch (ANG_ORDER)
00158 {
00159 case 3: wj = ublas::project(x, iaAngJerk);
00160 case 2: wa = ublas::project(x, iaAngAcc);
00161 case 1: w = ublas::project(x, iaAngVel);
00162 case 0: q = ublas::project(x, iaOriQuat);
00163 }
00164 }
00165
00166
00177 template<class Vp, class Vq, class Vv, class Vw,
00178 class Vva, class Vwa, class Vvj, class Vwj, class Vx>
00179 inline void unsplitState(const Vp & p, const Vq & q, const Vv & v, const Vw & w,
00180 const Vva & va, const Vwa & wa, const Vvj & vj, const Vwj & wj, Vx & x) const {
00181 switch (LIN_ORDER)
00182 {
00183 case 3: ublas::project(x, iaAbsJerk) = vj;
00184 case 2: ublas::project(x, iaAbsAcc) = va;
00185 case 1: ublas::project(x, iaAbsVel) = v;
00186 case 0: ublas::project(x, iaPos) = p;
00187 }
00188 switch (ANG_ORDER)
00189 {
00190 case 3: ublas::project(x, iaAngJerk) = wj;
00191 case 2: ublas::project(x, iaAngAcc) = wa;
00192 case 1: ublas::project(x, iaAngVel) = w;
00193 case 0: ublas::project(x, iaOriQuat) = q;
00194 }
00195 }
00196
00197
00198
00206 template<class Vu, class V>
00207 inline void splitControl(const Vu & u, V & vi, V & wi) const {
00208 vi = project(u, ublas::range(0, 3));
00209 wi = project(u, ublas::range(3, 6));
00210 }
00211
00212 private:
00213
00214 struct TempVariables
00215 {
00216 mat43 QWDT_wdt;
00217 mat44 QNEW_qwdt;
00218 mat43 QNEW_wdt;
00219 mat44 QNEW_q;
00220 mat44 QNORM_qnew;
00221 };
00222 mutable TempVariables tempvars0, tempvars1;
00223
00224 };
00225
00226 }
00227 }
00228
00229 #endif