65 std::vector<mrpt::math::TPoint3D> & points_this,
66 std::vector<mrpt::math::TPoint3D> & points_other,
69 bool forceScaleToUnity)
76 TPoint3D ct_others(0,0,0), ct_this(0,0,0);
77 const size_t nMatches = points_this.size();
82 for(
size_t i = 0; i < nMatches; i++ )
84 ct_others += points_other[i];
85 ct_this += points_this [i];
88 const double F = 1.0/nMatches;
95 for(
size_t i = 0; i < nMatches; i++ )
97 points_this[i] -= ct_this;
98 points_other[i] -= ct_others;
100 S.get_unsafe(0,0) += points_other[i].x * points_this[i].x;
101 S.get_unsafe(0,1) += points_other[i].x * points_this[i].y;
102 S.get_unsafe(0,2) += points_other[i].x * points_this[i].z;
104 S.get_unsafe(1,0) += points_other[i].y * points_this[i].x;
105 S.get_unsafe(1,1) += points_other[i].y * points_this[i].y;
106 S.get_unsafe(1,2) += points_other[i].y * points_this[i].z;
108 S.get_unsafe(2,0) += points_other[i].z * points_this[i].x;
109 S.get_unsafe(2,1) += points_other[i].z * points_this[i].y;
110 S.get_unsafe(2,2) += points_other[i].z * points_this[i].z;
116 N.set_unsafe( 0,0,S.get_unsafe(0,0) + S.get_unsafe(1,1) + S.get_unsafe(2,2) );
117 N.set_unsafe( 0,1,S.get_unsafe(1,2) - S.get_unsafe(2,1) );
118 N.set_unsafe( 0,2,S.get_unsafe(2,0) - S.get_unsafe(0,2) );
119 N.set_unsafe( 0,3,S.get_unsafe(0,1) - S.get_unsafe(1,0) );
121 N.set_unsafe( 1,0,N.get_unsafe(0,1) );
122 N.set_unsafe( 1,1,S.get_unsafe(0,0) - S.get_unsafe(1,1) - S.get_unsafe(2,2) );
123 N.set_unsafe( 1,2,S.get_unsafe(0,1) + S.get_unsafe(1,0) );
124 N.set_unsafe( 1,3,S.get_unsafe(2,0) + S.get_unsafe(0,2) );
126 N.set_unsafe( 2,0,N.get_unsafe(0,2) );
127 N.set_unsafe( 2,1,N.get_unsafe(1,2) );
128 N.set_unsafe( 2,2,-S.get_unsafe(0,0) + S.get_unsafe(1,1) - S.get_unsafe(2,2) );
129 N.set_unsafe( 2,3,S.get_unsafe(1,2) + S.get_unsafe(2,1) );
131 N.set_unsafe( 3,0,N.get_unsafe(0,3) );
132 N.set_unsafe( 3,1,N.get_unsafe(1,3) );
133 N.set_unsafe( 3,2,N.get_unsafe(2,3) );
134 N.set_unsafe( 3,3,-S.get_unsafe(0,0) - S.get_unsafe(1,1) + S.get_unsafe(2,2) );
140 N.eigenVectors( Z, D );
141 Z.extractCol( Z.getColCount()-1,
v );
143 ASSERTDEB_( fabs( sqrt(
v[0]*
v[0] +
v[1]*
v[1] +
v[2]*
v[2] +
v[3]*
v[3] ) - 1.0 ) < 0.1 );
146 if(
v[0] < 0 ){
v[0] *= -1;
v[1] *= -1;
v[2] *= -1;
v[3] *= -1; }
149 for(
unsigned int i = 0; i < 4; i++ )
150 out_transform[i+3] =
v[i];
154 if( forceScaleToUnity )
162 for(
size_t i = 0; i < nMatches; i++ )
169 s = std::sqrt(
num/den );
173 out_transform.
composePoint( ct_others.x, ct_others.y, ct_others.z, pp.
x, pp.
y, pp.
z );
176 out_transform[0] = ct_this.
x - pp.
x;
177 out_transform[1] = ct_this.
y - pp.
y;
178 out_transform[2] = ct_this.z - pp.
z;
188 const std::vector<mrpt::math::TPoint3D> & in_points_this,
189 const std::vector<mrpt::math::TPoint3D> & in_points_other,
192 bool forceScaleToUnity)
195 std::vector<mrpt::math::TPoint3D> points_this = in_points_this;
196 std::vector<mrpt::math::TPoint3D> points_other= in_points_other;
198 return se3_l2_internal(points_this,points_other,out_transform,out_scale,forceScaleToUnity);
205 bool forceScaleToUnity)
208 const size_t N = corrs.size();
209 std::vector<mrpt::math::TPoint3D> points_this(N), points_other(N);
210 for (
size_t i=0;i<N;i++)
212 points_this[i].x = corrs[i].this_x;
213 points_this[i].y = corrs[i].this_y;
214 points_this[i].z = corrs[i].this_z;
215 points_other[i].x = corrs[i].other_x;
216 points_other[i].y = corrs[i].other_y;
217 points_other[i].z = corrs[i].other_z;
219 return se3_l2_internal(points_this,points_other,out_transform,out_scale,forceScaleToUnity);
#define ASSERT_EQUAL_(__A, __B)
double x() const
Common members of all points & poses classes.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
void composePoint(const double lx, const double ly, const double lz, double &gx, double &gy, double &gz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 7 > *out_jacobian_df_dpose=NULL) const
Computes the 3D point G such as .
double z
X,Y,Z coordinates.
T square(const T x)
Inline function for the square of a number.
This base provides a set of functions for maths stuff.
bool se3_l2_internal(std::vector< mrpt::math::TPoint3D > &points_this, std::vector< mrpt::math::TPoint3D > &points_other, mrpt::poses::CPose3DQuat &out_transform, double &out_scale, bool forceScaleToUnity)
bool TFEST_IMPEXP se3_l2(const mrpt::utils::TMatchingPairList &in_correspondences, mrpt::poses::CPose3DQuat &out_transform, double &out_scale, bool forceScaleToUnity=false)
Least-squares (L2 norm) solution to finding the optimal SE(3) transform between two reference frames ...
A class used to store a 3D pose as a translation (x,y,z) and a quaternion (qr,qx,qy,qz).
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
#define ASSERTDEB_(f)
Defines an assertion mechanism - only when compiled in debug.
Functions for estimating the optimal transformation between two frames of references given measuremen...