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()