30 #ifndef ODOMETRY_MOTION_MODEL_HPP 31 #define ODOMETRY_MOTION_MODEL_HPP 35 #include <boost/shared_ptr.hpp> 36 #include <base-logging/Logging.hpp> 37 #include <Eigen/Geometry> 39 #include <Eigen/Dense> 40 #include <Eigen/Cholesky> 61 template <
typename _Scalar>
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)
114 Eigen::Matrix<_Scalar, Eigen::Dynamic, Eigen::Dynamic> spareI;
115 spareI.resize(6*this->number_chains, 6);
117 #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL 118 std::cout<<
"[MOTION_MODEL] navEquations\n";
123 spareI.block(i*6, 0, 6, 6) = Eigen::Matrix <_Scalar, 6, 6>::Identity();
126 unknownA.block(0, 0, 6*this->number_chains, 3) = spareI.block(0, 0, 6*this->number_chains, 3);
129 unknownx.block(0, 0, 3, 1) = cartesianVelocities.block(0, 0, 3, 1);
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);
136 if (known_contact_angles ==
false)
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);
143 knownB.block(0, 0, 6*this->number_chains, 3) = -spareI.block(0, 3, 6*this->number_chains, 3);
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);
147 knowny.block(0, 0, 3, 1) = cartesianVelocities.template block<3, 1> (3,0);
148 knowny.block(3, 0, this->number_robot_joints, 1) = modelVelocities.block(0, 0, this->number_robot_joints, 1);
151 if (known_contact_angles ==
true)
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);
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);
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;
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)
202 #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL 203 std::cout<<
"[MOTION_MODEL] Constructor. Model DoF:"<<this->model_dof<<
"\n";
206 #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL 207 std::cout<<
"\n[MOTION_MODEL] **** END ****\n";
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)
250 double normalizedError = std::numeric_limits<double>::quiet_NaN();
252 Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> unknownA;
253 Eigen::Matrix <_Scalar, Eigen::Dynamic, 1> unknownx;
254 Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> knownB;
255 Eigen::Matrix <_Scalar, Eigen::Dynamic, 1> knowny;
257 if (known_contact_angles ==
false)
260 unknownA.resize(6*this->number_chains, 3+this->number_chains+this->number_contact_joints);
261 unknownx.resize(3+this->number_chains+this->number_contact_joints, 1);
262 knownB.resize(6*this->number_chains, 3+this->number_robot_joints);
263 knowny.resize(3+this->number_robot_joints, 1);
268 unknownA.resize(6*this->number_chains, 3+this->number_chains);
269 unknownx.resize(3+this->number_chains);
270 knownB.resize(6*this->number_chains, 3+this->number_robot_joints+this->number_contact_joints);
271 knowny.resize(3+this->number_robot_joints+this->number_contact_joints, 1);
275 unknownA.setZero(); unknownx.setZero();
276 knownB.setZero(); knowny.setZero();
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;
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;
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());
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;
302 this->
navEquations (cartesianVelocities, modelVelocities, J, unknownA, unknownx, knownB, knowny, known_contact_angles);
305 Eigen::Matrix <_Scalar, Eigen::Dynamic, 1> knownb;
306 knownb.resize(6*this->number_chains, 1);
307 knownb = knownB*knowny;
309 #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL 310 if (known_contact_angles ==
false)
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);
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;
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;
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;
331 Eigen::Matrix<_Scalar, Eigen::Dynamic, Eigen::Dynamic> Conj;
332 Conj.resize(6*this->number_chains, 3+this->number_chains+1);
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;
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;
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;
352 unknownx = (unknownA.transpose() * Weight * unknownA).ldlt().solve(unknownA.transpose() * Weight * knownb);
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();
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;
363 Eigen::Matrix <_Scalar, Eigen::Dynamic, Eigen::Dynamic> uncertaintyCov;
366 if (known_contact_angles ==
false)
368 uncertaintyCov.resize(3+this->number_chains+this->number_contact_joints, 3+this->number_chains+this->number_contact_joints);
372 uncertaintyCov.resize(3+this->number_chains, 3+this->number_chains);
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))
380 uncertaintyCov = (unknownA.transpose() * errorCovinverse * unknownA).inverse();
384 uncertaintyCov = unknownA.transpose() * errorCov * unknownA;
387 uncertaintyCov = 0.5*(uncertaintyCov + uncertaintyCov.transpose());
390 cartesianVelocities.block(0, 0, 3, 1) = unknownx.block(0, 0, 3, 1);
391 cartesianVelCov.block(0, 0, 3, 3) = uncertaintyCov.block(0, 0, 3,3);
394 if (cartesianVelCov.block(3, 3, 3, 3) != cartesianVelCov.block(3, 3, 3, 3))
396 cartesianVelCov.block(3, 3, 3, 3).setZero();
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);
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);
409 if (known_contact_angles ==
false)
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];
419 #ifdef DEBUG_PRINTS_ODOMETRY_MOTION_MODEL 420 std::cout <<
"[MOTION_MODEL] L-S solution:\n"<<unknownx<<std::endl;
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;
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;
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;
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;
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;
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;
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";
449 return normalizedError;
455 #endif //ODOMETRY_MOTION_MODEL_HPP 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
~MotionModel()
Default destructor.
Definition: MotionModel.hpp:216