54 insertionOpts.loadFromConfigFile(
source, sectionNamePrefix+
string(
"_insertOpts") );
55 likelihoodOpts.loadFromConfigFile(
source, sectionNamePrefix+
string(
"_likelihoodOpts") );
62 this->insertionOpts.dumpToTextStream(out);
63 this->likelihoodOpts.dumpToTextStream(out);
102 return m_beacons.size();
124 out << genericMapParams;
149 in >> genericMapParams;
160 for (i=0;i<n;i++) in >> m_beacons[i];
205 beac=getBeaconByID( it_obs->beaconID );
208 it_obs->sensedDistance > 0 &&
209 !
isNaN(it_obs->sensedDistance))
211 float sensedRange = it_obs->sensedDistance;
216 sensor3D = robotPose3D + it_obs->sensorLocationOnRobot;
233 float expectedRange = sensor3D.
distance3DTo( it->d->x,it->d->y,it->d->z );
237 *itLL = -0.5*
square((sensedRange-expectedRange)/likelihoodOptions.rangeStd);
241 if (logWeights.size())
252 float varZ, varR =
square( likelihoodOptions.rangeStd );
260 H *= 1.0/expectedRange;
272 ret += -0.5 *
square( sensedRange - expectedRange ) / varZ;
289 double varZ, varR =
square( likelihoodOptions.rangeStd );
290 double Ax = it->val.mean.x() - sensor3D.
x();
291 double Ay = it->val.mean.y() - sensor3D.
y();
292 double Az = it->val.mean.z() - sensor3D.z();
296 double expectedRange = sensor3D.
distanceTo( it->val.mean );
297 H *= 1.0/expectedRange;
299 varZ = H.multiply_HCHt_scalar(it->val.cov);
307 *itLL = -0.5 *
square( sensedRange - expectedRange ) / varZ;
311 if (logWeights.size())
355 robotPose2D =
CPose2D(*robotPose);
356 robotPose3D = (*robotPose);
384 CPoint3D sensorPnt( robotPose3D + it->sensorLocationOnRobot );
385 float sensedRange = it->sensedDistance;
386 unsigned int sensedID = it->beaconID;
388 CBeacon *beac = getBeaconByID(sensedID);
398 newBeac.
m_ID = sensedID;
400 if ( insertionOptions.insertAsMonteCarlo )
407 size_t numParts =
round(insertionOptions.MC_numSamplesPerMeter * sensedRange);
408 ASSERT_(insertionOptions.minElevation_deg<=insertionOptions.maxElevation_deg)
409 double minA =
DEG2RAD(insertionOptions.minElevation_deg);
410 double maxA =
DEG2RAD(insertionOptions.maxElevation_deg);
417 itP->d->x = sensorPnt.
x() +
R*cos(th)*cos(el);
418 itP->d->y = sensorPnt.
y() +
R*sin(th)*cos(el);
419 itP->d->z = sensorPnt.z() +
R*sin(el);
436 m_beacons.push_back( newBeac );
451 double maxW = -1e308, sumW=0;
456 float expectedRange = sensorPnt.
distance3DTo( it->d->x,it->d->y,it->d->z );
459 it->log_w += -0.5*
square((sensedRange-expectedRange)/likelihoodOptions.rangeStd);
460 maxW=max(it->log_w,maxW);
461 sumW+=exp(it->log_w);
466 if (insertionOptions.MC_performResampling)
474 vector<double> log_ws;
475 vector<size_t> indxs;
479 CParticleFilterCapable::computeResampling(
480 CParticleFilter::prSystematic,
488 bool is2D = (insertionOptions.minElevation_deg==insertionOptions.maxElevation_deg);
489 float noiseStd = insertionOptions.MC_afterResamplingNoise;
512 if ( it->log_w < (maxW-insertionOptions.MC_thresholdNegligible) )
535 double D1 = sqrt(COV(0,0));
536 double D2 = sqrt(COV(1,1));
537 double D3 = sqrt(COV(2,2));
539 double mxVar =
max3( D1, D2, D3 );
541 if (mxVar < insertionOptions.MC_maxStdToGauss )
553 if (insertionOptions.minElevation_deg == insertionOptions.maxElevation_deg )
571 float varR =
square( likelihoodOptions.rangeStd );
582 float y = sensedRange - expectedRange;
590 H(0,0) = Ax; H(0,1) = Ay; H(0,2) = Az;
591 H *= 1.0/expectedRange;
615 float varR =
square( likelihoodOptions.rangeStd );
624 double expectedRange = sensorPnt.
distanceTo( it->val.mean );
627 double y = sensedRange - expectedRange;
632 double Ax = ( it->val.mean.x() - sensorPnt.
x());
633 double Ay = ( it->val.mean.y() - sensorPnt.
y());
634 double Az = ( it->val.mean.z() - sensorPnt.z());
635 H(0,0) = Ax; H(0,1) = Ay; H(0,2) = Az;
636 H *= 1.0/expectedRange;
637 varZ = H.multiply_HCHt_scalar( it->val.cov );
640 K.multiply( it->val.cov, H.transpose());
644 it->val.mean.x_incr( K(0,0) *
y );
645 it->val.mean.y_incr( K(1,0) *
y );
646 it->val.mean.z_incr( K(2,0) *
y );
648 it->val.cov = (Eigen::Matrix<double,3,3>::Identity() - K*H) * it->val.cov;
653 it->log_w += -0.5 *
square(
y ) / varZ;
655 max_w = max(max_w,it->log_w);
662 if (max_w - it->log_w > insertionOptions.SOG_thresholdNegligible )
681 double D1 = sqrt(curCov(0,0));
682 double D2 = sqrt(curCov(1,1));
683 double D3 = sqrt(curCov(2,2));
684 float maxDiag =
max3(D1,D2,D3);
731 CPose3D otherMapPose3D(otherMapPose);
736 vector<bool> otherCorrespondences;
742 computeMatchingWith3DLandmarks( otherMap2,
745 otherCorrespondences );
757 for (
iterator lm=m_beacons.begin();lm!=m_beacons.end();++lm)
758 lm->changeCoordinatesReference(newOrg);
768 changeCoordinatesReference(newOrg);
778 float &correspondencesRatio,
779 vector<bool> &otherCorrespondences)
const
788 vector<bool> thisLandmarkAssigned;
791 nThis = m_beacons.size();
795 thisLandmarkAssigned.resize( nThis,
false );
798 correspondences.clear();
799 otherCorrespondences.clear();
800 otherCorrespondences.resize( nOther,
false );
801 correspondencesRatio = 0;
803 for (k=0,otherIt=anotherMap->
m_beacons.begin();otherIt!=anotherMap->
m_beacons.end();++otherIt,++k)
805 for (j=0,thisIt=m_beacons.begin();thisIt!=m_beacons.end();++thisIt,++j)
808 if ( (otherIt)->m_ID == (thisIt)->m_ID )
811 if ( !thisLandmarkAssigned[ j ] )
813 thisLandmarkAssigned[ j ] =
true;
816 otherCorrespondences[ k ] =
true;
820 CPoint3D mean_j = m_beacons[j].getMeanVal();
824 match.
this_z = mean_j.z();
832 correspondences.push_back( match );
841 correspondencesRatio = 2.0f * correspondences.size() /
static_cast<float>( nThis + nOther);
852 float confInterval )
const
862 os::fprintf(f,
"%%-------------------------------------------------------\n");
863 os::fprintf(f,
"%% File automatically generated using the MRPT method:\n");
864 os::fprintf(f,
"%% 'CBeaconMap::saveToMATLABScript3D'\n");
867 os::fprintf(f,
"%% Jose Luis Blanco Claraco, University of Malaga @ 2006\n");
869 os::fprintf(f,
"%%-------------------------------------------------------\n\n");
876 for (
const_iterator it=m_beacons.begin();it!=m_beacons.end();++it)
878 it->getAsMatlabDrawCommands( strs );
902 out.
printf(
"\n----------- [CBeaconMap::TLikelihoodOptions] ------------ \n\n");
904 out.
printf(
"rangeStd = %f\n",rangeStd);
914 const string §ion)
916 rangeStd = iniFile.
read_float(section.c_str(),
"rangeStd",rangeStd);
923 insertAsMonteCarlo ( true ),
924 maxElevation_deg ( 0),
925 minElevation_deg ( 0 ),
926 MC_numSamplesPerMeter ( 1000 ),
927 MC_maxStdToGauss ( 0.4f ),
928 MC_thresholdNegligible ( 5 ),
929 MC_performResampling ( false ),
930 MC_afterResamplingNoise ( 0.01f ),
931 SOG_thresholdNegligible ( 20.0f ),
932 SOG_maxDistBetweenGaussians ( 1.0f ),
933 SOG_separationConstant ( 3.0f )
942 out.
printf(
"\n----------- [CBeaconMap::TInsertionOptions] ------------ \n\n");
944 out.
printf(
"insertAsMonteCarlo = %c\n",insertAsMonteCarlo ?
'Y':
'N');
945 out.
printf(
"minElevation_deg = %.03f\n",minElevation_deg);
946 out.
printf(
"maxElevation_deg = %.03f\n",maxElevation_deg);
947 out.
printf(
"MC_numSamplesPerMeter = %d\n",MC_numSamplesPerMeter);
948 out.
printf(
"MC_maxStdToGauss = %.03f\n",MC_maxStdToGauss);
949 out.
printf(
"MC_thresholdNegligible = %.03f\n",MC_thresholdNegligible);
950 out.
printf(
"MC_performResampling = %c\n",MC_performResampling ?
'Y':
'N');
951 out.
printf(
"MC_afterResamplingNoise = %.03f\n",MC_afterResamplingNoise);
952 out.
printf(
"SOG_thresholdNegligible = %.03f\n",SOG_thresholdNegligible);
953 out.
printf(
"SOG_maxDistBetweenGaussians = %.03f\n",SOG_maxDistBetweenGaussians);
954 out.
printf(
"SOG_separationConstant = %.03f\n",SOG_separationConstant);
965 const string §ion)
994 const CPoint3D &in_sensorLocationOnRobot,
1003 point3D = in_robotPose + in_sensorLocationOnRobot;
1011 it->getMean(beacon3D);
1026 out_Observations.
sensedData.push_back( newMeas );
1040 string fil1( filNamePrefix +
string(
"_3D.m") );
1053 string fil2( filNamePrefix +
string(
"_3D.3Dscene") );
1058 string fil3( filNamePrefix +
string(
"_covs.txt") );
1062 string fil4( filNamePrefix +
string(
"_population.txt") );
1067 size_t nParts = 0, nGaussians = 0;
1071 switch (it->m_typePDF)
1074 nParts += it->m_locationMC.size();
1077 nGaussians += it->m_locationSOG.size();
1085 fprintf(f,
"%u %u",
static_cast<unsigned>(nParts),
static_cast<unsigned>(nGaussians) );
1110 it->getAs3DObject( outObj );
1134 otherMap =
static_cast<const CBeaconMap*
>( otherMap2);
1136 if (!otherMap)
return 0;
1139 vector<bool> otherCorrespondences;
1140 float out_corrsRatio;
1150 otherCorrespondences );
1152 return out_corrsRatio;
1197 it->getCovarianceAndMean(C,
p);
1200 float D2 = C(0,0)*C(1,1) -
square( C(0,1) );
1201 os::fprintf(f,
"%i %f %f %f %e %e %e %e %e %e %e %e\n",
1202 static_cast<int>(it->m_ID),
1204 C(0,0),C(1,1),C(2,2),
1206 C(0,1),C(1,2),C(1,2)
#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...
#define CLASS_ID(class_name)
Access to runtime class ID for a defined class name.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
#define MAP_DEFINITION_REGISTER(_CLASSNAME_STRINGS, _CLASSNAME_WITH_NS)
Registers one map class into TMetricMapInitializer factory.
CParticleList m_particles
The array of particles.
void getWeights(std::vector< double > &out_logWeights) const
Returns a vector with the sequence of the logaritmic weights of all the samples.
The class for storing individual "beacon landmarks" under a variety of 3D position PDF distributions.
mrpt::poses::CPointPDFGaussian m_locationGauss
The individual PDF, if m_typePDF=pdfGauss (publicly accesible for ease of use, but the CPointPDF inte...
TTypePDF m_typePDF
Which one of the different 3D point PDF is currently used in this object: montecarlo,...
int64_t TBeaconID
The type for the IDs of landmarks.
static void generateRingSOG(const float &sensedRange, mrpt::poses::CPointPDFSOG &outPDF, const CBeaconMap *myBeaconMap, const mrpt::poses::CPoint3D &sensorPnt, const mrpt::math::CMatrixDouble33 *covarianceCompositionToAdd=NULL, bool clearPreviousContentsOutPDF=true, const mrpt::poses::CPoint3D ¢erPoint=mrpt::poses::CPoint3D(0, 0, 0), const float &maxDistanceFromCenter=0)
This static method returns a SOG with ring-shape (or as a 3D sphere) that can be used to initialize a...
mrpt::poses::CPointPDFSOG m_locationSOG
The individual PDF, if m_typePDF=pdfSOG (publicly accesible for ease of use, but the CPointPDF interf...
TBeaconID m_ID
An ID for the landmark (see details next...) This ID was introduced in the version 3 of this class (2...
mrpt::poses::CPointPDFParticles m_locationMC
The individual PDF, if m_typePDF=pdfMonteCarlo (publicly accesible for ease of use,...
A class for storing a map of 3D probabilistic beacons, using a Montecarlo, Gaussian,...
float compute3DMatchingRatio(const mrpt::maps::CMetricMap *otherMap, const mrpt::poses::CPose3D &otherMapPose, const TMatchingRatioParams ¶ms) const MRPT_OVERRIDE
Computes the ratio in [0,1] of correspondences between "this" and the "otherMap" map,...
void getAs3DObject(mrpt::opengl::CSetOfObjectsPtr &outObj) const MRPT_OVERRIDE
Returns a 3D object representing the map.
void saveMetricMapRepresentationToFile(const std::string &filNamePrefix) const MRPT_OVERRIDE
This virtual method saves the map to a file "filNamePrefix"+< some_file_extension >,...
virtual void determineMatching2D(const mrpt::maps::CMetricMap *otherMap, const mrpt::poses::CPose2D &otherMapPose, mrpt::utils::TMatchingPairList &correspondences, const TMatchingParams ¶ms, TMatchingExtraResults &extraResults) const MRPT_OVERRIDE
Computes the matching between this and another 2D point map, which includes finding:
void saveToTextFile(const std::string &fil) const
Save a text file with a row per beacon, containing this 11 elements:
const CBeacon * getBeaconByID(CBeacon::TBeaconID id) const
Returns a pointer to the beacon with the given ID, or NULL if it does not exist.
static mrpt::maps::CMetricMap * internal_CreateFromMapDefinition(const mrpt::maps::TMetricMapInitializer &def)
void resize(const size_t N)
Resize the number of SOG modes.
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const
Introduces a pure virtual method responsible for writing to a CStream.
void simulateBeaconReadings(const mrpt::poses::CPose3D &in_robotPose, const mrpt::poses::CPoint3D &in_sensorLocationOnRobot, mrpt::obs::CObservationBeaconRanges &out_Observations) const
Simulates a reading toward each of the beacons in the landmarks map, if any.
std::deque< CBeacon >::const_iterator const_iterator
virtual void internal_clear() MRPT_OVERRIDE
Internal method called by clear()
size_t size() const
Returns the stored landmarks count.
bool saveToMATLABScript3D(const std::string &file, const char *style="b", float confInterval=0.95f) const
Save to a MATLAB script which displays 3D error ellipses for the map.
void changeCoordinatesReference(const mrpt::poses::CPose3D &newOrg)
Changes the reference system of the map to a given 3D pose.
double internal_computeObservationLikelihood(const mrpt::obs::CObservation *obs, const mrpt::poses::CPose3D &takenFrom) MRPT_OVERRIDE
Internal method called by computeObservationLikelihood()
void readFromStream(mrpt::utils::CStream &in, int version)
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
bool isEmpty() const MRPT_OVERRIDE
Returns true if the map is empty/no observation has been inserted.
std::deque< CBeacon >::iterator iterator
void computeMatchingWith3DLandmarks(const mrpt::maps::CBeaconMap *otherMap, mrpt::utils::TMatchingPairList &correspondences, float &correspondencesRatio, std::vector< bool > &otherCorrespondences) const
Perform a search for correspondences between "this" and another lansmarks map: Firsly,...
virtual bool internal_insertObservation(const mrpt::obs::CObservation *obs, const mrpt::poses::CPose3D *robotPose=NULL) MRPT_OVERRIDE
Internal method called by insertObservation()
TSequenceBeacons m_beacons
The individual beacons.
Declares a virtual base class for all metric maps storage classes.
TMapGenericParams genericMapParams
Common params to all maps.
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const
Returns information about the class of an object in runtime.
bool enableSaveAs3DObject
(Default=true) If false, calling CMetricMap::getAs3DObject() will have no effects
A numeric matrix of compile-time fixed size.
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction.
Declares a class derived from "CObservation" that represents one (or more) range measurements to labe...
float maxSensorDistance
Info about sensor.
float stdError
The "sigma" of the sensor, assuming a zero-mean Gaussian noise model.
std::deque< TMeasurement > sensedData
The list of observed ranges.
Declares a class that represents any robot's observation.
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const
Returns information about the class of an object in runtime.
static CGridPlaneXYPtr Create()
This class allows the user to create, load, save, and render 3D scenes using OpenGL primitives.
void insert(const CRenderizablePtr &newObject, const std::string &viewportName=std::string("main"))
Insert a new object into the scene, in the given viewport (by default, into the "main" viewport).
static CSetOfObjectsPtr Create()
A class used to store a 3D point.
A gaussian distribution for 3D points.
mrpt::math::CMatrixDouble33 cov
The 3x3 covariance matrix.
CPoint3D mean
The mean value.
void getCovarianceAndMean(mrpt::math::CMatrixDouble33 &cov, CPoint3D &mean_point) const MRPT_OVERRIDE
Returns an estimate of the point covariance matrix (3x3 cov matrix) and the mean, both at once.
void setSize(size_t numberParticles, const CPoint3D &defaultValue=CPoint3D(0, 0, 0))
Erase all the previous particles and change the number of particles, with a given initial value
void clear()
Clear all the particles (free memory)
iterator erase(iterator i)
size_t size() const
Return the number of Gaussian modes.
void getCovarianceAndMean(mrpt::math::CMatrixDouble33 &cov, CPoint3D &mean_point) const MRPT_OVERRIDE
Returns an estimate of the point covariance matrix (3x3 cov matrix) and the mean, both at once.
std::deque< TGaussianMode >::const_iterator const_iterator
std::deque< TGaussianMode >::iterator iterator
void normalizeWeights()
Normalize the weights in m_modes such as the maximum log-weight is 0.
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).
double x() const
Common members of all points & poses classes.
void y_incr(const double v)
void x_incr(const double v)
double distance3DTo(double ax, double ay, double az) const
Returns the 3D distance from this pose/point to a 3D point.
double distanceTo(const CPoseOrPoint< OTHERCLASS > &b) const
Returns the Euclidean distance to another pose/point:
double drawGaussian1D(const double mean, const double std)
Generate a normally distributed pseudo-random number.
double drawUniform(const double Min, const double Max)
Generate a uniformly distributed pseudo-random number using the MT19937 algorithm,...
This class allows loading and storing values and vectors of different types from a configuration text...
float read_float(const std::string §ion, const std::string &name, float defaultValue, bool failIfNotFound=false) const
This CStream derived class allow using a file as a write-only, binary stream.
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
virtual int printf(const char *fmt,...) MRPT_printf_format_check(2
Writes a string to the stream in a textual form.
A class for storing a list of text lines.
void getText(std::string &outText) const
Returns the whole string list as a single string with '\r ' characters for newlines.
const Scalar * const_iterator
EIGEN_STRONG_INLINE iterator begin()
GLsizei GLsizei GLuint * obj
GLenum const GLfloat * params
GLsizei const GLchar ** string
GLsizei GLsizei GLchar * source
bool BASE_IMPEXP isNaN(float f) MRPT_NO_THROWS
Returns true if the number is NaN.
int round(const T value)
Returns the closer integer (int) to x.
int BASE_IMPEXP fprintf(FILE *fil, const char *format,...) MRPT_NO_THROWS MRPT_printf_format_check(2
An OS-independent version of fprintf.
FILE BASE_IMPEXP * fopen(const char *fileName, const char *mode) MRPT_NO_THROWS
An OS-independent version of fopen.
int BASE_IMPEXP void BASE_IMPEXP fclose(FILE *f)
An OS-independent version of fclose.
double BASE_IMPEXP averageLogLikelihood(const CVectorDouble &logLikelihoods)
A numerically-stable method to compute average likelihood values with strongly different ranges (unwe...
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
#define THROW_EXCEPTION(msg)
#define MRPT_CHECK_NORMAL_NUMBER(val)
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
The namespace for Bayesian filtering algorithm: different particle filters and Kalman filter algorith...
This base provides a set of functions for maths stuff.
CMatrixTemplateNumeric< double > CMatrixDouble
Declares a matrix of double numbers (non serializable).
T square(const T x)
Inline function for the square of a number.
This namespace contains representation of robot actions and observations.
CSetOfObjectsPtr OPENGL_IMPEXP CornerXYZ(float scale=1.0)
Returns three arrows representing a X,Y,Z 3D corner.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
A namespace of pseudo-random numbers genrators of diferent distributions.
BASE_IMPEXP CRandomGenerator randomGenerator
A static instance of a CRandomGenerator class, for use in single-thread applications.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation,...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
const T max3(const T &A, const T &B, const T &C)
void clear()
Clear the contents of this container.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
unsigned __int32 uint32_t
void performSubstitution(const std::vector< size_t > &indx) MRPT_OVERRIDE
Replaces the old particles by copies determined by the indexes in "indx", performing an efficient cop...
double ESS() const MRPT_OVERRIDE
Returns the normalized ESS (Estimated Sample Size), in the range [0,1].
void dumpToTextStream(mrpt::utils::CStream &out) const MRPT_OVERRIDE
This method should clearly display all the contents of the structure in textual form,...
TInsertionOptions()
Initilization of default parameters.
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string §ion) MRPT_OVERRIDE
This method load the options from a ".ini"-like file or memory-stored string list.
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string §ion) MRPT_OVERRIDE
This method load the options from a ".ini"-like file or memory-stored string list.
TLikelihoodOptions()
Initilization of default parameters.
void dumpToTextStream(mrpt::utils::CStream &out) const MRPT_OVERRIDE
This method should clearly display all the contents of the structure in textual form,...
void loadFromConfigFile_map_specific(const mrpt::utils::CConfigFileBase &source, const std::string §ionNamePrefix)
Load all map-specific params.
mrpt::maps::CBeaconMap::TLikelihoodOptions likelihoodOpts
Probabilistic observation likelihood options.
void dumpToTextStream_map_specific(mrpt::utils::CStream &out) const
mrpt::maps::CBeaconMap::TInsertionOptions insertionOpts
Observations insertion options.
Parameters for the determination of matchings between point clouds, etc.
Parameters for CMetricMap::compute3DMatchingRatio()
Virtual base for specifying the kind and parameters of one map (normally, to be inserted into mrpt::m...
Each one of the measurements.
mrpt::poses::CPoint3D sensorLocationOnRobot
Position of the sensor on the robot.
int32_t beaconID
The ID of the sensed beacon (or INVALID_BEACON_ID if unknown)
float sensedDistance
The sensed range itself (in meters).
A structure for holding correspondences between two sets of points or points-like entities in 2D or 3...