odometry
MotionModel.hpp
Go to the documentation of this file.
1 
26 #ifndef ODOMETRY_MOTION_MODEL_HPP
27 #define ODOMETRY_MOTION_MODEL_HPP
28 
29 #include <iostream>
30 #include <vector>
31 #include <boost/shared_ptr.hpp>
32 #include <base-logging/Logging.hpp>
33 #include <Eigen/Geometry>
34 #include <Eigen/Core>
35 #include <Eigen/Dense>
36 #include <Eigen/Cholesky>
37 #include "KinematicModel.hpp"
40 //#define DEBUG_PRINTS_ODOMETRY_MOTION_MODEL 1 //TO-DO: Remove this. Only for testing (master branch) purpose
41 
42 namespace odometry
43 {
48  {
50  unsigned int number;
51 
54  int contactId;
55 
57  : number(1), contactId(0) {}
58  };
59 
92  template <typename _Scalar, int _RobotTrees, int _RobotJointDoF, int _SlipDoF, int _ContactDoF>
94  {
95  public:
96  static const unsigned int MAX_CHAIN_DOF = _RobotJointDoF+_SlipDoF+_ContactDoF;
97 
99  static const unsigned int MODEL_DOF = _RobotJointDoF+_RobotTrees*(_SlipDoF+_ContactDoF);
100 
102  static const int NO_CONTACT = -1;
103 
104  public:
106  typedef boost::shared_ptr< KinematicModel <_Scalar, _RobotTrees, _RobotJointDoF, _SlipDoF, _ContactDoF> > kinematics_ptr;
107 
116  {
117  LOWEST_POINT = 0,
118  COMBINATORICS = 1
119  };
120 
122  kinematics_ptr robotModel;
123  std::vector<Eigen::Affine3d> fkRobot;
124  std::vector<base::Matrix6d> fkCov;
125  std::vector<TreeContactPoint> contactPoints;
127  protected:
128 
129  /* This function is deprecated
130  bool contactPointComparison(Eigen::Affine3d fkRobot1, Eigen::Affine3d fkRobot2)
131  {
132  return fkRobot1.translation()[2] < fkRobot2.translation()[2];
133  }*/
134 
144  {
145  register int j = 0;
146 
148  for (std::vector<TreeContactPoint>::iterator it = contactPoints.begin() ; it != contactPoints.end(); it++)
149  {
151  if ((*it).number > 1)
152  {
153  double zdistance = 0.00;
154  for (register unsigned int i=0; i<(*it).number; ++i)
155  {
156  if (zdistance > fkRobot[j+i].translation()[2])
157  {
158  zdistance = fkRobot[j+i].translation()[2];
159  (*it).contactId = i;
160  }
161  }
162  }
163  else if ((*it).number == 1)
164  {
165  contactPoints[j].contactId = 0;
166  }
167  else
168  {
169  contactPoints[j].contactId = NO_CONTACT;
170  }
171 
172  j = j+(*it).number;
173  }
174 
175  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
176  std::cout<<"[MOTION_MODEL] Selected Points in Contact:";
177  for (std::vector<TreeContactPoint>::iterator it = contactPoints.begin() ; it != contactPoints.end(); it++)
178  {
179  std::cout<<" "<<(*it).contactId;
180  }
181  std::cout<<"\n";
182  #endif
183 
184 
185  return;
186  }
187 
198  {
199  return;
200  }
201 
208  {
209 
211  if (method == LOWEST_POINT)
212  {
213  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
214  std::cout<< "[MOTION_MODEL SelectPoints] Lowest Points method\n";
215  #endif
216  this->lowestPointInContact();
217  }
218  else if (method == COMBINATORICS)
219  {
220  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
221  std::cout<< "[MOTION_MODEL SelectPoints] Combinatorics Points method\n";
222  #endif
223 
224  this->combinatoricsPointInContact();
225  }
226 
227  return;
228  }
229 
252  inline void navEquations(const Eigen::Matrix <_Scalar, 6, 1> &cartesianVelocities,
253  const Eigen::Matrix <_Scalar, MODEL_DOF, 1> &modelVelocities,
254  const Eigen::Matrix <_Scalar, 6*_RobotTrees, MODEL_DOF> &J,
255  const Eigen::Matrix <_Scalar, 6, 6> &cartesianVelCov,
256  const Eigen::Matrix <_Scalar, MODEL_DOF, MODEL_DOF> &modelVelCov,
257  Eigen::Matrix <_Scalar, 6*_RobotTrees, 3+_RobotTrees+(_RobotTrees*_ContactDoF)> &unknownA,
258  Eigen::Matrix <_Scalar, 3+_RobotTrees+(_RobotTrees*_ContactDoF), 1> &unknownx,
259  Eigen::Matrix <_Scalar, 6*_RobotTrees, 3+_RobotJointDoF> &knownB,
260  Eigen::Matrix <_Scalar, 3+_RobotJointDoF, 1> &knowny,
261  Eigen::Matrix <_Scalar, 6*_RobotTrees, 6*_RobotTrees> &Weight)
262  {
263  Eigen::Matrix<_Scalar, 6*_RobotTrees, 6> spareI;
264 
265  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
266  std::cout<<"[MOTION_MODEL] navEquations\n";
267  #endif
268 
270  for (register int i=0; i<_RobotTrees; ++i)
271  spareI.template block<6, 6>(i*6, 0) = Eigen::Matrix <_Scalar, 6, 6>::Identity();
272 
274  unknownA.template block<6*_RobotTrees, 3> (0,0) = spareI.template block<6*_RobotTrees, 3> (0,0);//Linear Velocities
275 
277  unknownx.template block<3, 1> (0,0) = cartesianVelocities.template block<3, 1> (0,0);
278 
280  for (register int i=0; i<_RobotTrees; ++i)
281  {
282  unknownA.col(3+i) = -J.col(_RobotJointDoF+(_SlipDoF*(i+1)-1));
283  unknownx[3+i] = modelVelocities[_RobotJointDoF+(_SlipDoF*(i+1)-1)];
284  }
285 
287  for (register int i=0; i<(_RobotTrees*_ContactDoF); ++i)
288  {
289  unknownA.col(3+_RobotTrees+i) = -J.col(_RobotJointDoF+(_RobotTrees*_SlipDoF)+i);
290  unknownx[3+_RobotTrees+i] = modelVelocities[_RobotJointDoF+(_RobotTrees*_SlipDoF)+i];
291  }
292 
294  knownB.template block< (6* _RobotTrees), 3> (0,0) = -spareI.template block<6*_RobotTrees, 3> (0,3); //Angular velocities
295  knownB.template block< (6* _RobotTrees), _RobotJointDoF> (0,3) = J.template block<6*_RobotTrees, _RobotJointDoF> (0,0);
296 
298  knowny.template block<3, 1> (0,0) = cartesianVelocities.template block<3, 1> (3,0);
299  knowny.template block<_RobotJointDoF, 1> (3,0) = modelVelocities.template block<_RobotJointDoF, 1> (0,0);
300 
301  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
302  std::cout<< "[MOTION_MODEL] spareI is of size "<<spareI.rows()<<"x"<<spareI.cols()<<"\n";
303  std::cout<< "[MOTION_MODEL] The spareI matrix:\n" << spareI << std::endl;
304  std::cout<< "[MOTION_MODEL] unknownA is of size "<<unknownA.rows()<<"x"<<unknownA.cols()<<"\n";
305  std::cout<< "[MOTION_MODEL] The unknownA matrix:\n" << unknownA << std::endl;
306  std::cout<< "[MOTION_MODEL] knownB is of size "<<knownB.rows()<<"x"<<knownB.cols()<<"\n";
307  std::cout<< "[MOTION_MODEL] The knownB matrix:\n" << knownB << std::endl;
308  std::cout<< "[MOTION_MODEL] Weight is of size "<<Weight.rows()<<"x"<<Weight.cols()<<"\n";
309  std::cout<< "[MOTION_MODEL] The Weight matrix:\n" << Weight << std::endl;
310  #endif
311 
312  return;
313  }
314 
337  inline void navEquationsNoAngVelo(const Eigen::Matrix <_Scalar, 6, 1> &cartesianVelocities,
338  const Eigen::Matrix <_Scalar, MODEL_DOF, 1> &modelVelocities,
339  const Eigen::Matrix <_Scalar, 6*_RobotTrees, MODEL_DOF> &J,
340  const Eigen::Matrix <_Scalar, 6, 6> &cartesianVelCov,
341  const Eigen::Matrix <_Scalar, MODEL_DOF, MODEL_DOF> &modelVelCov,
342  Eigen::Matrix <_Scalar, 6*_RobotTrees, 6+_RobotTrees+(_RobotTrees*_ContactDoF)> &unknownA,
343  Eigen::Matrix <_Scalar, 6+_RobotTrees+(_RobotTrees*_ContactDoF), 1> &unknownx,
344  Eigen::Matrix <_Scalar, 6*_RobotTrees, _RobotJointDoF> &knownB,
345  Eigen::Matrix <_Scalar, _RobotJointDoF, 1> &knowny,
346  Eigen::Matrix <_Scalar, 6*_RobotTrees, 6*_RobotTrees> &Weight)
347  {
348  Eigen::Matrix<_Scalar, 6*_RobotTrees, 6> spareI;
349 
350  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
351  std::cout<<"[MOTION_MODEL] navEquations\n";
352  #endif
353 
355  for (register int i=0; i<_RobotTrees; ++i)
356  spareI.template block<6, 6>(i*6, 0) = Eigen::Matrix <_Scalar, 6, 6>::Identity();
357 
359  unknownA.template block<6*_RobotTrees, 6> (0,0) = spareI;//Linear and Angular Velocities
360 
362  unknownx.template block<6, 1> (0,0) = cartesianVelocities;
363 
365  for (register int i=0; i<_RobotTrees; ++i)
366  {
367  unknownA.col(6+i) = -J.col(_RobotJointDoF+(_SlipDoF*(i+1)-1));
368  unknownx[6+i] = modelVelocities[_RobotJointDoF+(_SlipDoF*(i+1)-1)];
369  }
370 
372  for (register int i=0; i<(_RobotTrees*_ContactDoF); ++i)
373  {
374  unknownA.col(6+_RobotTrees+i) = -J.col(_RobotJointDoF+(_RobotTrees*_SlipDoF)+i);
375  unknownx[6+_RobotTrees+i] = modelVelocities[_RobotJointDoF+(_RobotTrees*_SlipDoF)+i];
376  }
377 
379  knownB.template block< (6*_RobotTrees), _RobotJointDoF> (0,0) = J.template block<6*_RobotTrees, _RobotJointDoF> (0,0);
380 
382  knowny.template block<_RobotJointDoF, 1> (0,0) = modelVelocities.template block<_RobotJointDoF, 1> (0,0);
383 
384  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
385  std::cout<< "[MOTION_MODEL] spareI is of size "<<spareI.rows()<<"x"<<spareI.cols()<<"\n";
386  std::cout<< "[MOTION_MODEL] The spareI matrix:\n" << spareI << std::endl;
387  std::cout<< "[MOTION_MODEL] unknownA is of size "<<unknownA.rows()<<"x"<<unknownA.cols()<<"\n";
388  std::cout<< "[MOTION_MODEL] The unknownA matrix:\n" << unknownA << std::endl;
389  std::cout<< "[MOTION_MODEL] knownB is of size "<<knownB.rows()<<"x"<<knownB.cols()<<"\n";
390  std::cout<< "[MOTION_MODEL] The knownB matrix:\n" << knownB << std::endl;
391  std::cout<< "[MOTION_MODEL] Weight is of size "<<Weight.rows()<<"x"<<Weight.cols()<<"\n";
392  std::cout<< "[MOTION_MODEL] The Weight matrix:\n" << Weight << std::endl;
393  #endif
394 
395  return;
396  }
397  public:
398 
402  {
403  }
404 
414  MotionModel(bool &status, MotionModel::methodContactPoint method, kinematics_ptr robotModel)
415  {
416  std::vector<unsigned int> numberContactPoints (_RobotTrees, 0);
417 
419  contactPoints.resize (_RobotTrees);
420 
422  this->robotModel = robotModel;
423  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
424  std::cout<<"[MOTION_MODEL] Constructor\n";
425  #endif
426 
428  robotModel->contactPointsPerTree(numberContactPoints);
429 
431  this->contactSelection = method;
432 
433  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
434  std::cout<<"[MOTION_MODEL] Get number of trees "<<robotModel->getNumberOfTrees()<<"\n";
435  #endif
436 
437  if ((robotModel->getNumberOfTrees() == static_cast<int>(numberContactPoints.size())) &&(numberContactPoints.size() == _RobotTrees))
438  {
440  for (register unsigned int i=0; i<numberContactPoints.size(); ++i)
441  {
442  contactPoints[i].number = numberContactPoints[i];
443  contactPoints[i].contactId = 0;
444  }
445 
447  LOG_INFO("[MOTION_MODEL] Created Motion Model using %s Robot Kinematics implementation\n", this->robotModel->name().c_str());
448  LOG_INFO("[MOTION_MODEL] %s has %d independent kinematic trees.\n", this->robotModel->name().c_str(), this->robotModel->getNumberOfTrees());
449  status = true;
450  }
451  else
452  {
453  LOG_ERROR("[MOTION_MODEL] Malfunction of the MotionModel. WRONG number of template parameters\n");
454  status = false;
455  }
456 
457  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
458  std::cout<<"[MOTION_MODEL] contactPoints contains: ";
459  for (std::vector<TreeContactPoint>::iterator it = contactPoints.begin() ; it != contactPoints.end(); it++)
460  {
461  std::cout<<" number: "<<(*it).number<<" contactId: "<<(*it).contactId;
462  }
463 
464  std::cout<<"\n[MOTION_MODEL] **** END ****\n";
465  #endif
466 
467  return;
468  }
469 
473  {
474  }
475 
482  void updateKinematics (const Eigen::Matrix <_Scalar, MODEL_DOF, 1> &modelPositions)
483  {
484  register int i=0;
485  std::vector<_Scalar> vectorPositions(MODEL_DOF, 0);
486  std::vector<int> contactId (_RobotTrees, 0);
487 
489  Eigen::Map <Eigen::Matrix <_Scalar, MODEL_DOF, 1> > (&(vectorPositions[0]), MODEL_DOF) = modelPositions;
490 
492  robotModel->fkSolver(vectorPositions, fkRobot, fkCov);
493 
495  this->selectPointsInContact (this->contactSelection);
496 
498  for (std::vector<TreeContactPoint>::iterator it = contactPoints.begin() ; it != contactPoints.end(); it++)
499  {
500  contactId[i] = (*it).contactId;
501  i++;
502  }
503  robotModel->setPointsInContact(contactId);
504 
505  return;
506  }
507 
508 
514  inline virtual void getKinematics (std::vector<Eigen::Affine3d> &currentFkRobot, std::vector<base::Matrix6d> &currentFkCov)
515  {
516  currentFkRobot = this->fkRobot;
517  currentFkCov = this->fkCov;
518 
519  return;
520  }
521 
527  virtual std::vector< int > getPointsInContact ()
528  {
529  register int i=0;
530  std::vector<int> contactId (_RobotTrees, 0);
531 
532  for (std::vector<TreeContactPoint>::iterator it = contactPoints.begin() ; it != contactPoints.end(); it++)
533  {
534  contactId[i] = (*it).contactId;
535  i++;
536  }
537 
538  return contactId;
539  }
540 
541 
559  virtual double navSolver(const Eigen::Matrix <_Scalar, MODEL_DOF, 1> &modelPositions,
560  Eigen::Matrix <_Scalar, 6, 1> &cartesianVelocities,
561  Eigen::Matrix <_Scalar, MODEL_DOF, 1> &modelVelocities,
562  Eigen::Matrix <_Scalar, 6, 6> &cartesianVelCov,
563  Eigen::Matrix <_Scalar, MODEL_DOF, MODEL_DOF> &modelVelCov,
564  Eigen::Matrix <_Scalar, 6*_RobotTrees, 6*_RobotTrees> Weight)
565  {
566  double normalizedError = std::numeric_limits<double>::quiet_NaN(); //solution error of the Least-Squares
567  std::vector<_Scalar> vectorPositions(MODEL_DOF, 0); // model positions in std_vector form
568  Eigen::Matrix <_Scalar, 6*_RobotTrees, MODEL_DOF> J; // Robot Jacobian
569  Eigen::Matrix <_Scalar, 6*_RobotTrees, 3+_RobotTrees+(_RobotTrees*_ContactDoF)> unknownA; // Nav non-sensed values matrix
570  Eigen::Matrix <_Scalar, 3+_RobotTrees+(_RobotTrees*_ContactDoF), 1> unknownx; // Nav non-sensed values vector
571  Eigen::Matrix <_Scalar, 6*_RobotTrees, 3+_RobotJointDoF> knownB; // Nav sensed values matrix
572  Eigen::Matrix <_Scalar, 3+_RobotJointDoF, 1> knowny; // Nav sensed values vector
573 
575  unknownA.setZero(); unknownx.setZero();
576  knownB.setZero(); knowny.setZero();
577 
578  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
579  std::cout << "[MOTION_MODEL] cartesianVelocities is of size "<<cartesianVelocities.rows()<<"x"<<cartesianVelocities.cols()<<"\n";
580  std::cout << "[MOTION_MODEL] cartesianVelocities is \n" << cartesianVelocities<< std::endl;
581 
582  std::cout << "[MOTION_MODEL] modelVelocities is of size "<<modelVelocities.rows()<<"x"<<modelVelocities.cols()<<"\n";
583  std::cout << "[MOTION_MODEL] modelVelocities is \n" << modelVelocities<< std::endl;
584  #endif
585 
587  Eigen::Map <Eigen::Matrix <_Scalar, MODEL_DOF, 1> > (&(vectorPositions[0]), MODEL_DOF) = modelPositions;
588 
590  J = robotModel->jacobianSolver (vectorPositions);
591 
592  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
593  std::cout<< "[MOTION_MODEL] J is of size "<<J.rows()<<"x"<<J.cols()<<"\n";
594  std::cout<< "[MOTION_MODEL] The J matrix \n" << J << std::endl;
595  #endif
596 
598  this->navEquations (cartesianVelocities, modelVelocities, J,
599  cartesianVelCov, modelVelCov, unknownA, unknownx, knownB, knowny, Weight);
600 
602  //Eigen::Matrix <_Scalar,3+_RobotTrees+(_RobotTrees*_ContactDoF), 3+_RobotTrees+(_RobotTrees*_ContactDoF)> pseudoInvUnknownA;
603  Eigen::Matrix <_Scalar, 6*_RobotTrees, 1> knownb = knownB*knowny;
604 
605  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
606 
607  typedef Eigen::Matrix <_Scalar, 6*_RobotTrees, 3+_RobotTrees+(_RobotTrees*_ContactDoF)> matrixAType;
608  typedef Eigen::Matrix <_Scalar, 6*_RobotTrees, 3+_RobotJointDoF> matrixBType;
609  typedef Eigen::Matrix <_Scalar, 6*_RobotTrees, 3+_RobotTrees+(_RobotTrees*_ContactDoF)+1> matrixConjType; // columns are columns of A + 1
610 
611  matrixConjType Conj;
612 
613  Eigen::FullPivLU<matrixAType> lu_decompA(unknownA);
614  std::cout << "[MOTION_MODEL] The rank of A is " << lu_decompA.rank() << std::endl;
615 
616  Eigen::FullPivLU<matrixBType> lu_decompB(knownB);
617  std::cout << "[MOTION_MODEL] The rank of B is " << lu_decompB.rank() << std::endl;
618 
619  Conj.template block<6*_RobotTrees,3+_RobotTrees+(_RobotTrees*_ContactDoF)>(0,0) = unknownA;
620  Conj.template block<6*_RobotTrees, 1>(0,3+_RobotTrees+(_RobotTrees*_ContactDoF)) = knownb;
621  Eigen::FullPivLU<matrixConjType> lu_decompConj(Conj);
622  std::cout << "[MOTION_MODEL] The rank of A|B*y is " << lu_decompConj.rank() << std::endl;
623  std::cout << "[MOTION_MODEL] Pseudoinverse of A\n" << (unknownA.transpose() * Weight * unknownA).inverse() << std::endl;
624  /*******************/
625  #endif
626 
627  unknownx = (unknownA.transpose() * Weight * unknownA).ldlt().solve(unknownA.transpose() * Weight * knownb);
628 
630  Eigen::Matrix<double, 1,1> squaredError = (((unknownA*unknownx - knownb).transpose() * Weight * (unknownA*unknownx - knownb)));
631  if (knownb.norm() != 0.00)
632  normalizedError = sqrt(squaredError[0]) / knownb.norm();
633 
634 
636  Eigen::Matrix <_Scalar, 6*_RobotTrees, 6*_RobotTrees> errorCov = (unknownA*unknownx - knownb).asDiagonal(); errorCov *= errorCov;// L-S error covariance
637  Eigen::Matrix <_Scalar, 3+_RobotTrees+(_RobotTrees*_ContactDoF), 3+_RobotTrees+(_RobotTrees*_ContactDoF)> uncertaintyCov; // noise cov
638  uncertaintyCov = (unknownA.transpose() * errorCov.inverse() * unknownA).inverse(); // Observer
639  uncertaintyCov = 0.5*(uncertaintyCov + uncertaintyCov.transpose());// Guarantee symmetry
640 
642  cartesianVelocities.template block<3, 1>(0,0) = unknownx.template block<3, 1>(0,0); // Linear velocities
643  cartesianVelCov.template block<3, 3> (0,0) = uncertaintyCov.template block<3,3>(0,0);//Linear Velocities noise
644 
646  if (cartesianVelCov.template block<3, 3> (3,3) == Eigen::Matrix3d::Zero())
647  {
649  for (register size_t i=0; i<_RobotTrees; ++i)
650  {
651  cartesianVelCov.template block<3, 3> (3,3) += Weight.template block<3,3> (3+(6*i), 3+(6*i)) * errorCov.template block<3,3> (3+(6*i),3+(6*i));//Angular Velocities noise
652  }
653  }
654 
656  for (register int i=0; i<_RobotTrees; ++i)
657  {
658  modelVelocities[_RobotJointDoF+(_SlipDoF*(i+1)-1)] = unknownx[3+i];
659  modelVelCov.col(_RobotJointDoF+(_SlipDoF*(i+1)-1))[_RobotJointDoF+(_SlipDoF*(i+1)-1)] = uncertaintyCov.col(3+i)[3+i];//pseudoInvUnknownA.col(3+i)[3+i]; For the time being set the error to the error in the estimation
660  }
661 
663  for (register int i=0; i<(_RobotTrees*_ContactDoF); ++i)
664  {
665  modelVelocities[_RobotJointDoF+(_RobotTrees*_SlipDoF)+i] = unknownx[3+_RobotTrees+i];
666  modelVelCov.col(_RobotJointDoF+(_RobotTrees*_SlipDoF)+i)[_RobotJointDoF+(_RobotTrees*_SlipDoF)+i] = uncertaintyCov.col(3+_RobotTrees+i)[3+_RobotTrees+i];//pseudoInvUnknownA.col(3+_RobotTrees+i)[3+_RobotTrees+i];
667  }
668 
669  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
670  std::cout << "[MOTION_MODEL] L-S solution:\n"<<unknownx<<std::endl;
671 
672  std::cout << "[MOTION_MODEL] RESULT errorCov is of size "<<errorCov.rows()<<"x"<<errorCov.cols()<<"\n";
673  std::cout << "[MOTION_MODEL] RESULT errorCov is \n" << errorCov << std::endl;
674 
675  std::cout << "[MOTION_MODEL] RESULT uncertaintyCov is of size "<<uncertaintyCov.rows()<<"x"<<uncertaintyCov.cols()<<"\n";
676  std::cout << "[MOTION_MODEL] RESULT uncertaintyCov is \n" << uncertaintyCov << std::endl;
677 
678  std::cout << "[MOTION_MODEL] RESULT cartesianVelocities is of size "<<cartesianVelocities.rows()<<"x"<<cartesianVelocities.cols()<<"\n";
679  std::cout << "[MOTION_MODEL] RESULT cartesianVelocities is \n" << cartesianVelocities<< std::endl;
680 
681  std::cout << "[MOTION_MODEL] RESULT cartesianVelCov is of size "<<cartesianVelCov.rows()<<"x"<<cartesianVelCov.cols()<<"\n";
682  std::cout << "[MOTION_MODEL] RESULT cartesianVelCov is \n" << cartesianVelCov<< std::endl;
683 
684  std::cout << "[MOTION_MODEL] RESULT modelVelocities is of size "<<modelVelocities.rows()<<"x"<<modelVelocities.cols()<<"\n";
685  std::cout << "[MOTION_MODEL] RESULT modelVelocities is \n" << modelVelocities<< std::endl;
686 
687  std::cout << "[MOTION_MODEL] RESULT modelVelCov is of size "<<modelVelCov.rows()<<"x"<<modelVelCov.cols()<<"\n";
688  std::cout << "[MOTION_MODEL] RESULT modelVelCov is \n" << modelVelCov<< std::endl;
689 
690  std::cout << "[MOTION_MODEL] RESULT The absolute least squared error is:\n" << squaredError << std::endl;
691  std::cout << "[MOTION_MODEL] RESULT The relative error is:\n" << normalizedError << std::endl;
692  std::cout << "[MOTION_MODEL] RESULT The error vector is \n"<<(unknownA*unknownx - knownb)<<"\n";
693  std::cout << "[MOTION_MODEL] RESULT The error variance is \n"<<errorCov<<"\n";
694  std::cout << "[MOTION_MODEL] RESULT The error variance.inverse() is \n"<<errorCov.inverse()<<"\n";
695  std::cout << "[MOTION_MODEL] RESULT The solution covariance is \n"<<cartesianVelCov<<"\n";
696  #endif
697 
698 
699  return normalizedError;
700  }
701 
719  virtual double navSolverNoAngVelo(const Eigen::Matrix <_Scalar, MODEL_DOF, 1> &modelPositions,
720  Eigen::Matrix <_Scalar, 6, 1> &cartesianVelocities,
721  Eigen::Matrix <_Scalar, MODEL_DOF, 1> &modelVelocities,
722  Eigen::Matrix <_Scalar, 6, 6> &cartesianVelCov,
723  Eigen::Matrix <_Scalar, MODEL_DOF, MODEL_DOF> &modelVelCov,
724  Eigen::Matrix <_Scalar, 6*_RobotTrees, 6*_RobotTrees> Weight)
725  {
726  double normalizedError = std::numeric_limits<double>::quiet_NaN(); //solution error of the Least-Squares
727  std::vector<_Scalar> vectorPositions(MODEL_DOF, 0); // model positions in std_vector form
728  Eigen::Matrix <_Scalar, 6*_RobotTrees, MODEL_DOF> J; // Robot Jacobian
729  Eigen::Matrix <_Scalar, 6*_RobotTrees, 6+_RobotTrees+(_RobotTrees*_ContactDoF)> unknownA; // Nav non-sensed values matrix
730  Eigen::Matrix <_Scalar, 6+_RobotTrees+(_RobotTrees*_ContactDoF), 1> unknownx; // Nav non-sensed values vector
731  Eigen::Matrix <_Scalar, 6*_RobotTrees, _RobotJointDoF> knownB; // Nav sensed values matrix
732  Eigen::Matrix <_Scalar, _RobotJointDoF, 1> knowny; // Nav sensed values vector
733 
735  unknownA.setZero(); unknownx.setZero();
736  knownB.setZero(); knowny.setZero();
737 
738  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
739  std::cout << "[MOTION_MODEL] cartesianVelocities is of size "<<cartesianVelocities.rows()<<"x"<<cartesianVelocities.cols()<<"\n";
740  std::cout << "[MOTION_MODEL] cartesianVelocities is \n" << cartesianVelocities<< std::endl;
741 
742  std::cout << "[MOTION_MODEL] modelVelocities is of size "<<modelVelocities.rows()<<"x"<<modelVelocities.cols()<<"\n";
743  std::cout << "[MOTION_MODEL] modelVelocities is \n" << modelVelocities<< std::endl;
744  #endif
745 
747  Eigen::Map <Eigen::Matrix <_Scalar, MODEL_DOF, 1> > (&(vectorPositions[0]), MODEL_DOF) = modelPositions;
748 
750  J = robotModel->jacobianSolver (vectorPositions);
751 
752  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
753  std::cout<< "[MOTION_MODEL] J is of size "<<J.rows()<<"x"<<J.cols()<<"\n";
754  std::cout<< "[MOTION_MODEL] The J matrix \n" << J << std::endl;
755  #endif
756 
758  this->navEquationsNoAngVelo (cartesianVelocities, modelVelocities, J,
759  cartesianVelCov, modelVelCov, unknownA, unknownx, knownB, knowny, Weight);
760 
762  //Eigen::Matrix <_Scalar,6+_RobotTrees+(_RobotTrees*_ContactDoF), 6+_RobotTrees+(_RobotTrees*_ContactDoF)> pseudoInvUnknownA;
763  Eigen::Matrix <_Scalar, 6*_RobotTrees, 1> knownb = knownB*knowny;
764 
765  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
766 
767  typedef Eigen::Matrix <_Scalar, 6*_RobotTrees, 6+_RobotTrees+(_RobotTrees*_ContactDoF)> matrixAType;
768  typedef Eigen::Matrix <_Scalar, 6*_RobotTrees, _RobotJointDoF> matrixBType;
769  typedef Eigen::Matrix <_Scalar, 6*_RobotTrees, 6+_RobotTrees+(_RobotTrees*_ContactDoF)+1> matrixConjType; // columns are columns of A + 1
770 
771  matrixConjType Conj;
772 
773  Eigen::FullPivLU<matrixAType> lu_decompA(unknownA);
774  std::cout << "[MOTION_MODEL] The rank of A is " << lu_decompA.rank() << std::endl;
775 
776  Eigen::FullPivLU<matrixBType> lu_decompB(knownB);
777  std::cout << "[MOTION_MODEL] The rank of B is " << lu_decompB.rank() << std::endl;
778 
779  Conj.template block<6*_RobotTrees,6+_RobotTrees+(_RobotTrees*_ContactDoF)>(0,0) = unknownA;
780  Conj.template block<6*_RobotTrees, 1>(0,_RobotTrees+(_RobotTrees*_ContactDoF)) = knownb;
781  Eigen::FullPivLU<matrixConjType> lu_decompConj(Conj);
782  std::cout << "[MOTION_MODEL] The rank of A|B*y is " << lu_decompConj.rank() << std::endl;
783  std::cout << "[MOTION_MODEL] Pseudoinverse of A\n" << (unknownA.transpose() * Weight * unknownA).inverse() << std::endl;
784  /*******************/
785  #endif
786 
787  unknownx = (unknownA.transpose() * Weight * unknownA).ldlt().solve(unknownA.transpose() * Weight * knownb);
788 
790  Eigen::Matrix<double, 1,1> squaredError = (((unknownA*unknownx - knownb).transpose() * Weight * (unknownA*unknownx - knownb)));
791  if (knownb.norm() != 0.00)
792  normalizedError = sqrt(squaredError[0]) / knownb.norm();
793 
795  Eigen::Matrix <_Scalar, 6*_RobotTrees, 6*_RobotTrees> errorCov; // L-S error covariance
796  Eigen::Matrix <_Scalar, 6+_RobotTrees+(_RobotTrees*_ContactDoF), 6+_RobotTrees+(_RobotTrees*_ContactDoF)> uncertaintyCov; // noise cov
797  errorCov = 0.6827 * squaredError[0] * Eigen::Matrix <_Scalar, 6*_RobotTrees, 6*_RobotTrees>::Identity();
798  uncertaintyCov = (unknownA.transpose() * errorCov.inverse() * unknownA).inverse();
799 
801  cartesianVelocities.template block<3, 1>(0,0) = unknownx.template block<3, 1>(0,0); // Linear velocities
802  cartesianVelocities.template block<3, 1>(3,0) = unknownx.template block<3, 1>(3,0); // Angular velocities
803  cartesianVelCov = uncertaintyCov.template block<6,6>(0,0);
804 
806  for (register int i=0; i<_RobotTrees; ++i)
807  {
808  modelVelocities[_RobotJointDoF+(_SlipDoF*(i+1)-1)] = unknownx[6+i];
809  modelVelCov.col(_RobotJointDoF+(_SlipDoF*(i+1)-1))[_RobotJointDoF+(_SlipDoF*(i+1)-1)] = uncertaintyCov.col(6+i)[6+i];
810  }
811 
813  for (register int i=0; i<(_RobotTrees*_ContactDoF); ++i)
814  {
815  modelVelocities[_RobotJointDoF+(_RobotTrees*_SlipDoF)+i] = unknownx[6+_RobotTrees+i];
816  modelVelCov.col(_RobotJointDoF+(_RobotTrees*_SlipDoF)+i)[_RobotJointDoF+(_RobotTrees*_SlipDoF)+i] = uncertaintyCov.col(6+_RobotTrees+i)[6+_RobotTrees+i];
817  }
818 
819  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
820  std::cout << "[MOTION_MODEL] L-S solution:\n"<<unknownx<<std::endl;
821 
822  std::cout << "[MOTION_MODEL] cartesianVelocities is of size "<<cartesianVelocities.rows()<<"x"<<cartesianVelocities.cols()<<"\n";
823  std::cout << "[MOTION_MODEL] cartesianVelocities is \n" << cartesianVelocities<< std::endl;
824 
825  std::cout << "[MOTION_MODEL] cartesianVelCov is of size "<<cartesianVelCov.rows()<<"x"<<cartesianVelCov.cols()<<"\n";
826  std::cout << "[MOTION_MODEL] cartesianVelCov is \n" << cartesianVelCov<< std::endl;
827 
828  std::cout << "[MOTION_MODEL] modelVelocities is of size "<<modelVelocities.rows()<<"x"<<modelVelocities.cols()<<"\n";
829  std::cout << "[MOTION_MODEL] modelVelocities is \n" << modelVelocities<< std::endl;
830 
831  std::cout << "[MOTION_MODEL] modelVelCov is of size "<<modelVelCov.rows()<<"x"<<modelVelCov.cols()<<"\n";
832  std::cout << "[MOTION_MODEL] modelVelCov is \n" << modelVelCov<< std::endl;
833 
834  std::cout << "[MOTION_MODEL] The absolute least squared error is:\n" << squaredError << std::endl;
835  std::cout << "[MOTION_MODEL] The relative error is:\n" << normalizedError << std::endl;
836  #endif
837 
838 
839  return normalizedError;
840  }
845  {
846  base::Vector6d s;
847 
848  return s;
849  }
850  };
851 
855  template<typename _Derived>
856  static inline bool isnotnan(const Eigen::MatrixBase<_Derived>& x)
857  {
858  return ((x.array() == x.array())).all();
859  };
860 
861 }
862 
863 #endif //ODOMETRY_MOTION_MODEL_HPP
864 
void navEquationsNoAngVelo(const Eigen::Matrix< _Scalar, 6, 1 > &cartesianVelocities, const Eigen::Matrix< _Scalar, MODEL_DOF, 1 > &modelVelocities, const Eigen::Matrix< _Scalar, 6 *_RobotTrees, MODEL_DOF > &J, const Eigen::Matrix< _Scalar, 6, 6 > &cartesianVelCov, const Eigen::Matrix< _Scalar, MODEL_DOF, MODEL_DOF > &modelVelCov, Eigen::Matrix< _Scalar, 6 *_RobotTrees, 6+_RobotTrees+(_RobotTrees *_ContactDoF)> &unknownA, Eigen::Matrix< _Scalar, 6+_RobotTrees+(_RobotTrees *_ContactDoF), 1 > &unknownx, Eigen::Matrix< _Scalar, 6 *_RobotTrees, _RobotJointDoF > &knownB, Eigen::Matrix< _Scalar, _RobotJointDoF, 1 > &knowny, Eigen::Matrix< _Scalar, 6 *_RobotTrees, 6 *_RobotTrees > &Weight)
Forms the Navigation Equations for the navigation kinematics(angular velocities are unknow variables)...
Definition: MotionModel.hpp:337
std::vector< base::Matrix6d > fkCov
Definition: MotionModel.hpp:124
MotionModel(bool &status, MotionModel::methodContactPoint method, kinematics_ptr robotModel)
Constructor.
Definition: MotionModel.hpp:414
methodContactPoint contactSelection
Definition: MotionModel.hpp:121
TreeContactPoint()
Definition: MotionModel.hpp:56
methodContactPoint
Definition: MotionModel.hpp:115
void selectPointsInContact(MotionModel::methodContactPoint method)
this method computes the point in contact depending on the method.
Definition: MotionModel.hpp:207
int contactId
Definition: MotionModel.hpp:54
void updateKinematics(const Eigen::Matrix< _Scalar, MODEL_DOF, 1 > &modelPositions)
Updates the Kinematic Model of the robot.
Definition: MotionModel.hpp:482
std::vector< Eigen::Affine3d > fkRobot
Definition: MotionModel.hpp:123
virtual std::vector< int > getPointsInContact()
Return the current points in contact.
Definition: MotionModel.hpp:527
virtual void getKinematics(std::vector< Eigen::Affine3d > &currentFkRobot, std::vector< base::Matrix6d > &currentFkCov)
Returns the kinematic of the robot.
Definition: MotionModel.hpp:514
Kinematic Model Abstract class.
virtual base::Vector6d slipSolver(void)
Solver for the Slip equations TO-DO.
Definition: MotionModel.hpp:844
Definition: MotionModel.hpp:47
Eigen::Matrix< double, 6, 1 > Vector6d
Definition: ContactOdometry.hpp:15
Definition: MotionModel.hpp:93
unsigned int number
Definition: MotionModel.hpp:50
MotionModel()
Default constructor.
Definition: MotionModel.hpp:401
void lowestPointInContact()
computes the current set of points in contact choosing the lowest point.
Definition: MotionModel.hpp:143
void navEquations(const Eigen::Matrix< _Scalar, 6, 1 > &cartesianVelocities, const Eigen::Matrix< _Scalar, MODEL_DOF, 1 > &modelVelocities, const Eigen::Matrix< _Scalar, 6 *_RobotTrees, MODEL_DOF > &J, const Eigen::Matrix< _Scalar, 6, 6 > &cartesianVelCov, const Eigen::Matrix< _Scalar, MODEL_DOF, MODEL_DOF > &modelVelCov, Eigen::Matrix< _Scalar, 6 *_RobotTrees, 3+_RobotTrees+(_RobotTrees *_ContactDoF)> &unknownA, Eigen::Matrix< _Scalar, 3+_RobotTrees+(_RobotTrees *_ContactDoF), 1 > &unknownx, Eigen::Matrix< _Scalar, 6 *_RobotTrees, 3+_RobotJointDoF > &knownB, Eigen::Matrix< _Scalar, 3+_RobotJointDoF, 1 > &knowny, Eigen::Matrix< _Scalar, 6 *_RobotTrees, 6 *_RobotTrees > &Weight)
Forms the Navigation Equations for the navigation kinematics.
Definition: MotionModel.hpp:252
void combinatoricsPointInContact()
Computes the points in contact using combinatorics.
Definition: MotionModel.hpp:197
boost::shared_ptr< KinematicModel< _Scalar, _RobotTrees, _RobotJointDoF, _SlipDoF, _ContactDoF > > kinematics_ptr
Definition: MotionModel.hpp:106
std::vector< TreeContactPoint > contactPoints
Definition: MotionModel.hpp:125
Definition: BodyState.cpp:5
kinematics_ptr robotModel
Definition: MotionModel.hpp:122
~MotionModel()
Default destructor.
Definition: MotionModel.hpp:472
virtual double navSolverNoAngVelo(const Eigen::Matrix< _Scalar, MODEL_DOF, 1 > &modelPositions, Eigen::Matrix< _Scalar, 6, 1 > &cartesianVelocities, Eigen::Matrix< _Scalar, MODEL_DOF, 1 > &modelVelocities, Eigen::Matrix< _Scalar, 6, 6 > &cartesianVelCov, Eigen::Matrix< _Scalar, MODEL_DOF, MODEL_DOF > &modelVelCov, Eigen::Matrix< _Scalar, 6 *_RobotTrees, 6 *_RobotTrees > Weight)
Definition: MotionModel.hpp:719
virtual double navSolver(const Eigen::Matrix< _Scalar, MODEL_DOF, 1 > &modelPositions, Eigen::Matrix< _Scalar, 6, 1 > &cartesianVelocities, Eigen::Matrix< _Scalar, MODEL_DOF, 1 > &modelVelocities, Eigen::Matrix< _Scalar, 6, 6 > &cartesianVelCov, Eigen::Matrix< _Scalar, MODEL_DOF, MODEL_DOF > &modelVelCov, Eigen::Matrix< _Scalar, 6 *_RobotTrees, 6 *_RobotTrees > Weight)
Definition: MotionModel.hpp:559