32 #include <pcl/io/pcd_io.h>
33 #include <pcl/point_types.h>
66 m_largestDistanceFromOrigin(0),
67 m_heightfilter_z_min(-10),
68 m_heightfilter_z_max(10),
69 m_heightfilter_enabled(false)
77 CPointsMap::~CPointsMap() {}
83 bool CPointsMap::save2D_to_text_file(
const string& file)
const
88 for (
unsigned int i = 0; i < m_x.size(); i++)
100 bool CPointsMap::save3D_to_text_file(
const string& file)
const
103 if (!f)
return false;
105 for (
unsigned int i = 0; i < m_x.size(); i++)
106 os::fprintf(f,
"%f %f %f\n", m_x[i], m_y[i], m_z[i]);
117 bool CPointsMap::load2Dor3D_from_text_file(
125 if (!f)
return false;
128 char *ptr, *ptr1, *ptr2, *ptr3;
137 if (!fgets(str,
sizeof(str), f))
break;
141 while (ptr[0] && (ptr[0] ==
' ' || ptr[0] ==
'\t' || ptr[0] ==
'\r' ||
146 float xx = strtod(ptr, &ptr1);
149 float yy = strtod(ptr1, &ptr2);
154 this->insertPoint(xx, yy, 0);
158 float zz = strtod(ptr2, &ptr3);
161 this->insertPoint(xx, yy, zz);
182 mxArray* CPointsMap::writeToMatlab()
const
185 MRPT_TODO(
"Create 3xN array xyz of points coordinates")
186 const
char* fields[] = {
"x",
"y",
"z"};
187 mexplus::MxArray map_struct(
188 mexplus::MxArray::Struct(
sizeof(fields) /
sizeof(fields[0]), fields));
190 map_struct.set(
"x", m_x);
191 map_struct.set(
"y", m_y);
192 map_struct.set(
"z", m_z);
193 return map_struct.release();
203 unsigned long CPointsMap::getPoint(
size_t index,
float&
x,
float&
y)
const
209 return getPointWeight(
index);
211 unsigned long CPointsMap::getPoint(
212 size_t index,
float&
x,
float&
y,
float&
z)
const
219 return getPointWeight(
index);
221 unsigned long CPointsMap::getPoint(
size_t index,
double&
x,
double&
y)
const
227 return getPointWeight(
index);
230 unsigned long CPointsMap::getPoint(
231 size_t index,
double&
x,
double&
y,
double&
z)
const
238 return getPointWeight(
index);
245 void CPointsMap::getPointsBuffer(
246 size_t& outPointsCount,
const float*& xs,
const float*& ys,
247 const float*& zs)
const
249 outPointsCount =
size();
251 if (outPointsCount > 0)
259 xs = ys = zs =
nullptr;
266 void CPointsMap::clipOutOfRangeInZ(
float zMin,
float zMax)
268 const size_t n =
size();
269 vector<bool> deletionMask(
n);
272 for (
size_t i = 0; i <
n; i++)
273 deletionMask[i] = (m_z[i] < zMin || m_z[i] > zMax);
276 applyDeletionMask(deletionMask);
284 void CPointsMap::clipOutOfRange(
const TPoint2D&
p,
float maxRange)
286 size_t i,
n =
size();
287 vector<bool> deletionMask;
290 deletionMask.resize(
n);
292 const auto max_sq = maxRange * maxRange;
295 for (i = 0; i <
n; i++)
296 deletionMask[i] =
square(
p.x - m_x[i]) +
square(
p.y - m_y[i]) > max_sq;
299 applyDeletionMask(deletionMask);
304 void CPointsMap::determineMatching2D(
315 params.offset_other_map_points,
params.decimation_other_map_points);
320 otherMapPose_.
x(), otherMapPose_.
y(), otherMapPose_.
phi());
322 const size_t nLocalPoints = otherMap->
size();
323 const size_t nGlobalPoints = this->
size();
324 float _sumSqrDist = 0;
325 size_t _sumSqrCount = 0;
326 size_t nOtherMapPointsWithCorrespondence =
329 float local_x_min = std::numeric_limits<float>::max(),
330 local_x_max = -std::numeric_limits<float>::max();
331 float global_x_min = std::numeric_limits<float>::max(),
332 global_x_max = -std::numeric_limits<float>::max();
333 float local_y_min = std::numeric_limits<float>::max(),
334 local_y_max = -std::numeric_limits<float>::max();
335 float global_y_min = std::numeric_limits<float>::max(),
336 global_y_max = -std::numeric_limits<float>::max();
338 double maxDistForCorrespondenceSquared;
339 float x_local, y_local;
340 unsigned int localIdx;
342 const float *x_other_it, *y_other_it, *z_other_it;
345 correspondences.clear();
346 correspondences.reserve(nLocalPoints);
347 extraResults.correspondencesRatio = 0;
350 _correspondences.reserve(nLocalPoints);
353 if (!nGlobalPoints || !nLocalPoints)
return;
355 const double sin_phi = sin(otherMapPose.
phi);
356 const double cos_phi = cos(otherMapPose.
phi);
364 size_t nPackets = nLocalPoints / 4;
366 Eigen::ArrayXf x_locals(nLocalPoints), y_locals(nLocalPoints);
369 const __m128 cos_4val = _mm_set1_ps(cos_phi);
370 const __m128 sin_4val = _mm_set1_ps(sin_phi);
371 const __m128 x0_4val = _mm_set1_ps(otherMapPose.
x);
372 const __m128 y0_4val = _mm_set1_ps(otherMapPose.
y);
375 __m128 x_mins = _mm_set1_ps(std::numeric_limits<float>::max());
377 __m128 y_mins = x_mins;
378 __m128 y_maxs = x_maxs;
380 const float* ptr_in_x = &otherMap->
m_x[0];
381 const float* ptr_in_y = &otherMap->
m_y[0];
382 float* ptr_out_x = &x_locals[0];
383 float* ptr_out_y = &y_locals[0];
385 for (; nPackets; nPackets--, ptr_in_x += 4, ptr_in_y += 4, ptr_out_x += 4,
388 const __m128 xs = _mm_loadu_ps(ptr_in_x);
389 const __m128 ys = _mm_loadu_ps(ptr_in_y);
391 const __m128 lxs = _mm_add_ps(
393 _mm_sub_ps(_mm_mul_ps(xs, cos_4val), _mm_mul_ps(ys, sin_4val)));
394 const __m128 lys = _mm_add_ps(
396 _mm_add_ps(_mm_mul_ps(xs, sin_4val), _mm_mul_ps(ys, cos_4val)));
397 _mm_store_ps(ptr_out_x, lxs);
398 _mm_store_ps(ptr_out_y, lys);
400 x_mins = _mm_min_ps(x_mins, lxs);
401 x_maxs = _mm_max_ps(x_maxs, lxs);
402 y_mins = _mm_min_ps(y_mins, lys);
403 y_maxs = _mm_max_ps(y_maxs, lys);
409 _mm_store_ps(temp_nums, x_mins);
411 min(
min(temp_nums[0], temp_nums[1]),
min(temp_nums[2], temp_nums[3]));
412 _mm_store_ps(temp_nums, y_mins);
414 min(
min(temp_nums[0], temp_nums[1]),
min(temp_nums[2], temp_nums[3]));
415 _mm_store_ps(temp_nums, x_maxs);
417 max(max(temp_nums[0], temp_nums[1]), max(temp_nums[2], temp_nums[3]));
418 _mm_store_ps(temp_nums, y_maxs);
420 max(max(temp_nums[0], temp_nums[1]), max(temp_nums[2], temp_nums[3]));
423 for (
size_t k = 0; k < nLocalPoints % 4; k++)
425 float x = ptr_in_x[k];
426 float y = ptr_in_y[k];
427 float out_x = otherMapPose.
x + cos_phi *
x - sin_phi *
y;
428 float out_y = otherMapPose.
y + sin_phi *
x + cos_phi *
y;
430 local_x_min =
std::min(local_x_min, out_x);
431 local_x_max = std::max(local_x_max, out_x);
433 local_y_min =
std::min(local_y_min, out_y);
434 local_y_max = std::max(local_y_max, out_y);
436 ptr_out_x[k] = out_x;
437 ptr_out_y[k] = out_y;
442 const Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, 1>> x_org(
443 const_cast<float*
>(&otherMap->
m_x[0]), otherMap->
m_x.size(), 1);
444 const Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, 1>> y_org(
445 const_cast<float*
>(&otherMap->
m_y[0]), otherMap->
m_y.size(), 1);
447 Eigen::Array<float, Eigen::Dynamic, 1> x_locals =
448 otherMapPose.
x + cos_phi * x_org.array() - sin_phi * y_org.array();
449 Eigen::Array<float, Eigen::Dynamic, 1> y_locals =
450 otherMapPose.
y + sin_phi * x_org.array() + cos_phi * y_org.array();
452 local_x_min = x_locals.minCoeff();
453 local_y_min = y_locals.minCoeff();
454 local_x_max = x_locals.maxCoeff();
455 local_y_max = y_locals.maxCoeff();
459 float global_z_min, global_z_max;
461 global_x_min, global_x_max, global_y_min, global_y_max, global_z_min,
466 if (local_x_min > global_x_max || local_x_max < global_x_min ||
467 local_y_min > global_y_max || local_y_max < global_y_min)
472 for (localIdx =
params.offset_other_map_points,
473 x_other_it = &otherMap->
m_x[
params.offset_other_map_points],
474 y_other_it = &otherMap->
m_y[
params.offset_other_map_points],
475 z_other_it = &otherMap->
m_z[
params.offset_other_map_points];
476 localIdx < nLocalPoints;
477 x_other_it +=
params.decimation_other_map_points,
478 y_other_it +=
params.decimation_other_map_points,
479 z_other_it +=
params.decimation_other_map_points,
480 localIdx +=
params.decimation_other_map_points)
483 x_local = x_locals[localIdx];
484 y_local = y_locals[localIdx];
493 float tentativ_err_sq;
494 unsigned int tentativ_this_idx = kdTreeClosestPoint2D(
500 maxDistForCorrespondenceSquared =
square(
501 params.maxAngularDistForCorrespondence *
505 params.maxDistForCorrespondence);
508 if (tentativ_err_sq < maxDistForCorrespondenceSquared)
511 _correspondences.resize(_correspondences.size() + 1);
515 p.this_idx = tentativ_this_idx;
516 p.this_x = m_x[tentativ_this_idx];
517 p.this_y = m_y[tentativ_this_idx];
518 p.this_z = m_z[tentativ_this_idx];
520 p.other_idx = localIdx;
521 p.other_x = *x_other_it;
522 p.other_y = *y_other_it;
523 p.other_z = *z_other_it;
525 p.errorSquareAfterTransformation = tentativ_err_sq;
528 nOtherMapPointsWithCorrespondence++;
531 _sumSqrDist +=
p.errorSquareAfterTransformation;
541 if (
params.onlyUniqueRobust)
544 params.onlyKeepTheClosest,
545 "ERROR: onlyKeepTheClosest must be also set to true when "
546 "onlyUniqueRobust=true.");
548 nGlobalPoints, correspondences);
552 correspondences.swap(_correspondences);
558 extraResults.sumSqrDist =
559 _sumSqrDist /
static_cast<double>(_sumSqrCount);
561 extraResults.sumSqrDist = 0;
564 extraResults.correspondencesRatio =
params.decimation_other_map_points *
565 nOtherMapPointsWithCorrespondence /
566 static_cast<float>(nLocalPoints);
574 void CPointsMap::changeCoordinatesReference(
const CPose2D& newBase)
576 const size_t N = m_x.size();
578 const CPose3D newBase3D(newBase);
580 for (
size_t i = 0; i < N; i++)
582 m_x[i], m_y[i], m_z[i],
583 m_x[i], m_y[i], m_z[i]
592 void CPointsMap::changeCoordinatesReference(
const CPose3D& newBase)
594 const size_t N = m_x.size();
596 for (
size_t i = 0; i < N; i++)
598 m_x[i], m_y[i], m_z[i],
599 m_x[i], m_y[i], m_z[i]
608 void CPointsMap::changeCoordinatesReference(
612 changeCoordinatesReference(newBase);
618 bool CPointsMap::isEmpty()
const {
return m_x.empty(); }
622 CPointsMap::TInsertionOptions::TInsertionOptions()
623 : minDistBetweenLaserPoints(0.02f),
624 addToExistingPointsMap(true),
625 also_interpolate(false),
626 disableDeletion(true),
627 fuseWithExisting(false),
629 horizontalTolerance(
DEG2RAD(0.05)),
630 maxDistForInterpolatePoints(2.0f),
631 insertInvalidPoints(false)
642 out << minDistBetweenLaserPoints << addToExistingPointsMap
643 << also_interpolate << disableDeletion << fuseWithExisting
644 << isPlanarMap << horizontalTolerance << maxDistForInterpolatePoints
645 << insertInvalidPoints;
657 in >> minDistBetweenLaserPoints >> addToExistingPointsMap >>
658 also_interpolate >> disableDeletion >> fuseWithExisting >>
659 isPlanarMap >> horizontalTolerance >>
660 maxDistForInterpolatePoints >> insertInvalidPoints;
669 : sigma_dist(0.0025), max_corr_distance(1.0), decimation(10)
678 out << sigma_dist << max_corr_distance << decimation;
690 in >> sigma_dist >> max_corr_distance >> decimation;
715 in >> point_size >> this->
color;
726 out <<
"\n----------- [CPointsMap::TInsertionOptions] ------------ \n\n";
745 out <<
"\n----------- [CPointsMap::TLikelihoodOptions] ------------ \n\n";
754 out <<
"\n----------- [CPointsMap::TRenderOptions] ------------ \n\n";
811 obj->loadFromPointsMap(
this);
814 obj->enableColorFromZ(
true);
822 obj->loadFromPointsMap(
this);
826 obj->recolorizeByCoordinate(
859 float maxDistSq = 0, d;
860 for (
auto X =
m_x.begin(), Y =
m_y.begin(), Z =
m_z.begin();
861 X !=
m_x.end(); ++X, ++Y, ++Z)
864 maxDistSq = max(d, maxDistSq);
877 vector<float>& xs, vector<float>& ys,
size_t decimation)
const
883 xs = vector<float>(
m_x.begin(),
m_x.end());
884 ys = vector<float>(
m_y.begin(),
m_y.end());
888 size_t N =
m_x.size() / decimation;
893 auto X =
m_x.begin();
894 auto Y =
m_y.begin();
895 for (
auto oX = xs.begin(), oY = ys.begin(); oX != xs.end();
896 X += decimation, Y += decimation, ++oX, ++oY)
909 float x0,
float y0)
const
917 float x1, y1, x2, y2, d1, d2;
928 if (d12 > 0.20f * 0.20f || d12 < 0.03f * 0.03f)
934 double interp_x, interp_y;
952 float& min_x,
float& max_x,
float& min_y,
float& max_y,
float& min_z,
955 const size_t nPoints =
m_x.size();
970 size_t nPackets = nPoints / 4;
973 __m128 x_mins = _mm_set1_ps(std::numeric_limits<float>::max());
975 __m128 y_mins = x_mins, y_maxs = x_maxs;
976 __m128 z_mins = x_mins, z_maxs = x_maxs;
978 const float* ptr_in_x = &
m_x[0];
979 const float* ptr_in_y = &
m_y[0];
980 const float* ptr_in_z = &
m_z[0];
983 nPackets--, ptr_in_x += 4, ptr_in_y += 4, ptr_in_z += 4)
985 const __m128 xs = _mm_loadu_ps(ptr_in_x);
986 x_mins = _mm_min_ps(x_mins, xs);
987 x_maxs = _mm_max_ps(x_maxs, xs);
989 const __m128 ys = _mm_loadu_ps(ptr_in_y);
990 y_mins = _mm_min_ps(y_mins, ys);
991 y_maxs = _mm_max_ps(y_maxs, ys);
993 const __m128 zs = _mm_loadu_ps(ptr_in_z);
994 z_mins = _mm_min_ps(z_mins, zs);
995 z_maxs = _mm_max_ps(z_maxs, zs);
1001 _mm_store_ps(temp_nums, x_mins);
1003 min(
min(temp_nums[0], temp_nums[1]),
1004 min(temp_nums[2], temp_nums[3]));
1005 _mm_store_ps(temp_nums, y_mins);
1007 min(
min(temp_nums[0], temp_nums[1]),
1008 min(temp_nums[2], temp_nums[3]));
1009 _mm_store_ps(temp_nums, z_mins);
1011 min(
min(temp_nums[0], temp_nums[1]),
1012 min(temp_nums[2], temp_nums[3]));
1013 _mm_store_ps(temp_nums, x_maxs);
1015 max(max(temp_nums[0], temp_nums[1]),
1016 max(temp_nums[2], temp_nums[3]));
1017 _mm_store_ps(temp_nums, y_maxs);
1019 max(max(temp_nums[0], temp_nums[1]),
1020 max(temp_nums[2], temp_nums[3]));
1021 _mm_store_ps(temp_nums, z_maxs);
1023 max(max(temp_nums[0], temp_nums[1]),
1024 max(temp_nums[2], temp_nums[3]));
1027 for (
size_t k = 0; k < nPoints % 4; k++)
1041 (std::numeric_limits<float>::max)();
1044 -(std::numeric_limits<float>::max)();
1046 for (
auto xi =
m_x.begin(), yi =
m_y.begin(), zi =
m_z.begin();
1047 xi !=
m_x.end(); xi++, yi++, zi++)
1083 params.offset_other_map_points,
params.decimation_other_map_points);
1088 const size_t nLocalPoints = otherMap->
size();
1089 const size_t nGlobalPoints = this->
size();
1090 float _sumSqrDist = 0;
1091 size_t _sumSqrCount = 0;
1092 size_t nOtherMapPointsWithCorrespondence =
1095 float local_x_min = std::numeric_limits<float>::max(),
1096 local_x_max = -std::numeric_limits<float>::max();
1097 float local_y_min = std::numeric_limits<float>::max(),
1098 local_y_max = -std::numeric_limits<float>::max();
1099 float local_z_min = std::numeric_limits<float>::max(),
1100 local_z_max = -std::numeric_limits<float>::max();
1102 double maxDistForCorrespondenceSquared;
1105 correspondences.clear();
1106 correspondences.reserve(nLocalPoints);
1109 _correspondences.reserve(nLocalPoints);
1112 if (!nGlobalPoints || !nLocalPoints)
return;
1116 vector<float> x_locals(nLocalPoints), y_locals(nLocalPoints),
1117 z_locals(nLocalPoints);
1119 for (
unsigned int localIdx =
params.offset_other_map_points;
1120 localIdx < nLocalPoints;
1121 localIdx +=
params.decimation_other_map_points)
1123 float x_local, y_local, z_local;
1125 otherMap->
m_x[localIdx], otherMap->
m_y[localIdx],
1126 otherMap->
m_z[localIdx], x_local, y_local, z_local);
1128 x_locals[localIdx] = x_local;
1129 y_locals[localIdx] = y_local;
1130 z_locals[localIdx] = z_local;
1133 local_x_min =
min(local_x_min, x_local);
1134 local_x_max = max(local_x_max, x_local);
1135 local_y_min =
min(local_y_min, y_local);
1136 local_y_max = max(local_y_max, y_local);
1137 local_z_min =
min(local_z_min, z_local);
1138 local_z_max = max(local_z_max, z_local);
1142 float global_x_min, global_x_max, global_y_min, global_y_max, global_z_min,
1145 global_x_min, global_x_max, global_y_min, global_y_max, global_z_min,
1150 if (local_x_min > global_x_max || local_x_max < global_x_min ||
1151 local_y_min > global_y_max || local_y_max < global_y_min)
1156 for (
unsigned int localIdx =
params.offset_other_map_points;
1157 localIdx < nLocalPoints;
1158 localIdx +=
params.decimation_other_map_points)
1161 const float x_local = x_locals[localIdx];
1162 const float y_local = y_locals[localIdx];
1163 const float z_local = z_locals[localIdx];
1171 float tentativ_err_sq;
1173 x_local, y_local, z_local,
1178 maxDistForCorrespondenceSquared =
square(
1179 params.maxAngularDistForCorrespondence *
1180 params.angularDistPivotPoint.distanceTo(
1181 TPoint3D(x_local, y_local, z_local)) +
1182 params.maxDistForCorrespondence);
1185 if (tentativ_err_sq < maxDistForCorrespondenceSquared)
1188 _correspondences.resize(_correspondences.size() + 1);
1192 p.this_idx = tentativ_this_idx;
1193 p.this_x =
m_x[tentativ_this_idx];
1194 p.this_y =
m_y[tentativ_this_idx];
1195 p.this_z =
m_z[tentativ_this_idx];
1197 p.other_idx = localIdx;
1198 p.other_x = otherMap->
m_x[localIdx];
1199 p.other_y = otherMap->
m_y[localIdx];
1200 p.other_z = otherMap->
m_z[localIdx];
1202 p.errorSquareAfterTransformation = tentativ_err_sq;
1205 nOtherMapPointsWithCorrespondence++;
1208 _sumSqrDist +=
p.errorSquareAfterTransformation;
1219 if (
params.onlyUniqueRobust)
1222 params.onlyKeepTheClosest,
1223 "ERROR: onlyKeepTheClosest must be also set to true when "
1224 "onlyUniqueRobust=true.");
1226 nGlobalPoints, correspondences);
1230 correspondences.swap(_correspondences);
1235 extraResults.sumSqrDist =
1236 (_sumSqrCount) ? _sumSqrDist /
static_cast<double>(_sumSqrCount) : 0;
1237 extraResults.correspondencesRatio =
params.decimation_other_map_points *
1238 nOtherMapPointsWithCorrespondence /
1239 static_cast<float>(nLocalPoints);
1248 const TPoint2D& center,
const double radius,
const double zmin,
1252 for (
size_t k = 0; k <
m_x.size(); k++)
1266 const double&
R,
const double&
G,
const double& B)
1269 double minX, maxX, minY, maxY, minZ, maxZ;
1270 minX =
min(corner1.
x, corner2.
x);
1271 maxX = max(corner1.
x, corner2.
x);
1272 minY =
min(corner1.
y, corner2.
y);
1273 maxY = max(corner1.
y, corner2.
y);
1274 minZ =
min(corner1.
z, corner2.
z);
1275 maxZ = max(corner1.
z, corner2.
z);
1276 for (
size_t k = 0; k <
m_x.size(); k++)
1278 if ((
m_x[k] >= minX &&
m_x[k] <= maxX) &&
1279 (
m_y[k] >= minY &&
m_y[k] <= maxY) &&
1280 (
m_z[k] >= minZ &&
m_z[k] <= maxZ))
1291 float& correspondencesRatio)
1298 const size_t nLocalPoints = otherMap->
size();
1299 const size_t nGlobalPoints = this->
size();
1300 size_t nOtherMapPointsWithCorrespondence =
1304 correspondences.clear();
1305 correspondences.reserve(nLocalPoints);
1306 correspondencesRatio = 0;
1310 _correspondences.reserve(nLocalPoints);
1313 if (!nGlobalPoints)
return;
1316 if (!nLocalPoints)
return;
1319 float local_x_min, local_x_max, local_y_min, local_y_max, local_z_min,
1322 local_x_min, local_x_max, local_y_min, local_y_max, local_z_min,
1326 float global_x_min, global_x_max, global_y_min, global_y_max, global_z_min,
1329 global_x_min, global_x_max, global_y_min, global_y_max, global_z_min,
1334 if (local_x_min > global_x_max || local_x_max < global_x_min ||
1335 local_y_min > global_y_max || local_y_max < global_y_min)
1339 std::vector<std::vector<size_t>> vIdx;
1344 std::vector<size_t> outIdx;
1345 for (
unsigned int localIdx = 0; localIdx < nLocalPoints; ++localIdx)
1348 const float x_local = otherMap->
m_x[localIdx];
1349 const float y_local = otherMap->
m_y[localIdx];
1350 const float z_local = otherMap->
m_z[localIdx];
1358 x_local, y_local, z_local,
1374 if (distanceForThisPoint < maxDistForCorrespondence)
1377 _correspondences.resize(_correspondences.size() + 1);
1381 p.this_idx = nOtherMapPointsWithCorrespondence++;
1388 p.other_idx = localIdx;
1389 p.other_x = otherMap->
m_x[localIdx];
1390 p.other_y = otherMap->
m_y[localIdx];
1391 p.other_z = otherMap->
m_z[localIdx];
1393 p.errorSquareAfterTransformation = distanceForThisPoint;
1396 std::sort(outIdx.begin(), outIdx.end());
1397 vIdx.push_back(outIdx);
1406 std::map<size_t, std::map<size_t, std::map<size_t, pair<size_t, float>>>>
1409 for (it = _correspondences.begin(); it != _correspondences.end(); ++it)
1411 const size_t i0 = vIdx[it->this_idx][0];
1412 const size_t i1 = vIdx[it->this_idx][1];
1413 const size_t i2 = vIdx[it->this_idx][2];
1415 if (best.find(i0) != best.end() &&
1416 best[i0].find(i1) != best[i0].end() &&
1417 best[i0][i1].find(i2) !=
1421 if (best[i0][i1][i2].second > it->errorSquareAfterTransformation)
1423 best[i0][i1][i2].first = it->this_idx;
1424 best[i0][i1][i2].second = it->errorSquareAfterTransformation;
1429 best[i0][i1][i2].first = it->this_idx;
1430 best[i0][i1][i2].second = it->errorSquareAfterTransformation;
1434 for (it = _correspondences.begin(); it != _correspondences.end(); ++it)
1436 const size_t i0 = vIdx[it->this_idx][0];
1437 const size_t i1 = vIdx[it->this_idx][1];
1438 const size_t i2 = vIdx[it->this_idx][2];
1440 if (best[i0][i1][i2].
first == it->this_idx)
1441 correspondences.push_back(*it);
1445 correspondencesRatio =
1446 nOtherMapPointsWithCorrespondence /
static_cast<float>(nLocalPoints);
1477 float sumSqrDist = 0;
1479 const size_t N = scanPoints->
m_x.size();
1480 if (!N || !this->
size())
return -100;
1482 const float* xs = &scanPoints->
m_x[0];
1483 const float* ys = &scanPoints->
m_y[0];
1484 const float* zs = &scanPoints->
m_z[0];
1486 float closest_x, closest_y, closest_z;
1489 int nPtsForAverage = 0;
1496 const float ccos = cos(takenFrom2D.
phi);
1497 const float csin = sin(takenFrom2D.
phi);
1499 for (
size_t i = 0; i < N;
1504 const float xg = takenFrom2D.
x + ccos * xs[i] - csin * ys[i];
1505 const float yg = takenFrom2D.
y + csin * xs[i] + ccos * ys[i];
1509 closest_x, closest_y,
1516 sumSqrDist += closest_err;
1523 for (
size_t i = 0; i < N;
1529 takenFrom.
composePoint(xs[i], ys[i], zs[i], xg, yg, zg);
1533 closest_x, closest_y,
1541 sumSqrDist += closest_err;
1545 sumSqrDist /= nPtsForAverage;
1558 double sumSqrDist = 0;
1565 if (!N || !this->
size())
return -100;
1573 float closest_x, closest_y, closest_z;
1576 int nPtsForAverage = 0;
1578 for (
size_t i = 0; i < N;
1584 sensorAbsPose.
composePoint(xs[i], ys[i], zs[i], xg, yg, zg);
1588 closest_x, closest_y,
1596 sumSqrDist += closest_err;
1599 sumSqrDist /= nPtsForAverage;
1629 if (out_map)
return;
1631 out_map = mrpt::make_aligned_shared<CSimplePointsMap>();
1637 out_map->insertObservation(&obs,
nullptr);
1680 pt_has_color =
false;
1691 const size_t nThis = this->
size();
1692 const size_t nOther = anotherMap.
size();
1694 const size_t nTot = nThis + nOther;
1698 for (
size_t i = 0, j = nThis; i < nOther; i++, j++)
1700 m_x[j] = anotherMap.
m_x[i];
1701 m_y[j] = anotherMap.
m_y[i];
1702 m_z[j] = anotherMap.
m_z[i];
1714 const std::string& filename,
bool save_as_binary)
const
1717 pcl::PointCloud<pcl::PointXYZ> cloud;
1720 return 0 == pcl::io::savePCDFile(filename, cloud, save_as_binary);
1725 THROW_EXCEPTION(
"Operation not available: MRPT was built without PCL");
1734 pcl::PointCloud<pcl::PointXYZ> cloud;
1735 if (0 != pcl::io::loadPCDFile(filename, cloud))
return false;
1742 THROW_EXCEPTION(
"Operation not available: MRPT was built without PCL");
1753 const size_t n =
mask.size();
1756 for (i = 0, j = 0; i <
n; i++)
1778 const size_t N_this =
size();
1779 const size_t N_other = otherMap->
size();
1782 this->
resize(N_this + N_other);
1810 if (
this == &
obj)
return;
1817 obj.m_largestDistanceFromOriginIsUpdated;
1843 robotPose2D =
CPose2D(*robotPose);
1844 robotPose3D = (*robotPose);
1861 bool reallyInsertIt;
1867 reallyInsertIt =
true;
1871 std::vector<bool> checkForDeletion;
1901 const float *xs, *ys, *zs;
1908 for (
size_t i = 0; i <
n; i++)
1910 if (checkForDeletion[i])
1917 checkForDeletion[i] =
1953 bool reallyInsertIt;
1959 reallyInsertIt =
true;
2026 const CPose3D sensorPose = robotPose3D +
CPose3D(it->sensorPose);
2027 const double rang = it->sensedDistance;
2029 if (rang <= 0 || rang < o->minSensorDistance ||
2035 const unsigned int nSteps =
round(1 + arc_len / 0.05);
2039 for (
double a1 = -aper_2;
a1 < aper_2;
a1 += Aa)
2041 for (
double a2 = -aper_2;
a2 < aper_2;
a2 += Aa)
2043 loc.
x = cos(
a1) * cos(
a2) * rang;
2044 loc.
y = cos(
a1) * sin(
a2) * rang;
2045 loc.
z = sin(
a1) * rang;
2106 std::vector<bool>* notFusedPoints)
2110 const CPose2D nullPose(0, 0, 0);
2115 const size_t nOther = otherMap->
size();
2122 params.maxAngularDistForCorrespondence = 0;
2123 params.maxDistForCorrespondence = minDistForFuse;
2128 correspondences,
params, extraResults);
2133 notFusedPoints->clear();
2134 notFusedPoints->reserve(
m_x.size() + nOther);
2135 notFusedPoints->resize(
m_x.size(),
true);
2144 for (
size_t i = 0; i < nOther; i++)
2146 const unsigned long w_a =
2150 int closestCorr = -1;
2151 float minDist = std::numeric_limits<float>::max();
2153 correspondences.begin();
2154 corrsIt != correspondences.end(); ++corrsIt)
2156 if (corrsIt->other_idx == i)
2158 float dist =
square(corrsIt->other_x - corrsIt->this_x) +
2159 square(corrsIt->other_y - corrsIt->this_y) +
2160 square(corrsIt->other_z - corrsIt->this_z);
2164 closestCorr = corrsIt->this_idx;
2169 if (closestCorr != -1)
2171 unsigned long w_b =
getPoint(closestCorr,
b);
2175 const float F = 1.0f / (w_a + w_b);
2177 m_x[closestCorr] = F * (w_a *
a.x + w_b *
b.x);
2178 m_y[closestCorr] = F * (w_a *
a.y + w_b *
b.y);
2179 m_z[closestCorr] = F * (w_a *
a.z + w_b *
b.z);
2184 if (notFusedPoints) (*notFusedPoints)[closestCorr] =
false;
2189 if (notFusedPoints) (*notFusedPoints).push_back(
false);
2212 const size_t nOldPtsCount = this->
size();
2214 const size_t nNewPtsCount = nOldPtsCount + nScanPts;
2215 this->
resize(nNewPtsCount);
2217 const float K = 1.0f / 255;
2222 sensorGlobalPose = *robotPose + scan.
sensorPose;
2229 const double m00 = HM.get_unsafe(0, 0), m01 = HM.get_unsafe(0, 1),
2230 m02 = HM.get_unsafe(0, 2), m03 = HM.get_unsafe(0, 3);
2231 const double m10 = HM.get_unsafe(1, 0), m11 = HM.get_unsafe(1, 1),
2232 m12 = HM.get_unsafe(1, 2), m13 = HM.get_unsafe(1, 3);
2233 const double m20 = HM.get_unsafe(2, 0), m21 = HM.get_unsafe(2, 1),
2234 m22 = HM.get_unsafe(2, 2), m23 = HM.get_unsafe(2, 3);
2237 for (
size_t i = 0; i < nScanPts; i++)
2244 const double gx = m00 * lx + m01 * ly + m02 * lz + m03;
2245 const double gy = m10 * lx + m11 * ly + m12 * lz + m13;
2246 const double gz = m20 * lx + m21 * ly + m22 * lz + m23;
2249 nOldPtsCount + i, gx, gy, gz,