9 #ifndef cpointsmap_crtp_common_H
10 #define cpointsmap_crtp_common_H
23 template <
class Derived>
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) ) ) );
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;
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 );
A "CObservation"-derived class that represents a 2D range scan measurement (typically from a laser sc...
mrpt::utils::ContainerReadOnlyProxyAccessor< std::vector< char > > validRange
It's false (=0) on no reflected rays, referenced to elements in scan.
size_t getScanSize() const
Get number of scan rays.
mrpt::poses::CPose3D sensorPose
The 6D pose of the sensor on the robot at the moment of starting the scan.
mrpt::utils::ContainerReadOnlyProxyAccessor< std::vector< float > > scan
The range values of the scan, in meters. Must have same length than validRange.
Declares a class derived from "CObservation" that encapsules a 3D range scan measurement,...
bool hasPoints3D
true means the field points3D contains valid data.
std::vector< float > points3D_x
std::vector< float > points3D_y
std::vector< float > points3D_z
If hasPoints3D=true, the (X,Y,Z) coordinates of the 3D point cloud detected by the camera.
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).
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...
void getHomogeneousMatrix(mrpt::math::CMatrixDouble44 &out_HM) const
Returns the corresponding 4x4 homogeneous transformation matrix for the point(translation) or pose (t...
GLsizei GLsizei GLuint * obj
GLdouble GLdouble GLdouble GLdouble q
int round(const T value)
Returns the closer integer (int) to x.
T square(const T x)
Inline function for the square of a number.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
double DEG2RAD(const double x)
Degrees to radians.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Helper struct used for internal_loadFromRangeScan2D_prepareOneRange()
mrpt::math::CMatrixDouble44 HM
Homog matrix of the local sensor pose within the robot.
Helper struct used for internal_loadFromRangeScan3D_prepareOneRange()
mrpt::math::CMatrixDouble44 HM
Homog matrix of the local sensor pose within the robot.
float scan_z
In internal_loadFromRangeScan3D_prepareOneRange, these are the local coordinates of the scan points b...
static void templ_loadFromRangeScan(Derived &obj, const mrpt::obs::CObservation2DRangeScan &rangeScan, const mrpt::poses::CPose3D *robotPose)
static void templ_loadFromRangeScan(Derived &obj, const mrpt::obs::CObservation3DRangeScan &rangeScan, const mrpt::poses::CPose3D *robotPose)
A pair of vectors with the cos and sin values.
mrpt::math::CVectorFloat csin
mrpt::math::CVectorFloat ccos