00001
00013 #ifndef ROBOTINERTIAL_HPP_
00014 #define ROBOTINERTIAL_HPP_
00015
00016 #include "jmath/jblas.hpp"
00017 #include "boost/shared_ptr.hpp"
00018 #include "rtslam/robotAbstract.hpp"
00019
00029 #define USE_NEW_STATE 1
00030
00034 #define INIT_Q_FROM_G 1
00035
00045 #define ESTIMATE_G_SIZE 0
00046
00050 #define ESTIMATE_BIASES 3
00051
00056 #define CONTROL_DETERMINISTIC 0
00057
00058
00059 #if INIT_Q_FROM_G==0 && ESTIMATE_G_SIZE!=3
00060 #error "Incompatible options INIT_Q_FROM_G and ESTIMATE_BIASES"
00061 #endif
00062
00063 namespace jafar {
00064 namespace rtslam {
00065
00066 class RobotInertial;
00067 typedef boost::shared_ptr<RobotInertial> robinertial_ptr_t;
00068
00069
00105 class RobotInertial: public RobotAbstract {
00106 private:
00107 static int g_size;
00108 double g_norm;
00109 double g_uncert;
00110 jblas::vec3 z_axis;
00111 ublas::range iaPos, iaOriQuat, iaAbsVel, iaBiasA, iaBiasW, iaG;
00112
00113 public:
00114
00115 RobotInertial(const map_ptr_t & _mapPtr);
00116
00117 ~RobotInertial() {
00118 }
00119
00120 virtual std::string typeName() const {
00121 return "Inertial";
00122 }
00123
00149 void move_func(const vec & _x, const vec & _u, const vec & _n, double _dt, vec & _xnew,
00150 mat & _XNEW_x, mat & _XNEW_pert, unsigned tempSet = 0) const;
00155 void init_func(const vec & _x, const vec & _u, const vec & _U, vec & _xnew);
00156
00157 virtual void move_func() {
00158 vec x = state.x();
00159 vec n = perturbation.x();
00160 vec xnew;
00161 move_func(x, control, n, dt_or_dx, x, XNEW_x, XNEW_pert);
00162 state.x() = xnew;
00163 }
00164
00165 static size_t size() {
00166 return 10
00167 #if ESTIMATE_BIASES&1
00168 +3
00169 #endif
00170 #if ESTIMATE_BIASES&2
00171 +3
00172 #endif
00173 +g_size;
00174 }
00175
00176 static size_t size_control() {
00177 return 6;
00178 }
00179
00180 static size_t size_perturbation() {
00181 return 6
00182 #if ESTIMATE_BIASES // perturbation is 12 even if only ab or ww is estimated, for simplification purpose
00183 +6
00184 #endif
00185 ;
00186 }
00187
00188 virtual size_t mySize() {return size();}
00189 virtual size_t mySize_control() {return size_control();}
00190 virtual size_t mySize_perturbation() {return size_perturbation();}
00191
00192
00193 void setInitialStd(double velLinStd, double aBiasStd, double wBiasStd, double gravStd){
00194 for (size_t i = iaAbsVel.start(); i < iaAbsVel.start()+iaAbsVel.size(); i++){
00195 state.P(i,i) = velLinStd*velLinStd;
00196 }
00197 #if ESTIMATE_BIASES&1
00198 for (size_t i = iaBiasA.start(); i < iaBiasA.start()+iaBiasA.size(); i++){
00199 state.P(i,i) = aBiasStd*aBiasStd;
00200 }
00201 #endif
00202 #if ESTIMATE_BIASES&2
00203 for (size_t i = iaBiasW.start(); i < iaBiasW.start()+iaBiasW.size(); i++){
00204 state.P(i,i) = wBiasStd*wBiasStd;
00205 }
00206 #endif
00207 if (g_size != 0)
00208 for (size_t i = iaG.start(); i < iaG.start()+iaG.size(); i++){
00209 #if !INIT_Q_FROM_G
00210 if (gravStd < 3) { gravStd = 6.0; std::cout << "Warning: gravity must be free to move, changing stdev to 6.0" << std::endl; }
00211 #endif
00212 state.P(i,i) = gravStd*gravStd;
00213 }
00214 else
00215 g_uncert = gravStd;
00216 }
00217
00218 void setInitialParams(double gNorm)
00219 {
00220 g_norm = gNorm;
00221 }
00222
00223 virtual void writeLogHeader(kernel::DataLogger& log) const;
00224 virtual void writeLogData(kernel::DataLogger& log) const;
00225
00226 protected:
00238 template<class Vx, class Vp, class Vq, class Vv, class Vab, class Vwb, class Vg>
00239 inline void splitState(const Vx & x, Vp & p, Vq & q, Vv & v, Vab & ab, Vwb & wb, Vg & g) const {
00240 p = ublas::project(x, iaPos);
00241 q = ublas::project(x, iaOriQuat);
00242 v = ublas::project(x, iaAbsVel);
00243 #if ESTIMATE_BIASES&1
00244 ab = ublas::project(x, iaBiasA);
00245 #else
00246 ab.clear();
00247 #endif
00248 #if ESTIMATE_BIASES&2
00249 wb = ublas::project(x, iaBiasW);
00250 #else
00251 wb.clear();
00252 #endif
00253 if (g_size != 0)
00254 g = ublas::project(x, iaG);
00255 else
00256 { g.resize(1); g(0) = -g_norm; }
00257 }
00258
00259
00271 template<class Vp, class Vq, class Vv, class Vab, class Vwb, class Vg, class Vx>
00272 inline void unsplitState(const Vp & p, const Vq & q, const Vv & v, const Vab & ab, const Vwb & wb, const Vg & g, Vx & x) const {
00273 ublas::project(x, iaPos) = p;
00274 ublas::project(x, iaOriQuat) = q;
00275 ublas::project(x, iaAbsVel) = v;
00276 #if ESTIMATE_BIASES&1
00277 ublas::project(x, iaBiasA) = ab;
00278 #endif
00279 #if ESTIMATE_BIASES&2
00280 ublas::project(x, iaBiasW) = wb;
00281 #endif
00282 if (g_size != 0)
00283 ublas::project(x, iaG) = g;
00284 }
00285
00286
00296 template<class Vu, class V>
00297 inline void splitControl(const Vu & u, V & am, V & wm) const {
00298 am = project(u, ublas::range(0, 3));
00299 wm = project(u, ublas::range(3, 6));
00300 }
00301
00311 template<class Vn, class V>
00312 inline void splitPert(const Vn & n, V & an, V & wn, V & ar, V & wr) const {
00313 an = project(n, ublas::range(0, 3));
00314 wn = project(n, ublas::range(3, 6));
00315 #if ESTIMATE_BIASES&1
00316 ar = project(n, ublas::range(6, 9));
00317 #else
00318 ar.clear();
00319 #endif
00320 #if ESTIMATE_BIASES&2
00321 wr = project(n, ublas::range(9, 12));
00322 #else
00323 wr.clear();
00324 #endif
00325 }
00326
00327 vec e_from_g(const vec3 & _g);
00328
00329 private:
00330
00331 struct TempVariables
00332 {
00333 mat33 Idt;
00334 mat33 Rdt;
00335 mat44 QN_q;
00336 mat44 QN_qwdt;
00337 mat44 QN_w;
00338 mat43 QWDT_w;
00339 mat34 VNEW_q;
00340 mat44 QNEW_qn;
00341 mat43 QNEW_w;
00342 };
00343 mutable TempVariables tempvars0, tempvars1;
00344
00345 };
00346
00347 }
00348 }
00349
00350 #endif