43 #include <visp3/vision/vpHandEyeCalibration.h> 45 #define DEBUG_LEVEL1 0 46 #define DEBUG_LEVEL2 0 58 void vpHandEyeCalibration::calibrationVerifrMo(
const std::vector<vpHomogeneousMatrix> &cMo,
const std::vector<vpHomogeneousMatrix> &rMe,
vpHomogeneousMatrix &eMc)
60 unsigned int nbPose = (
unsigned int) cMo.size();
61 std::vector<vpTranslationVector> rTo(nbPose);
62 std::vector<vpRotationMatrix> rRo(nbPose);
64 for (
unsigned int i = 0; i < nbPose; i++) {
74 std::cout <<
"Mean " << std::endl;
75 std::cout <<
"Translation: " << meanTrans.
t() << std::endl;
77 std::cout <<
"Rotation : theta (deg) = " <<
vpMath::deg(sqrt(P.sumSquare())) <<
" Matrice : " << std::endl << meanRot << std::endl;
84 for (
unsigned int i = 0; i < nbPose; i++) {
88 double theta = sqrt(P.sumSquare());
89 std::cout <<
"Distance theta between rMo(" << i <<
") and mean (deg) = " <<
vpMath::deg(theta) << std::endl;
92 resRot += theta*theta;
94 resRot = sqrt(resRot/nbPose);
95 std::cout <<
"Mean residual rMo(" << nbPose <<
") - rotation (deg) = " <<
vpMath::deg(resRot) << std::endl;
97 double resTrans = 0.0;
98 for (
unsigned int i = 0; i < nbPose; i++) {
101 std::cout <<
"Distance d between rMo(" << i <<
") and mean (m) = " << sqrt(errTrans.
sumSquare()) << std::endl;
103 resTrans = sqrt(resTrans/nbPose);
104 std::cout <<
"Mean residual rMo(" << nbPose <<
") - translation (m) = " << resTrans << std::endl;
105 double resPos = (resRot*resRot + resTrans*resTrans)*nbPose;
106 resPos = sqrt(resPos/(2*nbPose));
107 std::cout <<
"Mean residual rMo(" << nbPose <<
") - global = " << resPos << std::endl;
121 int vpHandEyeCalibration::calibrationRotationProcrustes(
const std::vector<vpHomogeneousMatrix> &cMo,
const std::vector<vpHomogeneousMatrix> &rMe,
vpRotationMatrix &eRc)
130 unsigned int nbPose = (
unsigned int) cMo.
size();
133 for (
unsigned int i = 0; i < nbPose; i++) {
135 rMe[i].extract(rRei);
136 cMo[i].extract(ciRo);
139 for (
unsigned int j = 0; j < nbPose; j++) {
143 rMe[j].extract(rRej);
144 cMo[j].extract(cjRo);
174 if (rank != 3)
return -1;
181 std::cout <<
"Rotation from Procrustes method " << std::endl;
185 residual = A * Ct.
t() - Et.
t();
188 printf(
"Mean residual (rotation) = %lf\n",res);
206 int vpHandEyeCalibration::calibrationRotationTsai(
const std::vector<vpHomogeneousMatrix> &cMo,
const std::vector<vpHomogeneousMatrix> &rMe,
vpRotationMatrix &eRc)
210 unsigned int nbPose = (
unsigned int) cMo.
size();
213 for (
unsigned int i = 0; i < nbPose; i++) {
215 rMe[i].extract(rRei);
216 cMo[i].extract(ciRo);
219 for (
unsigned int j = 0; j < nbPose; j++) {
223 rMe[j].extract(rRej);
224 cMo[j].extract(cjRo);
254 std::cout <<
"Tsai method: system A X = B " << std::endl;
255 std::cout <<
"A " << std::endl << A << std::endl;
256 std::cout <<
"B " << std::endl << B << std::endl;
264 if (rank != 3)
return -1;
272 double c = 1 / sqrt(1 + norm);
273 double alpha = acos(c);
275 for (
unsigned int i = 0; i < 3; i++) x[i] *= norm;
283 std::cout <<
"Rotation from Tsai method" << std::endl;
286 for (
unsigned int i = 0; i < 3; i++) x[i] /= norm;
291 printf(
"Mean residual (rotation) = %lf\n",res);
309 int vpHandEyeCalibration::calibrationRotationTsaiOld(
const std::vector<vpHomogeneousMatrix> &cMo,
const std::vector<vpHomogeneousMatrix> &rMe,
vpRotationMatrix &eRc)
311 unsigned int nbPose = (
unsigned int) cMo.size();
317 for (
unsigned int i = 0; i < nbPose; i++) {
319 rMe[i].extract(rRei);
320 cMo[i].extract(ciRo);
323 for (
unsigned int j = 0; j < nbPose; j++) {
326 rMe[j].extract(rRej);
327 cMo[j].extract(cjRo);
336 double theta = sqrt(rPeij[0] * rPeij[0] + rPeij[1] * rPeij[1] + rPeij[2] * rPeij[2]);
343 for (
unsigned int m = 0; m < 3; m++) {
348 theta = sqrt(cijPo[0] * cijPo[0] + cijPo[1] * cijPo[1] + cijPo[2] * cijPo[2]);
349 for (
unsigned int m = 0; m < 3; m++) {
384 if (rank != 3)
return -1;
405 for (
unsigned int i = 0; i < 3; i++)
406 x[i] = 2 * x[i] / sqrt(1 + d);
408 theta = 2 * asin(theta);
410 if (std::fabs(theta) > std::numeric_limits<double>::epsilon()) {
411 for (
unsigned int i = 0; i < 3; i++)
412 x[i] *= theta / (2 * sin(theta / 2));
422 std::cout <<
"Rotation from Old Tsai method" << std::endl;
429 printf(
"Mean residual (rotation) = %lf\n",res);
448 int vpHandEyeCalibration::calibrationTranslation(
const std::vector<vpHomogeneousMatrix> &cMo,
449 const std::vector<vpHomogeneousMatrix> &rMe,
456 unsigned int nbPose = (
unsigned int)cMo.size();
461 for (
unsigned int i = 0; i < nbPose; i++) {
462 for (
unsigned int j = 0; j < nbPose; j++) {
495 if (rank != 3)
return -1;
502 printf(
"New Hand-eye calibration : ");
503 std::cout <<
"Translation: " << eTc[0] <<
" " << eTc[1] <<
" " << eTc[2] << std::endl;
509 printf(
"Mean residual (translation) = %lf\n",res);
528 int vpHandEyeCalibration::calibrationTranslationOld(
const std::vector<vpHomogeneousMatrix> &cMo,
529 const std::vector<vpHomogeneousMatrix> &rMe,
540 unsigned int nbPose = (
unsigned int)cMo.size();
542 for (
unsigned int i = 0; i < nbPose; i++) {
545 rMe[i].extract(rRei);
546 cMo[i].extract(ciRo);
547 rMe[i].extract(rTei);
548 cMo[i].extract(ciTo);
550 for (
unsigned int j = 0; j < nbPose; j++) {
555 rMe[j].extract(rRej);
556 cMo[j].extract(cjRo);
559 rMe[j].extract(rTej);
560 cMo[j].extract(cjTo);
566 rTeij = rRej.
t() * rTeij;
571 b = eRc * cjTo - rReij * eRc * ciTo + rTeij;
591 if (rank != 3)
return -1;
593 AeTc = Ap * A.
t() * B;
598 printf(
"Old Hand-eye calibration : ");
599 std::cout <<
"Translation: " << eTc[0] <<
" " << eTc[1] <<
" " << eTc[2] << std::endl;
606 for (
unsigned int i=0; i < residual.
getRows(); i++)
607 res += residual[i]*residual[i];
608 res = sqrt(res/residual.
getRows());
609 printf(
"Mean residual (translation) = %lf\n",res);
627 double vpHandEyeCalibration::calibrationErrVVS(
const std::vector<vpHomogeneousMatrix> &cMo,
const std::vector<vpHomogeneousMatrix> &rMe,
630 unsigned int nbPose = (
unsigned int) cMo.size();
639 for (
unsigned int i = 0; i < nbPose; i++) {
640 for (
unsigned int j = 0; j < nbPose; j++) {
667 s = (
vpMatrix(ejRei) - I3) * eTc - eRc * cjTci + ejTei;
673 double resRot, resTrans, resPos;
674 resRot = resTrans = resPos = 0.0;
675 for (
unsigned int i=0; i < (
unsigned int) errVVS.
size() ; i += 6)
677 resRot += errVVS[i]*errVVS[i];
678 resRot += errVVS[i+1]*errVVS[i+1];
679 resRot += errVVS[i+2]*errVVS[i+2];
680 resTrans += errVVS[i+3]*errVVS[i+3];
681 resTrans += errVVS[i+4]*errVVS[i+4];
682 resTrans += errVVS[i+5]*errVVS[i+5];
684 resPos = resRot + resTrans;
685 resRot = sqrt(resRot*2/errVVS.
size());
686 resTrans = sqrt(resTrans*2/errVVS.
size());
687 resPos = sqrt(resPos/errVVS.
size());
690 printf(
"Mean VVS residual - rotation (deg) = %lf\n",
vpMath::deg(resRot));
691 printf(
"Mean VVS residual - translation = %lf\n",resTrans);
692 printf(
"Mean VVS residual - global = %lf\n",resPos);
708 #define NB_ITER_MAX 30 710 int vpHandEyeCalibration::calibrationVVS(
const std::vector<vpHomogeneousMatrix> &cMo,
711 const std::vector<vpHomogeneousMatrix> &rMe,
716 unsigned int nbPose = (
unsigned int) cMo.size();
731 while ((res > 1e-7) && (it < NB_ITER_MAX))
734 vpHandEyeCalibration::calibrationErrVVS(cMo, rMe, eMc, err);
737 for (
unsigned int i = 0; i < nbPose; i++) {
738 for (
unsigned int j = 0; j < nbPose; j++) {
757 for (
unsigned int m=0;m<3;m++)
758 for (
unsigned int n=0;n<3;n++)
761 Ls[m][n+3] = Lw[m][n];
772 for (
unsigned int m=0;m<3;m++)
773 for (
unsigned int n=0;n<3;n++)
776 Ls[m][n+3] = Lw[m][n];
786 if (rank != 6)
return -1;
799 printf(
" Iteration number for NL hand-eye minimisation : %d\n",it);
802 std::cout <<
"Translation: " << eTc[0] <<
" " << eTc[1] <<
" " << eTc[2] << std::endl;
805 res = sqrt(res/err.getRows());
806 printf(
"Mean residual (rotation+translation) = %lf\n",res);
809 if (it == NB_ITER_MAX)
return 1;
816 #define HE_TSAI_OROT 1 817 #define HE_TSAI_ORNT 2 818 #define HE_TSAI_NROT 3 819 #define HE_TSAI_NRNT 4 820 #define HE_PROCRUSTES_OT 5 821 #define HE_PROCRUSTES_NT 6 840 if (cMo.size() != rMe.size())
850 resPos = vpHandEyeCalibration::calibrationErrVVS(cMo, rMe, eMc, errVVS);
851 double vmin = resPos;
853 int He_method = HE_I;
857 int err = vpHandEyeCalibration::calibrationRotationTsaiOld(cMo, rMe, eRc);
858 if (err != 0) printf(
"\n Problem in solving Hand-Eye Rotation by Old Tsai method \n");
862 err = vpHandEyeCalibration::calibrationTranslationOld(cMo, rMe, eRc, eTc);
863 if (err != 0) printf(
"\n Problem in solving Hand-Eye Translation by Old Tsai method after Old Tsai method for Rotation\n");
869 printf(
"\nRotation by (old) Tsai, old implementation for translation\n");
870 vpHandEyeCalibration::calibrationVerifrMo(cMo, rMe, eMc);
873 resPos = vpHandEyeCalibration::calibrationErrVVS(cMo, rMe, eMc, errVVS);
879 He_method = HE_TSAI_OROT;
883 err = vpHandEyeCalibration::calibrationTranslation(cMo, rMe, eRc, eTc);
884 if (err != 0) printf(
"\n Problem in solving Hand-Eye Translation after Old Tsai method for Rotation\n");
890 printf(
"\nRotation by (old) Tsai, new implementation for translation\n");
891 vpHandEyeCalibration::calibrationVerifrMo(cMo, rMe, eMc);
894 resPos = vpHandEyeCalibration::calibrationErrVVS(cMo, rMe, eMc, errVVS);
900 He_method = HE_TSAI_ORNT;
906 err = vpHandEyeCalibration::calibrationRotationTsaiOld(cMo, rMe, eRc);
907 if (err != 0) printf(
"\n Problem in solving Hand-Eye Rotation by Tsai method \n");
911 err = vpHandEyeCalibration::calibrationTranslationOld(cMo, rMe, eRc, eTc);
912 if (err != 0) printf(
"\n Problem in solving Hand-Eye Translation by Old Tsai method after Tsai method for Rotation\n");
918 printf(
"\nRotation by Tsai, old implementation for translation\n");
919 vpHandEyeCalibration::calibrationVerifrMo(cMo, rMe, eMc);
922 resPos = vpHandEyeCalibration::calibrationErrVVS(cMo, rMe, eMc, errVVS);
928 He_method = HE_TSAI_NROT;
932 err = vpHandEyeCalibration::calibrationTranslation(cMo, rMe, eRc, eTc);
933 if (err != 0) printf(
"\n Problem in solving Hand-Eye Translation after Tsai method for Rotation \n");
939 printf(
"\nRotation by Tsai, new implementation for translation\n");
940 vpHandEyeCalibration::calibrationVerifrMo(cMo, rMe, eMc);
943 resPos = vpHandEyeCalibration::calibrationErrVVS(cMo, rMe, eMc, errVVS);
949 He_method = HE_TSAI_NRNT;
955 err = vpHandEyeCalibration::calibrationRotationProcrustes(cMo, rMe, eRc);
956 if (err != 0) printf(
"\n Problem in solving Hand-Eye Rotation by Procrustes method \n");
960 err = vpHandEyeCalibration::calibrationTranslationOld(cMo, rMe, eRc, eTc);
961 if (err != 0) printf(
"\n Problem in solving Hand-Eye Translation by Old Tsai method after Procrustes method for Rotation\n");
967 printf(
"\nRotation by Procrustes, old implementation for translation\n");
968 vpHandEyeCalibration::calibrationVerifrMo(cMo, rMe, eMc);
971 resPos = vpHandEyeCalibration::calibrationErrVVS(cMo, rMe, eMc, errVVS);
977 He_method = HE_PROCRUSTES_OT;
981 err = vpHandEyeCalibration::calibrationTranslation(cMo, rMe, eRc, eTc);
982 if (err != 0) printf(
"\n Problem in solving Hand-Eye Translation after Procrustes method for Rotation\n");
988 printf(
"\nRotation by Procrustes, new implementation for translation\n");
989 vpHandEyeCalibration::calibrationVerifrMo(cMo, rMe, eMc);
992 resPos = vpHandEyeCalibration::calibrationErrVVS(cMo, rMe, eMc, errVVS);
998 He_method = HE_PROCRUSTES_NT;
1008 if (He_method == HE_I) printf(
"Best method : I !!!, vmin = %lf\n",vmin);
1009 if (He_method == HE_TSAI_OROT) printf(
"Best method : TSAI_OROT, vmin = %lf\n",vmin);
1010 if (He_method == HE_TSAI_ORNT) printf(
"Best method : TSAI_ORNT, vmin = %lf\n",vmin);
1011 if (He_method == HE_TSAI_NROT) printf(
"Best method : TSAI_NROT, vmin = %lf\n",vmin);
1012 if (He_method == HE_TSAI_NRNT) printf(
"Best method : TSAI_NRNT, vmin = %lf\n",vmin);
1013 if (He_method == HE_PROCRUSTES_OT) printf(
"Best method : PROCRUSTES_OT, vmin = %lf\n",vmin);
1014 if (He_method == HE_PROCRUSTES_NT) printf(
"Best method : PROCRUSTES_NT, vmin = %lf\n",vmin);
1017 std::cout <<
"Translation: " << eMc[0][3] <<
" " << eMc[1][3] <<
" " << eMc[2][3] << std::endl;
1022 err = vpHandEyeCalibration::calibrationVVS(cMo, rMe, eMc);
1024 if (err != 0) printf(
"\n Problem in solving Hand-Eye Calibration by VVS \n");
1027 printf(
"\nRotation and translation after VVS\n");
1028 vpHandEyeCalibration::calibrationVerifrMo(cMo, rMe, eMc);
1038 #undef HE_PROCRUSTES_OT 1039 #undef HE_PROCRUSTES_NT Implementation of a matrix and operations on matrices.
Implementation of an homogeneous matrix and operations on such kind of matrices.
static int calibrate(const std::vector< vpHomogeneousMatrix > &cMo, const std::vector< vpHomogeneousMatrix > &rMe, vpHomogeneousMatrix &eMc)
void stack(const vpMatrix &A)
error that can be emited by ViSP classes.
vpRotationMatrix t() const
unsigned int size() const
Return the number of elements of the 2D array.
unsigned int getCols() const
static double sinc(double x)
Implementation of a rotation matrix and operations on such kind of matrices.
void insert(const vpRotationMatrix &R)
static vpRotationMatrix mean(const std::vector< vpHomogeneousMatrix > &vec_M)
vpRotationMatrix getRotationMatrix() const
vpTranslationVector getTranslationVector() const
void extract(vpRotationMatrix &R) const
unsigned int getRows() const
static vpTranslationVector mean(const std::vector< vpHomogeneousMatrix > &vec_M)
static double deg(double rad)
Implementation of column vector and the associated operations.
vpHomogeneousMatrix inverse() const
static vpHomogeneousMatrix direct(const vpColVector &v)
static vpMatrix skew(const vpColVector &v)
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Class that consider the case of a translation vector.
Implementation of a rotation vector as axis-angle minimal representation.