threed_odometry
MotionModel.hpp
Go to the documentation of this file.
1 
30 #ifndef ODOMETRY_MOTION_MODEL_HPP
31 #define ODOMETRY_MOTION_MODEL_HPP
32 
33 #include <iostream>
34 #include <vector>
35 #include <boost/shared_ptr.hpp>
36 #include <base-logging/Logging.hpp>
37 #include <Eigen/Geometry>
38 #include <Eigen/Core>
39 #include <Eigen/Dense>
40 #include <Eigen/Cholesky>
42 //#define DEBUG_PRINTS_ODOMETRY_MOTION_MODEL 1 //TO-DO: Remove this. Only for testing (master branch) purpose
43 
44 namespace threed_odometry
45 {
46 
61  template <typename _Scalar>
63  {
64  protected:
66 
67  public:
68  unsigned int model_dof;
69 
70  protected:
71 
105  inline void navEquations(const Eigen::Matrix <_Scalar, 6, 1> &cartesianVelocities,
106  const Eigen::Matrix <_Scalar, Eigen::Dynamic, 1> &modelVelocities,
107  const Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> &J,
108  Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> &unknownA,
109  Eigen::Matrix <_Scalar, Eigen::Dynamic, 1> &unknownx,
110  Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> &knownB,
111  Eigen::Matrix <_Scalar, Eigen::Dynamic, 1> &knowny,
112  bool known_contact_angles = false)
113  {
114  Eigen::Matrix<_Scalar, Eigen::Dynamic, Eigen::Dynamic> spareI;
115  spareI.resize(6*this->number_chains, 6);
116 
117  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
118  std::cout<<"[MOTION_MODEL] navEquations\n";
119  #endif
120 
122  for (register int i=0; i<this->number_chains; ++i)
123  spareI.block(i*6, 0, 6, 6) = Eigen::Matrix <_Scalar, 6, 6>::Identity();
124 
126  unknownA.block(0, 0, 6*this->number_chains, 3) = spareI.block(0, 0, 6*this->number_chains, 3);//Linear Velocities
127 
129  unknownx.block(0, 0, 3, 1) = cartesianVelocities.block(0, 0, 3, 1);
130 
132  unknownA.block(0, 3, 6*this->number_chains, this->number_chains) = -J.block(0, this->number_robot_joints+this->number_slip_joints-(this->number_chains), 6*this->number_chains, this->number_chains);
133  unknownx.block(3, 0, this->number_chains, 1) = modelVelocities.block(this->number_robot_joints+this->number_slip_joints-(this->number_chains), 0, this->number_chains, 1);
134 
136  if (known_contact_angles == false)
137  {
138  unknownA.block(0, 3+this->number_chains, 6*this->number_chains, this->number_contact_joints) = -J.block(0, this->number_robot_joints+this->number_slip_joints, 6*this->number_chains, this->number_contact_joints);
139  unknownx.block(3+this->number_chains, 0, this->number_contact_joints, 1) = modelVelocities.block(this->number_robot_joints+this->number_slip_joints, 0, this->number_contact_joints, 1);
140  }
141 
143  knownB.block(0, 0, 6*this->number_chains, 3) = -spareI.block(0, 3, 6*this->number_chains, 3); //Angular velocities
144  knownB.block(0, 3, 6*this->number_chains, this->number_robot_joints) = J.block(0, 0, 6*this->number_chains, this->number_robot_joints);//Robot joints
145 
147  knowny.block(0, 0, 3, 1) = cartesianVelocities.template block<3, 1> (3,0); //Angular velocities
148  knowny.block(3, 0, this->number_robot_joints, 1) = modelVelocities.block(0, 0, this->number_robot_joints, 1); //Robot joints
149 
151  if (known_contact_angles == true)
152  {
153  knownB.block(0, 3+this->number_robot_joints, 6*this->number_chains, this->number_contact_joints) = J.block(0, this->number_robot_joints+this->number_slip_joints, 6*this->number_chains, this->number_contact_joints);//Robot joints
154  knowny.block(3+this->number_robot_joints, 0, this->number_contact_joints, 1) = modelVelocities.block(this->number_robot_joints+this->number_slip_joints, 0, this->number_contact_joints, 1);
155  }
156 
157  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
158  std::cout<< "[MOTION_MODEL] spareI is of size "<<spareI.rows()<<"x"<<spareI.cols()<<"\n";
159  std::cout<< "[MOTION_MODEL] The spareI matrix:\n" << spareI << std::endl;
160  std::cout<< "[MOTION_MODEL] unknownA is of size "<<unknownA.rows()<<"x"<<unknownA.cols()<<"\n";
161  std::cout<< "[MOTION_MODEL] The unknownA matrix:\n" << unknownA << std::endl;
162  std::cout<< "[MOTION_MODEL] knownB is of size "<<knownB.rows()<<"x"<<knownB.cols()<<"\n";
163  std::cout<< "[MOTION_MODEL] The knownB matrix:\n" << knownB << std::endl;
164  #endif
165 
166  return;
167  }
168 
169  public:
170 
194  MotionModel (const int _number_chains, const int _number_robot_joints, const int _number_slip_joints, const int _number_contact_joints):
195  number_chains(_number_chains),
196  number_robot_joints(_number_robot_joints),
197  number_slip_joints(_number_slip_joints),
198  number_contact_joints(_number_contact_joints)
199  {
200  this->model_dof = number_robot_joints + number_slip_joints + number_contact_joints;
201 
202  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
203  std::cout<<"[MOTION_MODEL] Constructor. Model DoF:"<<this->model_dof<<"\n";
204  #endif
205 
206  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
207  std::cout<<"\n[MOTION_MODEL] **** END ****\n";
208  #endif
209 
210  return;
211  }
212 
213 
217  {
218  }
219 
241  virtual double navSolver(const Eigen::Matrix <_Scalar, Eigen::Dynamic, 1> &modelPositions,
242  Eigen::Matrix <_Scalar, Eigen::Dynamic, 1> &modelVelocities,
243  const Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> &J,
244  Eigen::Matrix <_Scalar, 6, 1> &cartesianVelocities,
245  Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> &modelVelCov,
246  Eigen::Matrix <_Scalar, 6, 6> &cartesianVelCov,
247  const Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> Weight,
248  bool known_contact_angles = false)
249  {
250  double normalizedError = std::numeric_limits<double>::quiet_NaN(); //solution error of the Least-Squares
251 
252  Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> unknownA; // Nav non-sensed values matrix
253  Eigen::Matrix <_Scalar, Eigen::Dynamic, 1> unknownx; // Nav non-sensed values vector
254  Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> knownB; // Nav sensed values matrix
255  Eigen::Matrix <_Scalar, Eigen::Dynamic, 1> knowny; // Nav sensed values vector
256 
257  if (known_contact_angles == false)
258  {
260  unknownA.resize(6*this->number_chains, 3+this->number_chains+this->number_contact_joints);// position, z-slip and contact angles
261  unknownx.resize(3+this->number_chains+this->number_contact_joints, 1);// position, z-slip and contact angles
262  knownB.resize(6*this->number_chains, 3+this->number_robot_joints);// rotation and robot joints
263  knowny.resize(3+this->number_robot_joints, 1);// rotation and robot joints
264  }
265  else
266  {
268  unknownA.resize(6*this->number_chains, 3+this->number_chains); // position and z-slip
269  unknownx.resize(3+this->number_chains); // position and z-slip
270  knownB.resize(6*this->number_chains, 3+this->number_robot_joints+this->number_contact_joints);// rotation, robot joints and contact angles
271  knowny.resize(3+this->number_robot_joints+this->number_contact_joints, 1);// rotation, robot joints and contact angles
272  }
273 
275  unknownA.setZero(); unknownx.setZero();
276  knownB.setZero(); knowny.setZero();
277 
278  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
279  std::cout << "[MOTION_MODEL] cartesianVelocities is of size "<<cartesianVelocities.rows()<<"x"<<cartesianVelocities.cols()<<"\n";
280  std::cout << "[MOTION_MODEL] cartesianVelocities is \n" << cartesianVelocities<< std::endl;
281 
282  std::cout << "[MOTION_MODEL] modelVelocities is of size "<<modelVelocities.rows()<<"x"<<modelVelocities.cols()<<"\n";
283  std::cout << "[MOTION_MODEL] modelVelocities is \n" << modelVelocities<< std::endl;
284  #endif
285 
287  assert(modelPositions.size() == modelVelocities.size());
288  assert(modelPositions.size() == this->model_dof);
289  assert(modelVelCov.cols() == modelVelCov.rows());
290  assert(modelVelCov.cols() == modelVelocities.size());
291  assert(Weight.cols() == 6*this->number_chains);
292  assert(Weight.rows() == 6*this->number_chains);
293 
294  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
295  std::cout<< "[MOTION_MODEL] Weight is of size "<<Weight.rows()<<"x"<<Weight.cols()<<"\n";
296  std::cout<< "[MOTION_MODEL] The Weight matrix:\n" << Weight << std::endl;
297  std::cout<< "[MOTION_MODEL] J is of size "<<J.rows()<<"x"<<J.cols()<<"\n";
298  std::cout<< "[MOTION_MODEL] The J matrix \n" << J << std::endl;
299  #endif
300 
302  this->navEquations (cartesianVelocities, modelVelocities, J, unknownA, unknownx, knownB, knowny, known_contact_angles);
303 
305  Eigen::Matrix <_Scalar, Eigen::Dynamic, 1> knownb;
306  knownb.resize(6*this->number_chains, 1);
307  knownb = knownB*knowny;
308 
309  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
310  if (known_contact_angles == false)
311  {
313  Eigen::Matrix<_Scalar, Eigen::Dynamic, Eigen::Dynamic> Conj;
314  Conj.resize(6*this->number_chains, 3+this->number_chains+this->number_contact_joints+1);
315 
316  Eigen::FullPivLU<Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> > lu_decompA(unknownA);
317  std::cout << "[MOTION_MODEL] The rank of A is " << lu_decompA.rank() << std::endl;
318 
319  Eigen::FullPivLU<Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> > lu_decompB(knownB);
320  std::cout << "[MOTION_MODEL] The rank of B is " << lu_decompB.rank() << std::endl;
321 
322  Conj.block(0, 0, 6*this->number_chains, 3+this->number_chains+this->number_contact_joints) = unknownA;
323  Conj.block(0, 3+this->number_chains+this->number_contact_joints, 6*this->number_chains, 1) = knownb;
324  Eigen::FullPivLU< Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> > lu_decompConj(Conj);
325  std::cout << "[MOTION_MODEL] The rank of A|B*y is " << lu_decompConj.rank() << std::endl;
326  std::cout << "[MOTION_MODEL] Pseudoinverse of A\n" << (unknownA.transpose() * Weight * unknownA).inverse() << std::endl;
327  }
328  else
329  {
331  Eigen::Matrix<_Scalar, Eigen::Dynamic, Eigen::Dynamic> Conj;
332  Conj.resize(6*this->number_chains, 3+this->number_chains+1);
333 
334  Eigen::FullPivLU<Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> > lu_decompA(unknownA);
335  std::cout << "[MOTION_MODEL] The rank of A is " << lu_decompA.rank() << std::endl;
336 
337  Eigen::FullPivLU<Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> > lu_decompB(knownB);
338  std::cout << "[MOTION_MODEL] The rank of B is " << lu_decompB.rank() << std::endl;
339 
340  Conj.block(0, 0, 6*this->number_chains, 3+this->number_chains) = unknownA;
341  Conj.block(0, 3+this->number_chains, 6*this->number_chains, 1) = knownb;
342  Eigen::FullPivLU< Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> > lu_decompConj(Conj);
343  std::cout << "[MOTION_MODEL] The rank of A|B*y is " << lu_decompConj.rank() << std::endl;
344  std::cout << "[MOTION_MODEL] Pseudoinverse of A\n" << (unknownA.transpose() * Weight * unknownA).inverse() << std::endl;
345 
346 
347  }
348  /*******************/
349  #endif
350 
352  unknownx = (unknownA.transpose() * Weight * unknownA).ldlt().solve(unknownA.transpose() * Weight * knownb);
353 
355  Eigen::Matrix<double, 1,1> squaredError = (((unknownA*unknownx - knownb).transpose() * Weight * (unknownA*unknownx - knownb)));
356  if (knownb.norm() != 0.00)
357  normalizedError = sqrt(squaredError[0]) / knownb.norm();
358 
360  Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> errorCov;
361  errorCov.resize(6*this->number_chains, 6*this->number_chains);
362  errorCov = (unknownA*unknownx - knownb).asDiagonal(); errorCov *= errorCov;// L-S error covariance
363  Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> uncertaintyCov; // noise cov
364 
366  if (known_contact_angles == false)
367  {
368  uncertaintyCov.resize(3+this->number_chains+this->number_contact_joints, 3+this->number_chains+this->number_contact_joints);
369  }
370  else
371  {
372  uncertaintyCov.resize(3+this->number_chains, 3+this->number_chains);
373  }
374 
376  Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> errorCovinverse;
377  errorCovinverse = errorCov.inverse();
378  if (base::isnotnan< Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> >(errorCovinverse))
379  {
380  uncertaintyCov = (unknownA.transpose() * errorCovinverse * unknownA).inverse(); // Observer
381  }
382  else
383  {
384  uncertaintyCov = unknownA.transpose() * errorCov * unknownA; // Observer
385  }
386 
387  uncertaintyCov = 0.5*(uncertaintyCov + uncertaintyCov.transpose());// Guarantee symmetry
388 
390  cartesianVelocities.block(0, 0, 3, 1) = unknownx.block(0, 0, 3, 1); // Linear velocities
391  cartesianVelCov.block(0, 0, 3, 3) = uncertaintyCov.block(0, 0, 3,3);//Linear Velocities noise
392 
394  if (cartesianVelCov.block(3, 3, 3, 3) != cartesianVelCov.block(3, 3, 3, 3))
395  {
396  cartesianVelCov.block(3, 3, 3, 3).setZero();
397 
399  for (register size_t i=0; i<this->number_chains; ++i)
400  {
401  cartesianVelCov.block(3, 3, 3, 3) += Weight.block(3+(6*i), 3+(6*i), 3, 3) * errorCov.block(3+(6*i),3+(6*i), 3, 3);//Angular Velocities noise
402  }
403  }
404 
406  modelVelocities.block(this->number_robot_joints+this->number_slip_joints-(this->number_chains), 0, this->number_chains, 1) = unknownx.block(3, 0, this->number_chains, 1);
407  modelVelCov.block(this->number_robot_joints+this->number_slip_joints-(this->number_chains), this->number_robot_joints+this->number_slip_joints-(this->number_chains), this->number_chains, this->number_chains) = uncertaintyCov.block(3, 3, this->number_chains, this->number_chains);//pseudoInvUnknownA.col(3+i)[3+i]; For the time being set the error to the error in the estimation
408 
409  if (known_contact_angles == false)
410  {
412  for (register int i=0; i<this->number_contact_joints; ++i)
413  {
414  modelVelocities[this->number_robot_joints+this->number_slip_joints+i] = unknownx[3+this->number_chains+i];
415  modelVelCov.col(this->number_robot_joints+this->number_slip_joints+i)[this->number_robot_joints+this->number_slip_joints+i] = uncertaintyCov.col(3+this->number_chains+i)[3+this->number_chains+i];//pseudoInvUnknownA.col(3+_RobotTrees+i)[3+_RobotTrees+i];
416  }
417  }
418 
419  #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL
420  std::cout << "[MOTION_MODEL] L-S solution:\n"<<unknownx<<std::endl;
421 
422  std::cout << "[MOTION_MODEL] RESULT errorCov is of size "<<errorCov.rows()<<"x"<<errorCov.cols()<<"\n";
423  std::cout << "[MOTION_MODEL] RESULT errorCov is \n" << errorCov << std::endl;
424 
425  std::cout << "[MOTION_MODEL] RESULT uncertaintyCov is of size "<<uncertaintyCov.rows()<<"x"<<uncertaintyCov.cols()<<"\n";
426  std::cout << "[MOTION_MODEL] RESULT uncertaintyCov is \n" << uncertaintyCov << std::endl;
427 
428  std::cout << "[MOTION_MODEL] RESULT cartesianVelocities is of size "<<cartesianVelocities.rows()<<"x"<<cartesianVelocities.cols()<<"\n";
429  std::cout << "[MOTION_MODEL] RESULT cartesianVelocities is \n" << cartesianVelocities<< std::endl;
430 
431  std::cout << "[MOTION_MODEL] RESULT cartesianVelCov is of size "<<cartesianVelCov.rows()<<"x"<<cartesianVelCov.cols()<<"\n";
432  std::cout << "[MOTION_MODEL] RESULT cartesianVelCov is \n" << cartesianVelCov<< std::endl;
433 
434  std::cout << "[MOTION_MODEL] RESULT modelVelocities is of size "<<modelVelocities.rows()<<"x"<<modelVelocities.cols()<<"\n";
435  std::cout << "[MOTION_MODEL] RESULT modelVelocities is \n" << modelVelocities<< std::endl;
436 
437  std::cout << "[MOTION_MODEL] RESULT modelVelCov is of size "<<modelVelCov.rows()<<"x"<<modelVelCov.cols()<<"\n";
438  std::cout << "[MOTION_MODEL] RESULT modelVelCov is \n" << modelVelCov<< std::endl;
439 
440  std::cout << "[MOTION_MODEL] RESULT The absolute least squared error is:\n" << squaredError << std::endl;
441  std::cout << "[MOTION_MODEL] RESULT The relative error is:\n" << normalizedError << std::endl;
442  std::cout << "[MOTION_MODEL] RESULT The error vector is \n"<<(unknownA*unknownx - knownb)<<"\n";
443  std::cout << "[MOTION_MODEL] RESULT The error variance is \n"<<errorCov<<"\n";
444  std::cout << "[MOTION_MODEL] RESULT The error variance.inverse() is \n"<<errorCov.inverse()<<"\n";
445  std::cout << "[MOTION_MODEL] RESULT The solution covariance is \n"<<cartesianVelCov<<"\n";
446  #endif
447 
448 
449  return normalizedError;
450  }
451 
452  };
453 }
454 
455 #endif //ODOMETRY_MOTION_MODEL_HPP
456 
void navEquations(const Eigen::Matrix< _Scalar, 6, 1 > &cartesianVelocities, const Eigen::Matrix< _Scalar, Eigen::Dynamic, 1 > &modelVelocities, const Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic > &J, Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic > &unknownA, Eigen::Matrix< _Scalar, Eigen::Dynamic, 1 > &unknownx, Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic > &knownB, Eigen::Matrix< _Scalar, Eigen::Dynamic, 1 > &knowny, bool known_contact_angles=false)
Forms the Navigation Equations for the navigation kinematics.
Definition: MotionModel.hpp:105
int number_robot_joints
Definition: MotionModel.hpp:65
Definition: MotionModel.hpp:62
int number_contact_joints
Definition: MotionModel.hpp:65
MotionModel(const int _number_chains, const int _number_robot_joints, const int _number_slip_joints, const int _number_contact_joints)
Constructor.
Definition: MotionModel.hpp:194
int number_slip_joints
Definition: MotionModel.hpp:65
unsigned int model_dof
Definition: MotionModel.hpp:68
virtual double navSolver(const Eigen::Matrix< _Scalar, Eigen::Dynamic, 1 > &modelPositions, Eigen::Matrix< _Scalar, Eigen::Dynamic, 1 > &modelVelocities, const Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic > &J, Eigen::Matrix< _Scalar, 6, 1 > &cartesianVelocities, Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic > &modelVelCov, Eigen::Matrix< _Scalar, 6, 6 > &cartesianVelCov, const Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic > Weight, bool known_contact_angles=false)
Definition: MotionModel.hpp:241
int number_chains
Definition: MotionModel.hpp:65
Definition: IIR.hpp:11
~MotionModel()
Default destructor.
Definition: MotionModel.hpp:216