9 #ifndef cpointsmap_crtp_common_H 10 #define cpointsmap_crtp_common_H 23 template <
class Derived>
24 struct loadFromRangeImpl
34 obj.mark_as_modified();
50 if (!
obj.insertionOptions.addToExistingPointsMap)
53 const int sizeRangeScan = rangeScan.
scan.
size();
59 if (
obj.x.size()+sizeRangeScan >
obj.x.capacity() )
61 obj.reserve( (
size_t) (
obj.x.size() * 1.2f) + 3*sizeRangeScan );
70 float m00 = lric.
HM.get_unsafe(0,0);
71 float m01 = lric.
HM.get_unsafe(0,1);
72 float m03 = lric.
HM.get_unsafe(0,3);
73 float m10 = lric.
HM.get_unsafe(1,0);
74 float m11 = lric.
HM.get_unsafe(1,1);
75 float m13 = lric.
HM.get_unsafe(1,3);
76 float m20 = lric.
HM.get_unsafe(2,0);
77 float m21 = lric.
HM.get_unsafe(2,1);
78 float m23 = lric.
HM.get_unsafe(2,3);
80 float lx_1,ly_1,lz_1,lx=0,ly=0,lz=0;
84 lx_1 = -100; ly_1 = -100; lz_1 = -100;
85 lx_2 = -100; ly_2 = -100;
88 const bool useMinDist =
obj.insertionOptions.minDistBetweenLaserPoints>0;
89 const float minDistSqrBetweenLaserPoints =
square(
obj.insertionOptions.minDistBetweenLaserPoints );
94 bool lastPointWasValid =
true;
95 bool thisIsTheFirst =
true;
96 bool lastPointWasInserted =
false;
103 const size_t nPointsAtStart =
obj.size();
104 size_t nextPtIdx = nPointsAtStart;
107 const size_t expectedMaxSize = nPointsAtStart+(sizeRangeScan* (
obj.insertionOptions.also_interpolate ? 3:1) );
108 obj.x.resize( expectedMaxSize );
109 obj.y.resize( expectedMaxSize );
110 obj.z.resize( expectedMaxSize );
120 Eigen::Array<float,Eigen::Dynamic,1> scan_gx(sizeRangeScan+3), scan_gy(sizeRangeScan+3),scan_gz(sizeRangeScan+3);
124 size_t nPackets = sizeRangeScan/4;
125 if ( (sizeRangeScan & 0x03)!=0) nPackets++;
135 const __m128 m00_4val = _mm_set1_ps(m00);
136 const __m128 m01_4val = _mm_set1_ps(m01);
137 const __m128 m03_4val = _mm_set1_ps(m03);
139 const __m128 m10_4val = _mm_set1_ps(m10);
140 const __m128 m11_4val = _mm_set1_ps(m11);
141 const __m128 m13_4val = _mm_set1_ps(m13);
143 const __m128 m20_4val = _mm_set1_ps(m20);
144 const __m128 m21_4val = _mm_set1_ps(m21);
145 const __m128 m23_4val = _mm_set1_ps(m23);
151 const float *ptr_in_scan = &rangeScan.
scan[0];
152 const float *ptr_in_cos = &sincos_vals.
ccos[0];
153 const float *ptr_in_sin = &sincos_vals.
csin[0];
155 float *ptr_out_x = &scan_gx[0];
156 float *ptr_out_y = &scan_gy[0];
157 float *ptr_out_z = &scan_gz[0];
159 for( ; nPackets; nPackets--, ptr_in_scan+=4, ptr_in_cos+=4, ptr_in_sin+=4, ptr_out_x+=4, ptr_out_y+=4, ptr_out_z+=4 )
161 const __m128 scan_4vals = _mm_loadu_ps(ptr_in_scan);
163 const __m128 xs = _mm_mul_ps(scan_4vals, _mm_load_ps(ptr_in_cos) );
164 const __m128 ys = _mm_mul_ps(scan_4vals, _mm_load_ps(ptr_in_sin) );
166 _mm_store_ps(ptr_out_x, _mm_add_ps(m03_4val, _mm_add_ps( _mm_mul_ps(xs,m00_4val), _mm_mul_ps(ys,m01_4val) ) ) );
167 _mm_store_ps(ptr_out_y, _mm_add_ps(m13_4val, _mm_add_ps( _mm_mul_ps(xs,m10_4val), _mm_mul_ps(ys,m11_4val) ) ) );
168 _mm_store_ps(ptr_out_z, _mm_add_ps(m23_4val, _mm_add_ps( _mm_mul_ps(xs,m20_4val), _mm_mul_ps(ys,m21_4val) ) ) );
170 #else // MRPT_HAS_SSE2 172 Eigen::Array<float,Eigen::Dynamic,1> scan_x(sizeRangeScan+3), scan_y(sizeRangeScan+3);
175 const Eigen::Map<Eigen::Matrix<float,Eigen::Dynamic,1> > scan_vals( const_cast<float*>(&rangeScan.
scan[0]),rangeScan.
scan.
size(),1 );
177 const Eigen::Map<Eigen::Matrix<float,Eigen::Dynamic,1> > ccos( const_cast<float*>(&sincos_vals.
ccos[0]),rangeScan.
scan.
size(),1 );
178 const Eigen::Map<Eigen::Matrix<float,Eigen::Dynamic,1> > csin( const_cast<float*>(&sincos_vals.
csin[0]),rangeScan.
scan.
size(),1 );
181 scan_x = scan_vals.array() * ccos.array();
182 scan_y = scan_vals.array() * csin.array();
186 scan_gx = m00*scan_x+m01*scan_y+m03;
187 scan_gy = m10*scan_x+m11*scan_y+m13;
188 scan_gz = m20*scan_x+m21*scan_y+m23;
189 #endif // MRPT_HAS_SSE2 193 for (
int i=0;i<sizeRangeScan;i++)
204 lastPointWasInserted =
false;
207 bool pt_pass_min_dist =
true;
209 if (useMinDist ||
obj.insertionOptions.also_interpolate)
211 if (!lastPointWasValid)
212 pt_pass_min_dist =
false;
216 pt_pass_min_dist = (d2 > minDistSqrBetweenLaserPoints);
220 if ( thisIsTheFirst || pt_pass_min_dist )
222 thisIsTheFirst =
false;
225 if (
obj.insertionOptions.also_interpolate && i>1)
227 float changeInDirection;
228 const float d = std::sqrt( d2 );
230 if ((lx!=lx_1 || ly!=ly_1) && (lx_1!=lx_2 || ly_1!=ly_2) )
231 changeInDirection = atan2(ly-ly_1,lx-lx_1)-atan2(ly_1-ly_2,lx_1-lx_2);
232 else changeInDirection = 0;
235 if (d>=2*
obj.insertionOptions.minDistBetweenLaserPoints &&
236 d<
obj.insertionOptions.maxDistForInterpolatePoints &&
237 fabs(changeInDirection)<
DEG2RAD(5) )
241 for (
int q=1;
q<nInterpol;
q++)
243 float i_x = lx_1 +
q*(lx-lx_1)/nInterpol;
244 float i_y = ly_1 +
q*(ly-ly_1)/nInterpol;
245 float i_z = lz_1 +
q*(lz-lz_1)/nInterpol;
246 if( !
obj.m_heightfilter_enabled || ( i_z >=
obj.m_heightfilter_z_min && i_z <=
obj.m_heightfilter_z_max ) )
248 obj.x.push_back( i_x );
249 obj.y.push_back( i_y );
250 obj.z.push_back( i_z );
258 if( !
obj.m_heightfilter_enabled || (lz >=
obj.m_heightfilter_z_min && lz <=
obj.m_heightfilter_z_max ) )
260 obj.x[nextPtIdx] = lx;
261 obj.y[nextPtIdx] = ly;
262 obj.z[nextPtIdx] = lz;
268 lastPointWasInserted =
true;
284 lastPointWasValid = rangeScan.
validRange[i] != 0;
288 if (lastPointWasValid && !lastPointWasInserted)
290 if( !
obj.m_heightfilter_enabled || (lz >=
obj.m_heightfilter_z_min && lz <=
obj.m_heightfilter_z_max ) )
292 obj.x[nextPtIdx] = lx;
293 obj.y[nextPtIdx] = ly;
294 obj.z[nextPtIdx] = lz;
302 obj.x.resize( nextPtIdx );
303 obj.y.resize( nextPtIdx );
304 obj.z.resize( nextPtIdx );
314 obj.mark_as_modified();
323 if (!
obj.insertionOptions.addToExistingPointsMap)
329 const size_t sizeRangeScan = rangeScan.
points3D_x.size();
332 if (
obj.x.size()+sizeRangeScan>
obj.x.capacity() )
333 obj.reserve(
size_t(
obj.x.size() + 1.1*sizeRangeScan) );
341 float m00 = lric.
HM.get_unsafe(0,0);
342 float m01 = lric.
HM.get_unsafe(0,1);
343 float m02 = lric.
HM.get_unsafe(0,2);
344 float m03 = lric.
HM.get_unsafe(0,3);
345 float m10 = lric.
HM.get_unsafe(1,0);
346 float m11 = lric.
HM.get_unsafe(1,1);
347 float m12 = lric.
HM.get_unsafe(1,2);
348 float m13 = lric.
HM.get_unsafe(1,3);
349 float m20 = lric.
HM.get_unsafe(2,0);
350 float m21 = lric.
HM.get_unsafe(2,1);
351 float m22 = lric.
HM.get_unsafe(2,2);
352 float m23 = lric.
HM.get_unsafe(2,3);
354 float lx_1,ly_1,lz_1,lx=0,ly=0,lz=0;
357 lx_1 = -100; ly_1 = -100; lz_1 = -100;
359 float minDistSqrBetweenLaserPoints =
square(
obj.insertionOptions.minDistBetweenLaserPoints );
362 if (
obj.insertionOptions.minDistBetweenLaserPoints<=0)
363 minDistSqrBetweenLaserPoints = -1;
368 bool lastPointWasValid =
true;
369 bool thisIsTheFirst =
true;
370 bool lastPointWasInserted =
false;
375 for (
size_t i=0;i<sizeRangeScan;i++)
391 lastPointWasInserted =
false;
395 if ( thisIsTheFirst || (lastPointWasValid && (d2 > minDistSqrBetweenLaserPoints)) )
397 thisIsTheFirst =
false;
399 obj.x.push_back( lx );
400 obj.y.push_back( ly );
401 obj.z.push_back( lz );
405 lastPointWasInserted =
true;
412 lastPointWasValid =
true;
416 lastPointWasValid =
false;
423 if (lastPointWasValid && !lastPointWasInserted)
425 if (lx!=0 || ly!=0 || lz!=0)
427 obj.x.push_back( lx );
428 obj.y.push_back( ly );
429 obj.z.push_back( lz );
double DEG2RAD(const double x)
Degrees to radians.
GLdouble GLdouble GLdouble GLdouble q
Declares a class derived from "CObservation" that encapsules a 3D range scan measurement, as from a time-of-flight range camera or any other RGBD sensor.
GLsizei GLsizei GLuint * obj
size_t getScanSize() const
Get number of scan rays.
float scan_z
In internal_loadFromRangeScan3D_prepareOneRange, these are the local coordinates of the scan points b...
T square(const T x)
Inline function for the square of a number.
std::vector< float > points3D_z
If hasPoints3D=true, the (X,Y,Z) coordinates of the 3D point cloud detected by the camera...
static void templ_loadFromRangeScan(Derived &obj, const mrpt::obs::CObservation3DRangeScan &rangeScan, const mrpt::poses::CPose3D *robotPose)
mrpt::math::CVectorFloat ccos
std::vector< float > points3D_y
void composeFrom(const CPose3D &A, const CPose3D &B)
Makes "this = A (+) B"; this method is slightly more efficient than "this= A + B;" since it avoids th...
mrpt::math::CMatrixDouble44 HM
Homog matrix of the local sensor pose within the robot.
mrpt::utils::ContainerReadOnlyProxyAccessor< std::vector< char > > validRange
It's false (=0) on no reflected rays, referenced to elements in scan.
static void templ_loadFromRangeScan(Derived &obj, const mrpt::obs::CObservation2DRangeScan &rangeScan, const mrpt::poses::CPose3D *robotPose)
bool hasPoints3D
true means the field points3D contains valid data.
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.
mrpt::math::CVectorFloat csin
A "CObservation"-derived class that represents a 2D range scan measurement (typically from a laser sc...
A pair of vectors with the cos and sin values.
mrpt::poses::CPose3D sensorPose
The 6D pose of the sensor on the robot.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
T square(const T x)
Inline function for the square of a number.
std::vector< float > points3D_x
int round(const T value)
Returns the closer integer (int) to x.
Helper struct used for internal_loadFromRangeScan3D_prepareOneRange()
mrpt::utils::ContainerReadOnlyProxyAccessor< std::vector< float > > scan
The range values of the scan, in meters. Must have same length than validRange.
mrpt::math::CMatrixDouble44 HM
Homog matrix of the local sensor pose within the robot.
mrpt::poses::CPose3D sensorPose
The 6D pose of the sensor on the robot at the moment of starting the scan.
void getHomogeneousMatrix(mrpt::math::CMatrixDouble44 &out_HM) const
Returns the corresponding 4x4 homogeneous transformation matrix for the point(translation) or pose (t...
Helper struct used for internal_loadFromRangeScan2D_prepareOneRange()