55 precomputedLikelihoodToBeRecomputed =
true;
59 robotPose2D =
CPose2D(*robotPose);
60 robotPose3D = (*robotPose);
77 CPose2D laserPose(sensorPose3D);
83 unsigned int decimation = insertionOptions.decimation;
86 if (insertionOptions.useMapAltitude &&
87 fabs(insertionOptions.mapAltitude - sensorPose3D.z()) > 0.001)
95 bool sensorIsBottomwards =
108 const float maxDistanceInsertion =
109 insertionOptions.maxDistanceInsertion;
110 const bool invalidAsFree =
111 insertionOptions.considerInvalidRangesAsFreeSpace;
112 float new_x_max, new_x_min;
113 float new_y_max, new_y_min;
114 float last_valid_range = maxDistanceInsertion;
116 float maxCertainty = insertionOptions.maxOccupancyUpdateCertainty;
117 cellType logodd_observation = p2l(maxCertainty);
118 cellType logodd_observation_occupied = 3 * logodd_observation;
121 if (logodd_observation <= 0) logodd_observation = 1;
124 OCCGRID_CELLTYPE_MIN + logodd_observation_occupied;
126 OCCGRID_CELLTYPE_MAX - logodd_observation;
128 int K = updateInfoChangeOnly.enabled
129 ? updateInfoChangeOnly.laserRaysSkip
131 size_t idx, nRanges = o->
scan.
size();
138 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 144 if (!insertionOptions.wideningBeamsWithDistance)
152 float* scanPoints_x =
154 float* scanPoints_y =
157 float *scanPoint_x, *scanPoint_y;
170 new_x_max = -(numeric_limits<float>::max)();
171 new_x_min = (numeric_limits<float>::max)();
172 new_y_max = -(numeric_limits<float>::max)();
173 new_y_min = (numeric_limits<float>::max)();
175 for (idx = 0, scanPoint_x = scanPoints_x,
176 scanPoint_y = scanPoints_y;
177 idx < nRanges; idx += K, scanPoint_x++, scanPoint_y++)
181 curRange = o->
scan[idx];
182 float R =
min(maxDistanceInsertion, curRange);
184 *scanPoint_x = px + cos(A) *
R;
185 *scanPoint_y = py + sin(A) *
R;
186 last_valid_range = curRange;
194 maxDistanceInsertion, 0.5f * last_valid_range);
195 *scanPoint_x = px + cos(A) *
R;
196 *scanPoint_y = py + sin(A) *
R;
207 new_x_max = max(new_x_max, *scanPoint_x);
208 new_x_min =
min(new_x_min, *scanPoint_x);
209 new_y_max = max(new_y_max, *scanPoint_y);
210 new_y_min =
min(new_y_min, *scanPoint_y);
214 float securMargen = 15 * resolution;
216 if (new_x_max > x_max - securMargen)
217 new_x_max += 2 * securMargen;
220 if (new_x_min < x_min + securMargen)
225 if (new_y_max > y_max - securMargen)
226 new_y_max += 2 * securMargen;
229 if (new_y_min < y_min + securMargen)
237 resizeGrid(new_x_min, new_x_max, new_y_min, new_y_max, 0.5);
241 unsigned theMapSize_x = size_x;
248 for (idx = 0; idx < nRanges; idx += K)
250 if (!o->
validRange[idx] && !invalidAsFree)
continue;
257 int trg_cx = x2idx(scanPoints_x[idx]);
258 int trg_cy = y2idx(scanPoints_y[idx]);
262 static_cast<unsigned int>(trg_cx) < size_x &&
263 static_cast<unsigned int>(trg_cy) < size_y);
267 int Acx = trg_cx - cx;
268 int Acy = trg_cy - cy;
273 int nStepsRay = max(Acx_, Acy_);
274 if (!nStepsRay)
continue;
277 float N_1 = 1.0f / nStepsRay;
281 (Acx < 0 ? -1 : +1) *
round((Acx_ <<
FRBITS) * N_1);
283 (Acy < 0 ? -1 : +1) *
round((Acy_ <<
FRBITS) * N_1);
288 for (
int nStep = 0; nStep < nStepsRay; nStep++)
290 updateCell_fast_free(
291 cx, cy, logodd_observation, logodd_thres_free,
292 theMapArray, theMapSize_x);
306 o->
scan[idx] < maxDistanceInsertion)
307 updateCell_fast_occupied(
308 trg_cx, trg_cy, logodd_observation_occupied,
309 logodd_thres_occupied, theMapArray, theMapSize_x);
334 new_x_max = -(numeric_limits<float>::max)();
335 new_x_min = (numeric_limits<float>::max)();
336 new_y_max = -(numeric_limits<float>::max)();
337 new_y_min = (numeric_limits<float>::max)();
339 last_valid_range = maxDistanceInsertion;
340 for (idx = 0; idx < nRanges; idx += K)
342 float scanPoint_x, scanPoint_y;
345 curRange = o->
scan[idx];
346 float R =
min(maxDistanceInsertion, curRange);
348 scanPoint_x = px + cos(A) *
R;
349 scanPoint_y = py + sin(A) *
R;
350 last_valid_range = curRange;
358 maxDistanceInsertion, 0.5f * last_valid_range);
359 scanPoint_x = px + cos(A) *
R;
360 scanPoint_y = py + sin(A) *
R;
371 new_x_max = max(new_x_max, scanPoint_x);
372 new_x_min =
min(new_x_min, scanPoint_x);
373 new_y_max = max(new_y_max, scanPoint_y);
374 new_y_min =
min(new_y_min, scanPoint_y);
378 float securMargen = 15 * resolution;
380 if (new_x_max > x_max - securMargen)
381 new_x_max += 2 * securMargen;
384 if (new_x_min < x_min + securMargen)
389 if (new_y_max > y_max - securMargen)
390 new_y_max += 2 * securMargen;
393 if (new_y_min < y_min + securMargen)
401 resizeGrid(new_x_min, new_x_max, new_y_min, new_y_max, 0.5);
405 unsigned theMapSize_x = size_x;
430 last_valid_range = maxDistanceInsertion;
432 const double dA_2 = 0.5 * o->
aperture / N;
433 for (idx = 0; idx < nRanges; idx += K, A += dAK)
438 curRange = o->
scan[idx];
439 last_valid_range = curRange;
440 theR =
min(maxDistanceInsertion, curRange);
448 maxDistanceInsertion, 0.5f * last_valid_range);
453 if (theR < resolution)
466 P1.
x = px + cos(A - dA_2) * theR;
467 P1.
y = py + sin(A - dA_2) * theR;
469 P2.
x = px + cos(A + dA_2) * theR;
470 P2.
y = py + sin(A + dA_2) * theR;
473 if (P2.
y < P1.
y) std::swap(P2, P1);
474 if (P2.
y < P0.
y) std::swap(P2, P0);
475 if (P1.
y < P0.
y) std::swap(P1, P0);
485 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 488 static_cast<unsigned int>(P0.
cx) < size_x &&
489 static_cast<unsigned int>(P0.
cy) < size_y);
491 static_cast<unsigned int>(P1.
cx) < size_x &&
492 static_cast<unsigned int>(P1.
cy) < size_y);
494 static_cast<unsigned int>(P2.
cx) < size_x &&
495 static_cast<unsigned int>(P2.
cy) < size_y);
505 if (P0.
cy == P2.
cy && P0.
cy == P1.
cy)
511 for (
int ccx = min_cx; ccx <= max_cx; ccx++)
512 updateCell_fast_free(
513 ccx, P0.
cy, logodd_observation,
514 logodd_thres_free, theMapArray, theMapSize_x);
522 (P1.
y - P0.
y) * (P2.
x - P0.
x) / (P2.
y - P0.
y);
524 P1b.
cx = x2idx(P1b.
x);
525 P1b.
cy = y2idx(P1b.
y);
530 const int Acx01 = P1.
cx - P0.
cx;
531 const int Acy01 = P1.
cy - P0.
cy;
532 const int Acx01b = P1b.
cx - P0.
cx;
536 const float inv_N_01 =
537 1.0f / (
max3(abs(Acx01), abs(Acy01), abs(Acx01b)) +
539 const int frAcx01 =
round(
540 (Acx01 <<
FRBITS) * inv_N_01);
541 const int frAcy01 =
round(
542 (Acy01 <<
FRBITS) * inv_N_01);
543 const int frAcx01b =
round(
544 (Acx01b <<
FRBITS) * inv_N_01);
554 int frAx_R1 = 0, frAx_R2 = 0;
555 int frAy_R1 = frAcy01;
585 int last_insert_cy = -1;
589 if (last_insert_cy !=
592 last_insert_cy = R1.cy;
595 for (
int ccx = R1.cx; ccx <= R2.cx; ccx++)
596 updateCell_fast_free(
597 ccx, R1.cy, logodd_observation,
598 logodd_thres_free, theMapArray,
609 }
while (R1.cy < P1.
cy);
618 const int Acx12 = P2.
cx - P1.
cx;
619 const int Acy12 = P2.
cy - P1.
cy;
620 const int Acx1b2 = P2.
cx - P1b.
cx;
624 const float inv_N_12 =
625 1.0f / (
max3(abs(Acx12), abs(Acy12), abs(Acx1b2)) +
627 const int frAcx12 =
round(
628 (Acx12 <<
FRBITS) * inv_N_12);
629 const int frAcy12 =
round(
630 (Acy12 <<
FRBITS) * inv_N_12);
631 const int frAcx1b2 =
round(
632 (Acx1b2 <<
FRBITS) * inv_N_12);
671 last_insert_cy = -100;
676 if (last_insert_cy !=
680 last_insert_cy = R1.cy;
681 for (
int ccx = R1.cx; ccx <= R2.cx; ccx++)
682 updateCell_fast_free(
683 ccx, R1.cy, logodd_observation,
684 logodd_thres_free, theMapArray,
695 }
while (R1.cy <= P2.
cy);
706 o->
scan[idx] < maxDistanceInsertion)
710 P1.
x = px + cos(A - dA_2) * theR;
711 P1.
y = py + sin(A - dA_2) * theR;
713 P2.
x = px + cos(A + dA_2) * theR;
714 P2.
y = py + sin(A + dA_2) * theR;
721 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 724 static_cast<unsigned int>(P1.
cx) < size_x &&
725 static_cast<unsigned int>(P1.
cy) < size_y);
727 static_cast<unsigned int>(P2.
cx) < size_x &&
728 static_cast<unsigned int>(P2.
cy) < size_y);
732 if (P2.
cx == P1.
cx && P2.
cy == P1.
cy)
734 updateCell_fast_occupied(
735 P1.
cx, P1.
cy, logodd_observation_occupied,
736 logodd_thres_occupied, theMapArray,
744 const int AcxE = P2.
cx - P1.
cx;
745 const int AcyE = P2.
cy - P1.
cy;
748 const int nSteps = (max(abs(AcxE), abs(AcyE)) + 1);
749 const float inv_N_12 =
751 const int frAcxE =
round(
752 (AcxE <<
FRBITS) * inv_N_12);
753 const int frAcyE =
round(
754 (AcyE <<
FRBITS) * inv_N_12);
761 for (
int nStep = 0; nStep <= nSteps; nStep++)
763 updateCell_fast_occupied(
764 R1.cx, R1.cy, logodd_observation_occupied,
765 logodd_thres_occupied, theMapArray,
796 CPose3D sensorPose3D = robotPose3D + spose;
797 CPose2D laserPose(sensorPose3D);
801 bool reallyInsert =
true;
802 unsigned int decimation = insertionOptions.decimation;
805 if (insertionOptions.useMapAltitude &&
806 fabs(insertionOptions.mapAltitude - sensorPose3D.z()) > 0.001)
808 reallyInsert =
false;
821 const float maxDistanceInsertion =
822 insertionOptions.maxDistanceInsertion;
823 const bool invalidAsFree =
824 insertionOptions.considerInvalidRangesAsFreeSpace;
825 float new_x_max, new_x_min;
826 float new_y_max, new_y_min;
827 float last_valid_range = maxDistanceInsertion;
829 float maxCertainty = insertionOptions.maxOccupancyUpdateCertainty;
830 cellType logodd_observation = p2l(maxCertainty);
831 cellType logodd_observation_occupied = 3 * logodd_observation;
834 if (logodd_observation <= 0) logodd_observation = 1;
837 OCCGRID_CELLTYPE_MIN + logodd_observation_occupied;
839 OCCGRID_CELLTYPE_MAX - logodd_observation;
841 int K = updateInfoChangeOnly.enabled
842 ? updateInfoChangeOnly.laserRaysSkip
851 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 863 new_x_max = -(numeric_limits<float>::max)();
864 new_x_min = (numeric_limits<float>::max)();
865 new_y_max = -(numeric_limits<float>::max)();
866 new_y_min = (numeric_limits<float>::max)();
868 last_valid_range = maxDistanceInsertion;
870 for (idx = 0; idx < nRanges; idx += K)
872 float scanPoint_x, scanPoint_y;
873 if (o->
sensedData[idx].sensedDistance < maxDistanceInsertion)
876 float R =
min(maxDistanceInsertion, curRange);
878 scanPoint_x = px + cos(A) *
R;
879 scanPoint_y = py + sin(A) *
R;
880 last_valid_range = curRange;
888 min(maxDistanceInsertion, 0.5f * last_valid_range);
889 scanPoint_x = px + cos(A) *
R;
890 scanPoint_y = py + sin(A) *
R;
901 new_x_max = max(new_x_max, scanPoint_x);
902 new_x_min =
min(new_x_min, scanPoint_x);
903 new_y_max = max(new_y_max, scanPoint_y);
904 new_y_min =
min(new_y_min, scanPoint_y);
908 float securMargen = 15 * resolution;
910 if (new_x_max > x_max - securMargen)
911 new_x_max += 2 * securMargen;
914 if (new_x_min < x_min + securMargen)
919 if (new_y_max > y_max - securMargen)
920 new_y_max += 2 * securMargen;
923 if (new_y_min < y_min + securMargen)
931 resizeGrid(new_x_min, new_x_max, new_y_min, new_y_max, 0.5);
935 unsigned theMapSize_x = size_x;
951 last_valid_range = maxDistanceInsertion;
954 for (idx = 0; idx < nRanges; idx += K, A += dAK)
957 if (o->
sensedData[idx].sensedDistance < maxDistanceInsertion)
960 last_valid_range = curRange;
961 theR =
min(maxDistanceInsertion, curRange);
969 min(maxDistanceInsertion, 0.5f * last_valid_range);
974 if (theR < resolution)
985 P1.
x = px + cos(A - dA_2) * theR;
986 P1.
y = py + sin(A - dA_2) * theR;
988 P2.
x = px + cos(A + dA_2) * theR;
989 P2.
y = py + sin(A + dA_2) * theR;
992 if (P2.
y < P1.
y) std::swap(P2, P1);
993 if (P2.
y < P0.
y) std::swap(P2, P0);
994 if (P1.
y < P0.
y) std::swap(P1, P0);
1000 P1.
cy = y2idx(P1.
y);
1001 P2.
cx = x2idx(P2.
x);
1002 P2.
cy = y2idx(P2.
y);
1004 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 1007 static_cast<unsigned int>(P0.
cx) < size_x &&
1008 static_cast<unsigned int>(P0.
cy) < size_y);
1010 static_cast<unsigned int>(P1.
cx) < size_x &&
1011 static_cast<unsigned int>(P1.
cy) < size_y);
1013 static_cast<unsigned int>(P2.
cx) < size_x &&
1014 static_cast<unsigned int>(P2.
cy) < size_y);
1024 if (P0.
cy == P2.
cy && P0.
cy == P1.
cy)
1030 for (
int ccx = min_cx; ccx <= max_cx; ccx++)
1031 updateCell_fast_free(
1032 ccx, P0.
cy, logodd_observation, logodd_thres_free,
1033 theMapArray, theMapSize_x);
1041 P0.
x + (P1.
y - P0.
y) * (P2.
x - P0.
x) / (P2.
y - P0.
y);
1043 P1b.
cx = x2idx(P1b.
x);
1044 P1b.
cy = y2idx(P1b.
y);
1049 const int Acx01 = P1.
cx - P0.
cx;
1050 const int Acy01 = P1.
cy - P0.
cy;
1051 const int Acx01b = P1b.
cx - P0.
cx;
1055 const float inv_N_01 =
1056 1.0f / (
max3(abs(Acx01), abs(Acy01), abs(Acx01b)) +
1062 const int frAcx01b =
1073 int frAx_R1 = 0, frAx_R2 = 0;
1074 int frAy_R1 = frAcy01;
1103 int last_insert_cy = -1;
1107 if (last_insert_cy !=
1110 last_insert_cy = R1.cy;
1113 for (
int ccx = R1.cx; ccx <= R2.cx; ccx++)
1114 updateCell_fast_free(
1115 ccx, R1.cy, logodd_observation,
1116 logodd_thres_free, theMapArray,
1124 R1.cx = R1.frX >>
FRBITS;
1125 R1.cy = R1.frY >>
FRBITS;
1126 R2.cx = R2.frX >>
FRBITS;
1127 }
while (R1.cy < P1.
cy);
1135 const int Acx12 = P2.
cx - P1.
cx;
1136 const int Acy12 = P2.
cy - P1.
cy;
1137 const int Acx1b2 = P2.
cx - P1b.
cx;
1141 const float inv_N_12 =
1142 1.0f / (
max3(abs(Acx12), abs(Acy12), abs(Acx1b2)) +
1148 const int frAcx1b2 =
1183 R1.frX = R1.cx <<
FRBITS;
1184 R1.frY = R1.cy <<
FRBITS;
1185 R2.frX = R2.cx <<
FRBITS;
1186 R2.frY = R2.cy <<
FRBITS;
1188 last_insert_cy = -100;
1193 if (last_insert_cy !=
1197 last_insert_cy = R1.cy;
1198 for (
int ccx = R1.cx; ccx <= R2.cx; ccx++)
1199 updateCell_fast_free(
1200 ccx, R1.cy, logodd_observation,
1201 logodd_thres_free, theMapArray,
1209 R1.cx = R1.frX >>
FRBITS;
1210 R1.cy = R1.frY >>
FRBITS;
1211 R2.cx = R2.frX >>
FRBITS;
1212 }
while (R1.cy <= P2.
cy);
1222 if (o->
sensedData[idx].sensedDistance < maxDistanceInsertion)
1226 P1.
x = px + cos(A - dA_2) * theR;
1227 P1.
y = py + sin(A - dA_2) * theR;
1229 P2.
x = px + cos(A + dA_2) * theR;
1230 P2.
y = py + sin(A + dA_2) * theR;
1232 P1.
cx = x2idx(P1.
x);
1233 P1.
cy = y2idx(P1.
y);
1234 P2.
cx = x2idx(P2.
x);
1235 P2.
cy = y2idx(P2.
y);
1237 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 1240 static_cast<unsigned int>(P1.
cx) < size_x &&
1241 static_cast<unsigned int>(P1.
cy) < size_y);
1243 static_cast<unsigned int>(P2.
cx) < size_x &&
1244 static_cast<unsigned int>(P2.
cy) < size_y);
1248 if (P2.
cx == P1.
cx && P2.
cy == P1.
cy)
1250 updateCell_fast_occupied(
1251 P1.
cx, P1.
cy, logodd_observation_occupied,
1252 logodd_thres_occupied, theMapArray, theMapSize_x);
1259 const int AcxE = P2.
cx - P1.
cx;
1260 const int AcyE = P2.
cy - P1.
cy;
1263 const int nSteps = (max(abs(AcxE), abs(AcyE)) + 1);
1264 const float inv_N_12 =
1273 R1.frX = R1.cx <<
FRBITS;
1274 R1.frY = R1.cy <<
FRBITS;
1276 for (
int nStep = 0; nStep <= nSteps; nStep++)
1278 updateCell_fast_occupied(
1279 R1.cx, R1.cy, logodd_observation_occupied,
1280 logodd_thres_occupied, theMapArray,
1285 R1.cx = R1.frX >>
FRBITS;
1286 R1.cy = R1.frY >>
FRBITS;
1316 useMapAltitude(false),
1317 maxDistanceInsertion(15.0f),
1318 maxOccupancyUpdateCertainty(0.65f),
1319 considerInvalidRangesAsFreeSpace(true),
1321 horizontalTolerance(
DEG2RAD(0.05)),
1323 CFD_features_gaussian_size(1),
1324 CFD_features_median_size(3),
1326 wideningBeamsWithDistance(false)
1341 considerInvalidRangesAsFreeSpace,
bool, iniFile, section);
1357 "\n----------- [COccupancyGridMap2D::TInsertionOptions] ------------ " double x() const
Common members of all points & poses classes.
Declares a class derived from "CObservation" that encapsules a single range measurement, and associated parameters.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
const T min3(const T &A, const T &B, const T &C)
Local stucture used in the next method (must be here for usage within STL stuff)
float sensorConeApperture
Cone aperture of each ultrasonic beam, in radians.
#define MRPT_CHECK_NORMAL_NUMBER(val)
#define LOADABLEOPTS_DUMP_VAR(variableName, variableType)
Macro for dumping a variable to a stream, within the method "dumpToTextStream(out)" (Variable types a...
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const override
Returns information about the class of an object in runtime.
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string §ion) override
This method load the options from a ".ini" file.
This class allows loading and storing values and vectors of different types from a configuration text...
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
virtual void OnPostSuccesfulInsertObs(const mrpt::obs::CObservation *) override
See base class.
#define CLASS_ID(T)
Access to runtime class ID for a defined class name.
mrpt::math::CMatrixDouble44 getHomogeneousMatrixVal() const
bool isPlanarScan(const double tolerance=0) const
Return true if the laser scanner is "horizontal", so it has an absolute value of "pitch" and "roll" l...
This namespace contains representation of robot actions and observations.
mrpt::utils::ContainerReadOnlyProxyAccessor< std::vector< char > > validRange
It's false (=0) on no reflected rays, referenced to elements in scan.
GLsizei const GLchar ** string
#define mrpt_alloca(nBytes)
In platforms and compilers with support to "alloca", allocate a memory block on the stack; if alloca ...
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.
A "CObservation"-derived class that represents a 2D range scan measurement (typically from a laser sc...
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Declares a class that represents any robot's observation.
const double & phi() const
Get the phi angle of the 2D pose (in radians)
bool m_is_empty
True upon construction; used by isEmpty()
virtual bool internal_insertObservation(const mrpt::obs::CObservation *obs, const mrpt::poses::CPose3D *robotPose=nullptr) override
Insert the observation information into this map.
float aperture
The "aperture" or field-of-view of the range finder, in radians (typically M_PI = 180 degrees)...
const T max3(const T &A, const T &B, const T &C)
int round(const T value)
Returns the closer integer (int) to x.
void dumpToTextStream(mrpt::utils::CStream &out) const override
This method should clearly display all the contents of the structure in textual form, sending it to a CStream.
#define MRPT_LOAD_CONFIG_VAR_DEGREES( variableName, configFileObject, sectionNameStr)
Loads a double variable, stored as radians but entered in the INI-file as degrees.
#define mrpt_alloca_free(mem_block)
This method must be called to "free" each memory block allocated with "system::alloca": If the block ...
#define MRPT_LOAD_CONFIG_VAR( variableName, variableType, configFileObject, sectionNameStr)
An useful macro for loading variables stored in a INI-like file under a key with the same name that t...
mrpt::utils::ContainerReadOnlyProxyAccessor< std::vector< float > > scan
The range values of the scan, in meters.
TInsertionOptions()
Initilization of default parameters.
void getSensorPose(mrpt::poses::CPose3D &out_sensorPose) const override
A general method to retrieve the sensor pose on the robot.
int16_t cellType
The type of the map cells:
mrpt::poses::CPose3D sensorPose
The 6D pose of the sensor on the robot at the moment of starting the scan.
TMeasurementList sensedData
All the measurements.
virtual int printf(const char *fmt,...) MRPT_printf_format_check(2
Writes a string to the stream in a textual form.
bool rightToLeft
The scanning direction: true=counterclockwise; false=clockwise.