53 const TPose3D *newPoseToBeInserted)
56 if (newPoseToBeInserted)
79 const TPose3D *newPoseToBeInserted)
81 const size_t lenBinPath = (currentParticleValue!=NULL) ? currentParticleValue->
robotPath.size() : 0;
84 outBin.
bins.resize(lenBinPath + (newPoseToBeInserted!=NULL ? 1:0) );
87 if (currentParticleValue!=NULL)
88 for (
size_t i=0;i<lenBinPath;++i)
96 if (newPoseToBeInserted!=NULL)
114 sensorLocationOnRobot(),
128 return a.nGaussiansInMap <
b.nGaussiansInMap;
139 void CMultiMetricMapPDF::prediction_and_update_pfAuxiliaryPFOptimal(
146 PF_SLAM_implementation_pfAuxiliaryPFOptimal<mrpt::slam::detail::TPoseBin2D>( actions, sf, PF_options,options.KLD_params);
154 void CMultiMetricMapPDF::prediction_and_update_pfAuxiliaryPFStandard(
161 PF_SLAM_implementation_pfAuxiliaryPFStandard<mrpt::slam::detail::TPoseBin2D>( actions, sf, PF_options,options.KLD_params);
182 void CMultiMetricMapPDF::prediction_and_update_pfOptimalProposal(
193 size_t M = m_particles.size();
194 bool updateStageAlreadyDone =
false;
195 CPose3D initialPose,incrPose, finalPose;
198 CICP icp (options.icp_params);
212 if (robotMovement2D.present())
214 robotActionSampler.
setPosePDF( robotMovement2D->poseChange.get_ptr() );
222 robotActionSampler.
setPosePDF( robotMovement3D->poseChange );
223 robotMovement3D->poseChange.getMean( motionModelMeanIncr );
233 averageMapIsUpdated =
false;
240 printf(
" 1) Prediction...");
241 M = m_particles.size();
244 size_t particleWithHighestW = 0;
245 for (
size_t i=0;i<M;i++)
246 if (getW(i)>getW(particleWithHighestW))
247 particleWithHighestW = i;
251 ASSERT_( !m_particles[0].d->robotPath.empty() )
256 bool built_map_points =
false;
257 bool built_map_lms =
false;
261 for (i=0,partIt = m_particles.begin(); partIt!=m_particles.end(); partIt++,i++)
263 double extra_log_lik = 0;
266 const CPose3D ith_last_pose =
CPose3D(*partIt->d->robotPath.rbegin());
268 CPose3D initialPoseEstimation = ith_last_pose + motionModelMeanIncr;
271 if ( options.pfOptimalProposal_mapSelection==0 ||
272 options.pfOptimalProposal_mapSelection==1 ||
273 options.pfOptimalProposal_mapSelection==3 )
278 if (partIt->d->mapTillNow.m_pointsMaps.size())
280 ASSERT_(partIt->d->mapTillNow.m_pointsMaps.size()==1);
286 if (options.pfOptimalProposal_mapSelection==0)
288 ASSERT_( !partIt->d->mapTillNow.m_gridMaps.empty() );
291 if (!built_map_points)
293 built_map_points=
true;
295 localMapPoints.insertionOptions.minDistBetweenLaserPoints = 0.02f;
296 localMapPoints.insertionOptions.isPlanarMap =
true;
300 map_to_align_to = partIt->d->mapTillNow.m_gridMaps[0].pointer();
303 if (options.pfOptimalProposal_mapSelection==3)
305 ASSERT_( !partIt->d->mapTillNow.m_pointsMaps.empty() );
308 if (!built_map_points)
310 built_map_points=
true;
312 localMapPoints.insertionOptions.minDistBetweenLaserPoints = 0.02f;
313 localMapPoints.insertionOptions.isPlanarMap =
true;
317 map_to_align_to = partIt->d->mapTillNow.m_pointsMaps[0].pointer();
321 ASSERT_( partIt->d->mapTillNow.m_landmarksMap.present() );
330 map_to_align_to = partIt->d->mapTillNow.m_landmarksMap.pointer();
333 ASSERT_(map_to_align_to!=NULL);
337 CPosePDFPtr alignEst =
341 CPose2D(initialPoseEstimation),
344 icpEstimation.
copyFrom( *alignEst );
348 if (i==particleWithHighestW)
350 newInfoIndex = 1 - icpInfo.
goodness;
357 if (icpInfo.
goodness<options.ICPGlobalAlign_MinQuality && SFs.size())
359 printf(
"[rbpf-slam] Warning: gridICP[%u]: %.02f%% -> Using odometry instead!\n", (
unsigned int)i, 100*icpInfo.
goodness);
360 icpEstimation.
mean =
CPose2D(initialPoseEstimation);
373 #if 0 // Use hacked ICP covariance: 374 CPose3D Ap = finalEstimatedPoseGauss.
mean - ith_last_pose;
375 const double Ap_dist = Ap.
norm();
377 finalEstimatedPoseGauss.
cov.zeros();
378 finalEstimatedPoseGauss.
cov(0,0) =
square( fabs(Ap_dist)*0.01 );
379 finalEstimatedPoseGauss.
cov(1,1) =
square( fabs(Ap_dist)*0.01 );
380 finalEstimatedPoseGauss.
cov(2,2) =
square( fabs(Ap.
yaw())*0.02 );
391 finalPose = finalEstimatedPoseGauss.
mean;
394 finalPose.setFromValues(
395 finalPose.x() + rndSamples[0],
396 finalPose.y() + rndSamples[1],
398 finalPose.yaw() + rndSamples[2],
403 if ( options.pfOptimalProposal_mapSelection==2)
411 ASSERT_( partIt->d->mapTillNow.m_beaconMap.present() );
412 CBeaconMapPtr beacMap = partIt->d->mapTillNow.m_beaconMap;
414 updateStageAlreadyDone =
true;
423 bool methodSOGorGrid =
false;
425 float firstEstimateRobotHeading=std::numeric_limits<float>::max();
428 CPoint3D centerPositionPrior( ith_last_pose );
429 float centerPositionPriorRadius=2.0f;
433 firstEstimateRobotHeading = ith_last_pose.
yaw();
437 if (!beacMap->size())
440 cerr <<
"[RO-SLAM] Optimal filtering without map & odometry...this message should appear only the first iteration!!" << endl;
446 if ( beacMap->get(0).m_typePDF==CBeacon::pdfSOG)
448 cerr <<
"[RO-SLAM] Optimal filtering without map & odometry->FIXING ONE BEACON!" << endl;
449 ASSERT_(beacMap->get(0).m_locationSOG.size()>0)
451 CPoint3D fixedBeacon( beacMap->get(0).m_locationSOG[0].val.mean );
454 beacMap->get(0).m_typePDF=CBeacon::pdfGauss;
455 beacMap->get(0).m_locationSOG.clear();
456 beacMap->get(0).m_locationGauss.mean = fixedBeacon;
457 beacMap->get(0).m_locationGauss.cov.unit(3, 1e-6);
465 deque<TAuxRangeMeasInfo> lstObservedRanges;
479 if ( (itBeacs)->m_ID == itRanges->beaconID)
482 newMeas.
beaconID = itRanges->beaconID;
486 ASSERT_( (itBeacs)->m_typePDF==CBeacon::pdfGauss || (itBeacs)->m_typePDF==CBeacon::pdfSOG )
487 newMeas.
nGaussiansInMap = (itBeacs)->m_typePDF==CBeacon::pdfSOG ? (itBeacs)->m_locationSOG.size() : 1 ;
489 lstObservedRanges.push_back( newMeas );
503 if ( methodSOGorGrid )
506 fusedObsModels.
clear();
517 CPose3D auxPose= ith_last_pose + motionModelMeanIncr;
518 firstEstimateRobotHeading = auxPose.
yaw();
527 poseCOV.setSize(2,2);
528 poseCOV.setSize(3,3);
541 if ((itBeacs)->m_ID==itObs->beaconID)
544 float sensedRange = itObs->sensedDistance;
547 (itBeacs)->generateObservationModelDistribution(
551 itObs->sensorLocationOnRobot,
553 centerPositionPriorRadius );
555 if (! fusedObsModels.
size() )
558 fusedObsModels = newObsModel;
569 fusedObsModels = tempFused;
576 cout <<
"#modes bef: " << fusedObsModels.
size() <<
" ESS: " << fusedObsModels.
ESS() << endl;
582 for (it=fusedObsModels.
begin();it!=fusedObsModels.
end();it++)
583 max_w = max(max_w,(it)->log_w);
585 for (it=fusedObsModels.
begin();it!=fusedObsModels.
end(); )
587 if (max_w - (it)->log_w > 20 )
588 it = fusedObsModels.
erase( it );
592 cout <<
"#modes after: " << fusedObsModels.
size() << endl;
599 ASSERT_(currentCov(0,0)>0 && currentCov(1,1)>0)
600 if ( sqrt(currentCov(0,0))< 0.10f &&
601 sqrt(currentCov(1,1))< 0.10f &&
602 sqrt(currentCov(2,2))< 0.10f )
606 fusedObsModels.
getMean(currentMean);
607 fusedObsModels[0].log_w = 0;
608 fusedObsModels[0].val.mean = currentMean;
609 fusedObsModels[0].val.cov = currentCov;
649 float grid_min_x = ith_last_pose.
x() - 0.5f;
650 float grid_max_x = ith_last_pose.
x() + 0.5f;
651 float grid_min_y = ith_last_pose.
y() - 0.5f;
652 float grid_max_y = ith_last_pose.
y() + 0.5f;
653 float grid_resXY = 0.02f;
655 bool repeatGridCalculation=
false;
660 grid_min_x,grid_max_x,
661 grid_min_y,grid_max_y,
662 grid_resXY,
DEG2RAD(180), 0, 0 );
673 if ((itBeacs)->m_ID==itObs->beaconID)
676 float sensedRange = itObs->sensedDistance;
688 for (
size_t idxX=0;idxX<pdfGrid->
getSizeX();idxX++)
690 float grid_x = pdfGrid->
idx2x(idxX);
691 for (
size_t idxY=0;idxY<pdfGrid->
getSizeY();idxY++)
693 double grid_y = pdfGrid->
idx2y(idxY);
696 double *cell = pdfGrid->
getByIndex(idxX,idxY,0);
700 switch ((itBeacs)->m_typePDF)
702 case CBeacon::pdfSOG:
705 double sensorSTD2 =
square(beacMap->likelihoodOptions.rangeStd);
708 for (it = sog->
begin();it!=sog->
end();it++)
710 lik *= exp( -0.5*
square( sensedRange -
711 (it)->
val.mean.distance2DTo( grid_x+itObs->sensorLocationOnRobot.x(), grid_y+itObs->sensorLocationOnRobot.y()))/sensorSTD2 );
734 for (
size_t idxX=0;idxX<pdfGrid->
getSizeX();idxX++)
737 for (
size_t idxY=0;idxY<pdfGrid->
getSizeY();idxY++)
746 maxX=pdfGrid->
idx2x(idxX);
747 maxY=pdfGrid->
idx2y(idxY);
751 newDrawnPosition.
x( maxX );
752 newDrawnPosition.
y( maxY );
760 outMat *= 1.0f/outMat.maxCoeff();
761 CImage imgF(outMat,
true);
762 static int autocount=0;
764 printf(
"grid res: %f MAX: %f,%f\n",grid_resXY,maxX,maxY);
769 if (grid_resXY>0.01f)
771 grid_min_x = maxX - 0.03f;
772 grid_max_x = maxX + 0.03f;
773 grid_min_y = maxY - 0.03f;
774 grid_max_y = maxY + 0.03f;
776 repeatGridCalculation =
true;
779 repeatGridCalculation =
false;
793 delete pdfGrid; pdfGrid = NULL;
795 }
while (repeatGridCalculation);
803 if (!beacMap->size())
806 finalPose = ith_last_pose;
810 cout <<
"Drawn: " << newDrawnPosition << endl;
813 ASSERT_(firstEstimateRobotHeading!=std::numeric_limits<float>::max())
816 newDrawnPosition.
x(),
817 newDrawnPosition.
y(),
818 newDrawnPosition.z(),
819 firstEstimateRobotHeading, 0,0);
829 double weightUpdate=0;
830 partIt->log_w += PF_options.
powFactor * weightUpdate;
838 THROW_EXCEPTION(
"Action list does not contain any CActionRobotMovement2D or CActionRobotMovement3D object!");
842 finalPose = ith_last_pose + incrPose;
846 partIt->d->robotPath.push_back( finalPose );
851 if (!updateStageAlreadyDone)
855 (PF_SLAM_computeObservationLikelihoodForParticle(PF_options,i,*sf,finalPose)
869 void CMultiMetricMapPDF::prediction_and_update_pfStandardProposal(
876 PF_SLAM_implementation_pfStandardProposal<mrpt::slam::detail::TPoseBin2D>(actions, sf, PF_options,options.KLD_params);
879 averageMapIsUpdated =
false;
886 void CMultiMetricMapPDF::PF_SLAM_implementation_custom_update_particle_with_new_pose(
890 particleData->
robotPath.push_back( newPose );
894 bool CMultiMetricMapPDF::PF_SLAM_implementation_doWeHaveValidObservations(
895 const CMultiMetricMapPDF::CParticleList &particles,
898 if (sf==NULL)
return false;
900 return particles.begin()->d.get()->mapTillNow.canComputeObservationsLikelihood( *sf );
904 bool CMultiMetricMapPDF::PF_SLAM_implementation_skipRobotMovement()
const 906 return 0==getNumberOfObservationsInSimplemap();
915 double CMultiMetricMapPDF::PF_SLAM_computeObservationLikelihoodForParticle(
917 const size_t particleIndexForMap,
A namespace of pseudo-random numbers genrators of diferent distributions.
void drawSingleSample(CPoint3D &outSample) const MRPT_OVERRIDE
Draw a sample from the pdf.
double x() const
Common members of all points & poses classes.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
CPose2D mean
The mean value.
CPose3D mean
The mean value.
This class is a "CSerializable" wrapper for "CMatrixTemplateNumeric<double>".
mrpt::poses::CPosePDFPtr Align(const mrpt::maps::CMetricMap *m1, const mrpt::maps::CMetricMap *m2, const mrpt::poses::CPose2D &grossEst, float *runningTime=NULL, void *info=NULL)
The method for aligning a pair of metric maps, aligning only 2D + orientation.
static bool cmp_Asc(const TAuxRangeMeasInfo &a, const TAuxRangeMeasInfo &b)
Auxiliary for optimal sampling in RO-SLAM.
A class for storing images as grayscale or RGB bitmaps.
CPoint3D mean
The mean value.
Several implementations of ICP (Iterative closest point) algorithms for aligning two point maps or a ...
The namespace for Bayesian filtering algorithm: different particle filters and Kalman filter algorith...
void resize(const size_t N)
Resize the number of SOG modes.
Declares a class that represents a Probability Density function (PDF) of a 3D point ...
#define THROW_EXCEPTION(msg)
The struct for each mode:
BASE_IMPEXP CRandomGenerator randomGenerator
A static instance of a CRandomGenerator class, for use in single-thread applications.
double computeObservationLikelihood(const mrpt::obs::CObservation *obs, const mrpt::poses::CPose3D &takenFrom)
Computes the log-likelihood of a given observation given an arbitrary robot 3D pose.
void uniformDistribution()
Assigns the same value to all the cells in the grid, so the sum 1.
This file contains the implementations of the template members declared in mrpt::slam::PF_implementat...
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction...
void clear()
Clear all the gaussian modes.
double yaw() const
Get the YAW angle (in radians)
Declares a class derived from "CObservation" that represents one (or more) range measurements to labe...
Option set for KLD algorithm.
A cloud of points in 2D or 3D, which can be built from a sequence of laser scans. ...
void getCovariance(mrpt::math::CMatrixDouble &cov) const
Returns the estimate of the covariance matrix (STATE_LEN x STATE_LEN covariance matrix) ...
std::deque< CBeacon >::iterator iterator
const Scalar * const_iterator
double yaw
Yaw coordinate (rotation angle over Z axis).
bool isPrepared() const
Return true if samples can be generated, which only requires a previous call to setPosePDF.
void KLF_loadBinFromParticle(detail::TPathBin2D &outBin, const TKLDParams &opts, const mrpt::maps::CRBPFParticleData *currentParticleValue, const TPose3D *newPoseToBeInserted)
Fills out a "TPathBin2D" variable, given a path hypotesis and (if not set to NULL) a new pose appende...
Declares a class for storing a collection of robot actions.
double idx2y(size_t y) const
Returns coordinates from "indexes":
std::deque< CObservationPtr >::const_iterator const_iterator
You can use CSensoryFrame::begin to get a iterator to the first element.
T square(const T x)
Inline function for the square of a number.
void getAsMatrix(const double &phi, MATRIXLIKE &outMat)
Returns the whole grid as a matrix, for a given constant "phi" and where each row contains values for...
const T * getByIndex(size_t x, size_t y, size_t phi) const
Reads the contents of a cell.
const_iterator begin() const
Returns a constant iterator to the first observation: this is an example of usage: ...
Represents a probabilistic 3D (6D) movement.
float goodness
A goodness measure for the alignment, it is a [0,1] range indicator of percentage of correspondences...
This base provides a set of functions for maths stuff.
A class for storing a map of 3D probabilistic landmarks.
Declares a class that represents a Probability Density function (PDF) of a 2D pose ...
void setPosePDF(const CPosePDF *pdf)
This method must be called to select the PDF from which to draw samples.
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
double norm() const
Returns the euclidean norm of vector: .
void push_back(const TGaussianMode &m)
Inserts a copy of the given mode into the SOG.
void getOriginalPDFCov2D(mrpt::math::CMatrixDouble33 &cov3x3) const
Retrieves the 3x3 covariance of the original PDF in .
mrpt::math::CMatrixDouble33 cov
The 3x3 covariance matrix.
std::deque< TMeasurement > sensedData
The list of observed ranges.
void getMean(CPoint3D &mean_point) const MRPT_OVERRIDE
Returns an estimate of the point, (the mean, or mathematical expectation of the PDF) ...
This namespace contains representation of robot actions and observations.
Declares a class for storing a "sensory frame", a set of "observations" taken by the robot approximat...
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
double KLD_binSize_XY
Parameters for the KLD adaptive sample size algorithm (see Dieter Fox's papers), which is used only i...
A class used to store a 3D point.
void keep_max(T &var, const K test_val)
If the second argument is above the first one, set the first argument to this higher value...
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Auxiliary class used in mrpt::maps::CMultiMetricMapPDF.
iterator erase(iterator i)
Auxiliary structure used in KLD-sampling in particle filters.
mrpt::math::CMatrixDouble66 cov
The 6x6 covariance matrix.
#define INVALID_BEACON_ID
Used for CObservationBeaconRange, CBeacon, etc.
void bayesianFusion(const CPointPDF &p1, const CPointPDF &p2, const double &minMahalanobisDistToDrop=0) MRPT_OVERRIDE
Bayesian fusion of two point distributions (product of two distributions->new distribution), then save the result in this object (WARNING: See implementing classes to see classes that can and cannot be mixtured!)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Declares a virtual base class for all metric maps storage classes.
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.
double powFactor
An optional step to "smooth" dramatic changes in the observation model to affect the variance of the ...
double ESS() const
Computes the "Effective sample size" (typical measure for Particle Filters), applied to the weights o...
CPoint3D sensorLocationOnRobot
#define IS_CLASS(ptrObj, class_name)
Evaluates to true if the given pointer to an object (derived from mrpt::utils::CSerializable) is of t...
The configuration of a particle filter.
size_t size() const
Return the number of Gaussian modes.
CActionRobotMovement2DPtr getBestMovementEstimation() const
Returns the best pose increment estimator in the collection, based on the determinant of its pose cha...
std::deque< mrpt::math::TPose3D > robotPath
void setFromValues(const double x0, const double y0, const double z0, const double yaw=0, const double pitch=0, const double roll=0)
Set the pose from a 3D position (meters) and yaw/pitch/roll angles (radians) - This method recomputes...
The ICP algorithm return information.
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
Declares a class that represents a Probability Density function (PDF) of a 3D pose ...
int round(const T value)
Returns the closer integer (int) to x.
bool saveToFile(const std::string &fileName, int jpeg_quality=95) const
Save the image to a file, whose format is determined from the extension (internally uses OpenCV)...
double log_w
The log-weight.
std::vector< TPoseBin2D > bins
double idx2x(size_t x) const
Returns coordinates from "indexes":
T::Ptr getActionByClass(const size_t &ith=0) const
Access to the i'th action of a given class, or a NULL smart pointer if there is no action of that cla...
Auxiliary for optimal sampling in RO-SLAM.
CPose2D & drawSample(CPose2D &p) const
Generate a new sample from the selected PDF.
std::deque< TGaussianMode >::iterator iterator
void drawGaussianMultivariate(std::vector< T > &out_result, const mrpt::math::CMatrixTemplateNumeric< T > &cov, const std::vector< T > *mean=NULL)
Generate multidimensional random samples according to a given covariance matrix.
const_iterator end() const
Returns a constant iterator to the end of the list of observations: this is an example of usage: ...
This class stores any customizable set of metric maps.
An efficient generator of random samples drawn from a given 2D (CPosePDF) or 3D (CPose3DPDF) pose pro...
Declares a class that represents a Probability Distribution function (PDF) of a 2D pose (x...
GLubyte GLubyte GLubyte a
void normalize()
Normalizes the PDF, such as all cells sum the unity.
bool insertObservationsInto(mrpt::maps::CMetricMap *theMap, const mrpt::poses::CPose3D *robotPose=NULL) const
Insert all the observations in this SF into a metric map or any kind (see mrpt::maps::CMetricMap).
void copyFrom(const CPosePDF &o) MRPT_OVERRIDE
Copy operator, translating if necesary (for example, between particles and gaussian representations) ...