50 const TPose3D* newPoseToBeInserted)
53 if (newPoseToBeInserted)
62 currentParticleValue && !currentParticleValue->
robotPath.empty());
77 const TPose3D* newPoseToBeInserted)
79 const size_t lenBinPath = (currentParticleValue !=
nullptr)
84 outBin.
bins.resize(lenBinPath + (newPoseToBeInserted !=
nullptr ? 1 : 0));
87 if (currentParticleValue !=
nullptr)
88 for (
size_t i = 0; i < lenBinPath; ++i)
99 if (newPoseToBeInserted !=
nullptr)
102 outBin.
bins[lenBinPath].x =
104 outBin.
bins[lenBinPath].y =
106 outBin.
bins[lenBinPath].phi =
120 : sensorLocationOnRobot(),
136 return a.nGaussiansInMap <
b.nGaussiansInMap;
145 void CMultiMetricMapPDF::prediction_and_update_pfAuxiliaryPFOptimal(
152 PF_SLAM_implementation_pfAuxiliaryPFOptimal<mrpt::slam::detail::TPoseBin2D>(
153 actions, sf, PF_options, options.KLD_params);
161 void CMultiMetricMapPDF::prediction_and_update_pfAuxiliaryPFStandard(
168 PF_SLAM_implementation_pfAuxiliaryPFStandard<
170 actions, sf, PF_options, options.KLD_params);
190 void CMultiMetricMapPDF::prediction_and_update_pfOptimalProposal(
201 size_t M = m_particles.size();
202 bool updateStageAlreadyDone =
false;
203 CPose3D initialPose, incrPose, finalPose;
224 robotMovement2D->poseChange.get_ptr());
225 motionModelMeanIncr =
234 robotActionSampler.
setPosePDF(robotMovement3D->poseChange);
235 robotMovement3D->poseChange.getMean(motionModelMeanIncr);
245 averageMapIsUpdated =
false;
253 printf(
" 1) Prediction...");
254 M = m_particles.size();
257 size_t particleWithHighestW = 0;
258 for (
size_t i = 0; i < M; i++)
259 if (getW(i) > getW(particleWithHighestW)) particleWithHighestW = i;
262 ASSERT_(!m_particles[0].d->robotPath.empty());
266 bool built_map_points =
false;
267 bool built_map_lms =
false;
271 for (i = 0, partIt = m_particles.begin(); partIt != m_particles.end();
274 double extra_log_lik = 0;
278 *partIt->d->robotPath.rbegin());
280 CPose3D initialPoseEstimation = ith_last_pose + motionModelMeanIncr;
283 if (options.pfOptimalProposal_mapSelection == 0 ||
284 options.pfOptimalProposal_mapSelection == 1 ||
285 options.pfOptimalProposal_mapSelection == 3)
290 if (partIt->d->mapTillNow.m_pointsMaps.size())
292 ASSERT_(partIt->d->mapTillNow.m_pointsMaps.size() == 1);
299 if (options.pfOptimalProposal_mapSelection == 0)
301 ASSERT_(!partIt->d->mapTillNow.m_gridMaps.empty());
304 if (!built_map_points)
306 built_map_points =
true;
315 map_to_align_to = partIt->d->mapTillNow.m_gridMaps[0].get();
317 else if (options.pfOptimalProposal_mapSelection == 3)
320 ASSERT_(!partIt->d->mapTillNow.m_pointsMaps.empty());
323 if (!built_map_points)
325 built_map_points =
true;
334 map_to_align_to = partIt->d->mapTillNow.m_pointsMaps[0].get();
338 ASSERT_(partIt->d->mapTillNow.m_landmarksMap);
343 built_map_lms =
true;
347 map_to_align_to = partIt->d->mapTillNow.m_landmarksMap.get();
350 ASSERT_(map_to_align_to !=
nullptr);
355 map_to_align_to, &localMapPoints,
356 CPose2D(initialPoseEstimation),
nullptr, &icpInfo);
360 if (i == particleWithHighestW)
362 newInfoIndex = 1 - icpInfo.
goodness;
371 if (icpInfo.
goodness < options.ICPGlobalAlign_MinQuality &&
375 "[rbpf-slam] Warning: gridICP[%u]: %.02f%% -> Using "
376 "odometry instead!\n",
377 (
unsigned int)i, 100 * icpInfo.
goodness);
378 icpEstimation.
mean =
CPose2D(initialPoseEstimation);
397 #if 0 // Use hacked ICP covariance:
398 CPose3D Ap = finalEstimatedPoseGauss.
mean - ith_last_pose;
399 const double Ap_dist = Ap.
norm();
401 finalEstimatedPoseGauss.
cov.zeros();
402 finalEstimatedPoseGauss.
cov(0,0) =
square( fabs(Ap_dist)*0.01 );
403 finalEstimatedPoseGauss.
cov(1,1) =
square( fabs(Ap_dist)*0.01 );
404 finalEstimatedPoseGauss.
cov(2,2) =
square( fabs(Ap.
yaw())*0.02 );
417 finalEstimatedPoseGauss.
mean;
419 rndSamples, finalEstimatedPoseGauss.
cov);
422 finalPose.
x() + rndSamples[0], finalPose.
y() + rndSamples[1],
423 finalPose.z(), finalPose.
yaw() + rndSamples[2],
426 else if (options.pfOptimalProposal_mapSelection == 2)
434 ASSERT_(partIt->d->mapTillNow.m_beaconMap);
437 updateStageAlreadyDone =
450 bool methodSOGorGrid =
false;
452 float firstEstimateRobotHeading = std::numeric_limits<float>::max();
455 CPoint3D centerPositionPrior(ith_last_pose);
456 float centerPositionPriorRadius = 2.0f;
460 firstEstimateRobotHeading = ith_last_pose.
yaw();
465 if (!beacMap->size())
468 cerr <<
"[RO-SLAM] Optimal filtering without map & "
469 "odometry...this message should appear only the "
478 if (beacMap->get(0).m_typePDF == CBeacon::pdfSOG)
480 cerr <<
"[RO-SLAM] Optimal filtering without map & "
481 "odometry->FIXING ONE BEACON!"
483 ASSERT_(beacMap->get(0).m_locationSOG.size() > 0);
485 beacMap->get(0).m_locationSOG[0].val.mean);
488 beacMap->get(0).m_typePDF = CBeacon::pdfGauss;
489 beacMap->get(0).m_locationSOG.clear();
490 beacMap->get(0).m_locationGauss.mean = fixedBeacon;
491 beacMap->get(0).m_locationGauss.cov.unit(3, 1e-6);
498 deque<TAuxRangeMeasInfo> lstObservedRanges;
501 itObs != sf->
end(); ++itObs)
508 deque<CObservationBeaconRanges::TMeasurement>::
509 const_iterator itRanges;
511 itRanges != obs->
sensedData.end(); itRanges++)
516 itBeacs != beacMap->end(); ++itBeacs)
518 if ((itBeacs)->m_ID == itRanges->beaconID)
521 newMeas.
beaconID = itRanges->beaconID;
523 itRanges->sensedDistance;
525 itRanges->sensorLocationOnRobot;
528 (itBeacs)->m_typePDF == CBeacon::pdfGauss ||
529 (itBeacs)->m_typePDF == CBeacon::pdfSOG);
531 (itBeacs)->m_typePDF == CBeacon::pdfSOG
532 ? (itBeacs)->m_locationSOG.size()
535 lstObservedRanges.push_back(newMeas);
548 lstObservedRanges.begin(), lstObservedRanges.end(),
555 fusedObsModels.
clear();
572 firstEstimateRobotHeading = auxPose.
yaw();
582 poseCOV.setSize(2, 2);
583 poseCOV.setSize(3, 3);
584 newMode.
val.
cov = poseCOV;
591 itBeacs != beacMap->end(); ++itBeacs)
596 lstObservedRanges.begin();
597 itObs != lstObservedRanges.end(); ++itObs)
599 if ((itBeacs)->m_ID == itObs->beaconID)
602 float sensedRange = itObs->sensedDistance;
605 (itBeacs)->generateObservationModelDistribution(
606 sensedRange, newObsModel,
608 itObs->sensorLocationOnRobot,
611 centerPositionPrior, centerPositionPriorRadius);
613 if (!fusedObsModels.
size())
617 fusedObsModels = newObsModel;
624 fusedObsModels, newObsModel,
627 fusedObsModels = tempFused;
634 cout <<
"#modes bef: " << fusedObsModels.
size()
635 <<
" ESS: " << fusedObsModels.
ESS()
637 double max_w = -1e100;
642 for (it = fusedObsModels.
begin();
643 it != fusedObsModels.
end(); it++)
645 max(max_w, (it)->log_w);
649 for (it = fusedObsModels.
begin();
650 it != fusedObsModels.
end();)
652 if (max_w - (it)->log_w >
654 it = fusedObsModels.
erase(it);
660 <<
"#modes after: " << fusedObsModels.
size()
669 currentCov(0, 0) > 0 && currentCov(1, 1) > 0);
670 if (sqrt(currentCov(0, 0)) < 0.10f &&
671 sqrt(currentCov(1, 1)) < 0.10f &&
672 sqrt(currentCov(2, 2)) < 0.10f)
676 fusedObsModels.
getMean(currentMean);
677 fusedObsModels[0].log_w = 0;
678 fusedObsModels[0].val.mean = currentMean;
679 fusedObsModels[0].val.cov = currentCov;
719 float grid_min_x = ith_last_pose.
x() - 0.5f;
720 float grid_max_x = ith_last_pose.
x() + 0.5f;
721 float grid_min_y = ith_last_pose.
y() - 0.5f;
722 float grid_max_y = ith_last_pose.
y() + 0.5f;
723 float grid_resXY = 0.02f;
725 bool repeatGridCalculation =
false;
730 grid_min_x, grid_max_x, grid_min_y, grid_max_y,
731 grid_resXY,
DEG2RAD(180), 0, 0);
738 itBeacs != beacMap->end(); ++itBeacs)
743 lstObservedRanges.begin();
744 itObs != lstObservedRanges.end(); ++itObs)
746 if ((itBeacs)->m_ID == itObs->beaconID)
749 float sensedRange = itObs->sensedDistance;
765 for (
size_t idxX = 0;
768 float grid_x = pdfGrid->
idx2x(idxX);
769 for (
size_t idxY = 0;
772 double grid_y = pdfGrid->
idx2y(idxY);
781 switch ((itBeacs)->m_typePDF)
783 case CBeacon::pdfSOG:
786 &(itBeacs)->m_locationSOG;
787 double sensorSTD2 =
square(
788 beacMap->likelihoodOptions
792 for (it = sog->
begin();
793 it != sog->
end(); it++)
799 (it)->
val.mean.distance2DTo(
802 ->sensorLocationOnRobot
806 ->sensorLocationOnRobot
830 float maxX = 0, maxY = 0;
831 for (
size_t idxX = 0; idxX < pdfGrid->
getSizeX();
835 for (
size_t idxY = 0; idxY < pdfGrid->
getSizeY();
845 maxX = pdfGrid->
idx2x(idxX);
846 maxY = pdfGrid->
idx2y(idxY);
850 newDrawnPosition.
x(maxX);
851 newDrawnPosition.
y(maxY);
859 outMat *= 1.0f/outMat.maxCoeff();
860 CImage imgF(outMat,
true);
861 static int autocount=0;
862 imgF.saveToFile(
format(
"debug_grid_%f_%05i.png",grid_resXY,autocount++));
863 printf(
"grid res: %f MAX: %f,%f\n",grid_resXY,maxX,maxY);
868 if (grid_resXY > 0.01f)
870 grid_min_x = maxX - 0.03f;
871 grid_max_x = maxX + 0.03f;
872 grid_min_y = maxY - 0.03f;
873 grid_max_y = maxY + 0.03f;
875 repeatGridCalculation =
true;
878 repeatGridCalculation =
false;
894 }
while (repeatGridCalculation);
903 if (!beacMap->size())
907 finalPose = ith_last_pose;
911 cout <<
"Drawn: " << newDrawnPosition << endl;
917 firstEstimateRobotHeading !=
918 std::numeric_limits<float>::max());
921 newDrawnPosition.
x(), newDrawnPosition.
y(),
922 newDrawnPosition.z(), firstEstimateRobotHeading, 0, 0);
933 double weightUpdate = 0;
934 partIt->log_w += PF_options.
powFactor * weightUpdate;
943 "Action list does not contain any CActionRobotMovement2D "
944 "or CActionRobotMovement3D object!");
948 finalPose = ith_last_pose + incrPose;
952 partIt->d->robotPath.push_back(finalPose.
asTPose());
957 if (!updateStageAlreadyDone)
960 (PF_SLAM_computeObservationLikelihoodForParticle(
961 PF_options, i, *sf, finalPose) +
975 void CMultiMetricMapPDF::prediction_and_update_pfStandardProposal(
982 PF_SLAM_implementation_pfStandardProposal<mrpt::slam::detail::TPoseBin2D>(
983 actions, sf, PF_options, options.KLD_params);
986 averageMapIsUpdated =
false;
992 void CMultiMetricMapPDF::
993 PF_SLAM_implementation_custom_update_particle_with_new_pose(
996 particleData->
robotPath.push_back(newPose);
1000 bool CMultiMetricMapPDF::PF_SLAM_implementation_doWeHaveValidObservations(
1001 const CMultiMetricMapPDF::CParticleList& particles,
1004 if (sf ==
nullptr)
return false;
1006 return particles.begin()
1008 ->mapTillNow.canComputeObservationsLikelihood(*sf);
1012 bool CMultiMetricMapPDF::PF_SLAM_implementation_skipRobotMovement()
const
1014 return 0 == getNumberOfObservationsInSimplemap();
1021 double CMultiMetricMapPDF::PF_SLAM_computeObservationLikelihoodForParticle(
1023 const size_t particleIndexForMap,
const CSensoryFrame& observation,
1028 &m_particles[particleIndexForMap].d->mapTillNow);
1031 it != observation.
end(); ++it)