56 precomputedLikelihoodToBeRecomputed =
true;
60 robotPose2D =
CPose2D(*robotPose);
61 robotPose3D = (*robotPose);
69 const float maxCertainty = insertionOptions.maxOccupancyUpdateCertainty;
70 float maxFreeCertainty = insertionOptions.maxFreenessUpdateCertainty;
71 if (maxFreeCertainty == .0f) maxFreeCertainty = maxCertainty;
72 float maxFreeCertaintyNoEcho = insertionOptions.maxFreenessInvalidRanges;
73 if (maxFreeCertaintyNoEcho == .0f) maxFreeCertaintyNoEcho = maxCertainty;
76 std::max<cellType>(1, p2l(maxFreeCertainty));
77 cellType logodd_observation_occupied =
78 3 * std::max<cellType>(1, p2l(maxCertainty));
80 std::max<cellType>(1, p2l(maxFreeCertaintyNoEcho));
84 OCCGRID_CELLTYPE_MIN + logodd_observation_occupied;
86 OCCGRID_CELLTYPE_MAX -
87 std::max(logodd_noecho_free, logodd_observation_free);
99 CPose2D laserPose(sensorPose3D);
105 unsigned int decimation = insertionOptions.decimation;
108 if (insertionOptions.useMapAltitude &&
109 fabs(insertionOptions.mapAltitude - sensorPose3D.z()) > 0.001)
111 reallyInsert =
false;
117 bool sensorIsBottomwards =
131 const float maxDistanceInsertion =
132 insertionOptions.maxDistanceInsertion;
133 const bool invalidAsFree =
134 insertionOptions.considerInvalidRangesAsFreeSpace;
135 float new_x_max, new_x_min;
136 float new_y_max, new_y_min;
137 float last_valid_range = maxDistanceInsertion;
139 int K = updateInfoChangeOnly.enabled
140 ? updateInfoChangeOnly.laserRaysSkip
142 size_t idx, nRanges = o->
scan.
size();
149 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG)
155 if (!insertionOptions.wideningBeamsWithDistance)
163 float* scanPoints_x =
165 float* scanPoints_y =
168 float *scanPoint_x, *scanPoint_y;
181 new_x_max = -(numeric_limits<float>::max)();
182 new_x_min = (numeric_limits<float>::max)();
183 new_y_max = -(numeric_limits<float>::max)();
184 new_y_min = (numeric_limits<float>::max)();
186 for (idx = 0, scanPoint_x = scanPoints_x,
187 scanPoint_y = scanPoints_y;
188 idx < nRanges; idx += K, scanPoint_x++, scanPoint_y++)
192 curRange = o->
scan[idx];
193 float R =
min(maxDistanceInsertion, curRange);
195 *scanPoint_x = px + cos(A) *
R;
196 *scanPoint_y = py + sin(A) *
R;
197 last_valid_range = curRange;
205 maxDistanceInsertion, 0.5f * last_valid_range);
206 *scanPoint_x = px + cos(A) *
R;
207 *scanPoint_y = py + sin(A) *
R;
218 new_x_max = max(new_x_max, *scanPoint_x);
219 new_x_min =
min(new_x_min, *scanPoint_x);
220 new_y_max = max(new_y_max, *scanPoint_y);
221 new_y_min =
min(new_y_min, *scanPoint_y);
225 float securMargen = 15 * resolution;
227 if (new_x_max > x_max - securMargen)
228 new_x_max += 2 * securMargen;
231 if (new_x_min < x_min + securMargen)
236 if (new_y_max > y_max - securMargen)
237 new_y_max += 2 * securMargen;
240 if (new_y_min < y_min + securMargen)
248 resizeGrid(new_x_min, new_x_max, new_y_min, new_y_max, 0.5);
252 unsigned theMapSize_x = size_x;
259 for (idx = 0; idx < nRanges; idx += K)
261 if (!o->
validRange[idx] && !invalidAsFree)
continue;
268 int trg_cx = x2idx(scanPoints_x[idx]);
269 int trg_cy = y2idx(scanPoints_y[idx]);
273 static_cast<unsigned int>(trg_cx) < size_x &&
274 static_cast<unsigned int>(trg_cy) < size_y);
278 int Acx = trg_cx - cx;
279 int Acy = trg_cy - cy;
284 int nStepsRay = max(Acx_, Acy_);
285 if (!nStepsRay)
continue;
288 float N_1 = 1.0f / nStepsRay;
292 (Acx < 0 ? -1 : +1) *
round((Acx_ <<
FRBITS) * N_1);
294 (Acy < 0 ? -1 : +1) *
round((Acy_ <<
FRBITS) * N_1);
299 ? logodd_observation_free
300 : logodd_noecho_free;
302 for (
int nStep = 0; nStep < nStepsRay; nStep++)
304 updateCell_fast_free(
305 cx, cy, logodd_free, logodd_thres_free, theMapArray,
320 o->
scan[idx] < maxDistanceInsertion)
321 updateCell_fast_occupied(
322 trg_cx, trg_cy, logodd_observation_occupied,
323 logodd_thres_occupied, theMapArray, theMapSize_x);
348 new_x_max = -(numeric_limits<float>::max)();
349 new_x_min = (numeric_limits<float>::max)();
350 new_y_max = -(numeric_limits<float>::max)();
351 new_y_min = (numeric_limits<float>::max)();
353 last_valid_range = maxDistanceInsertion;
354 for (idx = 0; idx < nRanges; idx += K)
356 float scanPoint_x, scanPoint_y;
359 curRange = o->
scan[idx];
360 float R =
min(maxDistanceInsertion, curRange);
362 scanPoint_x = px + cos(A) *
R;
363 scanPoint_y = py + sin(A) *
R;
364 last_valid_range = curRange;
372 maxDistanceInsertion, 0.5f * last_valid_range);
373 scanPoint_x = px + cos(A) *
R;
374 scanPoint_y = py + sin(A) *
R;
385 new_x_max = max(new_x_max, scanPoint_x);
386 new_x_min =
min(new_x_min, scanPoint_x);
387 new_y_max = max(new_y_max, scanPoint_y);
388 new_y_min =
min(new_y_min, scanPoint_y);
392 float securMargen = 15 * resolution;
394 if (new_x_max > x_max - securMargen)
395 new_x_max += 2 * securMargen;
398 if (new_x_min < x_min + securMargen)
403 if (new_y_max > y_max - securMargen)
404 new_y_max += 2 * securMargen;
407 if (new_y_min < y_min + securMargen)
415 resizeGrid(new_x_min, new_x_max, new_y_min, new_y_max, 0.5);
419 unsigned theMapSize_x = size_x;
444 last_valid_range = maxDistanceInsertion;
446 const double dA_2 = 0.5 * o->
aperture / N;
447 for (idx = 0; idx < nRanges; idx += K, A += dAK)
452 curRange = o->
scan[idx];
453 last_valid_range = curRange;
454 theR =
min(maxDistanceInsertion, curRange);
462 maxDistanceInsertion, 0.5f * last_valid_range);
467 if (theR < resolution)
480 P1.
x = px + cos(A - dA_2) * theR;
481 P1.
y = py + sin(A - dA_2) * theR;
483 P2.
x = px + cos(A + dA_2) * theR;
484 P2.
y = py + sin(A + dA_2) * theR;
487 if (P2.
y < P1.
y) std::swap(P2, P1);
488 if (P2.
y < P0.
y) std::swap(P2, P0);
489 if (P1.
y < P0.
y) std::swap(P1, P0);
499 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG)
502 static_cast<unsigned int>(P0.
cx) < size_x &&
503 static_cast<unsigned int>(P0.
cy) < size_y);
505 static_cast<unsigned int>(P1.
cx) < size_x &&
506 static_cast<unsigned int>(P1.
cy) < size_y);
508 static_cast<unsigned int>(P2.
cx) < size_x &&
509 static_cast<unsigned int>(P2.
cy) < size_y);
519 if (P0.
cy == P2.
cy && P0.
cy == P1.
cy)
525 for (
int ccx = min_cx; ccx <= max_cx; ccx++)
526 updateCell_fast_free(
527 ccx, P0.
cy, logodd_observation_free,
528 logodd_thres_free, theMapArray, theMapSize_x);
536 (P1.
y - P0.
y) * (P2.
x - P0.
x) / (P2.
y - P0.
y);
538 P1b.
cx = x2idx(P1b.
x);
539 P1b.
cy = y2idx(P1b.
y);
544 const int Acx01 = P1.
cx - P0.
cx;
545 const int Acy01 = P1.
cy - P0.
cy;
546 const int Acx01b = P1b.
cx - P0.
cx;
550 const float inv_N_01 =
551 1.0f / (
max3(abs(Acx01), abs(Acy01), abs(Acx01b)) +
553 const int frAcx01 =
round(
554 (Acx01 <<
FRBITS) * inv_N_01);
555 const int frAcy01 =
round(
556 (Acy01 <<
FRBITS) * inv_N_01);
557 const int frAcx01b =
round(
558 (Acx01b <<
FRBITS) * inv_N_01);
568 int frAx_R1 = 0, frAx_R2 = 0;
569 int frAy_R1 = frAcy01;
599 int last_insert_cy = -1;
603 if (last_insert_cy !=
606 last_insert_cy = R1.cy;
609 for (
int ccx = R1.cx; ccx <= R2.cx; ccx++)
610 updateCell_fast_free(
611 ccx, R1.cy, logodd_observation_free,
612 logodd_thres_free, theMapArray,
623 }
while (R1.cy < P1.
cy);
632 const int Acx12 = P2.
cx - P1.
cx;
633 const int Acy12 = P2.
cy - P1.
cy;
634 const int Acx1b2 = P2.
cx - P1b.
cx;
638 const float inv_N_12 =
639 1.0f / (
max3(abs(Acx12), abs(Acy12), abs(Acx1b2)) +
641 const int frAcx12 =
round(
642 (Acx12 <<
FRBITS) * inv_N_12);
643 const int frAcy12 =
round(
644 (Acy12 <<
FRBITS) * inv_N_12);
645 const int frAcx1b2 =
round(
646 (Acx1b2 <<
FRBITS) * inv_N_12);
685 last_insert_cy = -100;
690 if (last_insert_cy !=
694 last_insert_cy = R1.cy;
695 for (
int ccx = R1.cx; ccx <= R2.cx; ccx++)
696 updateCell_fast_free(
697 ccx, R1.cy, logodd_observation_free,
698 logodd_thres_free, theMapArray,
709 }
while (R1.cy <= P2.
cy);
720 o->
scan[idx] < maxDistanceInsertion)
724 P1.
x = px + cos(A - dA_2) * theR;
725 P1.
y = py + sin(A - dA_2) * theR;
727 P2.
x = px + cos(A + dA_2) * theR;
728 P2.
y = py + sin(A + dA_2) * theR;
735 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG)
738 static_cast<unsigned int>(P1.
cx) < size_x &&
739 static_cast<unsigned int>(P1.
cy) < size_y);
741 static_cast<unsigned int>(P2.
cx) < size_x &&
742 static_cast<unsigned int>(P2.
cy) < size_y);
746 if (P2.
cx == P1.
cx && P2.
cy == P1.
cy)
748 updateCell_fast_occupied(
749 P1.
cx, P1.
cy, logodd_observation_occupied,
750 logodd_thres_occupied, theMapArray,
758 const int AcxE = P2.
cx - P1.
cx;
759 const int AcyE = P2.
cy - P1.
cy;
762 const int nSteps = (max(abs(AcxE), abs(AcyE)) + 1);
763 const float inv_N_12 =
765 const int frAcxE =
round(
766 (AcxE <<
FRBITS) * inv_N_12);
767 const int frAcyE =
round(
768 (AcyE <<
FRBITS) * inv_N_12);
775 for (
int nStep = 0; nStep <= nSteps; nStep++)
777 updateCell_fast_occupied(
778 R1.cx, R1.cy, logodd_observation_occupied,
779 logodd_thres_occupied, theMapArray,
810 CPose3D sensorPose3D = robotPose3D + spose;
811 CPose2D laserPose(sensorPose3D);
815 bool reallyInsert =
true;
816 unsigned int decimation = insertionOptions.decimation;
819 if (insertionOptions.useMapAltitude &&
820 fabs(insertionOptions.mapAltitude - sensorPose3D.z()) > 0.001)
822 reallyInsert =
false;
835 const float maxDistanceInsertion =
836 insertionOptions.maxDistanceInsertion;
837 const bool invalidAsFree =
838 insertionOptions.considerInvalidRangesAsFreeSpace;
839 float new_x_max, new_x_min;
840 float new_y_max, new_y_min;
841 float last_valid_range = maxDistanceInsertion;
843 int K = updateInfoChangeOnly.enabled
844 ? updateInfoChangeOnly.laserRaysSkip
853 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG)
865 new_x_max = -(numeric_limits<float>::max)();
866 new_x_min = (numeric_limits<float>::max)();
867 new_y_max = -(numeric_limits<float>::max)();
868 new_y_min = (numeric_limits<float>::max)();
870 last_valid_range = maxDistanceInsertion;
872 for (idx = 0; idx < nRanges; idx += K)
874 float scanPoint_x, scanPoint_y;
875 if (o->
sensedData[idx].sensedDistance < maxDistanceInsertion)
878 float R =
min(maxDistanceInsertion, curRange);
880 scanPoint_x = px + cos(A) *
R;
881 scanPoint_y = py + sin(A) *
R;
882 last_valid_range = curRange;
890 min(maxDistanceInsertion, 0.5f * last_valid_range);
891 scanPoint_x = px + cos(A) *
R;
892 scanPoint_y = py + sin(A) *
R;
903 new_x_max = max(new_x_max, scanPoint_x);
904 new_x_min =
min(new_x_min, scanPoint_x);
905 new_y_max = max(new_y_max, scanPoint_y);
906 new_y_min =
min(new_y_min, scanPoint_y);
910 float securMargen = 15 * resolution;
912 if (new_x_max > x_max - securMargen)
913 new_x_max += 2 * securMargen;
916 if (new_x_min < x_min + securMargen)
921 if (new_y_max > y_max - securMargen)
922 new_y_max += 2 * securMargen;
925 if (new_y_min < y_min + securMargen)
933 resizeGrid(new_x_min, new_x_max, new_y_min, new_y_max, 0.5);
937 unsigned theMapSize_x = size_x;
953 last_valid_range = maxDistanceInsertion;
956 for (idx = 0; idx < nRanges; idx += K, A += dAK)
959 if (o->
sensedData[idx].sensedDistance < maxDistanceInsertion)
962 last_valid_range = curRange;
963 theR =
min(maxDistanceInsertion, curRange);
971 min(maxDistanceInsertion, 0.5f * last_valid_range);
976 if (theR < resolution)
987 P1.
x = px + cos(A - dA_2) * theR;
988 P1.
y = py + sin(A - dA_2) * theR;
990 P2.
x = px + cos(A + dA_2) * theR;
991 P2.
y = py + sin(A + dA_2) * theR;
994 if (P2.
y < P1.
y) std::swap(P2, P1);
995 if (P2.
y < P0.
y) std::swap(P2, P0);
996 if (P1.
y < P0.
y) std::swap(P1, P0);
1000 P0.
cy = y2idx(P0.
y);
1001 P1.
cx = x2idx(P1.
x);
1002 P1.
cy = y2idx(P1.
y);
1003 P2.
cx = x2idx(P2.
x);
1004 P2.
cy = y2idx(P2.
y);
1006 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG)
1009 static_cast<unsigned int>(P0.
cx) < size_x &&
1010 static_cast<unsigned int>(P0.
cy) < size_y);
1012 static_cast<unsigned int>(P1.
cx) < size_x &&
1013 static_cast<unsigned int>(P1.
cy) < size_y);
1015 static_cast<unsigned int>(P2.
cx) < size_x &&
1016 static_cast<unsigned int>(P2.
cy) < size_y);
1026 if (P0.
cy == P2.
cy && P0.
cy == P1.
cy)
1032 for (
int ccx = min_cx; ccx <= max_cx; ccx++)
1033 updateCell_fast_free(
1034 ccx, P0.
cy, logodd_observation_free,
1035 logodd_thres_free, theMapArray, theMapSize_x);
1043 P0.
x + (P1.
y - P0.
y) * (P2.
x - P0.
x) / (P2.
y - P0.
y);
1045 P1b.
cx = x2idx(P1b.
x);
1046 P1b.
cy = y2idx(P1b.
y);
1051 const int Acx01 = P1.
cx - P0.
cx;
1052 const int Acy01 = P1.
cy - P0.
cy;
1053 const int Acx01b = P1b.
cx - P0.
cx;
1057 const float inv_N_01 =
1058 1.0f / (
max3(abs(Acx01), abs(Acy01), abs(Acx01b)) +
1064 const int frAcx01b =
1075 int frAx_R1 = 0, frAx_R2 = 0;
1076 int frAy_R1 = frAcy01;
1105 int last_insert_cy = -1;
1109 if (last_insert_cy !=
1112 last_insert_cy = R1.cy;
1115 for (
int ccx = R1.cx; ccx <= R2.cx; ccx++)
1116 updateCell_fast_free(
1117 ccx, R1.cy, logodd_observation_free,
1118 logodd_thres_free, theMapArray,
1126 R1.cx = R1.frX >>
FRBITS;
1127 R1.cy = R1.frY >>
FRBITS;
1128 R2.cx = R2.frX >>
FRBITS;
1129 }
while (R1.cy < P1.
cy);
1137 const int Acx12 = P2.
cx - P1.
cx;
1138 const int Acy12 = P2.
cy - P1.
cy;
1139 const int Acx1b2 = P2.
cx - P1b.
cx;
1143 const float inv_N_12 =
1144 1.0f / (
max3(abs(Acx12), abs(Acy12), abs(Acx1b2)) +
1150 const int frAcx1b2 =
1185 R1.frX = R1.cx <<
FRBITS;
1186 R1.frY = R1.cy <<
FRBITS;
1187 R2.frX = R2.cx <<
FRBITS;
1188 R2.frY = R2.cy <<
FRBITS;
1190 last_insert_cy = -100;
1195 if (last_insert_cy !=
1199 last_insert_cy = R1.cy;
1200 for (
int ccx = R1.cx; ccx <= R2.cx; ccx++)
1201 updateCell_fast_free(
1202 ccx, R1.cy, logodd_observation_free,
1203 logodd_thres_free, theMapArray,
1211 R1.cx = R1.frX >>
FRBITS;
1212 R1.cy = R1.frY >>
FRBITS;
1213 R2.cx = R2.frX >>
FRBITS;
1214 }
while (R1.cy <= P2.
cy);
1224 if (o->
sensedData[idx].sensedDistance < maxDistanceInsertion)
1228 P1.
x = px + cos(A - dA_2) * theR;
1229 P1.
y = py + sin(A - dA_2) * theR;
1231 P2.
x = px + cos(A + dA_2) * theR;
1232 P2.
y = py + sin(A + dA_2) * theR;
1234 P1.
cx = x2idx(P1.
x);
1235 P1.
cy = y2idx(P1.
y);
1236 P2.
cx = x2idx(P2.
x);
1237 P2.
cy = y2idx(P2.
y);
1239 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG)
1242 static_cast<unsigned int>(P1.
cx) < size_x &&
1243 static_cast<unsigned int>(P1.
cy) < size_y);
1245 static_cast<unsigned int>(P2.
cx) < size_x &&
1246 static_cast<unsigned int>(P2.
cy) < size_y);
1250 if (P2.
cx == P1.
cx && P2.
cy == P1.
cy)
1252 updateCell_fast_occupied(
1253 P1.
cx, P1.
cy, logodd_observation_occupied,
1254 logodd_thres_occupied, theMapArray, theMapSize_x);
1261 const int AcxE = P2.
cx - P1.
cx;
1262 const int AcyE = P2.
cy - P1.
cy;
1265 const int nSteps = (max(abs(AcxE), abs(AcyE)) + 1);
1266 const float inv_N_12 =
1275 R1.frX = R1.cx <<
FRBITS;
1276 R1.frY = R1.cy <<
FRBITS;
1278 for (
int nStep = 0; nStep <= nSteps; nStep++)
1280 updateCell_fast_occupied(
1281 R1.cx, R1.cy, logodd_observation_occupied,
1282 logodd_thres_occupied, theMapArray,
1287 R1.cx = R1.frX >>
FRBITS;
1288 R1.cy = R1.frY >>
FRBITS;
1318 useMapAltitude(false),
1319 maxDistanceInsertion(15.0f),
1320 maxOccupancyUpdateCertainty(0.65f),
1321 maxFreenessUpdateCertainty(.0f),
1322 maxFreenessInvalidRanges(.0f),
1323 considerInvalidRangesAsFreeSpace(true),
1325 horizontalTolerance(
DEG2RAD(0.05)),
1327 CFD_features_gaussian_size(1),
1328 CFD_features_median_size(3),
1330 wideningBeamsWithDistance(false)
1347 considerInvalidRangesAsFreeSpace,
bool,
iniFile, section);
1360 std::ostream& out)
const
1363 "\n----------- [COccupancyGridMap2D::TInsertionOptions] ------------ "