14 #include <mrpt/core/exceptions.h> 
   15 #include <mrpt/poses/Lie/SE.h> 
   16 #include <mrpt/tfest/se3.h> 
   18 #include <Eigen/Dense> 
   25 static mrpt::poses::CPose3D 
gibbs2pose(
const Eigen::Vector3d& v)
 
   27     auto       x = v[0], y = v[1], z = v[2];
 
   28     const auto r = 1.0 / std::sqrt(1.0 + 
x * 
x + y * y + z * z);
 
   32     auto q = mrpt::math::CQuaternionDouble(r, -
x, -y, -z);
 
   35     return mrpt::poses::CPose3D(
q, .0, .0, .0);
 
   49     Eigen::Matrix3d M, Mx, My, 
Mz;
 
   50     Eigen::Vector3d v, vx, vy, 
vz;
 
   59     const mrpt::math::TPoint3D& ct_global, 
OutlierIndices& in_out_outliers)
 
   63     using mrpt::math::TPoint3D;
 
   64     using mrpt::math::TVector3D;
 
   69     res.M = Eigen::Matrix3d::Zero();
 
   70     res.v = Eigen::Vector3d::Zero();
 
   73     res.B = Eigen::Matrix3d::Zero();
 
   76     auto lambda_each_pair =
 
   77         [&](
const mrpt::math::TVector3D& bi, 
const mrpt::math::TVector3D& ri, 
const double wi)
 
   86     const double sx = bi.x + ri.x, sy = bi.y + ri.y, sz = bi.z + ri.z;
 
   99     const double c00 = -sy * sy - sz * sz;
 
  100     const double c11 = -sx * sx - sz * sz;
 
  101     const double c22 = -sx * sx - sy * sy;
 
  102     const double c01 = sx * sy;
 
  103     const double c02 = sx * sz;
 
  104     const double c12 = sy * sz;
 
  107     const auto dM = (Eigen::Matrix3d() <<
 
  110        c02, c12, c22 ).finished();
 
  133     const auto dV = (Eigen::Vector3d() <<
 
  134        (bi.y * ri.z - bi.z * ri.y),
 
  135        (-bi.x * ri.z + bi.z * ri.x),
 
  136        (bi.x * ri.y - bi.y * ri.x) ).finished();
 
  142     const auto dB = (Eigen::Matrix3d() <<
 
  143        bi.x * ri.x, bi.x * ri.y, bi.x * ri.z,
 
  144        bi.y * ri.x, bi.y * ri.y, bi.y * ri.z,
 
  145        bi.z * ri.x, bi.z * ri.y, bi.z * ri.z).finished();
 
  151     auto lambda_final = [&](
const double w_sum)
 
  156             const auto f = (1.0 / w_sum);
 
  169         in, wp, ct_local, ct_global, in_out_outliers, lambda_each_pair, lambda_final,
 
  176         const Eigen::Matrix3d S = 
res.B + 
res.B.transpose();
 
  177         const double          p = 
res.B.trace() + 1;
 
  178         const double          m = 
res.B.trace() - 1;
 
  180         const auto& v = 
res.v;
 
  184         res.M = (Eigen::Matrix3d() <<
 
  185            S(0,0)-p,  S(0,1), S(0,2),
 
  186            S(0,1),   S(1,1)-p, S(1,2),
 
  187            S(0,2),   S(1,2),  S(2,2)-p ).finished();
 
  190         const auto&  M0 = 
res.M;  
 
  191         const double z1 = v[0], z2 = v[1], z3 = v[2];
 
  195         res.Mx = (Eigen::Matrix3d() <<
 
  197            -z3   ,  M0(2,2),     -S(1,2),
 
  198            z2    ,  -S(1,2),    M0(1,1)).finished();
 
  199         res.vx = (Eigen::Vector3d() <<
 
  206         res.My = (Eigen::Matrix3d() <<
 
  207            M0(2,2),     z3  ,     -S(0,2),
 
  209          -S(0,2)  ,     -z1 ,   M0(0,0)).finished();
 
  210         res.vy = (Eigen::Vector3d() <<
 
  217         res.Mz = (Eigen::Matrix3d() <<
 
  218            M0(1,1),  -S(0,1),     -z2,
 
  219           -S(0,1) ,  M0(0,0),      z1,
 
  220              -z2  ,      z1 ,      m).finished();
 
  221         res.vz = (Eigen::Vector3d() <<
 
  238     using mrpt::math::TPoint3D;
 
  239     using mrpt::math::TVector3D;
 
  269         ct_local  = new_ct_local;
 
  270         ct_global = new_ct_global;
 
  279     const double detM_orig = std::abs(linsys.
M.determinant()),
 
  280                  detMx     = std::abs(linsys.
Mx.determinant()),
 
  281                  detMy     = std::abs(linsys.
My.determinant()),
 
  282                  detMz     = std::abs(linsys.
Mz.determinant());
 
  286     std::cout << 
" |M_orig|= " << detM_orig << 
"\n" 
  287                  " |M_x|   = " << detMx << 
"\n" 
  288                  " |M_t|   = " << detMy << 
"\n" 
  289                  " |M_z|   = " << detMz << 
"\n";
 
  293     if (detM_orig > mrpt::max3(detMx, detMy, detMz))
 
  296         const auto sol0    = 
gibbs2pose(linsys.
M.colPivHouseholderQr().solve(linsys.
v));
 
  299         std::cout << 
"M   : |M|=" 
  300                   << mrpt::format(
"%16.07f", linsys.
M.determinant())
 
  301                   << 
" sol: " << sol0.asString() << 
"\n";
 
  304     else if (detMx > mrpt::max3(detM_orig, detMy, detMz))
 
  307         auto sol1          = 
gibbs2pose(linsys.
Mx.colPivHouseholderQr().solve(linsys.
vx));
 
  308         sol1               = mrpt::poses::CPose3D(0, 0, 0, 0, 0, M_PI) + sol1;
 
  311         std::cout << 
"M_x : |M|=" 
  312                   << mrpt::format(
"%16.07f", linsys.
Mx.determinant())
 
  313                   << 
" sol: " << sol1.asString() << 
"\n";
 
  316     else if (detMy > mrpt::max3(detM_orig, detMx, detMz))
 
  319         auto sol2          = 
gibbs2pose(linsys.
My.colPivHouseholderQr().solve(linsys.
vy));
 
  320         sol2               = mrpt::poses::CPose3D(0, 0, 0, 0, M_PI, 0) + sol2;
 
  323         std::cout << 
"M_y : |M|=" 
  324                   << mrpt::format(
"%16.07f", linsys.
My.determinant())
 
  325                   << 
" sol: " << sol2.asString() << 
"\n";
 
  331         auto sol3          = 
gibbs2pose(linsys.
Mz.colPivHouseholderQr().solve(linsys.
vz));
 
  332         sol3               = mrpt::poses::CPose3D(0, 0, 0, M_PI, 0, 0) + sol3;
 
  335         std::cout << 
"M_z : |M|=" 
  336                   << mrpt::format(
"%16.07f", linsys.
Mz.determinant())
 
  337                   << 
" sol: " << sol3.asString() << 
"\n";
 
  342     mrpt::math::TPoint3D pp;
 
  343     result.
optimalPose.composePoint(ct_local.x, ct_local.y, ct_local.z, pp.x, pp.y, pp.z);