9 #ifndef CONSTRAINED_POSE_NETWORK_H
10 #define CONSTRAINED_POSE_NETWORK_H
38 #include <type_traits>
48 template <
class GRAPH_T>
54 class MAPS_IMPLEMENTATION,
class NODE_ANNOTATIONS,
class EDGE_ANNOTATIONS>
59 class MAPS_IMPLEMENTATION,
class NODE_ANNOTATIONS,
class EDGE_ANNOTATIONS>
117 class MAPS_IMPLEMENTATION =
132 CPOSE, MAPS_IMPLEMENTATION, NODE_ANNOTATIONS, EDGE_ANNOTATIONS>;
152 return literal(
"mrpt::graphs::CNetworkOfPoses<") +
165 CPOSE, MAPS_IMPLEMENTATION, NODE_ANNOTATIONS,
171 return literal(
"global_pose_t<") +
180 template <
typename ARG1>
184 template <
typename ARG1,
typename ARG2>
204 static_cast<const NODE_ANNOTATIONS
>(*
this) ==
205 static_cast<const NODE_ANNOTATIONS
>(other));
209 return (!(*
this == other));
213 std::ostream& o,
const self_t& global_pose)
215 o << global_pose.asString() <<
"| "
216 << global_pose.retAnnotsAsString();
228 using global_poses_t =
typename MAPS_IMPLEMENTATION::template map<
295 const std::string& fileName,
bool collapse_dup_edges =
true)
317 CPOSE, MAPS_IMPLEMENTATION, NODE_ANNOTATIONS, EDGE_ANNOTATIONS>;
319 CPOSE, MAPS_IMPLEMENTATION, NODE_ANNOTATIONS, EDGE_ANNOTATIONS>;
321 bool is_multirobot =
false;
322 std::unique_ptr<visualizer_t> viz;
323 is_multirobot = (std::is_base_of<
328 viz.reset(
new visualizer_multirobot_t(*
this));
332 viz.reset(
new visualizer_t(*
this));
334 viz->getAs3DObject(
object, viz_params);
381 itEdge != last_it; ++itEdge)
383 this, itEdge, ignoreCovariances);
405 const std::set<TNodeID>& node_IDs,
self_t* sub_graph,
407 const bool& auto_expand_set =
true)
const
410 using namespace mrpt;
419 "\nInvalid pointer to a CNetworkOfPoses instance is given. "
424 TNodeID root_node = root_node_in;
428 node_IDs.find(root_node) != node_IDs.end(),
429 "\nRoot_node does not exist in the given node_IDs set. "
435 node_IDs.size() >= 2,
437 "Very few nodes [%lu] for which to extract a subgraph. "
439 static_cast<unsigned long>(node_IDs.size())));
443 bool is_fully_connected_graph =
true;
444 std::set<TNodeID> node_IDs_real;
445 if (*node_IDs.rbegin() - *node_IDs.begin() + 1 == node_IDs.size())
447 node_IDs_real = node_IDs;
451 is_fully_connected_graph =
false;
455 for (
TNodeID curr_node_ID = *node_IDs.begin();
456 curr_node_ID != *node_IDs.rbegin(); ++curr_node_ID)
458 node_IDs_real.insert(curr_node_ID);
463 node_IDs_real = node_IDs;
469 node_IDs_real.begin();
470 node_IDs_it != node_IDs_real.end(); ++node_IDs_it)
474 for (own_it =
nodes.begin(); own_it !=
nodes.end(); ++own_it)
476 if (*node_IDs_it == own_it->first)
482 own_it !=
nodes.end(),
484 "NodeID [%lu] can't be found in the initial graph.",
485 static_cast<unsigned long>(*node_IDs_it)));
488 sub_graph->
nodes.insert(make_pair(*node_IDs_it, curr_node));
499 root_node = sub_graph->
nodes.begin()->first;
501 sub_graph->
root = root_node;
513 const TNodeID& from = it->first.first;
514 const TNodeID& to = it->first.second;
518 if (sub_graph->
nodes.find(from) != sub_graph->
nodes.end() &&
519 sub_graph->
nodes.find(to) != sub_graph->
nodes.end())
525 if (!auto_expand_set && !is_fully_connected_graph)
532 std::set<TNodeID> root_neighbors;
535 if (root_neighbors.empty())
541 if ((*root_it == *sub_graph->
nodes.rbegin()))
546 sub_graph, next_to_root, sub_graph->
root);
554 sub_graph, sub_graph->
root, next_to_root);
561 bool dijkstra_runs_successfully =
false;
565 while (!dijkstra_runs_successfully)
569 dijkstra_t dijkstra(*sub_graph, sub_graph->
root);
570 dijkstra_runs_successfully =
true;
574 dijkstra_runs_successfully =
false;
576 set<TNodeID> unconnected_nodeIDs;
589 const TNodeID& island_highest =
590 *unconnected_nodeIDs.rbegin();
591 const TNodeID& island_lowest = *unconnected_nodeIDs.begin();
599 std::set<TNodeID> mainland;
602 sub_graph->
nodes.begin();
603 n_it != sub_graph->
nodes.end(); ++n_it)
605 bool is_there =
false;
609 uncon_it = unconnected_nodeIDs.begin();
610 uncon_it != unconnected_nodeIDs.end(); ++uncon_it)
612 if (n_it->first == *uncon_it)
621 mainland.insert(n_it->first);
625 bool is_single_island =
626 (island_highest - island_lowest + 1 ==
627 unconnected_nodeIDs.size());
629 if (is_single_island)
643 const std::set<TNodeID>& island = unconnected_nodeIDs;
645 sub_graph, island, mainland);
656 std::vector<std::set<TNodeID>> vec_of_islands;
657 std::set<TNodeID> curr_island;
658 TNodeID prev_nodeID = *unconnected_nodeIDs.begin();
662 ++unconnected_nodeIDs.begin();
663 *it < sub_graph->
root &&
664 it != unconnected_nodeIDs.end();
667 if (!(
absDiff(*it, prev_nodeID) == 1))
669 vec_of_islands.push_back(curr_island);
672 curr_island.insert(*it);
677 vec_of_islands.push_back(curr_island);
685 sub_graph, vec_of_islands.back(), mainland);
716 const bool hypots_from_other_to_self =
true,
717 std::map<TNodeID, TNodeID>* old_to_new_nodeID_mappings_out = NULL)
728 const self_t& graph_from = (hypots_from_other_to_self ? other : *
this);
729 const self_t& graph_to = (hypots_from_other_to_self ? *this : other);
737 for (hypots_cit_t h_cit = common_hypots.begin();
738 h_cit != common_hypots.end(); ++h_cit)
741 graph_from.
nodes.find(h_cit->from) != graph_from.
nodes.end(),
742 format(
"NodeID %lu is not found in (from) graph", h_cit->from));
744 graph_to.
nodes.find(h_cit->to) != graph_to.
nodes.end(),
745 format(
"NodeID %lu is not found in (to) graph", h_cit->to));
750 for (nodes_cit_t n_cit = this->nodes.begin();
751 n_cit != this->nodes.end(); ++n_cit)
753 if (n_cit->first > max_nodeID)
755 max_nodeID = n_cit->first;
758 TNodeID renum_start = max_nodeID + 1;
759 size_t renum_counter = 0;
764 std::map<TNodeID, TNodeID>* old_to_new_nodeID_mappings;
770 std::map<TNodeID, TNodeID> mappings_tmp;
773 if (old_to_new_nodeID_mappings_out)
775 old_to_new_nodeID_mappings = old_to_new_nodeID_mappings_out;
779 old_to_new_nodeID_mappings = &mappings_tmp;
781 old_to_new_nodeID_mappings->clear();
786 for (nodes_cit_t n_cit = other.
nodes.begin();
787 n_cit != other.
nodes.end(); ++n_cit)
789 TNodeID new_nodeID = renum_start + renum_counter++;
790 old_to_new_nodeID_mappings->insert(
791 make_pair(n_cit->first, new_nodeID));
792 this->nodes.insert(make_pair(new_nodeID, n_cit->second));
800 for (hypots_cit_t h_cit = common_hypots.begin();
801 h_cit != common_hypots.end(); ++h_cit)
804 if (hypots_from_other_to_self)
806 from = old_to_new_nodeID_mappings->at(h_cit->from);
812 to = old_to_new_nodeID_mappings->at(h_cit->to);
823 g_cit != other.
end(); ++g_cit)
826 old_to_new_nodeID_mappings->at(g_cit->first.first);
828 old_to_new_nodeID_mappings->at(g_cit->first.second);
829 this->
insertEdge(new_from, new_to, g_cit->second);
851 self_t* sub_graph,
const std::set<TNodeID>& groupA,
852 const std::set<TNodeID>& groupB)
858 "\nInvalid pointer to a CNetworkOfPoses instance is given. "
860 ASSERTMSG_(!groupA.empty(),
"\ngroupA is empty.");
861 ASSERTMSG_(!groupB.empty(),
"\ngroupB is empty.");
865 *groupA.rend() < *groupB.rbegin() ||
866 *groupA.rbegin() > *groupB.rend(),
867 "Groups A, B contain overlapping nodeIDs");
871 const std::set<TNodeID>& low_nodeIDs =
872 *groupA.rbegin() < *groupB.rbegin() ? groupA : groupB;
873 const std::set<TNodeID>& high_nodeIDs =
874 *groupA.rbegin() > *groupB.rbegin() ? groupA : groupB;
877 const TNodeID& from_nodeID = *low_nodeIDs.rbegin();
878 const TNodeID& to_nodeID = *high_nodeIDs.begin();
891 bool ignoreCovariances =
true)
const
894 this, itEdge, ignoreCovariances);
907 bool ignoreCovariances =
true)
const
914 "Request for edge %u->%u that doesn't exist in graph.",
915 static_cast<unsigned int>(from_id),
916 static_cast<unsigned int>(to_id)));
947 graph,
"Invalid pointer to the graph instance was provided.");
959 class CPOSE,
class MAPS_IMPLEMENTATION,
class NODE_ANNOTATIONS,
960 class EDGE_ANNOTATIONS>
964 CPOSE, MAPS_IMPLEMENTATION, NODE_ANNOTATIONS, EDGE_ANNOTATIONS>&
obj)
967 CPOSE, MAPS_IMPLEMENTATION, NODE_ANNOTATIONS, EDGE_ANNOTATIONS>;
974 class CPOSE,
class MAPS_IMPLEMENTATION,
class NODE_ANNOTATIONS,
975 class EDGE_ANNOTATIONS>
979 CPOSE, MAPS_IMPLEMENTATION, NODE_ANNOTATIONS, EDGE_ANNOTATIONS>&
obj)
982 CPOSE, MAPS_IMPLEMENTATION, NODE_ANNOTATIONS, EDGE_ANNOTATIONS>;