14 #include <mrpt_msgs/GetCMGraph.h>
16 #include <mrpt/ros1bridge/pose.h>
18 #include <mrpt/math/CMatrixFixed.h>
22 template <
typename T, std::
size_t ROWS, std::
size_t COLS>
30 template <
class GRAPH_T>
33 const std::string& rawlog_fname ,
34 const std::string& fname_GT ,
35 mrpt::graphslam::CWindowManager* win_manager ,
36 mrpt::graphslam::deciders::CNodeRegistrationDecider<GRAPH_T>*
38 mrpt::graphslam::deciders::CEdgeRegistrationDecider<GRAPH_T>*
40 mrpt::graphslam::optimizers::CGraphSlamOptimizer<GRAPH_T>*
43 nh, config_file, rawlog_fname, fname_GT, win_manager, node_reg,
45 m_conn_manager(dynamic_cast<
mrpt::system::COutputLogger*>(this), nh),
47 m_graph_nodes_last_size(0),
48 m_registered_multiple_nodes(false),
49 cm_graph_async_spinner( 1, &this->custom_service_queue),
50 m_sec_alignment_params(
"AlignmentParameters"),
51 m_sec_mr_slam_params(
"MultiRobotParameters"),
57 template <
class GRAPH_T>
60 MRPT_LOG_DEBUG_STREAM(
61 "In Destructor: Deleting CGraphSlamEngine_MR instance...");
62 cm_graph_async_spinner.stop();
64 for (
typename neighbors_t::iterator neighbors_it = m_neighbors.begin();
65 neighbors_it != m_neighbors.end(); ++neighbors_it)
71 template <
class GRAPH_T>
78 for (
const auto& neighbor : m_neighbors)
82 ->tf_self_to_neighbor_first_integrated_pose) &&
84 neighbor->hasNewData() &&
85 neighbor->hasNewNodesBatch(m_opts.nodes_integration_batch_size))
87 bool loc_ret_val = this->addNodeBatchFromNeighbor(neighbor);
99 template <
class GRAPH_T>
105 using namespace mrpt::poses;
109 std::vector<TNodeID> nodeIDs;
110 std::map<TNodeID, node_props_t> nodes_params;
116 mrpt_msgs::GetCMGraph cm_graph_srv;
119 for (
const auto n : nodeIDs)
121 cm_graph_srv.request.node_ids.push_back(n);
124 MRPT_LOG_DEBUG_STREAM(
"Asking for the graph.");
128 MRPT_LOG_ERROR_STREAM(
"Service call for CM_Graph failed.");
131 MRPT_LOG_DEBUG_STREAM(
"Fetched graph successfully.");
132 MRPT_LOG_DEBUG_STREAM(cm_graph_srv.response.cm_graph);
140 MRPT_LOG_WARN_STREAM(
141 "Merging new batch from \""
143 <<
"Batch: " << getSTLContainerAsString(cm_graph_srv.request.node_ids));
148 pair<TNodeID, node_props_t> node_props_to_connect =
149 *nodes_params.begin();
153 c.mean = node_props_to_connect.second.pose -
155 c.cov_inv.setIdentity();
156 graph_conn.setEdge(c);
158 graph_conn.from = INVALID_NODEID;
161 for (
const auto& n : this->m_graph.nodes)
163 if (n.second.agent_ID_str == neighbor->
getAgentNs() &&
164 n.second.nodeID_loc ==
167 graph_conn.from = n.first;
171 ASSERT_(graph_conn.from != INVALID_NODEID);
172 graph_conn.to = node_props_to_connect.first;
174 MRPT_LOG_DEBUG_STREAM(
175 "Hypothesis for adding the batch of nodes: " << graph_conn);
176 graph_conns.push_back(graph_conn);
179 std::map<TNodeID, TNodeID> old_to_new_mappings;
180 this->m_graph.mergeGraph(
181 other_graph, graph_conns,
182 false, &old_to_new_mappings);
187 MRPT_LOG_WARN_STREAM(
"Marking used nodes as integrated - Integrating LSs");
189 for (
typename std::vector<TNodeID>::const_iterator n_cit = nodeIDs.begin();
190 n_cit != nodeIDs.end(); ++n_cit)
197 new_nodeIDs_to_scans_pairs.insert(make_pair(
198 old_to_new_mappings.at(*n_cit), nodes_params.at(*n_cit).scan));
199 MRPT_LOG_INFO_STREAM(
200 "Adding nodeID-LS of nodeID: "
201 <<
"\t[old:] " << *n_cit << endl
202 <<
"| [new:] " << old_to_new_mappings.at(*n_cit));
205 this->m_nodes_to_laser_scans2D.insert(
206 new_nodeIDs_to_scans_pairs.begin(), new_nodeIDs_to_scans_pairs.end());
210 this->execDijkstraNodesEstimation();
215 TNodeID last_node = *nodeIDs.rbegin();
217 make_pair(last_node, nodes_params.at(last_node).pose);
224 template <
class GRAPH_T>
230 if (this->m_graph.nodeCount() < m_opts.inter_group_node_count_thresh)
239 bool ret_val =
false;
242 for (
typename neighbors_t::iterator neighbors_it = m_neighbors.begin();
243 neighbors_it != m_neighbors.end(); ++neighbors_it)
247 if (!m_neighbor_to_found_initial_tf.at(*neighbors_it))
249 bool loc_ret_val = findTFWithNeighbor(*neighbors_it);
252 MRPT_LOG_DEBUG_STREAM(
253 "Updating own cached map after successful node "
259 m_neighbor_to_found_initial_tf.at(*neighbors_it) =
true;
270 template <
class GRAPH_T>
275 using namespace mrpt::slam;
277 using namespace mrpt::poses;
278 using namespace mrpt::maps;
281 bool ret_val =
false;
283 std::vector<TNodeID> neighbor_nodes;
284 std::map<TNodeID, node_props_t> nodes_params;
286 &neighbor_nodes, &nodes_params,
288 if (neighbor_nodes.size() < m_opts.inter_group_node_count_thresh ||
297 COccupancyGridMap2D::Ptr neighbor_gridmap = neighbor->
getGridMap();
298 CGridMapAligner gridmap_aligner;
299 gridmap_aligner.options = m_alignment_options;
301 CGridMapAligner::TReturnInfo results;
304 CPosePDFGaussian init_estim;
307 LVL_INFO,
"Trying to align the maps, initial estimation: %s",
308 init_estim.mean.asString().c_str());
317 TMetricMapAlignmentResult alignRes;
319 const CPosePDF::Ptr pdf_tmp = gridmap_aligner.AlignPDF(
320 this->m_gridmap_cached.get(), neighbor_gridmap.get(), init_estim,
323 const auto run_time = alignRes.executionTime;
325 this->logFmt(LVL_INFO,
"Elapsed Time: %f", run_time);
326 CPosePDFSOG::Ptr pdf_out = CPosePDFSOG::Create();
327 pdf_out->copyFrom(*pdf_tmp);
330 CMatrixDouble33 cov_out;
331 pdf_out->getMostLikelyCovarianceAndMean(cov_out, pose_out);
351 mrpt_msgs::GetCMGraph cm_graph_srv;
352 typedef mrpt_msgs::GetCMGraphRequest::_node_ids_type node_id_type;
353 node_id_type& matched_nodeIDs = cm_graph_srv.request.node_ids;
357 for (
typename std::vector<TNodeID>::const_iterator n_cit =
358 neighbor_nodes.begin();
359 n_cit != neighbor_nodes.end(); ++n_cit)
361 matched_nodeIDs.push_back(*n_cit);
364 MRPT_LOG_DEBUG_STREAM(
"Asking for the graph.");
368 MRPT_LOG_ERROR_STREAM(
"Service call for CM_Graph failed.");
371 MRPT_LOG_DEBUG_STREAM(
"Fetched graph successfully.");
372 MRPT_LOG_DEBUG_STREAM(cm_graph_srv.response.cm_graph);
380 MRPT_LOG_WARN_STREAM(
381 "Merging graph of \"" << neighbor->
getAgentNs() <<
"\"...");
390 cov_out = c.cov_inv.inverse();
391 graph_conn.setEdge(c);
394 graph_conn.to = *neighbor_nodes.begin();
396 graph_conn.goodness = results.goodness;
397 graph_conns.push_back(graph_conn);
400 std::map<TNodeID, TNodeID> old_to_new_mappings;
401 this->m_graph.mergeGraph(
402 other_graph, graph_conns,
403 false, &old_to_new_mappings);
408 MRPT_LOG_WARN_STREAM(
"Marking used nodes as integrated - Integrating LSs");
410 for (
typename std::vector<TNodeID>::const_iterator n_cit =
411 neighbor_nodes.begin();
412 n_cit != neighbor_nodes.end(); ++n_cit)
419 new_nodeIDs_to_scans_pairs.insert(make_pair(
420 old_to_new_mappings.at(*n_cit), nodes_params.at(*n_cit).scan));
421 MRPT_LOG_INFO_STREAM(
422 "Adding nodeID-LS of nodeID: "
423 <<
"\t[old:] " << *n_cit << endl
424 <<
"| [new:] " << old_to_new_mappings.at(*n_cit));
427 this->m_nodes_to_laser_scans2D.insert(
428 new_nodeIDs_to_scans_pairs.begin(), new_nodeIDs_to_scans_pairs.end());
436 MRPT_LOG_WARN_STREAM(
"Executing Dijkstra..." << endl);
437 this->execDijkstraNodesEstimation();
446 TNodeID last_node = *neighbor_nodes.rbegin();
448 make_pair(last_node, nodes_params.at(last_node).pose);
451 MRPT_LOG_WARN_STREAM(
452 "Nodes of neighbor [" << neighbor->
getAgentNs()
453 <<
"] have been integrated successfully");
461 template <
class GRAPH_T>
463 mrpt::obs::CActionCollection::Ptr& action,
464 mrpt::obs::CSensoryFrame::Ptr& observations,
465 mrpt::obs::CObservation::Ptr& observation,
size_t& rawlog_entry)
469 using namespace mrpt;
472 bool continue_exec = parent_t::_execGraphSlamStep(
473 action, observations, observation, rawlog_entry);
476 bool did_register_from_map_merge;
477 if (!m_opts.conservative_find_initial_tfs_to_neighbors)
479 did_register_from_map_merge = this->findTFsWithAllNeighbors();
484 "Conservative inter-graph TF computation is not yet implemented.");
487 bool did_register_from_batches = this->addNodeBatchesFromAllNeighbors();
488 m_registered_multiple_nodes =
489 (did_register_from_map_merge || did_register_from_batches);
491 if (m_registered_multiple_nodes)
493 if (this->m_enable_visuals)
495 this->updateAllVisuals();
499 return continue_exec;
503 template <
class GRAPH_T>
514 m_list_neighbors_topic = m_mr_ns +
"/" +
"neighbors";
515 m_last_regd_id_scan_topic = m_mr_ns +
"/" +
"last_nodeID_laser_scan";
516 m_last_regd_nodes_topic = m_mr_ns +
"/" +
"last_regd_nodes";
517 m_cm_graph_service = m_mr_ns +
"/" +
"get_cm_graph";
519 this->m_class_name =
"CGraphSlamEngine_MR_" + m_conn_manager.getTrimmedNs();
520 this->setLoggerName(this->m_class_name);
525 std::vector<string> nodes_up;
529 MRPT_LOG_INFO_STREAM(
530 "Waiting for master_discovery, master_sync nodes to come up....");
532 "/master_sync/get_sync_info");
533 MRPT_LOG_INFO_STREAM(
"master_discovery, master_sync are available.");
535 this->m_node_reg->setClassName(
536 this->m_node_reg->getClassName() +
"_" + m_conn_manager.getTrimmedNs());
537 this->m_edge_reg->setClassName(
538 this->m_edge_reg->getClassName() +
"_" + m_conn_manager.getTrimmedNs());
539 this->m_optimizer->setClassName(
540 this->m_optimizer->getClassName() +
"_" +
541 m_conn_manager.getTrimmedNs());
580 if (this->m_enable_visuals)
583 this->m_win_manager->assignTextMessageParameters(
586 this->m_win_manager->addTextMessage(
587 this->m_offset_x_left, -m_offset_y_nrd,
588 mrpt::format(
"NRD: %s", this->m_node_reg->getClassName().c_str()),
593 this->m_win_manager->assignTextMessageParameters(
596 this->m_win_manager->addTextMessage(
597 this->m_offset_x_left, -m_offset_y_erd,
598 mrpt::format(
"ERD: %s", this->m_edge_reg->getClassName().c_str()),
603 this->m_win_manager->assignTextMessageParameters(
606 this->m_win_manager->addTextMessage(
607 this->m_offset_x_left, -m_offset_y_gso,
608 mrpt::format(
"GSO: %s", this->m_optimizer->getClassName().c_str()),
613 this->m_win_manager->assignTextMessageParameters(
614 &m_offset_y_namespace,
615 &m_text_index_namespace);
616 this->m_win_manager->addTextMessage(
617 this->m_offset_x_left, -m_offset_y_namespace,
618 mrpt::format(
"Agent ID: %s", m_conn_manager.getTrimmedNs().c_str()),
620 m_text_index_namespace);
624 this->m_optimized_map_color = m_neighbor_colors_manager.getNextTColor();
627 cm_graph_async_spinner.start();
630 template <
class GRAPH_T>
633 const TNodeID nodeID)
const
636 using namespace mrpt::graphs::detail;
641 const TMRSlamNodeAnnotations* node_annots =
642 dynamic_cast<const TMRSlamNodeAnnotations*
>(
643 &this->m_graph.nodes.at(nodeID));
647 this->getNeighborByAgentID(node_annots->agent_ID_str, neighbor);
652 laser_pose = parent_t::getLSPoseForGridMapVisualization(nodeID);
664 template <
class GRAPH_T>
671 for (
auto neighbors_it = m_neighbors.begin();
672 neighbors_it != m_neighbors.end(); ++neighbors_it)
674 if ((*neighbors_it)->getAgentNs() == agent_ID_str)
677 neighbor = *neighbors_it;
686 template <
class GRAPH_T>
690 using namespace mrpt_msgs;
696 parent_t::usePublishersBroadcasters();
699 mrpt_msgs::GraphSlamAgents nearby_slam_agents;
700 m_conn_manager.getNearbySlamAgents(
703 m_list_neighbors_pub.publish(nearby_slam_agents);
710 for (GraphSlamAgents::_list_type::const_iterator it =
711 nearby_slam_agents.list.begin();
712 it != nearby_slam_agents.list.end(); ++it)
714 const GraphSlamAgent& gsa = *it;
718 return (neighbor->agent == gsa);
720 typename neighbors_t::const_iterator neighbor_it =
721 find_if(m_neighbors.begin(), m_neighbors.end(),
search);
723 if (neighbor_it == m_neighbors.end())
726 MRPT_LOG_DEBUG_STREAM(
727 "Initializing NeighborAgentProps instance for "
732 m_neighbor_colors_manager.getNextTColor());
733 m_neighbor_to_found_initial_tf.insert(
734 make_pair(latest_neighbor,
false));
740 this->pubUpdatedNodesList();
741 this->pubLastRegdIDScan();
746 template <
class GRAPH_T>
750 using namespace mrpt_msgs;
754 if (this->m_graph_nodes_last_size == this->m_graph.nodes.size())
758 MRPT_LOG_DEBUG_STREAM(
"Updating list of node poses");
761 typename GRAPH_T::global_poses_t poses_to_send;
762 int poses_counter = 0;
764 NodeIDWithPoseVec ros_nodes;
767 for (
typename GRAPH_T::global_poses_t::const_reverse_iterator cit =
768 this->m_graph.nodes.rbegin();
769 (poses_counter <= m_opts.num_last_regd_nodes &&
770 cit != this->m_graph.nodes.rend());
774 if (cit->second.agent_ID_str != m_conn_manager.getTrimmedNs())
779 NodeIDWithPose curr_node_w_pose;
781 curr_node_w_pose.node_id = cit->first;
782 curr_node_w_pose.pose = mrpt::ros1bridge::toROS_Pose(cit->second);
785 curr_node_w_pose.str_id.data = cit->second.agent_ID_str;
786 curr_node_w_pose.node_id_loc = cit->second.nodeID_loc;
788 ros_nodes.vec.push_back(curr_node_w_pose);
793 m_last_regd_nodes_pub.publish(ros_nodes);
796 m_graph_nodes_last_size = this->m_graph.nodeCount();
808 template <
class GRAPH_T>
812 using namespace mrpt_msgs;
820 if (!this->m_nodes_to_laser_scans2D.empty() &&
821 m_nodes_to_laser_scans2D_last_size <
822 this->m_nodes_to_laser_scans2D.size())
826 *(this->m_nodes_to_laser_scans2D.rbegin());
829 if (!this->isOwnNodeID(mrpt_last_regd_id_scan.first))
837 ASSERT_(mrpt_last_regd_id_scan.second);
840 mrpt_msgs::NodeIDWithLaserScan ros_last_regd_id_scan;
841 mrpt::ros1bridge::toROS(
842 *(mrpt_last_regd_id_scan.second), ros_last_regd_id_scan.scan);
843 ros_last_regd_id_scan.node_id = mrpt_last_regd_id_scan.first;
845 m_last_regd_id_scan_pub.publish(ros_last_regd_id_scan);
848 m_nodes_to_laser_scans2D_last_size =
849 this->m_nodes_to_laser_scans2D.size();
861 template <
class GRAPH_T>
866 using namespace mrpt::graphs::detail;
869 typename GRAPH_T::global_poses_t::const_iterator global_pose_search =
870 this->m_graph.nodes.find(nodeID);
872 global_pose_search != this->m_graph.nodes.end(),
874 "isOwnNodeID called for nodeID \"%lu\" which is not "
875 "found in the graph",
876 static_cast<unsigned long>(nodeID)));
881 pose_out = &global_pose_search->second;
885 const TMRSlamNodeAnnotations* node_annots =
886 dynamic_cast<const TMRSlamNodeAnnotations*
>(
887 &global_pose_search->second);
889 node_annots->agent_ID_str == m_conn_manager.getTrimmedNs()) ||
900 template <
class GRAPH_T>
903 using namespace mrpt::slam;
905 this->readROSParameters();
908 m_alignment_options.loadFromConfigFileName(
909 this->m_config_fname, m_sec_alignment_params);
913 m_alignment_options.methodSelection = CGridMapAligner::amModifiedRANSAC;
915 m_opts.loadFromConfigFileName(this->m_config_fname, m_sec_mr_slam_params);
918 template <
class GRAPH_T>
923 parent_t::readROSParameters();
926 template <
class GRAPH_T>
929 parent_t::printParams();
930 m_alignment_options.dumpToConsole();
931 m_opts.dumpToConsole();
934 template <
class GRAPH_T>
939 template <
class GRAPH_T>
942 using namespace mrpt_msgs;
945 m_list_neighbors_pub = m_nh->advertise<GraphSlamAgents>(
946 m_list_neighbors_topic, this->m_queue_size,
951 m_last_regd_id_scan_pub = m_nh->advertise<NodeIDWithLaserScan>(
952 m_last_regd_id_scan_topic, this->m_queue_size,
956 m_last_regd_nodes_pub = m_nh->advertise<NodeIDWithPoseVec>(
957 m_last_regd_nodes_topic, this->m_queue_size,
961 template <
class GRAPH_T>
967 m_nh->setCallbackQueue(&this->custom_service_queue);
969 m_cm_graph_srvserver = m_nh->advertiseService(
972 m_nh->setCallbackQueue(global_queue);
975 template <
class GRAPH_T>
977 mrpt_msgs::GetCMGraph::Request& req, mrpt_msgs::GetCMGraph::Response& res)
982 set<TNodeID> nodes_set(req.node_ids.begin(), req.node_ids.end());
983 MRPT_LOG_INFO_STREAM(
984 "Called the GetCMGraph service for nodeIDs: "
985 << getSTLContainerAsString(nodes_set));
987 if (nodes_set.size() < 2)
993 GRAPH_T mrpt_subgraph;
994 this->m_graph.extractSubGraph(
995 nodes_set, &mrpt_subgraph,
1002 template <
class GRAPH_T>
1004 const TNodeID nodeID, mrpt::opengl::CSetOfObjects::Ptr& viz_object)
1010 std::string& agent_ID_str = this->m_graph.nodes.at(nodeID).agent_ID_str;
1011 bool is_not_own = getNeighborByAgentID(agent_ID_str, neighbor);
1017 obj_color = this->m_optimized_map_color;
1022 obj_color = neighbor->
color;
1024 viz_object->setColor_u8(obj_color);
1029 template <
class GRAPH_T>
1031 bool registered , std::string class_name )
1035 if (m_registered_multiple_nodes)
1037 MRPT_LOG_ERROR_STREAM(
"m_registered_multiple_nodes = TRUE!");
1038 m_registered_multiple_nodes = !m_registered_multiple_nodes;
1039 this->m_nodeID_max = this->m_graph.nodeCount() - 1;
1043 parent_t::monitorNodeRegistration(registered, class_name);
1049 template <
class GRAPH_T>
1051 typename GRAPH_T::global_poses_t* graph_poses)
const
1054 ASSERT_(graph_poses);
1056 for (
const auto& n : this->m_graph.nodes)
1058 if (n.second.agent_ID_str == m_conn_manager.getTrimmedNs())
1060 graph_poses->insert(n);
1067 template <
class GRAPH_T>
1069 std::set<TNodeID>* nodes_set)
const
1074 for (
const auto& n : this->m_graph.nodes)
1076 if (n.second.agent_ID_str == m_conn_manager.getTrimmedNs())
1078 nodes_set->insert(n.first);
1083 template <
class GRAPH_T>
1085 std::set<TNodeID>* nodes_set)
const
1088 this->getAllOwnNodes(nodes_set);
1093 template <
class GRAPH_T>
1096 const mrpt_msgs::GraphSlamAgent& agent_in)
1097 : engine(engine_in), agent(agent_in), has_setup_comm(false)
1106 "/" +
agent.topic_namespace.data +
"/" +
engine.m_last_regd_nodes_topic;
1108 engine.m_last_regd_id_scan_topic;
1110 "/" +
agent.topic_namespace.data +
"/" +
engine.m_cm_graph_service;
1114 "In constructor of TNeighborAgentProps for topic namespace: %s",
1115 agent.topic_namespace.data.c_str());
1119 mrpt::maps::COccupancyGridMap2D::Ptr eng_gridmap =
engine.m_gridmap_cached;
1121 eng_gridmap->getXMin(), eng_gridmap->getXMax(), eng_gridmap->getYMin(),
1122 eng_gridmap->getYMax(), eng_gridmap->getResolution());
1126 template <
class GRAPH_T>
1131 template <
class GRAPH_T>
1139 "TNeighborAgentProps: Successfully set up subscribers/services "
1140 "to agent topics for namespace [%s].",
1141 agent.topic_namespace.data.c_str());
1143 has_setup_comm =
true;
1146 template <
class GRAPH_T>
1149 cm_graph_srvclient =
1150 nh->serviceClient<mrpt_msgs::GetCMGraph>(cm_graph_service);
1153 template <
class GRAPH_T>
1156 using namespace mrpt_msgs;
1158 last_regd_nodes_sub = nh->subscribe<NodeIDWithPoseVec>(
1161 last_regd_id_scan_sub = nh->subscribe<NodeIDWithLaserScan>(
1166 template <
class GRAPH_T>
1168 const mrpt_msgs::NodeIDWithPoseVec::ConstPtr& nodes)
1171 using namespace mrpt_msgs;
1172 using namespace std;
1174 typedef typename GRAPH_T::constraint_t::type_value
pose_t;
1175 engine.logFmt(LVL_DEBUG,
"In fetchUpdatedNodesList method.");
1177 for (NodeIDWithPoseVec::_vec_type::const_iterator n_it = nodes->vec.begin();
1178 n_it != nodes->vec.end(); ++n_it)
1181 TNodeID nodeID =
static_cast<TNodeID
>(n_it->node_id);
1182 std::pair<set<TNodeID>::iterator,
bool> res =
1183 nodeIDs_set.insert(nodeID);
1188 LVL_INFO,
"Just fetched a new nodeID: %lu",
1189 static_cast<unsigned long>(nodeID));
1190 nodeID_to_is_integrated.insert(make_pair(n_it->node_id,
false));
1195 curr_pose =
pose_t(mrpt::ros1bridge::fromROS(n_it->pose));
1199 poses[
static_cast<TNodeID
>(n_it->node_id)] =
pose_t(curr_pose);
1201 has_new_nodes =
true;
1234 template <
class GRAPH_T>
1236 const mrpt_msgs::NodeIDWithLaserScan::ConstPtr& last_regd_id_scan)
1239 using namespace std;
1240 ASSERT_(last_regd_id_scan);
1241 engine.logFmt(LVL_DEBUG,
"In fetchLastRegdIDScan method.");
1246 ros_scans.push_back(*last_regd_id_scan);
1247 has_new_scans =
true;
1252 template <
class GRAPH_T>
1254 std::vector<TNodeID>* nodeIDs ,
1255 std::map<TNodeID, node_props_t>* nodes_params ,
1256 bool only_unused )
const
1259 using namespace mrpt::obs;
1261 using namespace std;
1262 using namespace mrpt::poses;
1265 ASSERT_(nodeIDs || nodes_params);
1268 for (std::set<TNodeID>::const_iterator n_it = nodeIDs_set.begin();
1269 n_it != nodeIDs_set.end(); ++n_it)
1273 if (only_unused && nodeID_to_is_integrated.at(*n_it))
1281 std::pair<TNodeID, node_props_t>
1283 const pose_t* p = &poses.at(*n_it);
1285 params.first = *n_it;
1286 params.second.pose = *p;
1287 CObservation2DRangeScan::Ptr mrpt_scan =
1288 CObservation2DRangeScan::Create();
1289 const sensor_msgs::LaserScan* ros_laser_scan =
1290 this->getLaserScanByNodeID(*n_it);
1297 if (!ros_laser_scan)
1302 mrpt::ros1bridge::fromROS(*ros_laser_scan, CPose3D(*p), *mrpt_scan);
1303 params.second.scan = mrpt_scan;
1306 nodes_params->insert(params);
1320 if (!nodes_params && !this->getLaserScanByNodeID(*n_it))
1325 nodeIDs->push_back(*n_it);
1332 template <
class GRAPH_T>
1335 has_new_nodes =
false;
1336 has_new_scans =
false;
1339 template <
class GRAPH_T>
1345 auto is_not_integrated = [
this](
const std::pair<TNodeID, bool> pair) {
1346 return (pair.second ==
false && getLaserScanByNodeID(pair.first));
1348 int not_integrated_num = count_if(
1349 nodeID_to_is_integrated.begin(), nodeID_to_is_integrated.end(),
1352 return (not_integrated_num >= new_batch_size);
1357 template <
class GRAPH_T>
1358 const sensor_msgs::LaserScan*
1360 const TNodeID nodeID)
const
1365 ASSERT_(nodeIDs_set.find(nodeID) != nodeIDs_set.end());
1367 for (std::vector<mrpt_msgs::NodeIDWithLaserScan>::const_iterator it =
1369 it != ros_scans.end(); ++it)
1371 if (it->node_id == nodeID)
1382 template <
class GRAPH_T>
1384 const std::set<TNodeID>& nodeIDs,
paths_t* opt_paths)
const
1387 using namespace std;
1388 typedef std::set<TNodeID>::const_iterator set_cit;
1393 nodeIDs_set.begin(), nodeIDs_set.end(), nodeIDs.begin(),
1395 "nodeIDs is not a strict subset of the current neighbor's nodes");
1398 for (set_cit cit = nodeIDs.begin(); cit != std::prev(nodeIDs.end()); ++cit)
1400 for (set_cit cit2 = std::next(cit); cit2 != nodeIDs.end(); ++cit2)
1404 double, constraint_t::state_length,
1405 constraint_t::state_length>();
1409 opt_paths->push_back(
path_t(
1415 LVL_DEBUG,
"Filling optimal path for nodes: %lu => %lu: %s",
1416 static_cast<unsigned long>(*cit),
1417 static_cast<unsigned long>(*cit2),
1419 .curr_pose_pdf.getMeanVal()
1427 template <
class GRAPH_T>
1431 using namespace mrpt::poses;
1432 using namespace mrpt;
1434 using namespace std;
1436 gridmap_cached->clear();
1438 std::vector<TNodeID> nodeIDs;
1439 std::map<TNodeID, node_props_t> nodes_params;
1441 this->getCachedNodes(&nodeIDs, &nodes_params,
false);
1444 for (
typename map<TNodeID, node_props_t>::const_iterator it =
1445 nodes_params.begin();
1446 it != nodes_params.end(); ++it)
1448 const CPose3D curr_pose_3d;
1449 auto obs = it->second.scan.get();
1450 gridmap_cached->insertObservation(*obs, curr_pose_3d);
1456 template <
class GRAPH_T>
1457 const mrpt::maps::COccupancyGridMap2D::Ptr&
1463 this->computeGridMap();
1466 return gridmap_cached;
1470 template <
class GRAPH_T>
1472 mrpt::maps::COccupancyGridMap2D::Ptr& map)
const
1479 this->computeGridMap();
1482 map->copyMapContentFrom(*gridmap_cached);
1486 template <
class GRAPH_T>
1489 return has_new_nodes && has_new_scans;
1492 template <
class GRAPH_T>
1494 : conservative_find_initial_tfs_to_neighbors(false),
1495 nodes_integration_batch_size(4),
1496 num_last_regd_nodes(10),
1497 inter_group_node_count_thresh(40),
1498 inter_group_node_count_thresh_minadv(25),
1503 template <
class GRAPH_T>
1508 template <
class GRAPH_T>
1510 const CConfigFileBase& source,
const std::string& section)
1512 MRPT_LOAD_CONFIG_VAR(nodes_integration_batch_size,
int, source, section);
1513 MRPT_LOAD_CONFIG_VAR(num_last_regd_nodes,
int, source, section);
1515 MRPT_LOAD_CONFIG_VAR(
1516 conservative_find_initial_tfs_to_neighbors,
bool, source, section);
1518 !conservative_find_initial_tfs_to_neighbors,
1519 "Conservative behavior is not yet implemented.");
1521 MRPT_LOAD_CONFIG_VAR(inter_group_node_count_thresh,
int, source, section);
1523 if (inter_group_node_count_thresh < inter_group_node_count_thresh_minadv)
1527 "inter_group_node_count_thresh [%d]"
1528 "is set lower than the advised minimum [%d]",
1529 static_cast<int>(inter_group_node_count_thresh),
1530 static_cast<int>(inter_group_node_count_thresh_minadv));
1532 std::this_thread::sleep_for(std::chrono::milliseconds(2000));
1537 template <
class GRAPH_T>
1539 std::ostream& out)
const
1541 LOADABLEOPTS_DUMP_VAR(nodes_integration_batch_size,
int);
1542 LOADABLEOPTS_DUMP_VAR(num_last_regd_nodes,
int);
1543 LOADABLEOPTS_DUMP_VAR(conservative_find_initial_tfs_to_neighbors,
bool);
1544 LOADABLEOPTS_DUMP_VAR(
static_cast<int>(inter_group_node_count_thresh),
int)
1545 LOADABLEOPTS_DUMP_VAR(inter_group_node_count_thresh_minadv,
int)