25 #include <Eigen/Dense> 42 return kf1.metric_map->compute3DMatchingRatio(
43 kf2.metric_map.get(), relPose2wrt1, parent->options.mrp);
56 metricmap.push_back(def);
68 minimumNumberElementsEachCluster, uint64_t, source, section);
70 "minDistForCorrespondence",
double, mrp.maxDistForCorr, source,
73 "minMahaDistForCorrespondence",
double, mrp.maxMahaDistForCorr, source,
78 source, section + std::string(
"."),
"");
79 metricmap.loadFromConfigFile(cfp,
"metricmap");
80 MRPT_TODO(
"Add link to example INI file");
89 partitionThreshold,
"N-cut partition threshold [0,2]");
92 "Force bisection (true) or automatically determine number of " 93 "partitions(false = default)");
97 maxKeyFrameDistanceToEval,
"Max KF ID distance");
99 s,
"minDistForCorrespondence", mrp.maxDistForCorr,
103 s,
"minMahaDistForCorrespondence", mrp.maxMahaDistForCorr,
108 metricmap.saveToConfigFile(cfp,
"metricmap");
113 m_last_last_partition_are_new_ones =
false;
115 m_individualFrames.clear();
116 m_individualMaps.clear();
117 m_last_partition.clear();
126 const uint32_t new_id = m_individualMaps.size();
127 const size_t n = new_id + 1;
130 m_individualMaps.push_back(CMultiMetricMap::Create());
131 auto& newMetricMap = m_individualMaps.back();
132 newMetricMap->setListOfMaps(options.metricmap);
138 m_individualFrames.insert(&robotPose, frame);
143 ASSERT_(m_individualMaps.size() == n);
144 ASSERT_(m_individualFrames.size() == n);
148 using namespace std::placeholders;
149 switch (options.simil_method)
152 sim_func = std::bind(
159 sim_func = m_sim_func;
177 auto pose_i = posePDF_i->getMeanVal();
179 for (uint32_t j = 0; j < new_id; j++)
181 const auto id_diff = new_id - j;
183 if (id_diff > options.maxKeyFrameDistanceToEval)
195 auto pose_j = posePDF_j->getMeanVal();
198 auto relPose = pose_j - pose_i;
201 const auto s_ij = sim_func(map_i, map_j, relPose);
202 const auto s_ji = sim_func(map_j, map_i, relPose);
203 s_sym = 0.5 * (s_ij + s_ji);
205 m_A(i, j) = m_A(j, i) = s_sym;
210 m_A(new_id, new_id) = 0;
216 if (m_last_last_partition_are_new_ones)
219 m_last_partition[m_last_partition.size() - 1].push_back(n - 1);
224 std::vector<uint32_t> dummyPart;
225 dummyPart.push_back(n - 1);
226 m_last_partition.emplace_back(dummyPart);
229 m_last_last_partition_are_new_ones =
true;
238 vector<std::vector<uint32_t>>& partitions)
244 m_A, partitions, options.partitionThreshold,
true,
true,
245 !options.forceBisectionOnly, options.minimumNumberElementsEachCluster,
249 m_last_partition = partitions;
250 m_last_last_partition_are_new_ones =
false;
257 return m_individualFrames.size();
261 std::vector<uint32_t> indexesToRemove,
bool changeCoordsRef)
265 size_t nOld = m_A.cols();
266 size_t nNew = nOld - indexesToRemove.size();
270 std::sort(indexesToRemove.begin(), indexesToRemove.end());
275 std::vector<uint32_t> indexesToStay;
276 indexesToStay.reserve(nNew);
277 for (i = 0; i < nOld; i++)
280 for (j = 0; !remov && j < indexesToRemove.size(); j++)
282 if (indexesToRemove[j] == i) remov =
true;
285 if (!remov) indexesToStay.push_back(i);
288 ASSERT_(indexesToStay.size() == nNew);
293 for (i = 0; i < nNew; i++)
294 for (j = 0; j < nNew; j++)
295 newA(i, j) = m_A(indexesToStay[i], indexesToStay[j]);
302 m_last_partition.resize(1);
303 m_last_partition[0].resize(nNew);
304 for (i = 0; i < nNew; i++) m_last_partition[0][i] = i;
306 m_last_last_partition_are_new_ones =
false;
310 for (
auto it = indexesToRemove.rbegin(); it != indexesToRemove.rend(); ++it)
312 auto itM = m_individualMaps.begin() + *it;
313 m_individualMaps.erase(itM);
318 for (
auto it = indexesToRemove.rbegin(); it != indexesToRemove.rend(); ++it)
319 m_individualFrames.remove(*it);
327 ASSERT_(m_individualFrames.size() > 0);
328 m_individualFrames.get(0, posePDF, SF);
332 m_individualFrames.changeCoordinatesOrigin(p);
342 m_individualFrames.changeCoordinatesOrigin(newOrigin);
346 unsigned int newOriginPose)
352 m_individualFrames.get(newOriginPose, pdf, sf);
356 changeCoordinatesOrigin(-p);
363 const std::map<uint32_t, int64_t>* renameIndexes)
const 366 ASSERT_((
int)m_individualFrames.size() == m_A.cols());
369 objs->insert(gl_grid);
370 int bbminx = std::numeric_limits<int>::max(),
371 bbminy = std::numeric_limits<int>::max();
372 int bbmaxx = -bbminx, bbmaxy = -bbminy;
374 for (
size_t i = 0; i < m_individualFrames.size(); i++)
378 m_individualFrames.get(i, i_pdf, i_sf);
381 i_pdf->getMean(i_mean);
389 i_sph->setRadius(0.02f);
390 i_sph->setColor(0, 0, 1);
393 i_sph->setName(
format(
"%u", static_cast<unsigned int>(i)));
396 auto itName = renameIndexes->find(i);
397 ASSERT_(itName != renameIndexes->end());
399 format(
"%lu", static_cast<unsigned long>(itName->second)));
402 i_sph->enableShowName();
403 i_sph->setPose(i_mean);
408 for (
size_t j = i + 1; j < m_individualFrames.size(); j++)
412 m_individualFrames.get(j, j_pdf, j_sf);
415 j_pdf->getMean(j_mean);
417 float SSO_ij = m_A(i, j);
422 std::make_shared<opengl::CSimpleLine>();
424 i_mean.
x(), i_mean.
y(), i_mean.z(), j_mean.
x(), j_mean.
y(),
427 lin->setColor(SSO_ij, 0, 1 - SSO_ij, SSO_ij * 0.6);
428 lin->setLineWidth(SSO_ij * 10);
434 gl_grid->setPlaneLimits(bbminx, bbmaxx, bbminy, bbmaxy);
435 gl_grid->setGridFrequency(5);
446 in >> m_individualFrames >> m_individualMaps >> m_A >>
447 m_last_partition >> m_last_last_partition_are_new_ones;
451 std::vector<uint8_t> old_modified_nodes;
452 in >> old_modified_nodes;
465 out << m_individualFrames << m_individualMaps << m_A << m_last_partition
466 << m_last_last_partition_are_new_ones;
void updatePartitions(std::vector< std::vector< uint32_t >> &partitions)
Recalculate the map/graph partitions.
void keep_min(T &var, const K test_val)
If the second argument is below the first one, set the first argument to this lower value...
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
size_t getNodesCount()
Get the total node count currently in the internal map/graph.
void removeSetOfNodes(std::vector< uint32_t > indexesToRemove, bool changeCoordsRef=true)
Remove a list of keyframes, with indices as returned by addMapFrame()
#define THROW_EXCEPTION(msg)
std::string std::string format(std::string_view fmt, ARGS &&... args)
void loadFromConfigFile(const mrpt::config::CConfigFileBase &source, const std::string §ion) override
This method load the options from a ".ini"-like file or memory-stored string list.
mrpt::maps::CMultiMetricMap::Ptr metric_map
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
To be added to all CSerializable-classes implementation files.
int MRPT_SAVE_NAME_PADDING()
Default padding sizes for macros MRPT_SAVE_CONFIG_VAR_COMMENT(), etc.
Abstract graph and tree data structures, plus generic graph algorithms.
double observationsOverlap(const mrpt::obs::CObservation *o1, const mrpt::obs::CObservation *o2, const mrpt::poses::CPose3D *pose_o2_wrt_o1=nullptr)
Estimates the "overlap" or "matching ratio" of two observations (range [0,1]), possibly taking into a...
uint32_t addMapFrame(const mrpt::obs::CSensoryFrame &frame, const mrpt::poses::CPose3DPDF &robotPose3D)
Insert a new keyframe to the graph.
void changeCoordinatesOrigin(const mrpt::poses::CPose3D &newOrigin)
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
static double eval_similarity_metric_map_matching(const CIncrementalMapPartitioner *parent, const map_keyframe_t &kf1, const map_keyframe_t &kf2, const mrpt::poses::CPose3D &relPose2wrt1)
#define ASSERT_(f)
Defines an assertion mechanism.
This class allows loading and storing values and vectors of different types from a configuration text...
This base provides a set of functions for maths stuff.
std::function< double(const map_keyframe_t &kf1, const map_keyframe_t &kf2, const mrpt::poses::CPose3D &relPose2wrt1)> similarity_func_t
Type of similarity evaluator for map keyframes.
void changeCoordinatesOriginPoseIndex(unsigned int newOriginPose)
The new origin is given by the index of the pose that is to become the new origin.
Map keyframe, comprising raw observations and they as a metric map.
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...
mrpt::obs::CSensoryFrame::Ptr raw_observations
int MRPT_SAVE_VALUE_PADDING()
A wrapper for other CConfigFileBase-based objects that prefixes a given token to every key and/or sec...
double x() const
Common members of all points & poses classes.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
void saveToConfigFile(mrpt::config::CConfigFileBase &target, const std::string §ion) const override
This method saves the options to a ".ini"-like file or memory-stored string list. ...
void write(const std::string §ion, const std::string &name, enum_t value, const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment=std::string())
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...
#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...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
static double eval_similarity_observation_overlap(const map_keyframe_t &kf1, const map_keyframe_t &kf2, const mrpt::poses::CPose3D &relPose2wrt1)
Finds partitions in metric maps based on N-cut graph partition theory.
Virtual base class for "archives": classes abstracting I/O streams.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
mrpt::vision::TStereoCalibResults out
#define MRPT_SAVE_CONFIG_VAR_COMMENT(variableName, __comment)
#define MRPT_LOAD_HERE_CONFIG_VAR( variableName, variableType, targetVariable, configFileObject, sectionNameStr)
MRPT_TODO("toPointCloud / calibration")
void getAs3DScene(mrpt::opengl::CSetOfObjects::Ptr &objs, const std::map< uint32_t, int64_t > *renameIndexes=nullptr) const
Return a 3D representation of the graph: poses & links between them.
bool insertObservationsInto(mrpt::maps::CMetricMap *theMap, const mrpt::poses::CPose3D *robotPose=nullptr) const
Insert all the observations in this SF into a metric map or any kind (see mrpt::maps::CMetricMap).
Finds the min-normalized-cut of a weighted undirected graph.
static Ptr Create(Args &&... args)
Declares a class that represents a Probability Density Function (PDF) of a 3D pose (6D actually)...